Puppet is an open source configuration management tool that automates software provisioning, configuration, and state enforcement across your infrastructure. It follows a client-server model where the Puppet Server (formerly “Puppet Master”) compiles and serves configuration catalogs, and Puppet Agents running on managed nodes pull those catalogs and apply them.
This guide walks through installing and configuring Puppet 8 Server and Agent on Ubuntu 24.04 LTS. By the end, you will have a working Puppet Server managing at least one agent node, with certificate signing, manifests, and module usage covered. The same steps apply to Ubuntu 22.04 with minimal changes. For the official documentation, see the Puppet documentation.
Prerequisites
Before starting, make sure you have the following in place:
- Two servers running Ubuntu 24.04 LTS (one for Puppet Server, one for Puppet Agent)
- Puppet Server: minimum 4 GB RAM (Puppet Server runs on the JVM and needs memory), 2 CPU cores
- Puppet Agent: 1 GB RAM, 1 CPU core
- Root or sudo access on both servers
- Stable network connectivity between both servers
- Port 8140/TCP open between the agent and server
Our lab setup uses these details throughout the guide:
| Role | Hostname | IP Address |
|---|---|---|
| Puppet Server | puppet-server | 10.0.1.10 |
| Puppet Agent | puppet-agent | 10.0.1.20 |
Step 1: Configure DNS and /etc/hosts
Puppet relies heavily on hostnames for certificate validation. Every node must resolve the Puppet Server hostname correctly. If you do not have a DNS server, configure /etc/hosts on both machines.
Run this on both the Puppet Server and Agent nodes. Open the hosts file:
sudo vi /etc/hosts
Add the following entries, replacing the IP addresses with your actual values:
10.0.1.10 puppet-server puppet
10.0.1.20 puppet-agent
The alias puppet for the server is important – Puppet agents look for a host named puppet by default when no server is explicitly configured.
Set the correct hostname on each machine. On the Puppet Server:
sudo hostnamectl set-hostname puppet-server
On the Puppet Agent:
sudo hostnamectl set-hostname puppet-agent
Verify that name resolution works from both sides:
ping -c 2 puppet-server
ping -c 2 puppet-agent
You should see successful replies with the correct IP addresses. If pings fail, double-check your /etc/hosts entries and network configuration before proceeding.
Step 2: Install Puppet Server on Ubuntu 24.04
Puppet Server is the central component that compiles catalogs and serves configurations to agent nodes. Install it on the server designated as puppet-server.
Download and install the Puppet 8 release repository package:
wget https://apt.puppet.com/puppet8-release-noble.deb
sudo dpkg -i puppet8-release-noble.deb
sudo apt update
Install the puppetserver package:
sudo apt install -y puppetserver
This pulls in Puppet Server along with its dependencies including the Puppet agent, Facter, and a bundled JVM (AdoptOpenJDK). There is no need to install Java separately.
Step 3: Configure Puppet Server (puppet.conf)
The main Puppet configuration file is /etc/puppetlabs/puppet/puppet.conf. Configure the server section with the correct hostname and certificate name.
Open the configuration file:
sudo vi /etc/puppetlabs/puppet/puppet.conf
Add the following configuration:
[main]
certname = puppet-server
server = puppet-server
environment = production
[server]
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
The certname sets the SSL certificate identity for this server. The server directive tells Puppet which host acts as the primary server. The environment defaults to production, which is where your manifests and modules live.
Adjust JVM Memory Allocation
Puppet Server runs on the JVM and defaults to 2 GB of heap memory. If your server has 4 GB of RAM, the default is fine. For servers with less memory, or if you want to tune the allocation, edit the Puppet Server configuration:
sudo vi /etc/default/puppetserver
Find the JAVA_ARGS line and adjust the -Xms (initial heap) and -Xmx (maximum heap) values. For a server with 4 GB RAM, 2 GB is a good setting:
JAVA_ARGS="-Xms2g -Xmx2g -Djruby.logger.class=com.puppetlabs.jruby_utils.jruby.Slf4jLogger"
For smaller test environments with 2 GB total RAM, reduce this to -Xms512m -Xmx512m. Production environments managing hundreds of nodes should allocate 4-8 GB.
Step 4: Start and Enable Puppet Server
Start the Puppet Server service. The first start takes a couple of minutes because it generates the CA certificate and server certificates automatically.
sudo systemctl start puppetserver
sudo systemctl enable puppetserver
Check that the service is running:
sudo systemctl status puppetserver
The output should show the service as active and running:
● puppetserver.service - puppetserver Service
Loaded: loaded (/lib/systemd/system/puppetserver.service; enabled; preset: enabled)
Active: active (running) since Sun 2026-03-22 10:15:32 UTC; 1min ago
Main PID: 12345 (java)
Memory: 1.2G
CPU: 45.123s
CGroup: /system.slice/puppetserver.service
Verify the Puppet Server version and CA setup:
sudo /opt/puppetlabs/bin/puppetserver --version
You should see the installed Puppet Server version confirmed:
puppetserver version: 8.7.0
Add Puppet binaries to your system PATH so you can run puppet commands without typing the full path:
echo 'export PATH=$PATH:/opt/puppetlabs/bin:/opt/puppetlabs/puppet/bin' | sudo tee /etc/profile.d/puppet.sh
source /etc/profile.d/puppet.sh
Step 5: Install Puppet Agent on Ubuntu 24.04
Switch to the agent node (puppet-agent) and install the Puppet agent package. The agent connects to the Puppet Server, retrieves its catalog, and applies the desired configuration.
Download and install the Puppet 8 repository:
wget https://apt.puppet.com/puppet8-release-noble.deb
sudo dpkg -i puppet8-release-noble.deb
sudo apt update
Install the Puppet agent:
sudo apt install -y puppet-agent
Configure the agent to point to the Puppet Server. Open the configuration file:
sudo vi /etc/puppetlabs/puppet/puppet.conf
Add the following configuration:
[main]
certname = puppet-agent
server = puppet-server
environment = production
[agent]
runinterval = 30m
The runinterval controls how often the agent checks in with the server (default is 30 minutes). For testing, you can set this to 5m.
Add Puppet to the system PATH on the agent node as well:
echo 'export PATH=$PATH:/opt/puppetlabs/bin:/opt/puppetlabs/puppet/bin' | sudo tee /etc/profile.d/puppet.sh
source /etc/profile.d/puppet.sh
Start and enable the Puppet agent service:
sudo systemctl start puppet
sudo systemctl enable puppet
When the agent starts, it automatically sends a certificate signing request (CSR) to the Puppet Server.
Step 6: Sign the Agent Certificate on Puppet Server
Back on the Puppet Server, you need to sign the agent’s certificate before it can receive configurations. This certificate exchange establishes the encrypted trust relationship between server and agent.
List pending certificate requests:
sudo /opt/puppetlabs/bin/puppetserver ca list
You should see the agent’s certificate request waiting for approval:
Requested Certificates:
puppet-agent (SHA256) A1:B2:C3:D4:E5:F6:78:90:AB:CD:EF:12:34:56:78:90:A1:B2:C3:D4:E5:F6:78:90:AB:CD:EF:12:34:56:78:90
Sign the certificate:
sudo /opt/puppetlabs/bin/puppetserver ca sign --certname puppet-agent
The output confirms the certificate was signed successfully:
Successfully signed certificate request for puppet-agent
You can also list all signed certificates to verify:
sudo /opt/puppetlabs/bin/puppetserver ca list --all
This shows both the server’s own certificate and the newly signed agent certificate. If you have multiple agents to sign at once, use --all flag with the sign command:
sudo /opt/puppetlabs/bin/puppetserver ca sign --all
Test the connection from the agent node by running a manual Puppet run:
sudo /opt/puppetlabs/bin/puppet agent --test
A successful first run produces output similar to this:
Info: Using environment 'production'
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Caching catalog for puppet-agent
Info: Applying configuration version '1711108532'
Notice: Applied catalog in 0.02 seconds
If you see “Applied catalog” in the output, the agent is communicating with the server and applying configurations correctly.
Step 7: Write Your First Puppet Manifest (site.pp)
Puppet manifests are files with a .pp extension that declare the desired state of your systems. The main entry point is site.pp, located in the production environment’s manifests directory on the Puppet Server.
Create the manifests directory if it does not exist:
sudo mkdir -p /etc/puppetlabs/code/environments/production/manifests
Create the main site manifest:
sudo vi /etc/puppetlabs/code/environments/production/manifests/site.pp
Add a simple manifest that creates a file and installs a package on the agent node:
# /etc/puppetlabs/code/environments/production/manifests/site.pp
# Default node definition - applies to all agents
node default {
# Create a test file
file { '/tmp/puppet_test.txt':
ensure => file,
content => "Managed by Puppet on ${facts['fqdn']}\n",
owner => 'root',
group => 'root',
mode => '0644',
}
# Ensure NTP is installed and running
package { 'chrony':
ensure => installed,
}
service { 'chrony':
ensure => running,
enable => true,
require => Package['chrony'],
}
}
# Node-specific definition for the agent
node 'puppet-agent' {
# Ensure vim is installed
package { 'vim':
ensure => installed,
}
# Manage the MOTD file
file { '/etc/motd':
ensure => file,
content => "This server is managed by Puppet.\nHostname: ${facts['hostname']}\nOS: ${facts['os']['name']} ${facts['os']['release']['full']}\n",
owner => 'root',
group => 'root',
mode => '0644',
}
}
This manifest does three things: creates a test file on any node matching the default definition, ensures chrony (NTP) is running, and applies a custom MOTD specifically to the puppet-agent node. Puppet uses node definitions to target configurations to specific hosts based on their certname.
Step 8: Apply Manifests and Verify
Trigger a Puppet run on the agent to apply the manifest. On the agent node, run:
sudo /opt/puppetlabs/bin/puppet agent --test
The output shows each resource being applied:
Info: Using environment 'production'
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Caching catalog for puppet-agent
Info: Applying configuration version '1711108600'
Notice: /Stage[main]/Main/Node[puppet-agent]/Package[vim]/ensure: created
Notice: /Stage[main]/Main/Node[puppet-agent]/File[/etc/motd]/ensure: defined content as '{sha256}abc123...'
Notice: Applied catalog in 5.23 seconds
Verify the resources were applied correctly:
cat /etc/motd
The MOTD file should show the Puppet-managed content with the agent’s hostname and OS details:
This server is managed by Puppet.
Hostname: puppet-agent
OS: Ubuntu 24.04
Check that vim was installed:
dpkg -l | grep vim
You should see the vim package listed as installed. If you need to view the last Puppet run report on the server, check:
sudo /opt/puppetlabs/bin/puppet node status puppet-agent
Step 9: Use Puppet Modules from Puppet Forge
Puppet Forge is the official repository of pre-built Puppet modules maintained by Puppet and the community. Modules save you from writing everything from scratch – they handle complex configurations for services like Apache, Nginx, MySQL, PostgreSQL, and more.
Install a module from Puppet Forge on the Puppet Server. For example, install the puppetlabs-ntp module to manage NTP configuration across your infrastructure:
sudo /opt/puppetlabs/bin/puppet module install puppetlabs-ntp --environment production
The module gets installed to /etc/puppetlabs/code/environments/production/modules/:
Notice: Preparing to install into /etc/puppetlabs/code/environments/production/modules ...
Notice: Downloading from https://forgeapi.puppet.com ...
Notice: Installing -- do not interrupt ...
/etc/puppetlabs/code/environments/production/modules
└── puppetlabs-ntp (v10.1.0)
List installed modules to confirm:
sudo /opt/puppetlabs/bin/puppet module list --environment production
To use the NTP module, add it to your site.pp manifest. Open the file:
sudo vi /etc/puppetlabs/code/environments/production/manifests/site.pp
Add the NTP class inside a node definition:
node 'puppet-agent' {
class { 'ntp':
servers => ['0.ubuntu.pool.ntp.org', '1.ubuntu.pool.ntp.org'],
}
}
Other popular modules worth exploring include puppetlabs-apache for web server management, puppetlabs-mysql for database configuration, and puppetlabs-firewall for managing iptables/nftables rules. If you are looking for another approach to configuration management, the Ansible AWX web interface provides agentless automation as an alternative.
Step 10: Configure Firewall for Puppet (Port 8140)
Puppet Server listens on port 8140/TCP for agent connections. If you are running UFW (the default firewall on Ubuntu), you need to allow this port on the Puppet Server.
Allow port 8140 through UFW on the Puppet Server:
sudo ufw allow 8140/tcp
sudo ufw reload
Verify the rule was added:
sudo ufw status
The output should list port 8140 as allowed:
Status: active
To Action From
-- ------ ----
8140/tcp ALLOW Anywhere
8140/tcp (v6) ALLOW Anywhere (v6)
If you prefer Firewalld on Ubuntu instead of UFW, use these commands:
sudo firewall-cmd --permanent --add-port=8140/tcp
sudo firewall-cmd --reload
For production environments, restrict port 8140 to only your agent network rather than allowing it from anywhere. With UFW:
sudo ufw allow from 10.0.1.0/24 to any port 8140 proto tcp
You can also verify port 8140 is listening on the server:
sudo ss -tlnp | grep 8140
The output confirms Puppet Server is listening:
LISTEN 0 50 *:8140 *:* users:(("java",pid=12345,fd=42))
For a full reference of UFW firewall commands, including limiting access by source IP and managing complex rules, check our dedicated guide.
Useful Puppet Commands Reference
Here are commonly used Puppet commands for day-to-day management:
| Command | Description |
|---|---|
puppet agent --test | Trigger a one-time Puppet run with verbose output |
puppet agent --noop | Dry run – show what would change without applying |
puppetserver ca list | List pending certificate requests |
puppetserver ca sign --all | Sign all pending certificate requests |
puppetserver ca clean --certname NODE | Revoke and remove a node’s certificate |
puppet module install MODULE | Install a module from Puppet Forge |
puppet module list | List installed modules |
puppet resource package vim | Query the current state of a resource |
puppet parser validate manifest.pp | Check manifest syntax without applying |
facter | Show all system facts collected by Puppet |
Conclusion
You now have a working Puppet 8 setup on Ubuntu 24.04 with the server compiling catalogs and at least one agent pulling and applying configurations. From here, build out your manifests using Puppet’s resource types for files, packages, services, cron jobs, and users – or pull in community modules from Puppet Forge for complex stacks.
For production deployments, consider enabling PuppetDB for exported resources and stored catalogs, setting up r10k or Code Manager for Git-based workflow, configuring Puppet’s autosign for automated certificate handling in dynamic environments, and adding monitoring for the Puppet Server JVM metrics. Also look into Puppet on CentOS/RHEL if your infrastructure spans multiple distributions.
Many errors in the article
Hi Jack,
The article has been updated in the article.
Let us know if working okay for you now.
Hi, As of Oct 11th 2021 – this article is accurate for ubuntu 20.04, and is actually more helpful than Puppet documentation. Two thumbs up.
Thanks for the positive comment. We’re happy to learn the article was of help to you.
Nice article for installation puppet in ubuntu 20.04