How to automate your IT infrastructure with puppet

Hello everyone. In my previous article named “One puppet to rule them all“, I told you about what puppet is and how it works. if you miss the first part you can find it here. In this part i’ll show you the installation and configuration of Puppet.

In real life environment, we saw that multiple types of servers are running for multiple purpose. which means a heterogeneous environment. Considering that situation in mind, I setup my environment as mention below.

Master

Operating System: Ubuntu
Version : 16.04.1 LTS (Xenial Xerus)
IP Address : 172.19.12.10
Host name : master.traininglab.local

Client/Agent/Node

Client1

Operating System: CentOS Linux
Version : 7
IP Address : 172.19.12.11
Host name : agent1.traininglab.local

Client2

Operating System: Ubuntu
Version : 14.04.5 LTS, (Trusty Tahr)
IP Address : 172.19.12.13
Host name : agent3.traininglab.local

Before installation make sure that your master and client servers time are synchronized. You can use ntp for this purpose. Puppet master and client use host name to communicate, make sure your master and client can communicate with them using the host name. If you have a working dns server in your environment you can use that and if you don’t then you can use the hostname feature. To find out your server host name type hostname command in a shell, it will print out the server host name.

Puppet master

Lets start the installation in Ubuntu 16.04 which will be used as a puppet master server.

imtiaz@master:~$ sudo wget https://apt.puppetlabs.com/puppetlabs-release-pc1-xenial.deb
imtiaz@master:~$ sudo dpkg -i puppetlabs-release-pc1-xenial.deb
imtiaz@master:~$ sudo apt-get update

The above will download the “puppetlabs-release-pc1-xenial.deb” file, perform dpkg and update the source list.

To start the installation use the below command:

imtiaz@master:~$ sudo apt-get install -y puppetserver

After installation we will configure the server. Open the file puppet.conf located at /etc/puppetlabs/puppet/ with your favorite editor. I use vim editor.

imtiaz@master:~$ sudo vim /etc/puppetlabs/puppet/puppet.conf

Place the below line. Modify it according to your environment:

[master]
dns_alt_names = master.traininglab.local, master

[main]
certname = master.traininglab.local
server = master.traininglab.local
environment = production
runinterval = 30m

dns_alt_names is the name of the puppet master. you can use multiple server name here. By default puppet client/agent looks for its configuration at 30 mins of interval. You can change this time interval from here. You can find more about runinterval here.

imtiaz@master:~$ sudo systemctl start puppetserver

I usually saw it throws an error like below when you try to start the puppet server (version 4.7.0).

Job for puppetserver.service failed because the control process exited 
with error code. See "systemctl status puppetserver.service"and"journalctl -xe"for details.

Try the below to fix the problem. You need to adjust the memory allocation. Try the below step for 512mb of ram. Open the puppetserver file with your favorite editor.

imtiaz@master:~$ sudo vim /etc/default/puppetserver

By default, you will see a line like below.

JAVA_ARGS="-Xms2g -Xmx2g -XX:MaxPermSize=256m"

Change it according to your allocated amount of memory like below:

JAVA_ARGS="-Xms512m -Xmx512m"

now try to start the server:

imtiaz@master:~$ sudo systemctl start puppetserver

It should start this time without any error. enable the server so it will start after a reboot.

imtiaz@master:~$ sudo systemctl enable puppetserver

Puppet Client/Agent/Node

After installing the master its time to install the client, which will be managed by the puppet master. We will see how to install the client in CentOS 7 and Ubuntu 14.04.

CentOS 7

[imtiaz@agent1 ~]$ sudo rpm -ivh https://yum.puppetlabs.com/el/7/products/x86_64/puppetlabs-release-7-11.noarch.rpm
[imtiaz@agent1 ~]$ sudo yum install puppet

Ubuntu 14.014

imtiaz@agent3:~$ sudo apt-get install puppet

After installation open puppet.conf file. This is the file where you will mention the name of the puppet server, otherwise the client will look for the master as its default name “puppet”. Under [main] add the server name.

CentOS 7

[imtiaz@agent1 ~]$ sudo vim /etc/puppet/puppet.conf

[main]
server = master.traininglab.local

Ubuntu 14.04

imtiaz@agent3:~$ sudo vim /etc/puppet/puppet.conf

[main]
server = master.traininglab.local

Restart the puppet service:

CentOS 7

[imtiaz@agent1 ~]$ sudo systemctl restart puppet

Ubuntu 14.04

imtiaz@agent3:~$ sudo service puppet restart

If you run puppet agent -t in both clients it will through the below error message.

CentOS7

[imtiaz@agent1 ~]$sudo puppet agent -t
Info: Creating a new SSL key for agent1.traininglab.local
Error: Could not request certificate: getaddrinfo: Name or service not known
Exiting; failed to retrieve certificate and waitforcert is disabled

Ubuntu 14.04

imtiaz@agent3:~$sudo puppet agent -t
Info: Creating a new SSL key for agent3.traininglab.local
Error: Could not request certificate: getaddrinfo: Name or service not known
Exiting; failed to retrieve certificate and waitforcert is disabled

The reason of this error is the client is not certified by the master or the server not sign this client yet. It’s time to see how the server sign the certificate.

All about Certificate

To start the communication the server must accept the client certificate. Lets see how to see the pending certificate list, how to accept or sign them and when require removing them. Perform the following from the master:

##To see the pending certificate list
imtiaz@master:~$ sudo /opt/puppetlabs/bin/puppet cert list
  "agent1.traininglab.local" (SHA256) 60:9C:E7:38:E4:4C:5A:FC:84:B3:55:C4:74:C2:B5:DB:4C:32:97:1C:B1:6D:21:8A:CF:26:DC:B8:16:65:55:19
  "agent3.traininglab.local" (SHA256) AA:F2:AE:68:89:C2:58:FD:C5:45:04:48:C2:A4:6E:EA:34:3A:A3:82:35:6C:C3:FA:DF:95:7A:4F:42:71:43:ED
imtiaz@master:~$

As you can see that i have two client “agent1.traininglab.local” and “agent3.traininglab.local” are listed in the pending list.

To sign a certificate use the command “/opt/puppetlabs/bin/puppet cert sign <hostname>” like below:

#To sign a certificate request
imtiaz@master:~$ sudo /opt/puppetlabs/bin/puppet cert sign agent1.traininglab.local
imtiaz@master:~$ sudo /opt/puppetlabs/bin/puppet cert sign agent3.traininglab.local

#To sign all certificate request 
imtiaz@master:~$ sudo /opt/puppetlabs/bin/puppet cert sign --all

If you check the pending list you will find it empty. To see the signed certificate use the below command.

#To check the signed certficate list
imtiaz@master:~$ sudo /opt/puppetlabs/bin/puppet cert list --all
+ "agent1.traininglab.local" (SHA256) 6F:2B:0D:6C:08:49:B0:84:A2:AC:A4:7E:34:C2:E7:96:7E:3F:FB:D7:34:F0:F1:C2:F1:A0:A7:EB:42:A9:1F:DA
+ "agent3.traininglab.local" (SHA256) EF:64:1A:81:C3:57:4E:35:75:25:A6:3C:E7:F2:A2:F8:16:F0:B7:25:FA:0B:03:69:4D:2B:56:2D:75:0C:21:15
+ "master.traininglab.local" (SHA256) E5:AE:9E:8B:6D:8E:B8:33:60:E5:5F:2A:10:83:59:5E:B4:F7:B9:AD:D6:93:56:A6:01:C7:F1:01:76:DE:F0:04 (alt names:"DNS:master.traininglab.local", "DNS:master.traininglab.local", "DNS:master")
imtiaz@master:~$

The “+” sign in front of the client name indicates that the client is signed by the master. You can also see the master name in this list.

If you want to revoke the certificate just use the below command

#To clean a certificate
imtiaz@master:~$ sudo /opt/puppetlabs/bin/puppet cert clean <hostname>

Verify at client

Now perform the below command in the client:

CentOS 7
[imtiaz@agent1 ~]$ sudo puppet agent --test
[sudo] password forimtiaz:Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Caching catalog for agent1.traininglab.local
Info: Applying configuration version '1476954919'Notice: Finished catalog run in0.03 seconds
[imtiaz@agent1 ~]$

Run the same command in Ubuntu:

imtiaz@agent3:~$ sudo puppet agent --test
Notice: Skipping run of Puppet configuration client; administratively disabled (Reason:'Disabled by default on new installations');
Use 'puppet agent --enable' to re-enable.
imtiaz@agent3:~$

You will see a message like the above which simply tells to enable the puppet agent. Run the below command to enable the agent:

mtiaz@agent3:~$ sudo puppet agent --enable

imtiaz@agent3:~$ sudo puppet agent --test
Info: Caching certificate_revocation_list for ca
Info: Retrieving plugin
Info: Caching catalog for agent3.traininglab.local
Info: Applying configuration version '1477135514'Info: Creating state file /var/lib/puppet/state/state.yaml
Notice: Finished catalog run in0.03 seconds
imtiaz@agent3:~$

And after enabling you can see the client is communicating with the master.

Fun with puppet

Our puppet master and client are installed and ready to go. Lets write some basic puppet code and see what happen inside the client.

On master goto “/etc/puppetlabs/code/environments/production/manifests/” directory. Create a file called site.pp and paste the below line:

user { 'dev_user1':
   ensure => present,
   comment => 'Development user',
   home => '/home/dev_user1',
   managehome => true   
  }

This will create a user called dev_user1 in all nodes which full name will be ‘Development user‘ and the home directory will be ‘/home/dev_user1‘. Note that we didn’t set any password for the user. Lets set the password. Though in real life password didn’t set like this way. Linux users have their passwords stored as hash in /etc/shadow file. Generate your hash password using openssl command.

On master perform the following:

openssl passwd -1  
Enter your password here 
Password: 
Verifying - Password: 
$1$zUd5n2PQ$LQfmzV5TBaO0S9E8PtDyx0

As you can see the hash password is generated and printed on the screen. copy the line and paste it in the site.pp file like below:

user { 'dev_user1':
   ensure => present,
   comment => 'Development user',
   home => '/home/dev_user1',
   managehome => true,
   password => '$1$zUd5n2PQ$LQfmzV5TBaO0S9E8PtDyx0'
  }

Now go to the client and run “puppet agent –test” command:

CentOS 7
[imtiaz@agent1 ~]$ sudo puppet agent --test
Info: Retrieving pluginfacts
Info: Retrieving plugin Info: Caching catalog for agent1.traininglab.local 
Info: Applying configuration version '1477204112' 
Notice: /Stage[main]/Main/User[dev_user1]/ensure: created
Notice: Finished catalog run in 0.09 seconds
[imtiaz@agent1 ~]$

Ubuntu 14.04

imtiaz@agent3:~$ sudo puppet agent --test
Info: Retrieving plugin
Info: Caching catalog for agent3.traininglab.local
Info: Applying configuration version '1477204181'
Notice: /Stage[main]/Main/User[dev_user1]/ensure: created
Notice: Finished catalog run in 0.11 seconds
imtiaz@agent3:~$

You will see an output like above. Note the line “Notice: /Stage[main]/Main/User[dev_user1]/ensure: created” in both nodes. It means that the dev_user1 has been created. if you check the home directory you will see a directory name “dev_user1” in both nodes. If you don’t run the command “puppet agent –test” then it will run automatically after the mention time period you mention earlier in puppet.conf file in runinterval directives. In our case, it’s 30 minutes.

In this way you can create a user, set home directory, install software and many more things in puppet. In my next article i will show you how to write more complex puppet code. Till then take care and good bye.

If you enjoyed the post, please share it with your network and let me know your thoughts in the comments. 

About the Author: Imtiaz is working in a financial organization in Bangladesh and having experience in system, network and security administration. Feel free to contact with him on LinkedIn or Twitter

 

One Comment

Leave a Reply

Your email address will not be published. Required fields are marked *