Control a whole network of computers from PuppetMaster.
Wikipedia uses puppet for servers, Google uses puppet for OSX laptops. With this article, you can use puppet with Ubuntu servers and desktops.
Prequisites
To follow this article, you should be fluent with command line, apt, sudo, installing and configuring daemons. You should have basic knowledge about public key encryption, client server -model and networking.
I assume you do the obvious stuff without mentioning: Setup and use SSH to connect to your hosts, as logging in and out of hosts is not listed here. Run ‘sudo apt-get update’ before other apt commands.
I tested with Ubuntu 12.04 LTS. If you want to use 10.04 LTS, you can find the new Puppet 2.7.x packages in backports. At least 20 persons have successfully installed PuppetMaster with this guide.
Conventions
We have two computers, hostnames master and slave. Prompt shows where the commands are given, eg. running ‘pwd’ on host master.
master$ pwd
Test connectivity
slave$ ping -c 1 master.local
If your master doesn’t answer, fix that first.
Feel free to use whatever hostnames you want. If you hosts are in the same local network, you can use Avahi/ZeroConf/Rendevouz to use hostname.local names. If your master has a public DNS name or a dynamic name, you can use that, too.
To use .local names, you might need to ‘sudo apt-get -y install avahi-utils’.
Install PuppetMaster
master$ sudo apt-get -y install puppetmaster
Regenerate Master Certificate
Let’s create PuppetMaster certificate with correct names. Clients will only accept certificate if it matches the DNS name they use for contacting the master.
To avoid using hackish “puppet in hosts” method, create a certificate with all names of master. First, remove the old certificate.
If you find ‘rm -r’ frightening, feel free to make backups of the folder or use ‘trash-put’ or ‘trash’ commands.
master$ sudo service puppetmaster stop master$ sudo rm -r /var/lib/puppet/ssl
Add master’s name to config
master$ sudoedit /etc/puppet/puppet.conf
add these names under [master] heading
dns_alt_names = puppet, master.local, puppet.terokarvinen.com
Certificate is automatically generated when you start PuppetMaster
master$ sudo service puppetmaster start
You can verify certificate details with ‘sudo ls /var/lib/puppet/ssl/certs/’ and ‘sudo openssl x509 -in /var/lib/puppet/ssl/certs/puppet.terokarvinen.com.pem -text|grep -i dns’. It should show all of your DNS names.
Connect from Slave
slave$ sudo apt-get -y install puppet
slave$ sudoedit /etc/puppet/puppet.conf
Add master DNS name under [agent] heading. Puppet will connect to server.
[agent] server = master.local
Allow puppet slave (aka agent) to start
slave$ sudoedit /etc/default/puppet
Change to yes:
START=yes
If you have connected to master before, force slave certificate regeneration with ‘sudo service puppet stop’ and ‘sudo rm -r /var/lib/puppet/ssl’. The new slave certificate will be generated the next time puppet starts.
Start puppet agent
slave$ sudo service puppet restart
Slave should now connect to master.
Sign Slave Certificate on Master
master$ sudo puppet cert --list
master$ sudo puppet cert --sign slave.example.com
Of course, use the actual name of the slave you have chosen.
Create Site Manifest and a Module
Create site manifest, the config file that includes everyghing else:
master$ cd /etc/puppet
master$ sudo mkdir -p manifests/ modules/helloworld/manifests/
master$ sudoedit manifests/site.pp
Add just one line
include helloworld
Create a hello world module
master$ sudoedit modules/helloworld/manifests/init.pp
Write the module
class helloworld { file { '/tmp/helloFromMaster': content => "See you at http://terokarvinen.com/tag/puppet\n" } }
Test & Enjoy
Puppet will automatically fetch configuration every now and then. Restarting (or usually, just reloading) the service will fetch and apply configuration immediately.
slave$ sudo service puppet restart
Congratulate yourself when you see the file from PuppetMaster
slave$ cat /tmp/helloFromMaster See you at http://terokarvinen.com/tag/puppet
Administrivia
Tested on two instances of Xubuntu 12.04 LTS beta1 on Vagrant running on Xubuntu 12.04 LTS beta2. Also, at least 20 persons have successfully installed PuppetMaster with this tutorial.
Update: Fixed puppet.conf path on slave. About 20 persons successfully tested this guide. Update: ‘trash’ is now ‘trash-put’, but changed it to ‘rm’ for simplicity.
Next: Puppet Reading List >>
Notice when connecting from slave and editing puppet.conf, line “slave$ sudoedit /etc/puppet.conf” lacks puppet folder. Correct path “/etc/puppet/puppet.conf”
Thanks, fixed.
Great tutorial! Here’s my LAMP module:
http://awaseroot.wordpress.com/2012/04/30/puppet-module-for-lamp-installation/
Thank you, it works ^^
Can you write another article like doing password change using Puppet?
Thank you for the feedback!
I’ll think about writing an article about changing passwords. In the meanwhile, have a look at
http://docs.puppetlabs.com/references/2.7.0/type.html#user
http://www.puppetcookbook.com/posts/managing-user-password-fails.html
everything else worked but when running this command from slave “cat /tmp/helloFromMaster” it cannot find the file
Tens of students and collegues have succesfully completed this tutorial, so the instructions are probably correct.
You mention that the last step fails for you. This is often a symptom of following long instructions blindly, without tests. Try spliting your work into small parts (as small as possible) and testing each part separately.
Great example. It’s terse and gives just enough information to get an agent connected to a master. Just what I needed!
Thank you, I’m very happy to hear that.
Updated: wording.
How to Change Hostname in Linux
$ sudoedit /etc/hostname
$ cat /etc/hostname
teromachine
$ sudo hostname teromachine
$ sudoedit /etc/hosts
$ grep teromachine /etc/hosts
127.0.0.1 localhost teromachine
$ sudo service avahi-daemon restart
Test
$ hostname
teromachine
$ avahi-browse -at |grep teromachine
+ eth0 IPv6 co [73:88:f0:od:73:88] Workstation local
$ ping -c1 teromachine.local
1 packets transmitted, 1 received, 0% packet loss, time 0ms
# -*- mode: ruby -*-
# vi: set ft=ruby :
# Virtual hosts for testing puppet slaves
# http://terokarvinen.com/2012/puppetmaster-on-ubuntu-12-04
# Copyright 2013 Tero Karvinen http://TeroKarvinen.com
Vagrant::Config.run do |config|
config.vm.box = “precise32.box”
config.vm.box_url = “http://files.vagrantup.com/precise32.box”
config.vm.network :bridged
# config.vm.forward_port 80, 8080
end
Puppet Agent (Slave) Debug Log
slave$ sudo puppet agent –test –verbose –debug –noop
On Ubuntu 16.04 LTS xenial, you enable puppet agent (slave) with
$ sudo puppet agent --enable
In Xenial, /etc/default/puppet does not exist and you don’t need to create it.
Using ‘sudo puppet agent –enable’ is advised in /var/log/syslog: “Skipping run of Puppet configuration client; administratively disabled (Reason: ‘Disabled by default on new or unconfigured old installations’);” and “Use ‘puppet agent –enable’ to re-enable.”. After ‘sudo puppet agent –enable’ and ‘sudo service puppet restart’, puppet agent starts normally, and syslog shows “Finished catalog run in 0.05 seconds”.
Change hostname in Ubuntu 16.04:
$ sudo hostnamectl set-hostname tero
$ sudoedit /etc/hosts
$ head -2 /etc/hosts
127.0.0.1 localhost
127.0.1.1 xubuntu tero
$ sudo service avahi-daemon restart
include does not work, class {“helloworld”:} should be used instead
It seems that puppet 3.8.5 that comes with Ubuntu 16.04 doesn’t have puppet (agent/slave) service. But you can create a cronjob by hand. This example cronjob runs every minute. You can change the minute setting to every 15 minutes on production.
$ sudo service puppet start
Failed to start puppet.service: Unit puppet.service not found.
$ cat /etc/cron.d/puppet
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
#M H d m dow user command
* * * * * root puppet agent -t >/dev/null
$ sudo service cron restart
It seems that ‘sudo puppet service start’ is only failing in very specific conditions. In many cases, using cron.d/ is not required.
If you need to play with cron, see ‘man 5 crontab’ for explanation of the syntax.