I’m at Velocity 2009 and very happy to see Luke Kanies presenting around Puppet. If you’re not familiar, Luke’s a hard-core sysadmin type with the typical sysadmin bent for highly automated systems management solutions which require as little maintenance as possible. If you’re looking at things like cfengine, cft, etc. then you should be looking at Puppet as well.

Meanwhile, it’s been a while since I’ve live-blogged a session, so let’s see if my stream of consciousness technique still flows (or has stagnated):

It’s a workshop, not a talk; to follow along git clone git://github.com/reductivelabs/velocity_puppet_workshop_2009.git

You’ll also want the slideshow gem to see the slides (which are in the git repo): sudo gem install slideshow

You also probably want to install puppet. You can get it from github, through MacPorts, but easiest is sudo gem install puppet

Seek help: #puppet on freenode, puppet-users Google group

The usual problems obtain: keep everything configured correctly all the time.

Puppet provides a resource abstraction layer. Do you remember which command removes gems? Is it the same as the command to remove a package (via MacPorts, rpm, yum, et al)? Why work to remember all of those.

ralsh (resource abstraction layer shell) gives you direct access to the abstraction layer

ralsh package – list all pacakges on your machine via any known package installer; responds in puppet code.

(it chokes a bit if you have rpm installed via MacPorts and don’t run it as root. sudo ralsh package is a good workaround. That’s a bug in the rpm port; it should be able to query as non-root users.)

ralsh user – provides you the info around that user

ralsh user <p> ensure=present shell=/bin/tcsh home=/Users/</p> – be sure the user exists. Runs idempotently. First run creates; second takes no action. Change args (shell, home) and it will change to agree. Change ‘ensure=absent’ and it’s blown away.

Luke now uses ralsh for interactive administration to avoid having to remember all the various details of which args for what command, etc.

The language is mostly declarative and is very simple. No loops; only recently getting conditionals from “this crazy French guy”.

Aliases allow you to think of things by alias/title rather than technical name:

package { ssh: name => $operating systems ? { debian => "ssh", openssh => "openssh", default => "sshd" },ensure => installed}

… and now you can just talk about the “ssh” package, abstracting you from naming strangenesses. You’ll never have a DB of all the strangenesses, so you can at least to insulate yourself.

Executables: puppet, ralsh, puppetd, puppetmasterd, puppetca (there’s more, but that’s what we’ll touch today)

puppet executable allows you to fiddle and iterate via -e and –noop

>puppet -e 'file { "/tmp/foo" : ensure => present}'notice: //File[/tmp/foo]/ensure: created

(note: puppet barfed for me here because ~/.puppet/var didn’t exist; mkdir -p ~/.puppet/var fixed that up)

>puppet -e 'file { "/tmp/foo" : ensure => absent}'notice: //File[/tmp/foo]: Filebucketed to with sum d41d8cd98f00b204e9800998ecf8427enotice: //File[/tmp/foo]/ensure: removed

I was curious about the filebucketed thing, so I looked:

> ls ~/.puppet/var/clientbucket/d/4/1/d/8/c/d/9/d41d8cd98f00b204e9800998ecf8427e/contents paths

Turns out contents is the file itself, paths is the path from which it was removed.

With noop:

> puppet --noop -e 'file { "/tmp/foo" : ensure => present}'notice: //File[/tmp/foo]/ensure: is absent, should be present (noop)

You should keep a single repo of your config/code (see http://github.com/albanpeignier/gepetto/) which you can treat as an application.

A puppet “module” is related config and code (classes, plugins, etc) to handle a particular function – “Why do you have this?”

(jump into repo/modules)

puppet –configprint modulepath – what modules will be loaded? (also: confdir and vardir)

>puppet --modulepath $PWD/modules -e 'include foo'notice: //foo/File[/tmp/foo]/ensure: created

Put your nodes into the site manifest: manifests/site.pp … for simpler sites. As site gets more complex, there are ways to hook puppet to a DB.

default node matches all unmatched nodes. You can also inherit:

node my_host inherits default { notice "I'm your host!"}

puppet makes it easier to capture the many little uninteresting twiddles you forget you did in the middle of the night; you also capture them as somehting you can execute to repeat them.

puppet uses ssl certs for client and server to allow identity verification. Particularly, it uses self-signed certs

Running puppetmasterd in dev:

>mkdir /tmp/server>puppetmasterd --verbose --no-daemonize --modulepath $PWD/modules \ --confdir /tmp/server --vardir /tmp/server \ --manifest $PWD/manifests/site.pp --certdnsnames localhost

… and it’s all rock-and-roll from here.

Luke (paraphrased): “Puppet uses SSL just like your bank uses it – so most SSL errors are not Puppet’s fault. Be sure you know what you’re doing before you twiddle your Puppet conf around SSL; most of the errors people report turn out to be their own attempted cleverness biting them.”

Now use puppetd to talk to puppetmasterd to get config, etc. without knowing about anything:

> puppetd --test --confdir /tmp/server --vardir /tmp/server \ --no-daemonize --server localhostinfo: Caching catalog at /tmp/server/state/localconfig.yamlnotice: Starting catalog runinfo: Creating state file /tmp/server/state/state.yamlnotice: Finished catalog run in 0.01 seconds

It takes about 15 seconds for code changes in the repo to propagate through puppetmasterd.

… and then it’s a blur as he crammed the rest of the prezzo into the last 15 minutes, so I quit typing and just listened.

blog comments powered by Disqus


22 June 2009