Puppet is an open-source configuration management tool that helps automate the deployment and management of files and applications on target hosts. A puppet master contains the definition of the desired configurations in files called manifests or modules. Agents can query the master in order to know which configuration changes to apply.

Screen Shot 2016-06-02 at 19.16.55.pngpuppet labs logo from Puppet Keynote by Luke Kanies

 

 

In this post, I will cover the installation of the puppet master and puppet agent, along with a simple example manifest. I intend to fully puppetize my project, delivering a set of manifests and modules, making it possible to recreate it from scratch, with minimal effort.

 

Let's get puppetizing!

 

Preparation

 

For this guide, I am using a Raspberry Pi 3 running the latest version of Raspbian Jessie.

 

After connecting via SSH (via ethernet or wifi), the file system was expanded using "raspi-config":

Screen Shot 2016-05-29 at 14.29.35.png

 

Using the same application, the hostname was changed to "puppet":

Screen Shot 2016-05-29 at 14.29.58.pngScreen Shot 2016-05-29 at 14.30.07.png

 

Finally, the software has been fully updated:

 

pi@puppet:~ $ sudo apt-get update && sudo apt-get upgrade -y

 

With that taken care of, we can proceed to the actual installation.

 

Puppet Master

 

The puppet master holds the definition of every node by means of reusable modules. A node is then defined by a specific combination of modules, in order to obtain a specific role.

 

Screen Shot 2016-06-02 at 19.14.57.pngLifecycle of a Puppet Run from Puppet Keynote by Luke Kanies

 

 

 

Installation & Configuration

 

Installing puppet master is straightforward and can be done using the following command:

 

pi@puppet:~ $ sudo apt-get install puppetmaster-passenger

Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
apache2 apache2-bin apache2-data apache2-utils augeas-lenses facter hiera libapache2-mod-passenger libapr1 libaprutil1 libaprutil1-dbd-sqlite3 libaprutil1-ldap libaugeas0 libev4 libjsoncpp0 liblua5.1-0 libpci3 pciutils puppet-common puppetmaster-common
ruby-activemodel ruby-activerecord ruby-activerecord-deprecated-finders ruby-activesupport ruby-arel ruby-atomic ruby-augeas ruby-blankslate ruby-builder ruby-hiera ruby-i18n ruby-json ruby-minitest ruby-passenger ruby-rack ruby-rgen ruby-safe-yaml ruby-selinux
ruby-shadow ruby-thread-safe ruby-tzinfo ssl-cert virt-what
Suggested packages:
apache2-doc apache2-suexec-pristine apache2-suexec-custom augeas-doc mcollective-common augeas-tools ruby-rrd librrd-ruby puppet-el ruby-ldap ruby-stomp stompserver vim-puppet ruby-builder-doc rails ruby-passenger-doc openssl-blacklist
The following NEW packages will be installed:
apache2 apache2-bin apache2-data apache2-utils augeas-lenses facter hiera libapache2-mod-passenger libapr1 libaprutil1 libaprutil1-dbd-sqlite3 libaprutil1-ldap libaugeas0 libev4 libjsoncpp0 liblua5.1-0 libpci3 pciutils puppet-common puppetmaster-common
puppetmaster-passenger ruby-activemodel ruby-activerecord ruby-activerecord-deprecated-finders ruby-activesupport ruby-arel ruby-atomic ruby-augeas ruby-blankslate ruby-builder ruby-hiera ruby-i18n ruby-json ruby-minitest ruby-passenger ruby-rack ruby-rgen
ruby-safe-yaml ruby-selinux ruby-shadow ruby-thread-safe ruby-tzinfo ssl-cert virt-what
0 upgraded, 44 newly installed, 0 to remove and 0 not upgraded.
Need to get 5,905 kB of archives.
After this operation, 23.8 MB of additional disk space will be used.
Do you want to continue? [Y/n]

 

It will install the necessary dependencies.

 

Once installed, you should be able to query puppet to verify the installed certificates:

 

pi@puppet:~ $ sudo puppet cert --list --all

+ "puppet.home" (SHA256) 03:2D:C0:4A:33:FC:C7:A0:3B:45:A0:41:DC:B6:B4:97:3B:B3:32:39:67:3B:F5:69:17:C4:B9:46:50:EE:D7:99 (alt names: "DNS:puppet", "DNS:puppet.home")

 

When new agents will attempt to perform a puppet run, a certificate will be generated on the master. Only when it is signed by the master, will the agent be able to successfully perform the puppet run.

 

To start or stop the puppet master, simply call the apache2 service:

 

pi@puppet:~ $ sudo service apache2 status|start|stop|restart

 

Manifests & Modules

 

In puppet, manifests describe the configuration actions to be performed. This can be as simple as ensuring a certain file with specific content is present (or absent), but also more advanced like automatically installing and configuring a certain application.

 

To test the installation of the puppet master, a simple manifest can be used.

 

pi@puppet:~ $ sudo nano /etc/puppet/manifests/site.pp

file { '/tmp/testfile':
ensure => present,
mode => '0444',
content => 'test content',
}

 

This manifest will ensure the file "testfile" is present in the "/tmp" folder, with read permission containing the text "test content". If the file doesn't exist, or the permissions or content are not as expected, puppet will correct it accordingly.

 

This example showcases a standalone manifest. Manifests can be combined with files and templates into a module. The purpose of a module is to complete a set of related actions, such as installing an application and configuring it for example.

 

Let's install the agent and test out this simple manifest.

 

Puppet Agent

 

Puppet agent's role is to retrieve the local machine's configuration by contacting the puppet master, retrieve the configuration and apply it.

 

For this purpose, I used a second Raspberry Pi. I used the same preparation steps, except I gave it a different hostname: "piiot1".

 

Installation

 

Installing and activating the agent is as easy as installing the master:

 

pi@piiot1:~ $ sudo apt-get install puppet

Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages were automatically installed and are no longer required:
  libxfce4ui-1-0 xfce-keyboard-shortcuts
Use 'apt-get autoremove' to remove them.
The following extra packages will be installed:
  augeas-lenses facter hiera javascript-common libaugeas0 libjs-jquery libpci3 libruby2.0 libruby2.1 libyaml-0-2 pciutils puppet-common ruby ruby-augeas ruby-hiera ruby-json ruby-rgen ruby-safe-yaml ruby-selinux ruby-shadow ruby2.0 ruby2.1 rubygems-integration
  virt-what
Suggested packages:
  augeas-doc mcollective-common apache2 lighttpd httpd augeas-tools puppet-el vim-puppet etckeeper ruby-rrd librrd-ruby ri ruby-dev bundler
The following NEW packages will be installed:
  augeas-lenses facter hiera javascript-common libaugeas0 libjs-jquery libpci3 libruby2.0 libruby2.1 libyaml-0-2 pciutils puppet puppet-common ruby ruby-augeas ruby-hiera ruby-json ruby-rgen ruby-safe-yaml ruby-selinux ruby-shadow ruby2.0 ruby2.1 rubygems-integration
  virt-what
0 upgraded, 25 newly installed, 0 to remove and 10 not upgraded.
Need to get 8,866 kB/8,876 kB of archives.
After this operation, 36.1 MB of additional disk space will be used.
Do you want to continue? [Y/n]

 

Once the agent is installed, an initial "puppet run" is required to generate the certificate on the master:

 

pi@piiot1:~ $ sudo puppet agent -t

Info: Creating a new SSL key for piiot1.home
Info: csr_attributes file loading from /etc/puppet/csr_attributes.yaml
Info: Creating a new SSL certificate request for piiot1.home
Info: Certificate Request fingerprint (SHA256): D2:C5:40:64:A0:B9:C2:90:A0:19:EE:BF:24:3F:87:95:3E:33:38:26:48:07:1B:6B:A7:BD:10:73:D3:F7:75:F7
Exiting; no certificate found and waitforcert is disabled

 

On the puppet master, it is possible to list the certificates. The certificate for node "piiot1" is not signed yet, preventing the actual execution of the manifest.

 

pi@puppet:~ $ sudo puppet cert --list --all

"piiot1.home" (SHA256) D2:C5:40:64:A0:B9:C2:90:A0:19:EE:BF:24:3F:87:95:3E:33:38:26:48:07:1B:6B:A7:BD:10:73:D3:F7:75:F7
+ "puppet.home" (SHA256) 03:2D:C0:4A:33:FC:C7:A0:3B:45:A0:41:DC:B6:B4:97:3B:B3:32:39:67:3B:F5:69:17:C4:B9:46:50:EE:D7:99 (alt names: "DNS:puppet", "DNS:puppet.home")

 

On the same master, the certificate can be signed, as the node is known to be part of our setup.

 

pi@puppet:~ $ sudo puppet cert sign piiot1.home

Notice: Signed certificate request for piiot1.home
Notice: Removing file Puppet::SSL::CertificateRequest piiot1.home at '/var/lib/puppet/ssl/ca/requests/piiot1.home.pem'

 

A "+" sign is added in front of the certificate, indicating it is signed.

 

pi@puppet:~ $ sudo puppet cert --list --all

+ "piiot1.home" (SHA256) 23:44:D3:B6:70:68:77:F9:9E:A7:EB:72:09:E9:F1:67:FA:24:53:47:99:BB:D9:2F:74:A1:CC:3E:50:76:55:01
+ "puppet.home" (SHA256) 03:2D:C0:4A:33:FC:C7:A0:3B:45:A0:41:DC:B6:B4:97:3B:B3:32:39:67:3B:F5:69:17:C4:B9:46:50:EE:D7:99 (alt names: "DNS:puppet", "DNS:puppet.home")

 

With the certificate signed, it is now possible to perform a puppet run and execute the actions defined in the manifest.

 

Puppet Run

 

Repeating the same command to perform the puppet run, now results in the execution of the manifest defined on the master:

 

pi@piiot1:~ $ sudo puppet agent -t

Info: Caching certificate for piiot1.home
Info: Caching certificate_revocation_list for ca
Info: Caching certificate for piiot1.home
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Caching catalog for piiot1.home
Info: Applying configuration version '1464532909'
Notice: /Stage[main]/Main/File[/tmp/testfile]/ensure: created
Notice: Finished catalog run in 0.10 seconds

 

The test file has been created, has the required permissions and content:

 

pi@piiot1:~ $ ls -l /tmp/testfile

-r--r--r-- 1 root root 12 May 29 16:41 /tmp/testfile

 

pi@piiot1:~ $ cat /tmp/testfile

test content

 

Conclusion

 

Success! Puppet master and agent have successfully been deployed. We can now continue by defining more elaborate manifests and modules which will help us simplify future deployments.

 

It may be hard to grasp or see the advantages of setting up puppet based on this example, but instead of deploying a simple file, imagine this "puppet run" installing and configuring a set applications. Sounds rather neat, right? That's what you can expect for next post!

 

 


arrow_prev.png

 


Navigate to the next or previous post using the arrows.

arrow_next.png