Software >> Services >> Configuration Management >> Puppet >> How to get started with puppet

 

Getting started with puppet

In this article, we show how to build a test environment to get started with using puppet for configuration management.  We built several machines on virtual box running various Linux distributions.  We use one of them as the puppet server (puppet master) and the rest as puppet client (puppet nodes/agent)

 

The environment

Below are the configuration of the machines used.  The RHEL 6/7/8 were registered to RH for access to package repositories using Red Hat's Developer Subscription (free). 

Server Clients

mgmt8

  • OS : RHEL 8
  • RAM: 2GB

rhel6

  • OS : RHEL 6
  • RAM: 1GB

rhel7

  • OS : RHEL 7
  • RAM: 1GB

rhel8

  • OS : RHEL 8
  • RAM: 1GB

debian11

  • OS : Debian 11
  • RAM: 1GB

ubuntu20

  • OS : Ubuntu 20.04
  • RAM: 1GB

opensuse15

  • OS : OpenSUSE 15.3 (Leap)
  • RAM: 1GB

All the machines are on the same subnet and all have their /etc/hosts populated with all machine's IP address, e.g.


#
192.168.0.101   debian11    debian11_int
192.168.0.102   mgmt7       mgmt7_int
192.168.0.103   mgmt8       mgmt8_int
192.168.0.104   rhel6       rhel6_int
192.168.0.105   rhel7       rhel7_int
192.168.0.106   rhel8       rhel8_int
192.168.0.107   ubuntu20    ubuntu20_int
192.168.0.108   opensuse15  opensuse15_int



All the machines are using a non root user named admin (use whichever suites your environment) with sudo privilege.  In our examle, we let it have NOPASSWD privilege for convenience.

 

 

Building the puppet server

 


## On mgmt8, install the packages. 

sudo rpm -Uvh https://yum.puppet.com/puppet6-release-el-8.noarch.rpm
sudo yum install -y puppetserver


## edit the Java Memory setting as desired for the puppet server
## In our case we changed from the default of 2GB to 512MB

From:
JAVA_ARGS="-Xms2g -Xmx2g -Djruby.logger.class=com.puppetlabs.jruby_utils.jruby.Slf4jLogger"

To:
JAVA_ARGS="-Xms512m -Xmx512m -Djruby.logger.class=com.puppetlabs.jruby_utils.jruby.Slf4jLogger"


## The puppet binaries are in /opt/puppetlabs/bin
## To ensure this is present in the PATH environment when using sudo, we modify the secure_path parameter
## in /etc/sudoers


From
Defaults secure_path = [current_secure_path]

To:
Defaults secure_path = [current_secure_path]:/opt/puppetlabs/bin


## start, enable puppetserver service and add firewall rules


sudo systemctl start puppetserver
sudo systemctl enable puppetserver
sudo firewall-cmd --permanent --add-port=8140/tcp
sudo firewall-cmd --reload

 

 

 

Building the clients


## On debian11 & ubuntu20 machines

wget --no-check-certificate https://apt.puppetlabs.com/puppet6-release-focal.deb
sudo dpkg -i puppet6-release-focal.deb
sudo apt update
sudo apt install -y puppet-agent


## on rhel6 machine

sudo rpm -Uvh https://yum.puppet.com/puppet6-release-el-6.noarch.rpm
sudo yum install -y puppet-agent


## on rhel7 machine

rpm -Uvh https://yum.puppet.com/puppet6-release-el-7.noarch.rpm
sudo yum install -y puppet-agent


## on rhel8 machine

sudo rpm -Uvh https://yum.puppet.com/puppet6-release-el-8.noarch.rpm
sudo yum install -y puppet-agent


## on OpenSUSE15 clients

sudo rpm -Uvh http://yum.puppetlabs.com/puppet6-release-sles-15.noarch.rpm
sudo vi /etc/zypp/repos.d/puppet6.repo

## comment out line starting with gpgkey
## change from gpgcheck=1 to gpgcheck=0
## and save the updated puppet6.repo

sudo zypper install -y puppet-agent


## The puppet binaries are in /opt/puppetlabs/bin for all the above client machines
## To ensure this is present in the PATH environment when using sudo, we modify the secure_path parameter
## in /etc/sudoers


From
Defaults secure_path = [current_secure_path]

To:
Defaults secure_path = [current_secure_path]:/opt/puppetlabs/bin


## On the server machine and all client machines, test the puppet command
## Get puppet version

puppet agent --version


## To get help

puppet help

or

puppet help subcommand

e.g.

puppet help agent


## On all client machines, register with the puppet server
## For now ignore the warning "Certificate for XXXX has not been signed yet"

sudo puppet config set server mgmt8
sudo puppet resource service puppet ensure=running enable=true
sudo puppet agent -t

(sample command output)
Info: csr_attributes file loading from /etc/puppetlabs/puppet/csr_attributes.yaml
Info: Creating a new SSL certificate request for rhel7
Info: Certificate Request fingerprint (SHA256): 3E:E2:AF:94:C9:1E:1F:85:97:1A:C4:0C:2A:85:63:DD:84:44:F3:01:68:8F:CC:03:5A:67:53:37:FF:7A:34:99
Info: Certificate for rhel7 has not been signed yet
Couldn't fetch certificate from CA server; you might still need to sign this agent's certificate (rhel7).
Exiting now because the waitforcert setting is set to 0


## On server mgmt8 machine
## By default the puppetserver command will connect to https://puppet:8140

e.g.

[admin@mgmt8 ~]$ sudo puppetserver ca list
Fatal error when running action 'list'
  Error: Failed connecting to https://puppet:8140/puppet-ca/v1/certificate_statuses/any_key?state=requested
  Root cause: Failed to open TCP connection to puppet:8140 (getaddrinfo: Name or service not known)


## as a temporary workaround (until I figure a permanent fix),

## add to the end of the line that contains ip address for hostname mgmt8 in /etc/hosts the names puppetmaster and puppet

[admin@mgmt8 puppetserver]$ sudo grep puppet /etc/hosts
192.168.0.103   mgmt8       mgmt8_int      puppetmaster   puppet


## After all client machines have resgistered, list the client certs issued by the CA on this puppetserver
## to the clients

[admin@mgmt8 puppetserver]$ sudo puppetserver ca list

(command output)
Requested Certificates:
    opensuse15       (SHA256)  3B:D8:1F:A6:29:FB:3A:49:16:DF:E1:FC:44:83:84:FC:92:80:8A:65:A1:DF:DC:B3:35:14:94:63:57:8B:A7:EA
    debian11         (SHA256)  03:82:1B:C6:1B:2A:F8:C9:CD:9E:F3:D0:B9:60:A5:0B:DC:F3:A8:22:03:23:79:77:A0:FD:D0:61:AD:A1:9B:BC
    rhel8            (SHA256)  21:74:62:9C:12:45:0A:F4:DA:0E:4A:08:D4:12:41:A8:47:BC:2D:E6:AB:F8:97:45:2D:03:53:82:BC:1A:89:B6
    rhel6            (SHA256)  90:BF:3A:70:88:28:F3:04:67:7C:13:00:4A:31:E1:13:0B:93:F4:3F:BB:1D:09:E9:0B:17:FB:6F:27:0B:55:8D
    ubuntu20         (SHA256)  13:76:B4:4B:60:5A:32:BC:DF:28:AC:98:FB:B1:5E:92:4B:64:1B:33:1B:6F:F4:C8:9B:09:C8:CB:32:39:88:45
    rhel7            (SHA256)  3E:E2:AF:94:C9:1E:1F:85:97:1A:C4:0C:2A:85:63:DD:84:44:F3:01:68:8F:CC:03:5A:67:53:37:FF:7A:34:99


## To list all certs including the server

[admin@mgmt8 puppetserver]$ sudo puppetserver ca list  --all

(command output)
Requested Certificates:
    opensuse15       (SHA256)  3B:D8:1F:A6:29:FB:3A:49:16:DF:E1:FC:44:83:84:FC:92:80:8A:65:A1:DF:DC:B3:35:14:94:63:57:8B:A7:EA
    debian11         (SHA256)  03:82:1B:C6:1B:2A:F8:C9:CD:9E:F3:D0:B9:60:A5:0B:DC:F3:A8:22:03:23:79:77:A0:FD:D0:61:AD:A1:9B:BC
    rhel8            (SHA256)  21:74:62:9C:12:45:0A:F4:DA:0E:4A:08:D4:12:41:A8:47:BC:2D:E6:AB:F8:97:45:2D:03:53:82:BC:1A:89:B6
    rhel6            (SHA256)  90:BF:3A:70:88:28:F3:04:67:7C:13:00:4A:31:E1:13:0B:93:F4:3F:BB:1D:09:E9:0B:17:FB:6F:27:0B:55:8D
    ubuntu20         (SHA256)  13:76:B4:4B:60:5A:32:BC:DF:28:AC:98:FB:B1:5E:92:4B:64:1B:33:1B:6F:F4:C8:9B:09:C8:CB:32:39:88:45
    rhel7            (SHA256)  3E:E2:AF:94:C9:1E:1F:85:97:1A:C4:0C:2A:85:63:DD:84:44:F3:01:68:8F:CC:03:5A:67:53:37:FF:7A:34:99
Signed Certificates:
    mgmt8       (SHA256)  89:63:5E:2E:97:E9:22:90:52:E4:7E:A2:62:39:7A:AA:32:10:2A:4B:EE:CC:5E:4E:F2:B9:1B:96:88:D1:CC:53       alt names: ["DNS:puppet", "DNS:mgmt8"]


## Sign all client certs

[admin@mgmt8 ~]$ sudo puppetserver ca sign --all

(command output)
Successfully signed certificate request for opensuse15
Successfully signed certificate request for debian11
Successfully signed certificate request for rhel8
Successfully signed certificate request for rhel6
Successfully signed certificate request for ubuntu20
Successfully signed certificate request for rhel7



## Test again from the client machines

sudo puppet agent --test

(sample output)
Info: csr_attributes file loading from /etc/puppetlabs/puppet/csr_attributes.yaml
Info: Creating a new SSL certificate request for rhel7
Info: Certificate Request fingerprint (SHA256): 3E:E2:AF:94:C9:1E:1F:85:97:1A:C4:0C:2A:85:63:DD:84:44:F3:01:68:8F:CC:03:5A:67:53:37:FF:7A:34:99
Info: Downloaded certificate for rhel7 from https://mgmt8:8140/puppet-ca/v1
Info: Using environment 'production'
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Retrieving locales
Info: Caching catalog for rhel7
Info: Applying configuration version '1635423879'
Notice: Applied catalog in 0.04 seconds


## On both server and client machines, you can view the current configuration paramters by

puppet config print


 

 

Using puppet for configuration management

The puppet server is where we create the configuration as code in files called manifests.  These are then compiled into catalogs which are then pulled by the puppet agent in the client machines.  The client and server trust each other via mutual TLS authentication.

In the following example, we will create a manifest containing 2 modules. The first module (or class) we name it as packages and another we name it as machine_info.  The first will make the client nodes install software packages if not found and the second will collect machine information from the nodes and store into a file.


## On puppet server mgmt8, for the packages class
## create the following file /etc/puppetlabs/code/environments/production/modules/packages/manifests/init.pp
## create the subdirectories as ncessary if they are not yet there
## The content should be as shown

class packages {
   package { 'mc':
       ensure => installed,
   }
   if $facts[os][family] == "Debian" {
     package { 'golang':
       ensure => installed,
     }
  }
   if $facts[os][family] == "RedHat" {
     package { 'net-tools':
       ensure => installed,
     }
  }
}


## On puppet server mgmt8, for the machine_info class
## create the following file /etc/puppetlabs/code/environments/production/modules/machine_info/manifests/init.pp
## create the subdirectories as ncessary if they are not yet there
## The content should be as shown

class machine_info {
  if $facts[kernel] == "windows" {
       $info_path = "C:\Windows\Temp\Machine_Info.txt"
   } else {
       $info_path = "/tmp/machine_info.txt"
   }
 file { 'machine_info':
       path => $info_path,
       content => template('machine_info/info.erb'),
   }
}

## On puppet server mgmt8, for the machine_info template
## create the following file /etc/puppetlabs/code/environments/production/modules/machine_info/templates/info.erb
## create the subdirectories as ncessary if they are not yet there
## The content should be as shown

Machine Information
-------------------
Disks: <%= @disks %>
Memory: <%= @memory %>
Processors: <%= @processors %>
Network Interfaces: <%= @interfaces %>
}


## On puppet server mgmt8, put them all together into the site manifest
## create the following file /etc/puppetlabs/code/environments/production/manifests/site.pp
## create the subdirectories as ncessary if they are not yet there
## The content should be as shown

node default {
   class { 'packages': }
   class { 'machine_info': }
}


## The puppet agents run as a service named puppet and the nodes pull the catalog at time intervals
## defined by the runinterval config parameter, the default is 1800 seconds

sudo puppet config print runinterval

(sample output)
1800


## To apply the catalogs on the client machines immediately

puppet agent -t


## sample run on client machines

## rhel6

[admin@rhel6 ~]$ sudo puppet agent -t
Info: Using environment 'production'
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Retrieving locales
Info: Caching catalog for rhel6
Info: Applying configuration version '1635430849'
Notice: /Stage[main]/Machine_info/File[machine_info]/content:
--- /tmp/machine_info.txt       2021-10-28 22:10:00.841865708 +0800
+++ /tmp/puppet-file20211028-5394-1xizb7d       2021-10-28 22:20:40.046308209 +0800
@@ -1,7 +1,7 @@
 Machine Information
 -------------------
 Disks: {"sda"=>{"model"=>"VBOX HARDDISK", "size"=>"50.00 GiB", "size_bytes"=>53687091200, "vendor"=>"ATA"}, "sr0"=>{"model"=>"CD-ROM", "size"=>"1.00 GiB", "size_bytes"=>1073741312, "vendor"=>"VBOX"}}
-Memory: {"swap"=>{"available"=>"3.94 GiB", "available_bytes"=>4227854336, "capacity"=>"0%", "total"=>"3.94 GiB", "total_bytes"=>4227854336, "used"=>"0 bytes", "used_bytes"=>0}, "system"=>{"available"=>"484.03 MiB", "available_bytes"=>507543552, "capacity"=>"44.24%", "total"=>"868.01 MiB", "total_bytes"=>910176256, "used"=>"383.98 MiB", "used_bytes"=>402632704}}
+Memory: {"swap"=>{"available"=>"3.92 GiB", "available_bytes"=>4209696768, "capacity"=>"0.43%", "total"=>"3.94 GiB", "total_bytes"=>4227854336, "used"=>"17.32 MiB", "used_bytes"=>18157568}, "system"=>{"available"=>"509.54 MiB", "available_bytes"=>534290432, "capacity"=>"41.30%", "total"=>"868.01 MiB", "total_bytes"=>910176256, "used"=>"358.47 MiB", "used_bytes"=>375885824}}
 Processors: {"count"=>1, "isa"=>"x86_64", "models"=>["11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz"], "physicalcount"=>1}
 Network Interfaces: eth0,eth1,eth2,lo
 }

Info: Computing checksum on file /tmp/machine_info.txt
Info: /Stage[main]/Machine_info/File[machine_info]: Filebucketed /tmp/machine_info.txt to puppet with sum 254d236e091b9966b01831820b0c17c1
Notice: /Stage[main]/Machine_info/File[machine_info]/content: content changed '{md5}254d236e091b9966b01831820b0c17c1' to '{md5}1a741de47b86689c3e2e8c8fafa8bbf0'
Notice: Applied catalog in 0.29 seconds


## debian11

admin@debian11:~$ sudo puppet agent -t
Info: Using environment 'production'
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Retrieving locales
Info: Caching catalog for debian11
Info: Applying configuration version '1635430978'
Notice: /Stage[main]/Machine_info/File[machine_info]/content:
--- /tmp/machine_info.txt       2021-10-28 22:20:52.295527688 +0800
+++ /tmp/puppet-file20211028-4132-176t52x       2021-10-28 22:23:03.735998745 +0800
@@ -1,7 +1,7 @@
 Machine Information
 -------------------
 Disks: {"sda"=>{"model"=>"VBOX HARDDISK", "size"=>"50.00 GiB", "size_bytes"=>53687091200, "vendor"=>"ATA"}, "sr0"=>{"model"=>"CD-ROM", "size"=>"58.26 MiB", "size_bytes"=>61093888, "vendor"=>"VBOX"}}
-Memory: {"swap"=>{"available"=>"706.12 MiB", "available_bytes"=>740421632, "capacity"=>"27.95%", "total"=>"980.00 MiB", "total_bytes"=>1027600384, "used"=>"273.88 MiB", "used_bytes"=>287178752}, "system"=>{"available"=>"484.74 MiB", "available_bytes"=>508284928, "capacity"=>"50.36%", "total"=>"976.46 MiB", "total_bytes"=>1023889408, "used"=>"491.72 MiB", "used_bytes"=>515604480}}
+Memory: {"swap"=>{"available"=>"706.12 MiB", "available_bytes"=>740421632, "capacity"=>"27.95%", "total"=>"980.00 MiB", "total_bytes"=>1027600384, "used"=>"273.88 MiB", "used_bytes"=>287178752}, "system"=>{"available"=>"484.08 MiB", "available_bytes"=>507596800, "capacity"=>"50.42%", "total"=>"976.46 MiB", "total_bytes"=>1023889408, "used"=>"492.38 MiB", "used_bytes"=>516292608}}
 Processors: {"count"=>1, "isa"=>"unknown", "models"=>["11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz"], "physicalcount"=>1}
 Network Interfaces: enp0s3,enp0s8,enp0s9,lo
 }

Info: Computing checksum on file /tmp/machine_info.txt
Info: /Stage[main]/Machine_info/File[machine_info]: Filebucketed /tmp/machine_info.txt to puppet with sum c39d39c21d58eb1c0a6ad67172fe57a1
Notice: /Stage[main]/Machine_info/File[machine_info]/content: content changed '{md5}c39d39c21d58eb1c0a6ad67172fe57a1' to '{md5}9ceb2256c85423f41d4698ed4d041f0d'
Notice: Applied catalog in 0.24 seconds



## ubuntu20

admin@ubuntu20:~$ sudo puppet agent -t
Info: Using environment 'production'
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Retrieving locales
Info: Caching catalog for ubuntu20
Info: Applying configuration version '1635430999'
Notice: /Stage[main]/Machine_info/File[machine_info]/content:
--- /tmp/machine_info.txt       2021-10-28 22:20:53.093995903 +0800
+++ /tmp/puppet-file20211028-4959-15do4i3       2021-10-28 22:23:23.990446424 +0800
@@ -1,7 +1,7 @@
 Machine Information
 -------------------
 Disks: {"sda"=>{"model"=>"VBOX HARDDISK", "size"=>"20.00 GiB", "size_bytes"=>21474836480, "vendor"=>"ATA"}, "sr0"=>{"model"=>"CD-ROM", "size"=>"1.00 GiB", "size_bytes"=>1073741312, "vendor"=>"VBOX"}}
-Memory: {"swap"=>{"available"=>"299.13 MiB", "available_bytes"=>313663488, "capacity"=>"67.60%", "total"=>"923.26 MiB", "total_bytes"=>968105984, "used"=>"624.13 MiB", "used_bytes"=>654442496}, "system"=>{"available"=>"424.13 MiB", "available_bytes"=>444731392, "capacity"=>"56.67%", "total"=>"978.80 MiB", "total_bytes"=>1026342912, "used"=>"554.67 MiB", "used_bytes"=>581611520}}
+Memory: {"swap"=>{"available"=>"292.85 MiB", "available_bytes"=>307077120, "capacity"=>"68.28%", "total"=>"923.26 MiB", "total_bytes"=>968105984, "used"=>"630.41 MiB", "used_bytes"=>661028864}, "system"=>{"available"=>"429.87 MiB", "available_bytes"=>450748416, "capacity"=>"56.08%", "total"=>"978.80 MiB", "total_bytes"=>1026342912, "used"=>"548.93 MiB", "used_bytes"=>575594496}}
 Processors: {"count"=>1, "isa"=>"x86_64", "models"=>["11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz"], "physicalcount"=>1}
 Network Interfaces: enp0s3,enp0s8,enp0s9,lo
 }

Info: Computing checksum on file /tmp/machine_info.txt
Info: /Stage[main]/Machine_info/File[machine_info]: Filebucketed /tmp/machine_info.txt to puppet with sum 05830d007a029c30999fa312920b1823
Notice: /Stage[main]/Machine_info/File[machine_info]/content: content changed '{md5}05830d007a029c30999fa312920b1823' to '{md5}8f6ed6cab3189bb01af46559d8735bda'
Notice: Applied catalog in 0.47 seconds



## opensuse15

opensuse15:~$ sudo puppet agent -t
Info: Using environment 'production'
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Retrieving locales
Info: Caching catalog for opensuse15
Info: Applying configuration version '1635431023'
Notice: /Stage[main]/Machine_info/File[machine_info]/content:
--- /tmp/machine_info.txt       2021-10-28 22:20:52.042597729 +0800
+++ /tmp/puppet-file20211028-6436-1owp0uc       2021-10-28 22:23:47.120362841 +0800
@@ -1,7 +1,7 @@
 Machine Information
 -------------------
 Disks: {"sda"=>{"model"=>"VBOX HARDDISK", "size"=>"50.00 GiB", "size_bytes"=>53687091200, "vendor"=>"ATA"}, "sr0"=>{"model"=>"CD-ROM", "size"=>"1.00 GiB", "size_bytes"=>1073741312, "vendor"=>"VBOX"}}
-Memory: {"swap"=>{"available"=>"1.83 GiB", "available_bytes"=>1962909696, "capacity"=>"8.64%", "total"=>"2.00 GiB", "total_bytes"=>2148507648, "used"=>"177.00 MiB", "used_bytes"=>185597952}, "system"=>{"available"=>"457.89 MiB", "available_bytes"=>480133120, "capacity"=>"52.86%", "total"=>"971.29 MiB", "total_bytes"=>1018474496, "used"=>"513.40 MiB", "used_bytes"=>538341376}}
+Memory: {"swap"=>{"available"=>"1.82 GiB", "available_bytes"=>1949016064, "capacity"=>"9.29%", "total"=>"2.00 GiB", "total_bytes"=>2148507648, "used"=>"190.25 MiB", "used_bytes"=>199491584}, "system"=>{"available"=>"473.33 MiB", "available_bytes"=>496324608, "capacity"=>"51.27%", "total"=>"971.29 MiB", "total_bytes"=>1018474496, "used"=>"497.96 MiB", "used_bytes"=>522149888}}
 Processors: {"count"=>1, "isa"=>"x86_64", "models"=>["11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz"], "physicalcount"=>1}
 Network Interfaces: eth0,eth1,eth2,lo
 }

Info: Computing checksum on file /tmp/machine_info.txt
Info: /Stage[main]/Machine_info/File[machine_info]: Filebucketed /tmp/machine_info.txt to puppet with sum 9a4a42c73a297f87a8001ab1a2f5869f
Notice: /Stage[main]/Machine_info/File[machine_info]/content: content changed '{md5}9a4a42c73a297f87a8001ab1a2f5869f' to '{md5}5f03ac65eb9eaf746d2d4276c0c45c7c'
Notice: Applied catalog in 0.21 seconds