Skip to main content

Getting Started with @PuppetLabs - Part 4 - Supporting multiple operating systems

Most puppet modules can be designed to support multiple operating systems. Puppet has built in features to allow this through some simple syntax in the .pp file. It is a good practice to do that, whether you are publishing these modules on Puppet Forge or building highly customized modules for a specific purposes in a private enterprise.

1. Scalability - In case an organization chooses to switch operating systems or support other operating systems, your modules are already supporting them or they already have some operating systems and it is a matter of adding a few lines of code at the very top to add support for other operating systems.

2. Visibility and usability - The modules that support more than one operating system have higher usage counts on Puppet Forge because they support more than one type of need.

We will walk through a simple example to demonstrate multi-OS support. I checked in this code in GitHub at

Module: Install Apache web server and start it as a service.
OS Support: CentOs, Ubuntu and RHEL

Step 1: Folder structure
Create the following folder structure and blank files.

Folder: puppetApache
|-> Folder: apache -> Folder: manifests -> File: init.pp
|->  runner.pp

Step 2: Create runner.pp
We can use runner.pp to make it easy for us to apply the module from command line. Open the puppetApache/runner.pp file and enter the following line of code.

include apache

Step 3: Create the apache class
Open puppetApache/manifests/init.pp and enter the following code. I will explain each line of code in comments here.

#Create a class named apache
class apache {
#Case: when operating system is: case $::operatingsystem { #When operating system is ubuntu, set the package name and service name to apache2
"ubuntu": {
$packagename = "apache2"
$servicename = "apache2"
} #When operating system is centos or rhel, set the package name and service name to httpd
"centos", "rhel": {
$packagename = "httpd"
$sercicename = "httpd"
} #Default condition when the operating system is not supported, fail and stop.
default: {
fail("Ubsupported OS: ${::operatingsystem}")
#Ensure Apache is installed #Refer to puppet type reference
package { 'apache':
name => $packagename,
ensure => installed,
#Ensure Apache is running #Refer to puppet type reference
service { 'apache':
name => $servicename,
ensure => running, #require acts as a dependency. In this case, this service section requires the apache package section to be completed before this service section can run. #This ensures that dependencies are met before a particular section can execute.
require => Package['apache'],

Step #4: Run the module
Execute the following command from the puppetApache folder in the command line.

sudo puppet apply --modulepath . runner.pp

Step #5: Verify that apache is installed and running as a service
Execute the following command on the command line. You may have to run it with sudo depending on the user permissions.

For CentOs/RHEL:
service httpd status

For Ubuntu:
service apache2 status

Step #6: A little fun.
Now that we have confirmed that the apache web server is installed and running, let us stop the service and re-apply the puppet module.

Stop the Apache service
service apache2 stop #will stop the service on Ubuntu

Check the status of the service
service apache2 status #will show that the service is stopped

Apply the puppet module again.
sudo puppet apply --modulepath . runner.pp

Check the status of the service
service apache2 status #will show that the service is running

Here's what happened: When the puppet client applied the module:
1. It observed that apache is already installed (ensure => installed) and it does nothing with apache package.
2. It observed that the apache service is stopped (ensure => running) and it started the service.

Helpful Tip: If you really want your module to support multiple operating systems, I recommend setting up the case $::operatingsystem part as soon as you create the init.pp. As you add more sections, update the case $::operatingsystem part in parallel.

Have fun!

Popular posts from this blog

Create #VirtualPrivateCloud, NAT Instance and NAT Gateways on @AWSCloud

Create a Virtual Private Cloud, NAT instance and the new NAT Gatweay ... and making it all work. This is a YouTube playlist of three videos.

A @trello board to get kids excited

My 8 year old just started his summer break. He did so well in school and I am proud of him. He skipped second grade, got into the gold honor roll in every quarter and got a medal for doing that. Last night, I promised to install a new app for him on his iPad mini. I installed Trello and created a board for him while he watched. I showed him how to create cards, add labels to them and move them from To Do, to Doing to Done. I had him create some cards and label them. He could not stop creating cards. I could not convince him to go to bed after that. He created cards for everything he wants to do in the summer and he is not done with creating cards. He even created a card to email a screenshot of his Trello board to his teacher. Later last night, he was still awake in bed when I checked on him. He told me that he wanted to add three more labels - Math, Science and One-on-One. He wanted a label titled 'One-on-one' for tasks that he wants to do with me and he wants one-on-one at

Cheat sheet to create a #VPC and Subnets on @AWSCloud

One of the critical things to remember for working with a AWS VPC is creating and using it. I had hard time remembering how to do it, so, I wrote down a cheat sheet for myself.  If anyone wants to follow along, just navigate to the VPC page on the AWS Console and start with 'Create VPC' button. Please note that this may cost some dollars if you are not on the free tier. If you are on the free tier and make mistakes, it may cost some dollars. In the steps below, we will be creating the following on a new VPC: An internet gateway One public subnet with routes for accessibility from the internet One private subnet without any routes One EC2 web server with Apache installed in it and serving a sample html page - using the public subnet. One EC2 server with the private subnet and security group that allows access to resources running on the public subnet only.  Create VPC Name tag: myVPC CIDR Block: Tenancy: default (Must have default. Otherwise, it