homeblogmodule of week puppetlabs apt pull apt strings puppet

Module of the Week: puppetlabs/apt – Pull APT Strings with Puppet

Purpose Provides helpful definitions for dealing with APT
Module puppetlabs/apt
Puppet Version 2.7+
Platforms Debian, Ubuntu

I know we've been covering Puppet Labs modules for the last few weeks, but I'd like to specifically call out all the great community contributions we've had on this module. In fact, this module started out as a community members project, was forked by someone at Puppet Labs, modified and later enjoyed significant contributions from other community members.

Thank you (in no particular order) for your contributions!

So, what does the module do? Its description on the Puppet Forge is modest, but accurate: "Provides helpful definitions for dealing with APT." Did you know that Puppet Labs has an APT repository? I'll show you how to use this module to configure it on your Debian/Ubuntu system and mention some other features as well.

Let's dig in.

Installing the module

Complexity Easy
Installation Time 2 minutes

This should look familiar to MOTW devotees. I used Puppet 2.7.12 & Ubuntu 11.10 while writing this blog post.

Installing the puppetlabs/apt module is as simple as using the puppet module tool (available as a rubygem, on github; and coming soon in Puppet and Puppet Enterprise):

$ puppet config print modulepath
$ cd /etc/puppet/modules
$ gem install puppet-module
$ puppet-module install puppetlabs/apt
You should now have an apt directory in your module path.

Resource Overview

This module can do a number of things for you, mostly through defined resource types. I'll briefly describe the functionality modeled in each class/define in the modules manifests folder.

├── builddep.pp # Define: Interface to apt-get build-dep.
├── force.pp      # Define: Forcibly install a package from a specific release.
├── init.pp          # Class: Sets options/logic, manages sources.list & sources.list.d.
├── key.pp        # Define: Manage APT gpg keys.
├── params.pp  # Class: Sets up a few parameters.
├── pin.pp         # Define: Pin a release in APT.
├── ppa.pp        # Define: Manage ppa repositories. 
├── release.pp  # Class: Set the default APT release. 
└── source.pp   # Define: Manage APT sources.

This blog post will cover installing an APT source and key.

Testing the module

This module is mostly a collection of defined resource types, which provide reusable logic that consumers of the module can leverage for managing APT.

It provides smoke tests for testing its functionality on a target system and spec tests for checking a compiled catalog against an expected set of resources as you're developing on the module. Both sets of tests are pretty comprehensive for this module but if you find something missing or broken, feel free to open an issue against it.

If you'd like to quickly try out some of the modules functionality, take a look at and apply the smoke tests located in the modules tests folder.

Configuring the module

Complexity Easy
Installation Time 5 minutes

There isn't much to configure in this module as there aren't many classes. Some parameters are declared in params.pp while others are configured through the apt class itself. That said, the default set of options should be perfectly appropriate for your use. The modules documentation covers the available parameters pretty well, though it could definitely be improved.

Let's look at a couple of important options in the apt class, both set to false by default:


When you declare the apt class, Puppet will manage your systems sources.list file and sources.list.d directory but will do its best to respect existing content. If you declare your apt class with the above parameters set to true, Puppet will unapologetically purge any existing content it finds that you haven't declared with Puppet. So by default, Puppet assumes you'll be managing APT with Puppet along with system defaults and/or locally managed content but you have the option to authoritatively manage your APT sources.

With this in mind, let's move on to actually managing an APT source.

Example usage

We're going to use this module to setup the Puppet Labs apt repository where we can get the latest stable releases of Puppet, right from the horse's mouth.

Start by creating a new smoke test in your newly installed apt modules test folder, called puppetlabs-apt.pp. Inside we're going to declare a single resource representing our desired APT source and key.

$ cd module_path_from_above/apt
$ vim tests/puppetlabs-apt.pp
# The Puppet Labs APT source and gpg key.
apt::source { 'puppetlabs':
  location   => 'http://apt.puppetlabs.com',
  repos      => 'main',
  key        => '4BD6EC30',
  key_server => 'pgp.mit.edu',

With this resource, we're creating an APT source named puppetlabs and gave Puppet information about the repositories location and the key used to sign its packages. Puppet will leverage Facter to determine the appropriate release (like oneiric) but you can set it directly by adding the release attribute. Check your new smoke test for syntax errors using the Puppet Parser subcommand.

$ puppet parser validate tests/puppetlabs-apt.pp

Receive no output from that command? Great, nothing is wrong! Let's apply this code now, as an example usage of the apt module.

$ puppet apply --verbose tests/puppetlabs-apt.pp
notice: /Stage[main]//Apt::Source[puppetlabs]/File[puppetlabs.list]/ensure: defined content as '{md5}3be1da4923fb910f1102a233b77e982e'
info: /Stage[main]//Apt::Source[puppetlabs]/File[puppetlabs.list]: Scheduling refresh of Exec[puppetlabs apt update]
notice: /Stage[main]//Apt::Source[puppetlabs]/Exec[puppetlabs apt update]: Triggered 'refresh' from 1 events>

Great, you're ready to update Puppet directly from Puppet Labs!

We used a new smoke test to easily lay down our resource declaration and apply it on our system. Realistically, you may want to declare your APT sources inside the classes where they're needed, say in a class that installs packages requiring a certain APT repository. Remember that dependency meta-parameters like require and before work just fine on the defined resource types provided by the APT module.


Hopefully I've shown that this module provides extremely simple interfaces for managing an APT source and key and lets you leverage Puppet to do all the heavy lifting, a thousand times over if you want. That's the power of this module and that's the power of Puppet.

Before I leave you, I have a confession to make. My systems administration experience is almost exclusively RedHat based and until recently, my knowledge of APT went about as far as apt-get install foo. Traditionally, I understand how something works and go about implementing that thing in Puppet but in reviewing community pull requests against the module, I stumbled onto something awesome — I learned how APT worked by reading the Puppet code in the puppet-apt module! It had never occurred to me before that we as sysadmins can leverage the shared language Puppet provides us to discover and understand how systems work in an entirely different way.

If you follow the Forge link at the top of this post, you'll see that this module does much more than what I've shown you here and it's all made possible by the contributors credited at the top of the post. I can't thank our community enough for its contributions to Puppet and over 300(!) Forge modules. You make system administration better each and every day. Thank you!

Additional Resources