Zero to puppet in one day

From finninday
Jump to navigation Jump to search

This page explains how to get started using puppet to maintain Ubuntu 10.10 (Maverick).

Pick a server

Since this is machine will have the task of maintaining or rebuilding your important machines, it should not be one of those machines. Maybe spin up a VM that can be used on any of your machines and make that your puppet server.

a note about making virtual machines

For our purposes, (making a puppet master or test puppet client) we'll need a VM that appears to be a real machine on the network. That means turning on bridged networking in Virtualbox. With the VM running bridged networking, you can watch your normal dhcp server's logs, see the VM ask for a lease, and then add that machine to your dhcpd.conf.

With normal NAT networking, the VM is hidden within the host and uses the Virtualbox internal dhcp server, and so your VM is not a first class citizen on the network.

Install puppetmaster

Puppet has a lot of dependencies, but in this distro they are well managed and we can just say

apt-get install puppetmaster

I can't remember if the master starts automatically upon install. Check:

service puppetmaster status

If it isn't running, start it:

service puppetmaster start

Install puppet client on a test VM

Create a bridged network VM, install Ubuntu on it, and then install puppet client:

apt-get install puppet

Configure the client to start at boot by editing /etc/default/puppet:

# Defaults for puppet - sourced by /etc/init.d/puppet

# Start puppet on boot?
START=yes

# Startup options
DAEMON_OPTS=""

Start puppet

service puppet start

Sign the client's cert on the puppet master

puppet cert --list

You should see the client that just started in the output. Sign the cert to authorize communication between the client and the master:

puppet cert --sign <hostname>

Now you should have a puppet master that can control a VM client. Any horrible mistakes will only affect the VM which can easily be rebuilt.

Puppet master configs

How do you tell the puppet master what to make the clients do?

/etc/puppet/manifests/site.pp

#import "templates"
import "nodes"

The site.pp is entry point for puppetmaster configuration. This file simply tells puppet to look in the nodes.pp file. Other site-wide configuration can go here as well.

/etc/puppet/manifests/nodes.pp

node default {

}

node testingdefault {
	include hosts
}

node 'merkli.finninday.net' inherits testingdefault {
}
node 'ferret.finninday.net' inherits testingdefault {
}
node 'stinkerbelle.finninday.net' inherits testingdefault {
}
node 'potato.finninday.net' inherits testingdefault {
}

node 'weasel.finninday.net' {

}

The first node defined here is the default node. This tells puppet what to do with any machine that talks to the master, but is not specifically mentioned in the nodes.pp. In this case, do nothing with such machines.

The testingdefault node is defined to get a resource called "hosts". Notice that order is not important in this file. We haven't defined what nodes are in the testingdefault node before saying what should happen to such nodes.

The next four nodes insert actual hosts into the testingdefault group.

The last node is a place holder for a machine that does not get the testingdefault treatment.

So, what's a "hosts" resource?

Puppet modules

root@merkli:/etc/puppet/modules/hosts# tree
.
├── files
├── lib
├── manifests
│   └── init.pp
├── templates
│   └── hosts.erb
└── tests
    └── init.pp

I've created a puppet module called hosts by creating this file structure.

  • files: this is where puppet looks for files that the module will push out as part of this module
  • lib: this isn't important yet
  • manifests: this is where puppet gets the configuration files for this module. init.pp is the default starting point.
  • templates: this is where puppet looks for templates (files that are modified before being distributed)
  • tests: this is where you can put unit tests

/etc/puppet/modules/hosts/manifests/init.pp

class hosts {
    file { "/etc/hosts":
        owner => root,
        group => root,
        mode => 644,
        content => template("hosts/hosts.erb"),
    }
}

Puppet only does things that you specifically tell it to do. Here we tell it to make sure there is a file called /etc/hosts and that it has certain permissions and certain content.

/etc/puppet/modules/hosts/templates/hosts.erb

<%= ipaddress %>	<%= fqdn %> <%= hostname %>
127.0.0.1       localhost.localdomain   localhost
::1     <%= hostname %>    localhost6.localdomain6 localhost6
127.0.1.1       <%= hostname %>

# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts

This is a ruby template that contains variables and static text. When the template is populated, it looks something like this:

10.0.0.14	merkli.finninday.net merkli
127.0.0.1       localhost.localdomain   localhost
::1     merkli    localhost6.localdomain6 localhost6
127.0.1.1       merkli

# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts