Patterns

These are collections of patterns ranging from infrastructure to software design that I have come across, studied and have or will implement. These are posted here for my own reference, but anyone is welcomed to use or comment on them as you see fit.

[Provision Patterns]

spoke and hub (git+puppet):

workstation# mkdir -p puppet/manifests puppet/files puppet/modules workstation# cd puppet workstation# git init workstation# echo description > manifests/README workstation# (create your first puppet module or migrate your existing modules) workstation# ssh-keygen -f git.rsa 

run bootstrap.pp on all spokes:

user { "git":   ensure => "present",   home => "/var/git", }  file {   "/var/git": ensure => directory, owner => git,    require => User["git"];   "/var/git/puppet": ensure => directory, owner => git,    require => [User["git"], File["/var/git"]], }  ssh_authorized_key { "git":   ensure => present,   key => "INSERT PUBLIC KEY HERE",   name => "git@atalanta-systems.com",   target => "/var/git/.ssh/authorized_keys",   type => rsa,   require => File["/var/git"], }  yumrepo { "example":   baseurl => "http://packages.example.com",   descr => "Example Package Repository",   enabled => 1,   gpgcheck => 0,   name => "example", }  package { "git":   ensure => installed,   require => Yumrepo["example"], }  exec { "Create puppet Git repo":   cwd => "/var/git/puppet",   user => "git",   command => "/usr/bin/git init --bare",   creates => "/var/git/puppet/HEAD",   require => [File["/var/git/puppet"], Package["git"], User["git"]], }

I suggest installing the private key (git.rsa) on your workstation and on your hub server - this allows you to connect over SSH to all your spoke machines, as the Git user.

So, now we need to push a copy of our Puppet code from our workstation to the hub:

workstation# git remote add hub ssh://git@hubserver/var/git/puppet workstation# git add . workstation# git commit -am 'Initial commit' workstation# ssh-add /path/to/git.rsa workstation# git push hub master 

So now we have a central repo on our hub server. We can clone this to any other workstations as required, and push updates from our local repos to the Puppet hub. We now want to be able to push out Puppet config from the hub.

The principle is very simple - we simply add remotes to the repo on the hub. For example:

hub# cd /var/git/puppet hub# git remote add spokes ssh://git@web1.bluecentre.net/var/git/puppet 

Where it gets clever is that we can specify multiple URLs for each remote. In the Git config (/var/git/puppet/config in our example), we just add a stanza such as the following:

[remote "spokes"]         url = ssh://git@web1/var/git/puppet         url = ssh://git@web2/var/git/puppet         url = ssh://git@web3/var/git/puppet 

Now, provided we stash the ssh key using ssh-agent, or craft an SSH config file which specifies it, we can push from the hub to any machine, or any group of machines.

On the hub where we just added the spokes to our remote, you would push puppet configs like so:

hub# cd /var/git/puppet hub# git push spokes master

We now need to arrange for the Puppet code to appear on the spoke machines.

To achieve this we use a Git post-receive hook (/var/git/puppet/hooks/post-receive) on all spoke hosts and chmod +x:

#!/bin/sh git archive --format=tar HEAD | (cd /etc/puppet && rm -rf * && tar xf -) 

We could have the post-receive hook actually run Puppet if we wanted, or we could run Puppet out of cron, or we could run Puppet manually - I leave the choice up to the reader.

Either way, you'll need to point Puppet to the path where your modules have been pushed, for example:

spokes# puppet -v --modulepath=/etc/puppet/modules /etc/puppet/manifests/site

[References]

http://bitfieldconsulting.com/scaling-puppet-with-distributed-version-control