nav search
Data Center Software Security Transformation DevOps Business Personal Tech Science Emergent Tech Bootnotes BOFH

Getting a grip on Puppet: A guide for beginners

We're not just stringing you along...

By Kat McIvor, 9 Feb 2016

QA's Kat McIvor will be taking to the stage at Continuous Lifecycle London to talk about automating security. But her skills don't end there. If config management's your thing, here's Kat's take on getting started with Puppet.

Puppet is another configuration management tool available as part of the DevOps toolbox. It uses a master / node setup to ensure that the correct set of files, programs and configuration is present on each of the nodes it looks after. This may not be so useful in a single machine system, or even when you only have a handful of servers to look after. But as the number of servers we need to look after increases, having a single Puppet master controlling what happens on each of the nodes is much more handy.

Puppet comes in two flavours. Enterprise or Open Source. Enterprise systems have access to the web front end for the Puppet master and an automated build tool which will configure everything for you. They also get access to other features that may not be available to the open source users. However, you will need to pay to control more than ten nodes with the Enterprise edition.

Open Source Puppet is a collection of different services as well as the core Puppet master. You can chose whether or not you want to include services based on your needs, rather than have everything included at once.

Setting up the Puppet master

There are two modes the enterprise Puppet master can use: monolithic or split. A monolithic system will be able to handle up to 500 nodes. For anything larger you'll want to look at using a split installation, moving the database, console and Puppet master to different machines.

To install the open source Puppet system all the configuration must be handled manually, starting with setting up the repositories for Puppet and ending with configuring the certificates for the machine.

As with most configuration management tools, the Puppet master requires a *nix server, but it can handle nodes of any operating system. We will be using Ubuntu 14.04, the open source Puppet community edition and Puppet 4.2 for these examples.

Step 1: Enable the Puppet repositories

wget https://apt.puppetlabs.com/puppetlabs-release-pc1-trusty.deb

sudo dpkg -i puppetlabs-release-pc1-trusty.deb

sudo apt-get update

Step 2: Install the Puppet server and start it with:

sudo apt-get install -y puppetserver

sudo service puppetserver start

All the configuration files will be present in the /etc/puppetlabs/puppetserver directory. These can be used to control and change the server settings.

Creating the Puppet agent

The Puppet agent will check in with the master every 30 minutes (by default) on port 8140 and request its current config catalogue. To install the agent we need to do similar steps to installing the Puppet master. Again, this is assuming Ubuntu 14.04

Step 1: Enable the repositories

wget https://apt.puppetlabs.com/puppetlabs-release-pc1-trusty.deb

sudo dpkg -i puppetlabs-release-pc1-trusty.deb

sudo apt-get update

Step 2: Install the agent

sudo apt-get install puppet-agent

Step 3: Update your hosts file

The agent will need to know where to find the Puppet master, we can achieve this by changing the hosts file to point at the current Puppet master with the name 'puppet'. You should change the IP address to be your Puppet master's IP! echo '52.30.70.51 puppet' >> /etc/hosts

Step 4: Start the Puppet agent

The Puppet agent will attempt to talk to the Puppet master and request a certificate. To start the agent use the following line:

sudo /opt/puppetlabs/bin/puppet agent --test

It should come up with an output saying something like:

root@ip-172-31-29-110:~# sudo /opt/puppetlabs/bin/puppet agent --test

Info: Creating a new SSL key for ip-172-31-29-110.eu-west-1.compute.internal

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 ip-172-31-29-110.eu-west-1.compute.internal

Info: Certificate Request fingerprint (SHA256):

EC:92:6E:2E:58:E2:15:4E:3D:0D:6D:D8:EC:E4:54:67:E5:9B:89:AD:68:5B:A7:9F:E8:​48​:EC:0E:5F:B0:B5:5E/

Info: Caching certificate for ca

Exiting; no certificate found and waitforcert is disabled

(Yes, I'm in aws, don't you love the cloud?)

You can create a symbolic link between the Puppet executable and /usr/bin if you want to call Puppet directly.

sudo ln -s /opt/puppetlabs/bin/puppet /usr/bin/puppet

The check in interval can be changed on the Puppet agent with:

puppet config set runinterval xxx

The time given is in seconds, so the default is 1800. You can see the currently configured time with:

puppet agent --configprint runinterval

Connecting the two - accepting certificates

So the Puppet master has been set up and is waiting for nodes, the agent has requested a certificate. The next step is to accept the certificate on the master. This can be automated, but it isn't recommended. If you trust your firewall rules, then you can configure the Puppet master to only accept traffic on port 8140 from known machines (for example, an IP range) and then auto sign everything. But it's not considered secure. To manually accept a certificate we need to look at the Puppet master again. Run:

sudo /opt/puppetlabs/bin/puppet cert list

to see any outstanding certificate requests.

To sign a certificate:

sudo /opt/puppetlabs/bin/puppet cert sign [[nameofcertificate]]

The output should look something like this:

root@ip-172-31-36-134:/etc/puppetlabs# sudo /opt/puppetlabs/bin/puppet cert list "ip-172-31-29-110.eu-west-1.compute.internal" (SHA256) EC:92:6E:2E:58:E2:15:4E:3D:0D:6D:D8:EC:E4:54:67:E5:9B:89:AD:68:5B:A7:9F:E8:48:EC:0E:5F:B0:B5:5E

root@ip-172-31-36-134:/etc/puppetlabs# sudo /opt/puppetlabs/bin/puppet cert sign ip-172-31-29-110.eu-west-1.compute.internal

Notice: Signed certificate request for ip-172-31-29-110.eu-west-1.compute.internal

Notice: Removing file Puppet::SSL::CertificateRequest ip-172-31-29-110.eu-west-1.compute.internal at '/etc/puppetlabs/puppet/ssl/ca/requests/ip-172-31-29-110.eu-west-1.compute.internal.pem'

So far, so good. We have the two communicating. Now we need to tell the Puppet agent to actually do something!

Puppet Modules

Puppet uses modules and manifests to describe how a machine should be configured. These are collections of files written in a ruby-like syntax (similar to the chef recipe) which describe the ideal state of the node.

Modules are stored in the puppetlabs directory: /etc/puppetlabs/code/modules. We're going to make a simple webserver. In the modules directory we need to create the directory structure required.

cd /etc/puppetlabs/code/modules

mkdir webserver

cd webserver

mkdir files manifests tests You should have the following structure:

root@ip-172-31-36-134:/etc/puppetlabs/code/modules# tree

.

└── webserver

├── files

├── manifests

└── tests

Now we're going to fill this up. First create a file in the files directory called 'index.html' and add some html code to it. For example:

Hello World!

In the manifests directory, create a file called init.pp. This is the default file used to look up what to do to a machine. Add the following to the file:

class webserver {

case $operatingsystem {

centos, redhat: { $apache = "httpd" }

debian, ubuntu: { $apache = "apache2" }

default: { fail("Unrecognized operating system for webserver") }

}

package {$apache:

ensure => installed,

}

file { '/var/www':

ensure => directory,

}

file { '/var/www/html':

ensure => directory,

}

file { '/var/www/html/index.html':

ensure => file,

source => 'puppet:///modules/webserver/index.html',

}

service { 'apache2':

ensure => running,

}

}

The class uses the same name as the base directory, this is what our module is called. The case statement works out which operating system we are on and ensures that the apache can be installed via both yum and apt-get (they have different names). Then it goes on to ensure two directories are present (/var/www and /var/www/html) and to copy in the index file to that directory. Finally, the apache service is started. Finally we want to add a test to see if our module will work. Create another file called init.pp, this time in the tests directory and add the following line:

include webserver

This will include our module when we are running the tests.

At the end of this you should have:

root@ip-172-31-36-134:/etc/puppetlabs/code/modules# tree

.

└── webserver

├── files

│ └── index.html

├── manifests

│ └── init.pp

└── tests

└── init.pp

You could also have generated the Puppet module automatically:

puppet module generate <USERNAME>-<MODULE NAME> This sets up the structure for you and ensures everything is in the correct place. Also, the tests directory is being deprecated and so you should use "examples" instead. But this example works for now, who knows what else will change with the new version of Puppet!

Assign the manifest to the node, watch the webserver configure, save the world (okay, maybe not that last part...)

In Puppet enterprise we can do this via the GUI, but that is backed up by a set of configuration files which we can manipulate in the community version of Puppet.

The Puppet master requires a site.pp file which assigns different classes to nodes. This is, by default, located in the /etc/puppetlabs/code/environments/production/manifests/ directory.

For our configuration, create the site.pp file and add the following:

node 'ip-172-31-29-110.eu-west-1.compute.internal' {

include webserver

}

The node name is created using the certificate name, so for ours it is the Puppet agent instance in AWS. Go back to your agent and run:

puppet agent -t

The agent should download your manifest, apply it and ensure everything is up and running. As for saving the world? That'll be in a future post.

Hello world box on Puppet

Kat McIvor is Principal Technologist for DevOps at QA, the sole UK partner for Chef training delivery, and the UK’s biggest provider of technical and business training.

®

Want to learn more about DevOps, Continuous Delivery, and Agile? Head to our Continuous Lifecycle Conference from May 3-5. Full details here.

The Register - Independent news and views for the tech community. Part of Situation Publishing