DevOps with Puppet: Tips on Setting it up for Configuring Servers

Today I will describe briefly how Puppet works, as well as basic configuration and installation of the server and two clients.

 

Puppet is an open-source configuration management tool that is used for software update and configuration on client servers. With Puppet, going to the servers and updating them manually will no longer be needed, as all you’ll have to do is monitor if the servers are operating correctly.

How we apply Puppet

So, let’s begin. We have 3 servers with OS installed. We’re typically using CentOS 6.5.

Installing the server:

Hostname «puppets1»

 

Connect the repository and update the system. If the repository is outdated, it will update

rpm -ivh http://yum.puppetlabs.com/el/6/products/i386/puppetlabs-release-6-7.noarch.rpm
yum update -y

Set up the puppet server

yum install -y puppet-server

Configuration files are called manifests. They can be found in the directory /etc/puppet/manifests

 

Standard Manifest – site.pp. Puppet searches for it in the first place.

The basic element of the manifest is a resource. A resource is a file, cron task, package, or user service.

 

Let’s make changes to the file /etc/puppet/manifests/site.pp

file { "/etc/passwd":
owner => "root",
group => "bin",
mode => 644,
}

This resource launches verification of the /etc/passwd file owner, and if it differs from the root, Puppet sets the root user as the owner of the file. The same occurs with the group and permissions.

 

(node) is the most important element in the configuration file. In a nutshell, it’s the type of the machine where puppet configuration will be deployed.

 

Here’s an example of NGINX manifest for node server{n} Nginx.pp:

class nginx {
  package { 'nginx':
    ensure => latest
  }
  service { 'nginx':
    ensure => running,
    enable => true,
    require => Package['nginx']
  }
}
node /^server(d+)$/ {
  include nginx
}

Run puppetmaster:

/etc/init.d/puppetmaster start

Installing and configuring the Puppet client

Hostname «puppet c1»

 

Set up the repository:

rpm -ivh http://yum.puppetlabs.com/el/6/products/i386/puppetlabs-release-6-7.noarch.rpm
yum update -y

Set up the puppet client:

yum install puppet
chkconfig puppet on
service puppet start

Run the command on the client:

puppet agent --server puppets1 --waitforcert 60 --test

Add the node on the server:

puppet cert --list
puppet cert --sign puppetc1

Check if our puppet works on the client:

chmod 777 /etc/passwd
puppet agent --server puppets1 --waitforcert 60 --test

Info: Retrieving pluginfacts

Info: Retrieving plugin

Info: Caching catalog for puppetc2.ln.ua

Info: Applying configuration version ‘1404892414’

Notice: /Stage[main]/Main/File[/etc/passwd]/mode: mode changed ‘0777’ to ‘0644’

Notice: Finished catalog run in 6.15 seconds

Next, let’s edit the site.pp on the server:

node 'puppetc1' {
        include nmap
        include nginx
}
 
 
class nmap {
        package { "nmap":
                ensure => "latest",
        }
}
import '/etc/puppet/manifests/nginx.pp'

On the client, run the command:

puppet agent --server puppets1 --waitforcert 60 --test

Info: Retrieving pluginfacts

Info: Retrieving plugin

Info: Caching catalog for puppetc2.ln.ua

Info: Applying configuration version ‘1404892414’

Notice: /Stage[main]/Nmap/Package[nmap]/ensure: created

Notice: /Stage[main]/Nginx/Package[nginx]/ensure: created

Notice: /Stage[main]/Nginx/Service[nginx]/ensure: ensure changed ‘stopped’ to ‘running’

Info: /Stage[main]/Nginx/Service[nginx]: Unscheduling refresh on Service[nginx] Notice: Finished catalog run in 34.49 seconds

tail /var/log/yum.log

Jul 09 12:47:53 Installed: 2:nmap-5.51-3.el6.x86_64

Jul 09 12:48:07 Installed: nginx-1.0.15-5.el6.x86_64

 

As we can see, we have two packages set up on the client that we have registered in site.pp.

 

Now, let’s add a couple of lines in the config file so that we don’t have to run puppet manually:

server=puppets1
node_name=puppetc1
cerntname=puppetc1

Run puppet:

/etc/init.d/puppet start

By default, there is a check with the master every 30 minutes.

Writing manifests and classes

On the server, edit manifests/site.pp

$emailaddress="[email protected]"
 
import '/etc/puppet/classes/*-class.pp'
import "/etc/puppet/nodes/*.pp"

classes directory – for the location of classes files

nodes directory – for settings files of our server clients

$emailaddress – set the values to send reports by email

 

Class basic-class.pp: 

 

class basic-class{
 
        package { "mailx":
                ensure => "latest",
        }
 
	file {'motd':
                ensure  => file,
                path    => '/etc/motd',
                mode    => 0644,
                content => "WARRNING: Welcome to ${fqdn} ( ${operatingsystem} ${operatingsystemrelease} )
          It`s private server. Your login will be registered!
          Have a nice work!
        ",
	}
}

For basic settings, we need the latest version of the mailx package, which we indicate by ensure => latest
We also make changes to the motd file for the salutation after a successful login to the system. Puppet already has in its arsenal such variables as: 

 

${Fqdn} – Fully Qualified Domain Name of your host

${Operatingsystem} – Defines the version of your operating system. In my case, it’s CentOS

${Operatingsystemrelease} – Defines the version of your operating system. At the moment of finishing this article, I had a version 6.6 system installed.

 

The next class software-class.pp is required for installation and removal of the needed and not needed packages:

class software {
 
$removepackeges = [ "sendmail", "exim" ]
$installpackeges = [ "nmap", "iptraf", "postfix", "mc", "nano", "sudo" ]
 
 
        package {$removepackeges : ensure => purged, }
        package { $installpackeges :   ensure => "installed", }
}

$Removepackeges – lists the packages for removal

$Installpackeges – lists the packages to be installed

 

Now let’s view the ssh-config-class.pp class

class sshdconfig {
        package { "openssh-server":
                ensure => "latest",
                allow_virtual => true,
        }
 
	service { "sshd":
                ensure  => "running",
                enable  => "true",
                require => Package["openssh-server"],
        }
 
	file { "/etc/ssh/sshrc" :
                mode    => 755,
                owner   => "root",
                group   => "root",
                require => Package["openssh-server"],
                source => "puppet:///files/ssh/sshrc",
        }
 
	file { "/etc/ssh/ssh_banner":
                mode    => 644,
                owner   => "root",
                group   => "root",
                require => Package["openssh-server"],
                source => "puppet:///files/ssh/ssh_banner",
        }
 
	file { "/etc/ssh/sshd_config":
                notify  => Service["sshd"],  # this sets up the relationship
                mode    => 600,
                owner   => "root",
                group   => "root",
                require => Package["openssh-server"],
                source => "puppet:///files/ssh/sshd_config",
        }
 
}

In this class, we will:

 

 

– Install openssh-server in the package section

– Keep running sshd service that requires an installed openssh-server package

– Copy 3 files from the /files/ssh directory with settings for our ssh server

 

 

Now, let’s see the crontab-class.pp class

class crontab-basic{
 
        package { "cronie":
                ensure => "latest",
        }
 
	file { "/opt/bin/scripts/puppetrun.sh" :
                mode    => 755,
                owner   => "root",
                group   => "root",
                source => "puppet:///files/puppet-agent/puppetrun.sh",
        }
 
	cron { Puppet:
                command => "bash /opt/bin/scripts/puppetrun.sh",
                user    => root,
                hour    => 22,
                minute  => 30,
                environment  => ['PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin', "MAILTO=$emailaddress"],
        }
 
}

In this class, we:

 

– Set up cronnie if it wasn’t set up yet somehow  

– Download and copy the puppetrun.sh file from the file/puppetagent directory to /opt/bin/scripts directory on our client

– Specify which user will have our script running and when. Also, add the PATH and MAILTO values for cron

 

Now let’s proceed with the setup of the manifests for our servers. Create nodes/hardnodes.pp file

node /^puppetcd+$/ {
        include basic-class
        include software
        include sshdconfig
        include crontab-basic
}

Here we have indicated:

 

 

* For all servers with the hostname puppetc {1,2,3,4,5 ……} the above-described classes will be applied.

 

That’s all for now. Stay tuned, I will have more tips for you soon!

 

Featured blog posts