Differences Between ‘Puppet Apply’ and ‘Puppet Agent’ to Puppetmaster

puppetpuppetmaster

We're in the process of migrating away from a monolithic puppet repository that contains all of the config. This one repo contains things that really shouldn't be on every node ever, so a puppetmaster-based system seems the best way to appropriately segregate things.

The problem I'm having is that the same repo works just fine when copied to the local nodes and puppet apply /etc/puppet/manifests/site.pp run on it. Our installs run very cleanly.

When I put the puppet repo on the puppetmaster and get the agent signed, it doesn't appear to do anything other than report it's local catalog to the puppetmaster.

For a while there, and I haven't been able to reproduce the config that did this, one of our self-built modules was throwing an error that suggested it was attempting to copy a file from the local machine's modules directory, rather than the puppetmaster like it should.

Which suggests that there may be module and manifest syntax differences when building a repo for local use and via puppetmaster.

If there are any differences, what are they, or what are the main tripping points for conversion efforts?


The /etc/puppet/puppet.conf file on the master:

[main]
logdir=/var/log/puppet
vardir=/var/lib/puppet
ssldir=/var/lib/puppet/ssl
rundir=/var/run/puppet
factpath=$vardir/lib/facter
pluginsync=true

# Set up Environments
## Each environment has a dedicated 'modules' directory under /environments/ from
## which puppet will preferentially pull. Otherwise, it'll use the top level  
## 'modules' directory. That is where common code goes.
[master]
  manifest=$confdir/manifests/site.pp
  modulepath=$confdir/environments/$environment/modules:$confdir/modules
  ssl_client_header= SSL_CLIENT_S_DN
  ssl_client_verify_header = SSL_CLIENT_VERIFY
[production]
  manifest=$confdir/manifests/site_prod.pp
[integration]
  manifest=$confdir/manifests/site_integ.pp
[development]
  manifest=$confdir/manifests/site_dev.pp
[operations]
  manifest=$confdir/manifests/site_ops.pp

At the moment, the site_prod.pp file and ilk are symlinks to site.pp.

The classes defined in the site.pp file work off of the hostname. As I mentioned, when run via puppet apply things work just fine. If worse comes to worst I can do what I need by way of a temporary NFS mount but I'd rather not do that.


site.pp For your enjoyment:

filebucket { "main": server => $server; }
File { backup => "main" }

Exec { path => "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" }

import "stages.pp"
import "int_setup.pp"
import "nodes.pp"

The imported .pp files are in the same directory as site.pp. nodes.pp is where the meat is, but also contains secret-sauce. Some excerpts:

node /clunod\-wk\d+\.sub\.example\.local/ {

  class { "int_setup": stage => "setup"; }
  include base
  include curl
  include custommodule
  [...]
}

Which can and does match nodes named clunod-wk01234.sub.example.local when run via puppet apply.

[int-setup.pp]

class int_setup {
  file { "/var/cluebat":
    ensure => directory,
    mode => "755",
    owner => "root",
    group => "root";
  }

  group{"puppet":
    ensure => present
  }

}

Best Answer

The only trickiness that I'm aware of is in the file resource type.

Backup for replaced files behaves differently, using the server's filebucket by default instead of the local filebucket.

The more significant thing to be aware of is the source parameter.


source => '/tmp/somepath/sshd_config',

With a raw file path, it'll always try the local path.


source => 'puppet://puppetmaster1/modules/sshd/sshd_config',

With a puppet://server/ path, it'll always try the remote path.


source => 'puppet:///modules/sshd/sshd_config',

With an empty server specification, then it gets interesting.

Applied locally, the local puppet module path is used to find the file.

When reporting to a puppetmaster, the server that gave it the manifest is treated as the server.


Additionally, if you need to get creative about the source of a file, you can give the source parameter a list:

source => [ '/tmp/somepath/sshd_config', 'puppet:///modules/sshd/sshd_config'],

The first location where something's found will be used.