Image for post
Image for post

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.

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:

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.

$ 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}

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
$ vagrant up
$ vagrant ssh

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
$ puppet apply hello.pp
$ 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'
}
$ 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.

1. Create a Module

Let’s sore our modules in a directory called site:

$ mkdir site && cd site
$ puppet module generate learn/learn_puppet_apache2 --skip-interview
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'
$ sudo puppet module install puppetlabs-stdlib --modulepath=site

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.

Written by

Linux NinjaPants Automation Engineering Mutant — exploring DevOps, Kubernetes, CNI, IAC

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store