In this post, we will see on how to install software in a machine using Puppet. Puppet is all about how you manage servers/machines in a programmatical way by using underlying tools. For example take installing a software, puppet will talk to software installing tools like rpm/Yum/apt-get/MSI(Windows Microsoft Installer) etc in order to install required packages. In this post we will see how it do it and some examples of installing software using Puppet tool.

How Puppet install packages?

It is simple, Puppet uses ruby scripts which are located in /usr/lib/ruby/vendor_ruby/puppet/provider/package(On Linux based machine) to talk to above mention software installation tools. When you say to Puppet “please install some XYZ package”, then our puppet do below stuff.

  1. Will check all system properties provided by facter tool.
  2. Read Puppet manifests and check what packages to install.
  3. After doing this, Puppet will just pass those details to these package installation tools for installation.
  4. Puppet tries to execute one of the matched script from the above mention folder in order to install a package on a node.

Just for your understanding try to visit /usr/lib/ruby/vendor_ruby/puppet/provider/package and see how many package installation tool Puppet can talk. Below is the list of tools scripts for people who do not want to visit them

root@sanne-taggle:/usr/lib/ruby/vendor_ruby/puppet/provider/package# ls
aix.rb aptrpm.rb gem.rb openbsd.rb pkgin.rb portupgrade.rb up2date.rb yum.rb
appdmg.rb blastwave.rb hpux.rb opkg.rb pkg.rb rpm.rb urpmi.rb zypper.rb
apple.rb dpkg.rb macports.rb pacman.rb pkgutil.rb rug.rb windows
aptitude.rb fink.rb msi.rb pip.rb portage.rb sunfreeware.rb windows.rb
apt.rb freebsd.rb nim.rb pkgdmg.rb ports.rb sun.rb yumhelper.py

Want to see for Windows? Have a look at below output:

root@sanne-taggle:/usr/lib/ruby/vendor_ruby/puppet/provider/package# cd windows
root@sanne-taggle:/usr/lib/ruby/vendor_ruby/puppet/provider/package/windows# ls
exe_package.rb msi_package.rb package.rb.

Hope this gives you a bit of introduction on how Puppet can install those many types of software irrespective of OS you are using. Let use see how we can install a package using Puppet. We will try to walk through as given below sequence to get more about how we can install packages in different ways.

Syntax for installing a package:

type { 'title':
argument => value,
other_arg => value,
}

Type: This is a type of resource which can be a package, file, user etc.

Title: Can be a name of the resource or description.

Argument: Is a task what you have to do, this explains what title has to do.

Value: Is something to take effect.

To understand more about this syntax we will see below example:

My site.pp file content, we will keep the content as simple as possible:

root@linuxnix:/etc/puppet# cat manifests/site.pp
node 'linuxnix' {
include testmodule
}

If you observe my site.pp which is the main file to do any puppet activity contain only one node linuxnix and include only one module called “testmodule”

My testmodule for this post in it.pp file content is:

root@linuxnix:/etc/puppet# cat modules/testmodule/manifests/init.pp
class multipack {
package { 'screen':
ensure => absent,
}

}

Note: I am going to use puppet apply command in order to execute code on the same machine where my manifests are there.

Installing a single package using Puppet

Example 1: Change the ensure value in testmodule/manifests/init.pp from absent to present

package {'screen':

ensure => present,

}

Output:

root@linuxnix:/etc/puppet# puppet apply manifests/site.pp -v
Notice: Compiled catalog for linuxnix in environment production in 0.35 seconds
Info: Applying configuration version '1476572384'
Notice: /Stage[main]/Testmodule/Package[screen]/ensure: created
Notice: Finished catalog run in 7.42 seconds

The above code says “install screen package”. We are giving package name as a screen and what we are doing with that package. This no need to be the latest version, just this package should be present on the target machine. Suppose you want to install package to latest version, use below code

Install a package to latest version using Puppet

Example 2: Change ensure to latest in testmodule/manifests/init.pp

package {'screen':

ensure => latest,

}

Output:

root@linuxnix:/etc/puppet# puppet apply manifests/site.pp -v
Notice: Compiled catalog for linuxnix in environment production in 0.35 seconds
Info: Applying configuration version '1476650937'
Notice: /Stage[main]/Testmodule/Package[screen]/ensure: created
Notice: Finished catalog run in 3.92 seconds

This code will install screen package to the latest version. The difference between the first example and the second one is that second one always checks if the installed version is up to date or not. If it is not up to date, puppet will make sure it install the latest version whenever puppet run catalogs on that machine.

Installing multiple packages using Puppet

If we want to install multiple packages we can do that one as well using Puppet DSL arrays as shown below.

instead of below three codes for installing screen, git, wget

package {'screen':

ensure => present,

}

package {'git':

ensure => present,

}

package {'wget':

ensure => present,

}

We use below code using arrays.

package { ['screen', 'git', 'wget']:
ensure => installed,

}

Output:

root@linuxnix:/etc/puppet# puppet apply manifests/site.pp -vv
Notice: Compiled catalog for linuxnix in environment production in 0.37 seconds
Info: Applying configuration version '1476651466'
Notice: Finished catalog run in 0.12 seconds

Installing a package after a particular task

We can force Puppet to install a package after doing particular task only after doing some task. This can be achieved by using require keyword as shown below.

class testmodule {
package { ['screen', 'git', 'wget']:
ensure => installed,
require => Package['apache2'],
}

package {'apache2':
ensure => 'absent',
}

What the above code do is first uninstall apache2 and then install screen, git and wget software.

Install package to specific operating system

If you observe above example, We uninstall the apache2 package. This package name is specific to Ubuntu based machines. If you want to install Apache on Redhat based machines, we have to use httpd. We can modify our code as below so that we can accommodate two operating systems without any issue.

class testmodule {
 $apache = $::operatingsystem ? {
 Fedora => 'httpd',
 ubuntu => 'apache2',
 }
package { ['screen', 'git', 'wget']:
ensure => installed,
require => Package['apache'],
}

package {'apache':
ensure => 'absent',
}

Installing a package with a particular provider

Many of you are aware we can install software using multiple tools. Suppose if you are on a Ubuntu based machine, we can use apt-get, dpkg or aptitude tools. When using Redhat based one we can use either rpm, yum or dfn tools. We can specify to puppet to use a specific tool to install that package. Below example installs apache2 in Ubuntu.

class testmodule {
package {'apache2':
ensure => 'present',
provider => 'apt',
}


}

Installing a package from a specific source

We can install packages from different repositories in Debian or Redhat based machines. We can specify from what source we can install the software.

class testmodule {
package {'apache2':
ensure => 'present',
provider => 'apt',
install_options => ['--enablerepo', 'my_local_repo'],
}

}

In our next tutorial, we will see how to deal with files and folders in Puppet.