Puppet notes:


puppet resource ...

Displays information in PDL:

# puppet resource mailalias postmaster
mailalias { 'postmaster':
  ensure    => 'present',
  recipient => ['root'],
  target    => '/etc/aliases',
# puppet resource user root
user { 'root':
  ensure           => 'present',
  comment          => 'root',
  gid              => '0',
  home             => '/root',
  password         => '[[snipped]]',
  password_max_age => '99999',
  password_min_age => '0',
  shell            => '/bin/ksh',
  uid              => '0',
puppet filebucket –local list

Displays files that have been backed up:

# puppet filebucket --local list
0eb429526e5e170cd9ed4f84c24e442b 2016-05-11 22:28:27 /tmp/testfile.txt
f97e55cfcd8d901b00d278d9dacb438b 2016-05-11 22:28:56 /tmp/testfile.txt
3d508c856685853ed8a168a290dd709c 2016-05-11 22:30:28 /tmp/testfile.txt
puppet filebucket –local get ${hash_ref}
Restores a file. You’ll need to have the hash ref available.
puppet filebucket –local restore ${new_file_loc} ${hashref}
Restores a file to a location other than what is defined in the bucketdir.
puppet filebucket –local diff ${hash_ref} ${file}
Displays the difference between the hashref and the file.
puppet apply -e “notice(lookup(‘${yaml_variable}’))”

Looks up the requsted data in the yaml using the hiearchy in place:

# puppet apply -e "notice(lookup('puppet::enabled'))"
Notice: Scope(Class[main]): false
Notice: Compiled catalog for node2.olearycomputers.com in environment production in 0.17 seconds
Notice: Applied catalog in 0.08 seconds
puppet lookup ${yaml}

Same thing as the lookup function but less typing:

# puppet lookup puppet::enabled
--- false
puppet module search ${search_string}
Searches puppet forge for particular modules
puppet module install ${module} –environment ${env}
Installs the module to ${env}’s modules directory along with any prerequisites.
puppet module generate ${module}
Generates the module skeleton in the current directory
puppet agent –test –server=${puppet_server}

Runs puppet agent in the foreground, registering w/the server if necessary:

# puppet agent --test --server=osps.olearycomputers.com
Info: Creating a new SSL key for node1.olearycomputers.com
Info: Caching certificate for ca
Info: csr_attributes file loading from /etc/puppetlabs/puppet/csr_attributes.yaml
Info: Creating a new SSL certificate request for node1.olearycomputers.com
Info: Certificate Request fingerprint (SHA256): F3:F8:AE:70:0F:39:53:5C:2B:2E:25:08:39:40:5F:36:BF:A2:0D:FA:79:44:71:EC:4D:4A:CA:42:11:95:C4:93
Info: Caching certificate for ca
Exiting; no certificate found and waitforcert is disabled

Lessons learned:

  • Puppet ver 4 directories have changed... lots

    • /etc/puppetlabs/puppet: default configuration directory
    • /etc/puppetlabs/code: modules, manifests, and hiera config files.
    • /etc/puppetlabs/mcollective: default mcollective directory
    • /etc/puppetlabs/puppet/ssl: default ssl directory
    • /opt/puppetlabs/bin: Most of the ‘binaries’ are links to elsewhere
    • /opt/puppetlabs/puppet: bin directory containing other things like the local installation of ruby.
    • /opt/puppetlabs/puppet/cache: $vardir:
    • /var/run/puppetlabs: contains pid files only.
  • Can set up a local puppet.conf. More info needed on this one:

    cat ~/.puppetlabs/etc/puppet/puppet.conf
        logdest = console
        confdir = /etc/puppetlabs/puppet
        codedir = /etc/puppetlabs/code
  • Preceding file type resources with absolute paths will limit conflicts:

    • Bad:

      file { 'my_file':
        ensure => present,
        path   => 'my_file.txt',
      file { 'my_file':
        ensure => present,
        path   => 'my_file.csv',
    • Good:

      file { ‘/home/vagrant/my_file.txt’:

      ensure => present, path => ‘my_file.txt’,


      file { ‘/home/vagrant/my_file.csv’:

      ensure => present, path => ‘my_file.csv’,


  • When creating resource definitions for files using puppet resource, remember to remove type (redundant), ctime (read-only), and mtime (read-only) attributes before attempting to apply it.

  • Always set a default value when performing hiera lookups

  • Hyphens are not allowed in module names. When generating a module skeleton, you’ll use mpi-${module}. The skeleton directory will get generated w/o the “mpi-”. The class definition and hiera updates all have to have the module name w/o the “mpi-”. Unfortunately, the errors aren’t straight forward like “You used an invalid module name, numbnut” but more obtuse like:

    Error: Evaluation Error: Error while evaluating a Method call, Could
    not find class ::oci-puppet for node2.olearycomputers.com at
    /etc/puppetlabs/code/environments/test/manifests/site.pp:6:42 on node
  • Learning Ruby, Michael Fitzgerald: Ebook ISBN:978-0-596-15964-1 | ISBN 10:0-596-15964-1

  • Any config options available in the conf.d files will be ignored in puppet.conf. Another warning: a setting left undefined in config files will revert to default value rather than using the values from puppet.conf. Long story short: don’t use puppet.conf for puppet server. puppet commands, though, will use this file so keep the parameters in sync.

Things to do:

  • Configure puppset server to use an alt name - not the hostname.
  • Check out Gerald Carter’s book, LDAP System Administration (O’Reilly)
  • Research r10k: probably don’t need it but when puppet becomes much more complex, might be useful.
  • Check out Jo Rhett Learning MCollective


Restarting puppet training as I will now be bringing it in to MPI. Long, long overdue. As it turns out, puppet’s been busy while I’ve been away. The version I studied was ver 2. They’ve gone completey through version 3 into version 4. Nice.

So, bought another book - this one from O’Reilly’s. I like them and, so far, like the book. Learning Puppet 4: A guide to configuration management and automation.

First couple of chapters were overview - standard stuff.

I’m using node2 for the initial training. I’ve rekicked pm and node1 as well.

Chapter 2:

Preparing a test environment:

  • Mount the learning-puppet4 directory as /vagrant:

    # git clone https://github.com/jorhett/learning-puppet4
    Initialized empty Git repository in /ignite/root/learning-puppet4/.git/
    remote: Counting objects: 234, done.
    remote: Total 234 (delta 0), reused 0 (delta 0), pack-reused 234
    Receiving objects: 100% (234/234), 37.96 KiB, done.
    Resolving deltas: 100% (108/108), done.

Chapter 3: Installing puppet agent

Puppet 4 book is based on rhel7 and ipv6. I’ll have some minor issues converting that to centos6 and ipv4.

Puppet has also taken all the dependency crap that I wrestled with in earlier versions. All of it is in the collection repo - including a guaranteed puppet compatible ruby implementation.

  • Install the puppet collection repo:

    yum -y install \
  • Install puppet-agent:

    # yum install puppet-agent
  • If going to connect to a puppet server, run:

    # puppet resource service puppet ensure=running enable=true
  • To make the puppet resource command permanent:

    # chkconfig puppet on
    # service puppet start

Directory structure has changed quite a bit. Notes on what’s where in the lessons learned section.

Chapter 4: writing manifests:

Manifests are the policies that get applied to nodes. They define how resources should be configured.

Manifest application process:

  1. Builds/compiles the puppet catalog
  2. Uses dependency and ordering information to determine evaluation order
  3. Evaluates the target resource on the node to determine if changes are required.
  4. Creates, modifies, or removes the resourse. A notification resource is created.
  5. Provides verbose feedback about the catalog creation.

Declaring resources::

resource_type { ‘resource_title’:
ensure => present, attribute1 => 1234, attribute2 => ‘value’, attribute3 => [‘red’, ‘blue’], noop => false



cat myfile.pp
file { 'my_file':
  ensure => present,
  path   => 'my_file.txt',

file { 'my_file':
  ensure => present,
  path   => 'my_file.csv',

notify { 'my_file':
  message => 'My file is present',

# puppet apply ./bad_myfile.pp
Error: Evaluation Error: Error while evaluating a Resource Statement, Duplicate declaration: File[my_file] is already declared in file /ignite/root/manifests/bad_myfile.pp:1; cannot redeclare at /ignite/root/manifests/bad_myfile.pp:6 at /ignite/root/manifests/bad_myfile.pp:6:1 on node node2.olearycomputers.com

exec resource:

Executes a script..on the agent:

exec { 'echo-holy-cow':
  path      => ['/bin'],
  cwd       => '/tmp',
  command   => 'echo "holy cow!" > testfile.txt',
  creates   => '/tmp/testfile.txt',
  returns   => [0],
  logoutput => on_failure,


  • The creates attribute defines the expected result. If the output file is already there, it won’t re-execute.
  • Use was an example. Best to avoid if at all possible. Example given states that, at one client, an exec initiated an automatic code review.

file resource:

The proper way to get the previous example:

file { '/tmp/testfile.txt':
  ensure   => present,
  mode     => '0644',
  replace  => true,
  content  => "holy cow!\n",


Note the double quotes since the newline is to be interpreted...

File backups:

Every file that’s changed gets backed up on the client. Where that backup ends up can be a bit confusing. It’ll be either:

  • $clientbucketdir
  • $bucketdir

To rectify the confusion, add the following to the puppet.conf on each of the nodes:

    bucketdir = $clientbucketdir

Chapter 5: Using the puppet configuration language:

Some differences between puppet4 and the versions with which I’m familiar. The rules seem to have been tightened and made more stringent.


Vars can no longer have mixed case - all lower case.

  • Must start with lower case letter or ‘_’
  • May only contain
    • lower case letters
    • numbers
    • underscores
  • Variables can only be defined once per scope. Parser will throw an error if multiple definitions are found.

Arrays and hashes:


$my_num   = [1,2,3,4,5]
$my_names = ['Jayu', 'Eugene', 'Justin', 'Doug']
$mixed    = ['Jayu', 3, true ]

[$first, $middle, $last ] = ['Doug', 'K', 'OLeary']

$homes = {  'dkoleary' => '/home/dkoleary',
            'esmirnov' => '/home/esmirnov',

Pointer syntax required when passing array to a function that requires a list of comma separated values:

myfunction ( *$array ) {...}

Can also splice hashes:

[$Jack] = $homes           # identical to $Jack = $homes['Jack']
[$username,$uid] = $users  # Gets values assigned to keys "username" and "uid"

Interesting use of hashes to define default attributes:

$resource_attributes = {
  ensure    => present,
  owner     => 'root',
  group     => 'root',
  'mode'    => '0644',
  'replace' => true,

file { '/etc/config/first.cfg':
  source => 'first.cfg',
  *      => $resource_attributes,

Arrays can be used as multiple resource titles in definitions:

file { ['/tmp/file1', '/tmp/file2',...]:
    ensure => present,
    owner  => 'root',

A better way to define default values:

file {
    ensure => present,
    owner  => 'root',

  'file1': path => '/tmp/file1',
  'file2': path => '/tmp/file2',

Adding elements to arrays and hashes:

$arr1 = [1,4,7]
$arr2 = $arr1 + [14,17]               # $arr2 now [1,4,7,14,17]

$kp = { name => 'joe', uid = 1001 }
ud = $kp + {gid => 5000}              # hash has name, uid, gid

Removing items from arrays and hashes:

$names = ['jayu','eugene','doug','justin']
$no_j  = $names - 'jayu'
$no_g  = $names - ['doug','justin']
$kp = { name => ‘joe’, uid = 1001, gid => 5000 } $nn = $kp - ‘name’

Puppet heredoc:


$message_text = @(END)
this is a test of the emergency broadcasting system.
This is only a test.
Had this been an actual emergency, you'd be instructed to:

To interpolate vars:

$message_text = @(“END”) ${user}@$facts[‘hostname’] This is a test of the emergency broadcasting system. This is only a test. Had this been an actual emergency, you’d be instructed to: KISS YOUR ASS GOODBYE! END

Curly braces:

Curly braces should be used - but only when variables are being interpolated - not when they’re used in manifests:

$filename = "/tmp/${user}s_testies"  # use braces
file { $filename:                    # dont use braces
  ensure => present,


Additional facts supplied by puppet:

    Client's certname config value

    Client's version of puppet

    Whether or not noop was enabled to perform comparison without actually
    making changes.

    The environment requested by the client which can be overridden at the
    server level.  If this parameter is blank, *production* is used.

When referring to facts, always use the hash to avoid confusion. New to puppet4:


Logging levels:

  • debug( ‘debug message goes here’)
  • info (‘info message goes here’)
  • notice(‘the old tried and true’)
  • warning(‘warning message goes here’)
  • err(‘you fucked up, mate’)


  • Standard if/then/elsif/else - else new to puppet4.

  • Case statements: remember to always include a default:

    case $what_drank {
      'wine':             { include state::california }
      $stumptown:         { include state::portland }
      /(scotch|whiskey)/: { include state::scotland }
      is_tea($drink):     { include state::england }
      default:            {}
  • Selectors - more options than just a trinary:

    $native_of = $what_drank ? {
      'wine'             => 'california',
      $stumptown         => 'portland',
      /(scotch|whiskey)/ => 'scotland',
      is_tea($drink)     => 'england',
      default            => 'unknown',


Described as a function without a name. It’s a block of code that allows parameters to be passed in. New in puppet 4, not available in any previous version.


| $val1, $val2 | {
  block of code goes here

# cat mountpoints.pp
each ($facts['partitions']) | $name, $device| {
  notice("${facts['hostname']} has device ${name} with size ${device['size']}")


Definitely one of those advanced things I’m going to have to do some more reading on. I’m able to follow them but for the sake of KISS; probably won’t be using them at MPI for a good while.

Chapter 6: Controlling resource processing:


Basically, assigning namevar specifically so we don’t have to refer to a file resource as ‘/tmp/testfile.txt’. The two file resources are syntactically equivalent; however, the latter will be easier to reference in other manifests:

file { '/tmp/testfile.txt':
  ensure   => present,
  content  => 'your mother was a hamster and your father stunk of elderberries',
  mode     => '0644',
  owner    => '0',

file { 'testfile':
  ensure   => present,
  path     => '/tmp/testfile.txt',
  content  => 'your mother was a hamster and your father stunk of elderberries',
  mode     => '0644',
  owner    => '0',

noop: can add a noop attribute to prevent the manifest from being evaluated.

Audit parameter could be useful...

Long winded section on schedules. I don’t see us using those initially; but, further down the road: ‘run this apply only during approved change windows’... I can see that pretty easily.

Chapter 7: Expressing relationships:

Obviously, one should explicitly define dependencies rather than relying on automatic ordering. One way to verify all dependencies have been defined:

$ puppet apply --ordering=random ${manifest}

The random ordering of the manifest run will show if there are any undefined dependencies.

Troubleshooting dependency loops:

When puppet alerts to a dependency loop, one can use the graphing feature to help find it. Simple code won’t need this; however, when involving multiple teams/manifests, etc, this will almost assuredly end up being a problem:

# puppet apply ./depcycle.pp --graph
Notice: Compiled catalog for node2.olearycomputers.com in environment production in 0.12 seconds
Error: Failed to apply catalog: Found 1 dependency cycle:
(Cron[check-exists] => File[/tmp/file-exists.txt] => Cron[check-exists])
Cycle graph written to /opt/puppetlabs/puppet/cache/state/graphs/cycles.dot.

Copy/paste output of ‘.dot’ file to http://www.webgraphviz.com/

Chapter 8: upgrading puppet 3 manifests:

Not using puppet yet (thanks engineering) so just skimming this chapter.

So much for skimming...

Upgrading config environments:

In puppet 2.X, config environments were defined in puppet.conf. Upgrade process for puppet 4 is:

  1. mkdir -p -m 755 /etc/puppetlabs/code/enviroments/production
  2. Add environment = /etc/puppetlabs/code/environments to [main] section of puppet.conf
  3. Create a directory for each environment in the preceding path.
  4. Mode module path settings from old puppet.conf to environment.conf in each environment’s directory.
  5. Copy manifests used by each environment to the manifests/ subdirectory of each environment
  6. Move modules use by specific environments to modules/ subidrectory of each environment.
  7. Move modules used by all environments to ${confdir}/modules subdirectory

Chapter 9: wrap up of puppet basics:

Read/review/retain, and use the puppet style guide.

Chapter 10: Creating a test environment:

Puppet 4 (and probably 3) take environments to a level not seen in ver 2.

Short version:

  • mkdir -p -m 755 /etc/puppetlabs/code/environments/${env}/{hierdata,modules,manifests}
  • Copy/Create /etc/puppetlabs/codes/environments/${env}/environment.conf if desired.
  • Base modules - or well tested, well verified modules go into /etc/puppetlabs/code/modules

Chapter 11: Separating data from code (hiera)

Going to be lots of notes in this chapter...


So, short version: hiera is a way of organizing the configuration data into a hierarchy. Examples will help clarify:

  • Small company:
    • Company wide common data (password expiration, for example)
    • Operating system specific changes
    • Site specific information.
  • Global company - or one that is much larger, for instance:
    • Enterprise level common data
    • Company specifics
    • Division overrides
    • production/staging/QA/dev
    • Region (us/eu, asia, etc)
    • OS specific configs
    • Cluster specific configs
    • Application specific configs

Files should end in *.yaml - for yaml backend which appears to be the most common.

Backends and data types:

JSON or yaml

  • String
  • number
  • Boolean
  • Array
  • Hash

yaml uses spacing as method of differntiating data categories; json uses braces. yaml seesm to be more common and would definitely be less typing.

Examples of the data type into one main monster hash:

puppet:                # hash
  ensure: 'present'    #  string
  version: '4.4.0'
  agent:               # hash
    running: 'running' # string
    atboot: true       # boolean
  components:          # array
    - 'facter'
    - 'puppet'

  "puppet": {
    "ensure": "present",
    "version":  "4.4.0",
    "agent": {
      "running":  "running",
      "atboot": true
    "components": [

Configuring hiera:

Default config file is ${codedir}/hiera.yaml. It’s a standard yaml hash with global settings

The backend to use. json and yaml are understood by default. you can use others but that is beyond the scope of the book.
backend configuration:

Each backend type given in backends should have a section. The only required parameter is datadir andit defaults to ${codedir}/environments/%{::environment}/hieradata Using the default as an example:

  - yaml
  - "nodes/%{::trusted.certname}"
  - common

Last required entry. This one delineates the priority order that should be used to evaluate data. Most specific at the top. Author suggests the following for a starting point:

  1. Default values in common.yaml
  2. All OS specific info in a file named for the OS family eg: RedHat.yaml
  3. Node-specific info in a file based on fqdn.

To implement:

  - "fqdn/%{facts.fqdn}"
  - "os/%{facts.osfamily}"
  - common

The complete example provided in the book shares hiera data across all environments. The note in the book says:

When the environments are distinct only to test code, use a shared
hiera path for ease of data management.

Use lookup function as part of a puppet apply command to lookup and/or verify hiera data:

# puppet apply -e "notice(lookup('puppet::enabled'))"
Notice: Scope(Class[main]): false
Notice: Compiled catalog for node2.olearycomputers.com in environment production in 0.17 seconds
Notice: Applied catalog in 0.08 seconds

Chapter 12: Using modules:

Module sources:

  • puppet forge
  • github
  • internal repositories

Forge modules to install:

Prereq for a lot of other forge modules.

Items to check:

  • OS support
  • module namespace
  • Environment assumptions
  • Sloppy code
  • Resource namespace
  • Greedy collectors

Chapter 13: Designing a custom module:

Note about naming modules: avoid names that are available on puppet forge as some asshat will download it and cause a naming collision.

Generate a module skeleton:

$ puppet module generate ${module}

That will generate the directory structure and required files for a module.


Classes are a subset of manifests. What makes a class different than a manifest?

  • A class is a manifest that can be called by name.
  • A class has a namespace scope of the same name.
  • A class is not used until called by name.
  • A class may include or be included by other modules
  • A class may be passed parameters when called.


Contains a documentation skeleton (discussed later) and an empty class. The module name is the same as the class name. Remember (ll entry above) module names cannot contain hyphens.

Directory syncing:

Author suggest that puppet is not well suited for synching large files or directories - even defining ‘large’ as anything over 100meg.


Templates are going to take some work. puppet 4 comes with epp templates which the author says are better than the erp templates. First one uses any valid puppet code; second uses ruby.

I can see where those will come in handy; hwoever, the syntax is strange. Going to have to take those slow and steady.

Chapter 14: Improving the modules:

Chapter starts out in a long dissertation on parameter validation. I have a hard time seeing where this will be useful at MPI so I’m skimming the section.

NOTE: Any time you would need an if/then block in a module to handle different needs for different nodes, use subclasses instead.

Interesting notes on how to handle things like ntp.server vs ntp.client...

Chapter 15: Extending modules with plugins:

Thought this chapter was going to be about extending facter; turns out, you can add ‘facts’ to modules specifcally through a ${sub}/facts.d directory. Thse facts will get distributed to the client nodes.

Yea; skimmed that chapter. Can’t see us hitting that for a very long time.

Chapter 16: Documenting modules:

This one’ll be important.

puppet4 uses markdown - very similar to rst. I’ll have to get used to that as well. I’ll need to hack a few docs to see what that looks like; generally, it gives the ability to create module docs in the dosc subdir for each module.

There is a changelog.md which we’ll have to keep track of.

Chapter 17: testing modules:

We’ll be starting out very simple so this should be a matter for later. However, I’m going to read the chapter anyway.

Per the author:

Set up testing tools:

  • Install dependencies:
    • ruby
    • install bundler gem for local installation of dependencies

wow; seems very complicated... I’m thinking we just do code reviews and ensure the modules are tested on a select set of hosts first.

Chapter 18: publishing modules:

Also not likely to happen but significantly easier than the testing chapter. Sweet Jayzus.

Chapter 19: Preparing for puppet server:

Puppet Server is ‘fast new’ server... faster and easier, one hopes, than the puppet master. I believe this chapter is the overview of the server.

Planning for puppet server:

  1. The server is not the node. Select a unique name for the puppet server - a name that is not the hostname of the system on which the server will be running. (relocatable). The server name will be identified in /etc/puppetlabs/puppet/puppet.conf:

        server = puppet.example.com
        certname = puppet.example.com
  2. The node is not the server. Don’t put certname in the main section. This sets up a conflict for when the server is migrated and the node has to recertify.

  3. Store server data file separately. Configure server to place all volatile files within the /var filesystem:

        vardir = /var/opt/puppetlabs/server
        ssldir = $vardir/ssl
        vardir = /var/opt/puppetlabs/server
        ssldir = $vardir/ssl
  4. Functions run as a result of catalog building are on the server. This has 3 concerns:

    • log messages will be on the server, not on the client node.
    • Data used by the catalog must be on the server or available via facts
    • The only method to provide local node data to the server is facts.

Choice of puppet master vs puppet server really isn’t a choice:

Puppet master has been deprecated and will not exist in puppet 5

Chapter 20: Creating a puppet master - skipping

Chapter 21: creating a puppet server:

  1. Install the latest puppetlabs collection repo:

    yum install http://yum.puppetlabs.com/puppetlabs-release-pc1-el-6.noarch.rpm
  2. Install the puppet server:

    yum install puppetserver
  3. Update firewall as needed:

    # iptables -I INPUT 5 -p tcp --dport 8140 -j ACCEPT
    # show input
    Chain INPUT (policy ACCEPT)
    num  target     prot opt source               destination
    1    ACCEPT     all  --             state RELATED,ESTABLISHED
    2    ACCEPT     icmp --  
    3    ACCEPT     all  --  
    4    ACCEPT     tcp  --             state NEW tcp dpt:22
    5    ACCEPT     tcp  --             tcp dpt:8140
    6    REJECT     all  --             reject-with icmp-host-prohibited
  4. Configure the puppet server:

    • Config files:
      • Primary config file at /etc/puppetlabs/puppetserver/conf.d
      • Historic config file at /etc/puppetlabs/puppet/puppet.conf
    • Any config options available in the conf.d files will be ignored in puppet.conf. Another warning: a setting left undefined in config files will revert to default value rather than using the values from puppet.conf. Long story short: don’t use puppet.conf for puppet server. puppet commands, though, will use this file so keep the parameters in sync. Options to keep in sync:
puppet.server puppet.conf Default
master-conf-dir confdir /etc/puppetlabs/puppet
master-code-dir codedir /etc/puppetlabs/code
master-var-dir vardir /opt/puppetlabs/server/data/puppetserver
master-run-dir rundir /var/run/puppetlabs/puppetserver
master-log-dir logdir /var/log/puppetlabs/puppetserver
  • Update puppet.conf to put volatile files under /var in puppet.conf and puppetserver.conf. Update ownership and perms:

    # /etc/puppetlabs/puppet/puppet.conf
      vardir = /var/opt/puppetlabs/puppetserver
      sslrid = $vardir/ssl
      vardir = /var/opt/puppetlabs/puppetserver
      sslrid = $vardir/ssl
    # /etc/puppetlabs/puppetserver/conf.d/puppetserver.conf
    # (optional) path to puppet conf dir; if not specified, will use
    # /etc/puppetlabs/puppet
    master-conf-dir: /var/opt/puppetlabs/puppetserver
    # mkdir -p -m 755 /var/opt/puppetlabs/puppetserver && \
        chown puppet:puppet /var/opt/puppetlabs/puppetserver
  • Update memory usage in /etc/sysconfig/puppetserver. In test system, decrease to 512m. In production env, increase... How much? when? how to tell?

  • Update TLS cert info, if desired in /etc/puppetlabs/puppetserver/conf.d/webserver.conf. Book suggests not doing this as CA info is still in puppet.conf

ssl-cert     = /var/opt/puppetlabs/puppetserver/ssl/certs/osps.olearycomputers.com.pem
ssl-key      = /var/opt/puppetlabs/puppetserver/ssl/private_keys/osps.olearycomputers.com.pem
ssl-ca-cert  = /var/opt/puppetlabs/puppetserver/ssl/certs/ca.pem
ssl-crl-cert = /var/opt/puppetlabs/puppetserver/ssl/certs/crl.pem

*   Update logging if so desired.  Option to send logs to syslog.
*   Update authorization as needed.  Book quite literally says::

        If you are new to puppet, skip ahead to running puppet server
        and come back later.

Configuration files:

Authentication and authorization controls for puppet server and the CA.
Global config files. Mostly reserved for future use. Currently only contains the location fo the logback config file.
Config options for puppet server. Some options overlap with puppet.conf. These must be kept in sync or different behavior for puppet server and puppet agent will result.
web server config: authorization, tcp ports, etc.
Service mount points - managed by puppet server package

Chapter 22: connecting a node:

  • Install puppet agent, if necessary

  • Ensure puppet is configured to run:

    • puppet resource service puppet ensure=running enable=true
    • chkconfig puppet on && service puppet start
  • Run puppet agent in the foreground to register w/the puppet server:

    # puppet agent --test --server=osps.olearycomputers.com
    Info: Creating a new SSL key for node1.olearycomputers.com
    Info: Caching certificate for ca
    Info: csr_attributes file loading from /etc/puppetlabs/puppet/csr_attributes.yaml
    Info: Creating a new SSL certificate request for node1.olearycomputers.com
    Info: Certificate Request fingerprint (SHA256): F3:F8:AE:70:0F:39:53:5C:2B:2E:25:08:39:40:5F:36:BF:A2:0D:FA:79:44:71:EC:4D:4A:CA:42:11:95:C4:93
    Info: Caching certificate for ca
    Exiting; no certificate found and waitforcert is disabled
  • On the puppet server, sign the new certficate:

    # puppet cert sign dumper.olearycomputers.com
  • Load up modules and start running...

Chapter 23: migrating from an old puppet master - skipped

Chapter 24: Utilizing advantages of puppet server:

  • Trusted facts: Short version is that, when a node connects to the puppet server, it presents a list of facts. Those facts are not and cannot be validated. Trusted facts are ones that the server knows for a fact:
    • $trusted[‘hostname’]/$trusted[‘domain’]
    • $trusted[‘certname’]
    • $trusted[‘authenticated’] = (remote|local|false)
  • List of trusted facts:
    • Trusted facts
    • Server facts
    • custom facter facts added to a puppet module.

Chapter 25: TLS

  • Autosigning:
    • Can be done by name... not very good.
    • Can be done by policy. In short, an executable that figures out whether or not to sign the request.
      • Script receives $certname as sole cli
      • Must return 0 to sign or non-zero to reject.
      • I’m thinking a query to mysql cmdb...

Chapter 26: Growing your puppet env

  • Node terminus: basically an ENC
    • Book suggests using an enc only when we cannot provide the data using puppet lookup. Will have to play with this one a bit...
    • LDAP: You just know this is where Sue’s going with this.
  • Community examples:
    • ilikejam/hiera-enc (github)
    • awesomescot/mysql-enc (github)