
Learn Puppet: Puppet Basics
Puppet Basics on Vagrant/VirtualBox with Ubuntu
I used Puppet back in 2013, and now 5 years later, I started to play with Puppet again. The complexity has greatly increased, and documentation is still leaves many opportunities for improvement.
I decided to write some small tutorial material inspired by LearnChef website, so here is my first in the series.
Setup the Host
This tutorial was tested on Ubuntu 16.04 Xenial, but should work fine on Windows or macOS. You need to get the following components:
- Puppet Agent (optional for this tutorial)
- VirtualBox
- Vagrant
Installing Virtualbox
Virtualbox is an open source virtual machine system that is free and runs on macOS, Windows, and Linux. For new comers to virtualization, you will have to have virtual technology enabled (default these days) and Trusted Computing disabled in your BIOS. On Windows, you cannot have Hyper-V enabled, and on Linux, you cannot have KVM or Xen enabled.
On Ubuntu 16.04 Xenial Xerus, you can install Virtualbox on the command line:
$ sudo apt-get -y install gcc make linux-headers-$(uname -r) dkms$ DEB_KEY="https://www.virtualbox.org/download/oracle_vbox_2016.asc"
$ DEB_URL"=http://download.virtualbox.org/virtualbox/debian"
$ DEB_SRC="deb ${DEB_URL} $(lsb_release -cs) contrib"$ wget -q ${DEB_KEY} -O- | sudo apt-key add -
$ sudo echo ${DEB_SRC} > /etc/apt/sources.list.d/virtualbox.list
$ sudo apt update
$ sudo apt install -y virtualbox-5.2
Installing Vagrant
For those unfamiliar, vagrant automates virtual systems like Virtualbox. You can install this on Ubuntu 16.04 Xenial like this:
$ VERSION='2.0.4'
$ PACKAGE="vagrant_${VERSION}_x86_64.deb"
$ curl -O https://releases.hashicorp.com/vagrant/${VERSION}/${PACKAGE}
$ sudo dpkg -i ${PACKAGE}
This version is the latest as of April 30th, 2018.
Installing Puppet
Puppet may not be the easiest tool to setup. I have a previous article on this this process for Ubuntu:
Setup the Guest
Now that we have all the prerequisites installed, it is time to create our virtual machine guest. Create some work area, e.g. mkdir $HOME/puppetbasics
, and then create a Vagrantfile
inside that directory:
Vagrant.configure('2') do |config|
config.vm.box = 'puppetlabs/ubuntu-14.04-64-nocm'
config.vm.hostname = "learn.box"
end
Now we need to download Ubuntu 14.04 Trusty for our virtual guest system, and SSH into the box:
$ vagrant up
$ vagrant ssh
From here, we install the Puppet 5 agent, using the exact same pattern we tried on the host. I also created a small script that you can use on your guest system.
Configure a Resource
The essential part of change configuration management system is the resource: a description of a system’s configuration that we will change.
1. Create a MOTD file
We’ll create what is called a manifest to describe the state our our MOTD file resource.
$ cat <<-EOF > hello.pp
file { '/tmp/motd':
content => 'hello world'
}
EOF
To apply our changes, we simply type:
$ puppet apply hello.pp
And we can inspect the results:
$ more /tmp/motd
/tmp/motd
hello world
2. Update the MOTD file’s contents
Now let’s update the state for the file resource in our manifest. Change hello.pp
to look like this:
file { '/tmp/motd':
content => 'hello puppet'
}
Then apply and check the results:
$ puppet apply hello.pp
$ more /tmp/motd
/tmp/motd
hello puppet
3. Ensure the MOTD file’s contents are not changed by anyone else
An essential part of change configuration tool like Puppet is to change resources to match what we configure as our desired state. If a change occurs outside of what we specify, Puppet will change the state back what we specified.
$ echo 'hello data' > /tmp/motd
$ puppet apply hello.pp
$ more /tmp/motd
/tmp/motd
hello puppet
4. Delete the MOTD file
Let’s create new state that removes the MOTD file in goodbye.pp
manifest.
$ cat <<-EOF > goodbye.pp
file { '/tmp/motd':
ensure => absent
}
EOF
Configure a Package and Service
Now let’s create something more exciting, like a web server with webserver.pp
.
1. Install the Apache Package
We'll start with a package and service resource:
$ cat <<-EOF > webserver.pp
package { 'apache2':
ensure => present,
}
EOF
2. Start and Enable the Apache Service
$ cat <<-EOF >> webserver.ppservice { 'apache2':
ensure => running,
enable => true,
}
EOF
3. Add a home page
Let’s add a home page:
$ cat <<-EOF >> webserver.ppfile { '/var/www/html/index.html':
content => '<html>
<body>
<h1>hello world</h1>
</body>
</html>',
}
EOF
4. Apply and Confirm Web Site is running
$ puppet apply webserver.pp
$ curl localhost
<html>
<body>
<h1>hello world</h1>
</body>
</html>
Make the Manifest more Manageable
We now know how to manage a package and configure a web server, but there is one problem: our content it embedded into our script. We need to separate this out.
To do this, we need make our manifest more modular by creating a module. A module is a way to organize up one ore more manifests into a single component that we can reuse.
1. Create a Module
Let’s sore our modules in a directory called site:
$ mkdir site && cd site
We can use puppet to generate a skeleton module that we can change later:
$ puppet module generate learn/learn_puppet_apache2 --skip-interview
This will create a directory structure that looks like this:
site
└── learn_puppet_apache2
├── examples
│ └── init.pp
├── Gemfile
├── manifests
│ └── init.pp
├── metadata.json
├── Rakefile
├── README.md
└── spec
├── classes
│ └── init_spec.rb
└── spec_helper.rb
2. Create a template
Let’s create a template for our website:
$ mkdir learn_puppet_apache2/templates
$ cat <<-EOF > learn_puppet_apache2/templates/index.html.erb
<html>
<body>
<h1>hello world</h1>
</body>
</html>
EOF
3. Update Manifest to reference the HTML template
$ cat <<-EOF > learn_puppet_apache2/manifests/init.pp
class learn_puppet_apache2 {
package { 'apache2':
ensure => present,
} service { 'apache2':
ensure => running,
enable => true,
} file { '/var/www/html/index.html':
content => template('learn_puppet_apache2/index.html.erb'),
}
}
4. Run the Module
Now we want to run the module:
$ cd ..
$ sudo puppet apply --modulepath=site -e 'include ::learn_puppet_apache2'
Note that due to a bug in puppet module generate, we will get a warning. We can work around this with this:
$ sudo puppet module install puppetlabs-stdlib --modulepath=site
This is not the best practice, but shortest path to work around the issue. Best practices involve using a tool r10k and placing external modules downloaded from PuppetForge in their own vendored directory. We’ll leave this for a future tutorial.
5. Verify It Works
$ curl localhost
<html>
<body>
<h1>hello world</h1>
</body>
</html>
Conclusion
I hope this is useful for new comers to the Puppet platform. This shows the basics of how, what, and why to use change configuration and a walk through of basic manifest and module creation.