Running Puppet from cron
You can do a lot with the setup you already have: work on your Puppet manifests as a team, communicate changes via a central Git repository, and manually apply them on a machine using the papply
script.
However, you still have to log into each machine to update the Git repo and rerun Puppet. It would be helpful to have each machine update itself and apply any changes automatically. Then all you need to do is to push a change to the repo, and it will go out to all your machines within a certain time.
The simplest way to do this is with a cron job that pulls updates from the repo at regular intervals and then runs Puppet if anything has changed.
Getting ready
You'll need the Git repo we set up in the Managing your manifests with Git and Creating a decentralized Puppet architecture recipes, and the papply
script from the Writing a papply script recipe. You'll need to apply the bootstrap.pp
manifest we created to install ssh
keys to download the latest repository.
How to do it...
Follow these steps:
- Copy the
bootstrap.pp
script to any node you wish to enroll. Thebootstrap.pp
manifest includes the private key used to access the Git repository, it should be protected in a production environment. - Create the
modules/puppet/files/pull-updates.sh
file with the following contents:#!/bin/sh cd /etc/puppet/cookbook sudo –u puppet git pull && /usr/local/bin/papply
- Modify the
modules/puppet/manifests/init.pp
file and add the following snippet after thepapply
file definition:file { '/usr/local/bin/pull-updates': source => 'puppet:///modules/puppet/pull-updates.sh', mode => '0755', } cron { 'run-puppet': ensure => 'present', user => 'puppet', command => '/usr/local/bin/pull-updates', minute => '*/10', hour => '*', }
- Commit the changes as before and push to the Git server as shown in the following command line:
t@mylaptop puppet$ git add modules/puppet t@mylaptop puppet$ git commit -m "adding pull-updates" [master 7e9bac3] adding pull-updates 2 files changed, 14 insertions(+) create mode 100644 modules/puppet/files/pull-updates.sh t@mylaptop puppet$ git push Counting objects: 14, done. Delta compression using up to 4 threads. Compressing objects: 100% (7/7), done. Writing objects: 100% (8/8), 839 bytes | 0 bytes/s, done. Total 8 (delta 0), reused 0 (delta 0) To git@git.example.com:repos/puppet.git 7c2e3d5..7e9bac3 master -> master
- Issue a Git pull on the test node:
root@testnode ~# cd /etc/puppet/cookbook/ root@testnode /etc/puppet/cookbook# sudo –u puppet git pull remote: Counting objects: 14, done. remote: Compressing objects: 100% (7/7), done. remote: Total 8 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (8/8), done. From git.example.com:repos/puppet 23e887c..7e9bac3 master -> origin/master Updating 7c2e3d5..7e9bac3 Fast-forward modules/puppet/files/pull-updates.sh | 3 +++ modules/puppet/manifests/init.pp | 11 +++++++++++ 2 files changed, 14 insertions(+), 0 deletions(-) create mode 100644 modules/puppet/files/pull-updates.sh
- Run Puppet on the test node:
root@testnode /etc/puppet/cookbook# papply Notice: Compiled catalog for testnode.example.com in environment production in 0.17 seconds Notice: /Stage[main]/Puppet/Cron[run-puppet]/ensure: created Notice: /Stage[main]/Puppet/File[/usr/local/bin/pull-updates]/ensure: defined content as '{md5}04c023feb5d566a417b519ea51586398' Notice: Finished catalog run in 0.16 seconds
- Check that the
pull-updates
script works properly:root@testnode /etc/puppet/cookbook# pull-updates Already up-to-date. Notice: Compiled catalog for testnode.example.com in environment production in 0.15 seconds Notice: Finished catalog run in 0.14 seconds
- Verify the
cron
job was created successfully:root@testnode /etc/puppet/cookbook# crontab -l -u puppet # HEADER: This file was autogenerated at Tue Sep 09 02:31:00 -0400 2014 by puppet. # HEADER: While it can still be managed manually, it is definitely not recommended. # HEADER: Note particularly that the comments starting with 'Puppet Name' should # HEADER: not be deleted, as doing so could cause duplicate cron jobs. # Puppet Name: run-puppet */10 * * * * /usr/local/bin/pull-updates
How it works...
When we created the bootstrap.pp
manifest, we made sure that the Puppet user can checkout the Git repository using an ssh
key. This enables the Puppet user to run the Git pull in the cookbook directory unattended. We've also added the pull-updates
script, which does this and runs Puppet if any changes are pulled:
#!/bin/sh cd /etc/puppet/cookbook sudo –u puppet git pull && papply
We deploy this script to the node with Puppet:
file { '/usr/local/bin/pull-updates': source => 'puppet:///modules/puppet/pull-updates.sh', mode => '0755', }
Finally, we've created a cron
job that runs pull-updates
at regular intervals (every 10 minutes, but feel free to change this if you need to):
cron { 'run-puppet': ensure => 'present', command => '/usr/local/bin/pull-updates', minute => '*/10', hour => '*', }
There's more...
Congratulations, you now have a fully-automated Puppet infrastructure! Once you have applied the bootstrap.pp
manifest, run Puppet on the repository; the machine will be set up to pull any new changes and apply them automatically.
So, for example, if you wanted to add a new user account to all your machines, all you have to do is add the account in your working copy of the manifest, and commit and push the changes to the central Git repository. Within 10 minutes, it will automatically be applied to every machine that's running Puppet.