Overview #
In this tutorial I’m using the following VMs based on Ubuntu 22.04:
192.168.30.90 puppet.jklug.local # Puppet Server
192.168.30.91 host1.jklug.local # Example host with Puppet Agent
Puppet Server #
Define Hostname #
# Set an appropriate hostname for the Puppet server
sudo hostnamectl set-hostname puppet.jklug.local
# Verify the hostname
hostname
# Shell output:
puppet.jklug.local
DNS / Hosts Entry #
- Make sure the puppet server is also known as puppet
# Edit the hosts file
sudo vi /etc/hosts
# Set the following hosts entries:
127.0.0.1 localhost
127.0.1.1 puppet-server
192.168.30.90 puppet.jklug.local puppet
Puppet Repository #
Find Package for Distribution #
# Find the Apt package URL for your distribution:
https://apt.puppet.com/
# For Example: Jammy (Ubuntu 22.04)
https://apt.puppet.com/puppet8-release-jammy.deb
Add Puppet Repository #
# Download package
cd /tmp && wget https://apt.puppet.com/puppet8-release-jammy.deb
# Add Puppet repository
sudo dpkg -i puppet*.deb
# Update package index
sudo apt update
Install Puppet Server #
Installation #
# Install Puppet Server
sudo apt install puppetserver -y
Verify the Installation #
# Check installation / version: (logout/login first)
puppetserver -v
# Shell output:
puppetserver version: 8.6.2
Start Puppet & Verify Status #
- Start and enable Puppet Server
# Start puppet server (Service is stopped by default)
sudo systemctl start puppetserver
# Enable start at boot
sudo systemctl enable puppetserver
# Verify Puppet status
sudo systemctl status puppetserver
Export Path Variable #
# Switch to root user
sudo su
- Add the Puppet path variable for the root user
# Add the Puppet binaries to your PATH environment variable (User specific)
echo 'export PATH=/opt/puppetlabs/bin:$PATH' >> ~/.bashrc
# Apply changes / reload the .bashrc file
source ~/.bashrc
Verify Root CA Certificate #
- Make sure to check the root certificate, to see if there are any errors with the DNS configuration
# Check the root certificate
puppetserver ca list --all
# Shell output:
Signed Certificates:
puppet.jklug.local (SHA256) E2:7A:0E:5A:01:CE:9D:9C:12:63:11:ED:6D:24:63:34:5C:8D:FC:2B:5B:FA:B5:00:6B:26:49:29:51:1B:91:63 alt names: ["DNS:puppet", "DNS:puppet.jklug.local"] authorization extensions: [ pp_cli_auth: true]
Configuration File #
Optional adopt the Puppetserver configuration:
# Puppet Server main configuration
sudo vi /etc/default/puppetserver
###########################################
# Init settings for puppetserver
###########################################
# Location of your Java binary (version 8)
JAVA_BIN="/usr/bin/java"
# Modify this if you'd like to change the memory allocation, enable JMX, etc
JAVA_ARGS="-Xms2g -Xmx2g -Djruby.logger.class=com.puppetlabs.jruby_utils.jruby.Slf4jLogger"
# Modify this as you would JAVA_ARGS but for non-service related subcommands
JAVA_ARGS_CLI="${JAVA_ARGS_CLI:-}"
# Modify this if you'd like TrapperKeeper specific arguments
TK_ARGS=""
# These normally shouldn't need to be edited if using OS packages
USER="puppet"
GROUP="puppet"
INSTALL_DIR="/opt/puppetlabs/server/apps/puppetserver"
CONFIG="/etc/puppetlabs/puppetserver/conf.d"
# Bootstrap path
BOOTSTRAP_CONFIG="/etc/puppetlabs/puppetserver/services.d/,/opt/puppetlabs/server/apps/puppetserver/config/services.d/"
# SERVICE_STOP_RETRIES can be set here to alter the default stop timeout in
# seconds. For systemd, the shorter of this setting or 'TimeoutStopSec' in
# the systemd.service definition will effectively be the timeout which is used.
SERVICE_STOP_RETRIES=60
# START_TIMEOUT can be set here to alter the default startup timeout in
# seconds. For systemd, the shorter of this setting or 'TimeoutStartSec'
# in the service's systemd.service configuration file will effectively be the
# timeout which is used.
START_TIMEOUT=300
# Maximum number of seconds that can expire for a service reload attempt before
# the result of the attempt is interpreted as a failure.
RELOAD_TIMEOUT=120
Add Hosts / Install Puppet Agent #
Define Hostname #
# Set a hostname for the host server
sudo hostnamectl set-hostname host1.jklug.local
# Verify the hostname
hostname
# Shell output:
host1.jklug.local
DNS / Hosts Entry #
- Adopt the hosts file as follows
# Edit the hosts file
sudo vi /etc/hosts
# Add the following hosts entry:
127.0.0.1 localhost
127.0.1.1 host1
192.168.30.90 puppet.jklug.local puppet
192.168.30.90 host1.jklug.local host1
Add Puppet Repository #
# Download package
cd /tmp && wget https://apt.puppet.com/puppet8-release-jammy.deb
# Add Puppet repository
sudo dpkg -i puppet*.deb
# Update package index
sudo apt update
Install Puppet Agent #
Installation #
# Install Puppet agent
sudo apt install puppet-agent -y
Verify Installation #
# Verify installation / check version
sudo /opt/puppetlabs/bin/puppet --version
# Shell output:
8.8.1
Start Puppet Agent #
# Start the Puppet agent service
sudo /opt/puppetlabs/bin/puppet resource service puppet ensure=running enable=true
# Shell output:
service { 'puppet':
ensure => 'running',
enable => 'true',
provider => 'systemd',
}
List Puppet Agent Commands #
# List Puppet Commands / Help
sudo /opt/puppetlabs/bin/puppet --help
Export Path Variable #
# Switch to root user
sudo su
- Add the Puppet path variable for the root user
# Add the Puppet binaries to your PATH environment variable (User specific)
echo 'export PATH=/opt/puppetlabs/bin:$PATH' >> ~/.bashrc
# Apply changes / reload the .bashrc file
source ~/.bashrc
Connect Agent to Server #
Define Server Hostname #
# Define the Puppet Server hostname
puppet config set server puppet.jklug.local --section main
Configuration File #
Alternative manually define the Puppet server hostname:
# Open Puppet Agent main configuration
sudo vi /etc/puppetlabs/puppet/puppet.conf
# Add the Puppet Server hostname
[main]
server = puppet.jklug.local
Connect Agent to Server #
- Request SSL certificate for the Puppet Agent
# Connect Agent to Server: Creating SSL certificate request for hos1.jklug.local
puppet ssl bootstrap
- Switch to Puppet Server
# List the pending certificate signing requests
puppetserver ca list
# Shell output:
Requested Certificates:
host1.jklug.local (SHA256) AC:4D:CE:8F:CD:DA:48:6E:58:3A:CC:BF:C3:3F:A4:93:0B:4E:97:7D:FD:4C:30:9D:8D:62:05:1E:CA:46:E4:8F
# Sign the agent's certificate request
puppetserver ca sign --certname host1.jklug.local
# Shell output:
Successfully signed certificate request for host1.jklug.local
- Switch to Puppet Agent and wait till the certificate exchange is Complete
# Shell output:
Notice: Completed SSL initialization
# Optional rerun the bootstrap command to verify the certificate exchange
sudo /opt/puppetlabs/bin/puppet ssl bootstrap
# Shell output:
Notice: Completed SSL initialization
# Verify the connection to the Puppet Server
puppet agent --test
# Shell output:
Info: Using environment 'production'
Info: Retrieving pluginfacts
Info: Retrieving plugin
Notice: Requesting catalog from puppet.jklug.local:8140 (192.168.30.90)
Notice: Catalog compiled by puppet.jklug.local
Info: Caching catalog for host1.jklug.local
Info: Applying configuration version '1725973174'
Notice: Applied catalog in 0.00 seconds
Agent Scheduling #
# Open Puppet Agent main configuration
vi /etc/puppetlabs/puppet/puppet.conf
# Define pull interval
[main]
server = puppet.jklug.local
[agent]
runinterval = 30m
# Restart the Puppet Agent
sudo systemctl restart puppet
Puppet Structure #
- Modules: Create a directory whose name matches the module name, with a subdirectory “manifests” that containers the file “init.pp”.
# Module structure
/etc/puppetlabs/code/modules/modulename/manifests/init.pp
- Manifest Files
A manifest is a file that contains client configurations that can be used to install modules
# Manifest path
/etc/puppetlabs/code/environments/production/manifests/node-name.pp
Puppet Testrun #
Manifest Example #
- Here is an example manifest for testing purposes
# Create new manifest
vi /etc/puppetlabs/code/environments/production/manifests/testing.pp
# testing.pp
node 'host1.jklug.local' {
file { '/tmp/puppet-testing':
ensure => file,
content => "Puppet testing\n",
}
}
Apply Manifest #
Puppet is designed around a pull configuration model, where the agent nodes pull configuration data from the server at regular intervals.
- Manually trigger the pull
# Apply Puppent Manifest from the Puppet Agent host (Run as root user)
/opt/puppetlabs/bin/puppet agent -t
Verify Manifest Deployment #
# Cat the example file
cat /tmp/puppet-testing
# Shell output
Puppet testing
Remove the Example Manifest #
Remove the example “testing.pp” manifest after the testrun, so that it does not interfere with any feature host manifests.
# Delete example manifest
rm /etc/puppetlabs/code/environments/production/manifests/testing.pp
Puppet Examples #
Install Apache #
Define Class #
# Create the folderstructure for apache2 class
mkdir -p /etc/puppetlabs/code/modules/apache2/manifests
# Create the init file for apache2 class
vi /etc/puppetlabs/code/modules/apache2/manifests/init.pp
class apache2 {
# Apt update
exec { 'apt-update':
command => '/usr/bin/apt-get update'
}
# Apache2
package { 'apache2':
require => Exec['apt-update'],
ensure => installed,
}
service { 'apache2':
ensure => true,
enable => true,
require => Package['apache2'],
}
}
Host Manifest #
# Create the host Manifest
vi /etc/puppetlabs/code/environments/production/manifests/host1.pp
# host1.pp
node 'host1.jklug.local' {
include apache2
}
Apply Manifest #
- Manually trigger the pull
# Apply Puppent Manifest from the Puppet Agent host (Run as root user)
/opt/puppetlabs/bin/puppet agent -t
# Shell output:
Notice: Requesting catalog from puppet.jklug.local:8140 (192.168.30.90)
Notice: Catalog compiled by puppet.jklug.local
Info: Caching catalog for host1.jklug.local
Info: Applying configuration version '1725973744'
Notice: /Stage[main]/Apache2/Exec[apt-update]/returns: executed successfully
Notice: /Stage[main]/Apache2/Package[apache2]/ensure: created
Notice: Applied catalog in 7.09 seconds
Verify the Apache Deployment #
# Verify the Apache status
systemctl status apache2
# Shell output:
● apache2.service - The Apache HTTP Server
Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled)
Remove Apache #
Adopt Class #
# Edit the init file for apache2 class
vi /etc/puppetlabs/code/modules/apache2/manifests/init.pp
class apache2 {
package { 'apache2':
ensure => absent,
}
service { 'apache2':
ensure => stopped,
enable => false,
require => Package['apache2'],
subscribe => Package['apache2'],
}
}
Apply Changes #
- Manually trigger the pull
# Apply Puppent Manifest from the Puppet Agent host (Run as root user)
/opt/puppetlabs/bin/puppet agent -t
# Shell output:
Notice: Requesting catalog from puppet.jklug.local:8140 (192.168.30.90)
Notice: Catalog compiled by puppet.jklug.local
Info: Caching catalog for host1.jklug.local
Info: Applying configuration version '1725974007'
Notice: /Stage[main]/Apache2/Package[apache2]/ensure: removed
Info: /Stage[main]/Apache2/Package[apache2]: Scheduling refresh of Service[apache2]
Notice: /Stage[main]/Apache2/Service[apache2]: Triggered 'refresh' from 1 event
Notice: Applied catalog in 2.13 seconds
Verify the Apache Deletion #
# Verify the Apache status
systemctl status apache2
# Shell output:
○ apache2.service
Loaded: masked (Reason: Unit apache2.service is masked.)
Install LAMP Stack #
Define Class #
# Create folder for lamp class
mkdir -p /etc/puppetlabs/code/modules/lamp/manifests
# Create init file for lamp class
vi /etc/puppetlabs/code/modules/lamp/manifests/init.pp
# /etc/puppetlabs/code/modules/lamp/manifests/init.pp
class lamp {
# Apt update
exec { 'apt-update':
command => '/usr/bin/apt-get update'
}
# Apache2
package { 'apache2':
require => Exec['apt-update'],
ensure => installed,
}
service { 'apache2':
ensure => running,
enable => true,
require => Package['apache2'],
}
# MySQL
package { 'mysql-server':
require => Exec['apt-update'],
ensure => installed,
}
service { 'mysql':
ensure => running,
enable => true,
require => Package['mysql-server'],
}
# PHP
package { 'php':
require => Exec['apt-update'],
ensure => installed,
}
}
Adopt Host Manifest #
# Create the host Manifest
vi /etc/puppetlabs/code/environments/production/manifests/host1.pp
# host1.pp
node 'host1.jklug.local' {
include lamp
}
Apply Manifest #
- Manually trigger the pull
# Apply Puppent Manifest from the Puppet Agent host (Run as root user)
/opt/puppetlabs/bin/puppet agent -t
# Shell output:
Info: Using environment 'production'
Info: Retrieving pluginfacts
Info: Retrieving plugin
Notice: Requesting catalog from puppet.jklug.local:8140 (192.168.30.90)
Notice: Catalog compiled by puppet.jklug.local
Info: Caching catalog for host1.jklug.local
Info: Applying configuration version '1725974512'
Notice: /Stage[main]/Lamp/Exec[apt-update]/returns: executed successfully
Notice: /Stage[main]/Lamp/Package[apache2]/ensure: created
Notice: /Stage[main]/Lamp/Package[mysql-server]/ensure: created
Notice: /Stage[main]/Lamp/Package[php]/ensure: created
Notice: Applied catalog in 31.97 seconds
Verify the Lamp Stack #
# Verify the Apache status
systemctl status apache2
# Shell output:
● apache2.service - The Apache HTTP Server
Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled)
# Verify SQL installation / check version
mysql --version
# Shell output:
mysql Ver 8.0.39-0ubuntu0.22.04.1 for Linux on x86_64 ((Ubuntu))
# Verify PHP installation / check version
php --version
# Shell output:
PHP 8.1.2-1ubuntu2.18 (cli) (built: Jun 14 2024 15:52:55) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.2, Copyright (c) Zend Technologies
with Zend OPcache v8.1.2-1ubuntu2.18, Copyright (c), by Zend Technologies
Links #
# Official Documentation: Find Repository Package
https://www.puppet.com/docs/puppet/8/install_puppet#install_puppet