• Get application security done the right way! Detect, Protect, Monitor, Accelerate, and more…
  • Learn how to install a Puppet server & agent and set up, so they talk to each other.

    Puppet is one of the most enterprise adopted configuration management tools in the DevOps world. As a DevOps engineer, you must know how to set up a puppet on your system.

    But before we begin, let me tell you that installing a puppet is not an easy task at all. If you miss a single step or if you change the flow of steps mentioned in this tutorial, even at one place, you might be scratching your head all day with a lot of error, but your setup would be incomplete. So, follow each step very carefully.

    Puppet has client-server architecture, which consists of a puppet master (server) and puppet agents (client). Puppet Master has all the configurations, and it compiles and supplies the configurations to puppet agents. Puppet Agents send the facts to puppet master requesting catalogs in intervals. Puppet Master sends the back the requested catalog to the puppet agent. Puppet Agent then applies that catalog on the node and reports back to the master.

    Now that you have a basic understanding of Puppet let’s get started and set up a Puppet Master and Puppet Agent.

    If you are an absolute beginner, you may like to take this online video course.

    Environment Details

    I am using 2 Ubuntu 18.04 machines. One will act as a puppet master and the other one as a puppet agent. Below are the details of the machines:

    Puppet Master (Server)

    • Hostname: puppet, puppet.geekflate.com
    • IP Address: 192.168.0.108

    Puppet Agent (Client)

    • Hostname: puppetagent
    • Ip Address: 192.168.0.107

    Installing Puppet Server

    Before I begin the installation, I need to edit the /etc/hosts file on both master and agent so that they can resolve each other.

    On the Master node

    [email protected]:~$ sudo gedit /etc/hosts
    
    [sudo] password for geekflare:
    
    127.0.0.1 localhost
    127.0.1.1 geekflare
    192.168.0.108 puppet puppet.geekflare.com

    On Agent Node

    [email protected]:~$ sudo gedit /etc/hosts
    
    127.0.0.1 localhost
    127.0.1.1 geekflare
    192.168.0.107 puppetagent
    192.168.0.108 puppet puppet.geekflare.com

    ­Now, I need to get a puppet repository on my master node and update it.

    Download the puppet repository.

    [email protected]:~$ wget https://apt.puppetlabs.com/puppet6-release-bionic.deb
    
    --2019-10-15 15:41:34-- https://apt.puppetlabs.com/puppet6-release-bionic.deb
    
    Resolving apt.puppetlabs.com (apt.puppetlabs.com)... 99.86.19.107, 99.86.19.59, 99.86.19.2, ...
    
    Connecting to apt.puppetlabs.com (apt.puppetlabs.com)|99.86.19.107|:443... connected.
    
    HTTP request sent, awaiting response... 200 OK
    
    Length: 11736 (11K) [application/x-debian-package]
    
    Saving to: ‘puppet6-release-bionic.deb’
    
    puppet6-release-bio 100%[===================>] 11.46K --.-KB/s in 0s     
    
    2019-10-15 15:41:34 (236 MB/s) - ‘puppet6-release-bionic.deb’ saved [11736/11736]

    Add and configure puppet 6 repo.

    [email protected]:~$ sudo dpkg -i puppet6-release-bionic.deb
    
    Selecting previously unselected package puppet6-release.
    
    (Reading database ... 187041 files and directories currently installed.)
    
    Preparing to unpack puppet6-release-bionic.deb ...
    
    Unpacking puppet6-release (6.0.0-5bionic) ...
    
    Setting up puppet6-release (6.0.0-5bionic) ...

    Update the repository list.

    [email protected]:~$ sudo apt update
    
    Hit:1 https://download.docker.com/linux/ubuntu bionic InRelease
    
    Hit:2 http://security.ubuntu.com/ubuntu cosmic-security InRelease             
    
    Hit:3 http://ppa.launchpad.net/ansible/ansible/ubuntu cosmic InRelease        
    
    Get:4 http://download.virtualbox.org/virtualbox/debian cosmic InRelease [4,429 B]
    
    Get:5 http://apt.puppetlabs.com bionic InRelease [85.3 kB]                    
    
    Hit:6 http://us.archive.ubuntu.com/ubuntu cosmic InRelease                    
    
    Hit:7 http://us.archive.ubuntu.com/ubuntu cosmic-updates InRelease            
    
    Get:8 http://download.virtualbox.org/virtualbox/debian cosmic/contrib amd64 Packages [1,466 B]
    
    Get:9 http://apt.puppetlabs.com bionic/puppet6 all Packages [13.5 kB]
    
    Hit:10 http://us.archive.ubuntu.com/ubuntu cosmic-backports InRelease
    
    Get:11 http://apt.puppetlabs.com bionic/puppet6 i386 Packages [13.5 kB]
    
    Get:12 http://apt.puppetlabs.com bionic/puppet6 amd64 Packages [32.3 kB]
    
    Fetched 151 kB in 2s (61.9 kB/s) 
    
    Reading package lists... Done
    
    Building dependency tree      
    
    Reading state information... Done
    
    234 packages can be upgraded. Run 'apt list --upgradable' to see them.

    Installing Puppet Server

    Let’s run the below command on the master node to install the puppet server on it.

    [email protected]:~$ sudo apt install -y puppetserver
    
    Reading package lists... Done
    
    Building dependency tree      
    
    Reading state information... Done
    
    The following additional packages will be installed:
    
     ca-certificates-java java-common openjdk-8-jre-headless puppet-agent
    
    Suggested packages:
    
     default-jre fonts-dejavu-extra fonts-ipafont-gothic fonts-ipafont-mincho
    
     fonts-wqy-microhei fonts-wqy-zenhei
    
    The following NEW packages will be installed:
    
     ca-certificates-java java-common openjdk-8-jre-headless puppet-agent
    
     puppetserver
    
    0 upgraded, 5 newly installed, 0 to remove and 234 not upgraded.
    
    Need to get 109 MB of archives.
    
    After this operation, 287 MB of additional disk space will be used.
    
    Get:1 http://us.archive.ubuntu.com/ubuntu cosmic/main amd64 java-common all 0.68ubuntu1 [6,988 B]
    
    Get:2 http://apt.puppetlabs.com bionic/puppet6 amd64 puppet-agent amd64 6.10.1-1bionic [19.9 MB]
    
    Get:3 http://us.archive.ubuntu.com/ubuntu cosmic-updates/universe amd64 openjdk-8-jre-headless amd64 8u212-b03-0ubuntu1.18.10.1 [27.2 MB]
    
    Get:4 http://apt.puppetlabs.com bionic/puppet6 amd64 puppetserver all 6.7.1-1bionic [61.5 MB]
    
    Get:5 http://us.archive.ubuntu.com/ubuntu cosmic/main amd64 ca-certificates-java all 20180516ubuntu1 [12.3 kB]
    
    Fetched 109 MB in 1min 41s (1,072 kB/s)                                       
    
    Unpacking puppetserver (6.7.1-1bionic) ...
    
    Setting up puppet-agent (6.10.1-1bionic) ...
    
    Created symlink /etc/systemd/system/multi-user.target.wants/puppet.service → /lib/systemd/system/puppet.service.
    
    Created symlink /etc/systemd/system/multi-user.target.wants/pxp-agent.service → /lib/systemd/system/pxp-agent.service.
    
    Removed /etc/systemd/system/multi-user.target.wants/pxp-agent.service.
    
    Setting up java-common (0.68ubuntu1) ...
    
    Processing triggers for libc-bin (2.28-0ubuntu1) ...
    
    Processing triggers for systemd (239-7ubuntu10.12) ...
    
    Processing triggers for man-db (2.8.4-2) ...
    
    Processing triggers for ca-certificates (20180409) ...
    
    Updating certificates in /etc/ssl/certs...
    
    0 added, 0 removed; done.
    
    Running hooks in /etc/ca-certificates/update.d...
    
    done.
    
    Setting up ca-certificates-java (20180516ubuntu1) ...
    
    head: cannot open '/etc/ssl/certs/java/cacerts' for reading: No such file or directory
    
    Adding debian:SSL.com_EV_Root_Certification_Authority_ECC.pem
    
    Adding debian:ssl-cert-snakeoil.pem
    
    Adding debian:SwissSign_Gold_CA_-_G2.pem
    
    Adding debian:SZAFIR_ROOT_CA2.pem
    
    Adding debian:OpenTrust_Root_CA_G3.pem
    
    Adding debian:TWCA_Root_Certification_Authority.pem
    
    Adding debian:QuoVadis_Root_CA_2_G3.pem
    
    Adding debian:DST_Root_CA_X3.pem
    
    Adding debian:SecureSign_RootCA11.pem
    
    Adding debian:QuoVadis_Root_CA_1_G3.pem
    
    Adding debian:T-TeleSec_GlobalRoot_Class_3.pem
    
    Adding debian:Go_Daddy_Root_Certificate_Authority_-_G2.pem
    
    Adding debian:Actalis_Authentication_Root_CA.pem
    
    Adding debian:Chambers_of_Commerce_Root_-_2008.pem
    
    done.
    
    Processing triggers for ca-certificates (20180409) ...
    
    Updating certificates in /etc/ssl/certs...
    
    0 added, 0 removed; done.
    
    Running hooks in /etc/ca-certificates/update.d...
    
    done.
    
    done.
    
    Setting up openjdk-8-jre-headless:amd64 (8u212-b03-0ubuntu1.18.10.1) ...
    
    Setting up puppetserver (6.7.1-1bionic) ...
    
    usermod: no changes
    
    Processing triggers for systemd (239-7ubuntu10.12) ...

    Configuring Puppet Server

     Edit the puppetserver file, as shown below. This to configure JVM of the puppet server.

    [email protected]:~$ sudo gedit /etc/default/puppetserver
    
     
    # Modify this if you'd like to change the memory allocation, enable JMX, etc
    
    JAVA_ARGS="-Xms512m -Xmx512m -Djruby.logger.class=com.puppetlabs.jruby_utils.jruby.Slf4jLogger"

     Edit puppet configuration file to modify puppet server settings.

    [email protected]:~$ sudo gedit /etc/puppetlabs/puppet/puppet.conf
    
    
    # This file can be used to override the default puppet settings.
    
    # See the following links for more details on what settings are available:
    
    # - https://puppet.com/docs/puppet/latest/config_important_settings.html
    
    # - https://puppet.com/docs/puppet/latest/config_about_settings.html
    
    # - https://puppet.com/docs/puppet/latest/config_file_main.html
    
    # - https://puppet.com/docs/puppet/latest/configuration.html
    
    [master]
    
    vardir = /opt/puppetlabs/server/data/puppetserver
    
    logdir = /var/log/puppetlabs/puppetserver
    
    rundir = /var/run/puppetlabs/puppetserver
    
    pidfile = /var/run/puppetlabs/puppetserver/puppetserver.pid
    
    codedir = /etc/puppetlabs/code
    
    dns_alt_names = puppet,puppet.geekflare.com
    
    [main]
    
    certname = puppet.geekflare.com
    
    server = puppet.geekflare.com
    
    environment = production
    
    runinterval = 15m

    Puppet Server needs to generate a root and intermediate signing, CA.

    [email protected]:~$ sudo /opt/puppetlabs/bin/puppetserver ca setup
    
    Generation succeeded. Find your files in /etc/puppetlabs/puppet/ssl/ca

     Start and enable the puppet server service.

    [email protected]:~$ sudo systemctl start puppetserver
    
    [email protected]:~$ sudo systemctl enable puppetserver
    
    Synchronizing state of puppetserver.service with SysV service script with /lib/systemd/systemd-sysv-install.
    
    Executing: /lib/systemd/systemd-sysv-install enable puppetserver

    Installing Puppet Agent

    Follow the below steps on the agent node as you did for the master system. Puppet repository needs to present on all the agent nodes.

    [email protected]:~$ wget https://apt.puppetlabs.com/puppet6-release-bionic.deb
    
    [email protected]:~$ sudo dpkg -i puppet6-release-bionic.deb
    
    [email protected]:~$ sudo apt update

    Run the below command on the agent node to install the puppet agent.

    [email protected]:~$ sudo apt install -y puppet-agent
    
    Reading package lists... Done
    
    Building dependency tree      
    
    Reading state information... Done
    
    The following NEW packages will be installed:
    
     puppet-agent
    
    0 upgraded, 1 newly installed, 0 to remove and 233 not upgraded.
    
    Need to get 19.9 MB of archives.
    
    After this operation, 115 MB of additional disk space will be used.
    
    Get:1 http://apt.puppetlabs.com bionic/puppet6 amd64 puppet-agent amd64 6.10.1-1bionic [19.9 MB]
    
    Fetched 19.9 MB in 2s (8,488 kB/s)      
    
    Selecting previously unselected package puppet-agent.
    
    (Reading database ... 185786 files and directories currently installed.)
    
    Preparing to unpack .../puppet-agent_6.10.1-1bionic_amd64.deb ...
    
    Unpacking puppet-agent (6.10.1-1bionic) ...
    
    Setting up puppet-agent (6.10.1-1bionic) ...
    
    Created symlink /etc/systemd/system/multi-user.target.wants/puppet.service → /lib/systemd/system/puppet.service.
    
    Created symlink /etc/systemd/system/multi-user.target.wants/pxp-agent.service → /lib/systemd/system/pxp-agent.service.
    
    Removed /etc/systemd/system/multi-user.target.wants/pxp-agent.service.
    
    Processing triggers for libc-bin (2.28-0ubuntu1) ...

    Configuring Puppet Agent

     Edit the puppet configuration file on the agent node.

    [email protected]:~$ sudo gedit /etc/puppetlabs/puppet/puppet.conf
    
    [main]
    
    certname = puppetagent
    
    server = puppet.geekflare.com
    
    environment = production
    
    runinterval = 15m

    Run the below command to start the puppet service. This command will also start automatically after it boots.

    [email protected]:~$ sudo /opt/puppetlabs/bin/puppet resource service puppet ensure=running enable=true
    
    service { 'puppet':
    
     ensure => 'running',
    
     enable => 'true',
    
    } 

    Generate and Sign Certificates

    When the agent starts for the first time, it sends a certificate signing request to the puppet master. The master needs to check and sign this certificate. After this, the agent will fetch catalogs from the master and apply them to agent nodes regularly.

    Now that the puppet agent is running run the below command on the master node to check if it has received any certificate signing request.

    On the Master Node

    [email protected]:~$ sudo /opt/puppetlabs/bin/puppetserver ca list
    
    [sudo] password for geekflare:
    
    Requested Certificates:
    
       puppetagent (SHA256) EA:68:23:B5:C3:71:2C:E6:4A:6A:3B:2F:24:F5:B8:5B:50:F7:3F:12:89:DE:B1:EB:D1:0A:74:3E:48:C3:D7:35

    Sign the certificate sent by the agent.

    [email protected]:~$ sudo /opt/puppetlabs/bin/puppetserver ca list
    
    [sudo] password for geekflare:
    
    Requested Certificates:
    
       puppetagent (SHA256) EA:68:23:B5:C3:71:2C:E6:4A:6A:3B:2F:24:F5:B8:5B:50:F7:3F:12:89:DE:B1:EB:D1:0A:74:3E:48:C3:D7:35

    Run the below command to check all the certificate list. One certificate is already there, be a default of master node, and the other one is from the agent node.

    [email protected]:~$ sudo /opt/puppetlabs/bin/puppetserver ca list --all
    
    Signed Certificates:
    
       puppetagent (SHA256) EA:68:23:B5:C3:71:2C:E6:4A:6A:3B:2F:24:F5:B8:5B:50:F7:3F:12:89:DE:B1:EB:D1:0A:74:3E:48:C3:D7:35
    
       puppet.geekflare.com (SHA256) 71:30:5B:C8:C5:CE:28:A0:60:5C:4F:39:26:D0:FC:DA:DF:0A:0F:4D:ED:D4:B1:9C:05:1A:38:2F:D6:5F:9C:06 alt names: ["DNS:puppet.geekflare.com", "DNS:puppet", "DNS:puppet.geekflare.com"]

    On Agent Node

    Now run this command to test if the connection has been established between master and agent nodes, and everything is running fine.

    geekf[email protected]:~$ sudo /opt/puppetlabs/bin/puppet agent --test
    
    Info: Using configured environment 'production'
    
    Info: Retrieving pluginfacts
    
    Info: Retrieving plugin
    
    Info: Retrieving locales
    
    Info: Caching catalog for puppet-agent
    
    Info: Applying configuration version '1571171191'
    
    Notice: Applied catalog in 0.02 seconds

    Sample Puppet Example

    Let’s run a simple puppet example. I will create a simple puppet manifest, which creates a directory with a certain permission.

    On the Master Node:

    [email protected]:~$ sudo gedit /etc/puppetlabs/code/environments/production/manifests/site.pp

     Put the below content.

    node 'puppetagent' { # Applies only to mentioned node. If nothing mentioned, applies to all.
    
        file { '/home/test': # Resource type file
    
                ensure => 'directory', # Create a directory
    
                owner => 'root', # Ownership
    
                group => 'root', # Group Name
    
                mode => '0755', # Directory permissions
    
             }
    
    }

    Now run the below command for an agent to reach out to master and pull the configurations. After running this command, it should create that directory on the agent node.

    On Agent Node

    [email protected]:~$ sudo /opt/puppetlabs/bin/puppet agent --test
    
    [sudo] password for geekflare:
    
    Info: Using configured environment 'production'
    
    Info: Retrieving pluginfacts
    
    Info: Retrieving plugin
    
    Info: Retrieving locales
    
    Info: Caching catalog for puppetagent
    
    Info: Applying configuration version '1571333010'
    
    Notice: /Stage[main]/Main/Node[puppetagent]/File[/home/test]/ensure: created
    
    Notice: Applied catalog in 0.05 seconds

    Run the ls command to check if the director has been created successfully. 

    [email protected]:~$ ls -l /home/
    
    total 32
    
    drwxr-xr-x 13 geekflare geekflare 4096 Jul 19 08:06 geekflare
    
    drwx------ 2 root root 16384 Oct 23 2018 lost+found
    
    drwxr-xr-x 23 geekflare geekflare 4096 Oct 17 11:02 geekflare
    
    drwxr-xr-x 2 root root 4096 Oct 17 13:23 test
    
    drwxr-xr-x 2 username username 4096 Jun 29 09:38 username

    There you go!

    Conclusion

    This was a simple example to demonstrate its working. But imagine a bigger scenario, where you got to install or apply a certain configuration on hundreds of servers. Puppet can help you achieve it in minutes.

    If you are involved in automation and interested in learning more, you may check this Udemy course, which talks about Ansible, Puppet, and Salt.