When automating Puppet infrastructure deployment, the standard puppet cert
command often falls short for multi-master environments. The main issue arises from certificate mismatches between masters and agents, as shown in the error message:
Could not prepare for execution: The certificate retrieved from the master does not match the agent's private key.
Certificate fingerprint: 4F:08:AE:01:B9:14:AC:A4:EA:A7:92:D7:02:E9:34:39:1C:5F:0D:93:A0:85:1C:CF:68:E4:52:B8:25:D1:11:64
- OpenSSL installed on your system
- Basic understanding of x509 certificates
- Puppet master configuration files access
First, generate the private key and root certificate for your Puppet CA:
openssl genrsa -out ca.key 4096
openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 -out ca.crt \
-subj "/CN=Puppet CA/OU=Operations/O=Example Corp"
Modify your puppet.conf
to point to the custom CA:
[master]
ssldir = /etc/puppetlabs/puppet/ssl
cadir = /etc/puppetlabs/puppet/ssl/ca
certname = puppetmaster.example.com
Create a certificate signing request (CSR) for your Puppet master:
openssl genrsa -out puppetmaster.key 2048
openssl req -new -key puppetmaster.key -out puppetmaster.csr \
-subj "/CN=puppetmaster.example.com/OU=Puppet Masters/O=Example Corp"
Then sign it with your CA:
openssl x509 -req -in puppetmaster.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
-out puppetmaster.crt -days 365 -sha256
For each agent node, create a certificate in similar fashion:
# Generate private key
openssl genrsa -out agent01.key 2048
# Create CSR
openssl req -new -key agent01.key -out agent01.csr \
-subj "/CN=agent01.example.com/OU=Puppet Agents/O=Example Corp"
# Sign with CA
openssl x509 -req -in agent01.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
-out agent01.crt -days 365 -sha256
For multiple masters, you'll want to:
- Generate one root CA
- Distribute ca.crt to all masters
- Create unique certificates for each master
- Use the same CA for all agent certificates
To verify certificate consistency:
openssl x509 -noout -modulus -in puppetmaster.crt | openssl md5
openssl rsa -noout -modulus -in puppetmaster.key | openssl md5
The MD5 hashes must match. If they don't, you'll see the fingerprint mismatch error mentioned in the original problem.
For multiple environments, consider this bash script template:
#!/bin/bash
# Variables
CA_PEM="ca.crt"
CA_KEY="ca.key"
CERT_DAYS=365
MASTER_CN="puppetmaster.example.com"
generate_cert() {
local name=$1
local ou=$2
local cn=${3:-$name}
openssl genrsa -out ${name}.key 2048
openssl req -new -key ${name}.key -out ${name}.csr \
-subj "/CN=${cn}/OU=${ou}/O=Example Corp"
openssl x509 -req -in ${name}.csr -CA ${CA_PEM} -CAkey ${CA_KEY} \
-CAcreateserial -out ${name}.crt -days ${CERT_DAYS} -sha256
}
# Generate master cert
generate_cert "puppetmaster" "Puppet Masters" "${MASTER_CN}"
# Generate agent certs
generate_cert "web01" "Web Servers"
generate_cert "db01" "Database Servers"
Puppet relies on a Public Key Infrastructure (PKI) system where the Puppet master acts as the Certificate Authority (CA). While Puppet provides built-in commands like puppet cert
, there are scenarios where manual certificate generation is preferred:
- Automated deployment across multiple masters
- Custom certificate attributes
- Pre-staging certificates before server deployment
Here's the complete workflow to create a Puppet-compatible CA and certificates:
1. Create the CA Structure
mkdir -p puppet_ssl/{certs,private_keys,public_keys,requests}
cd puppet_ssl
2. Generate the CA Key and Certificate
openssl genrsa -out private_keys/ca.pem 4096
openssl req -new -x509 -days 3650 \
-key private_keys/ca.pem \
-out certs/ca.pem \
-subj "/CN=Puppet CA/OU=Operations/O=Example Corp"
3. Create Puppet Master Certificate
# Generate private key
openssl genrsa -out private_keys/puppetmaster.pem 2048
# Create CSR
openssl req -new -sha256 \
-key private_keys/puppetmaster.pem \
-out requests/puppetmaster.csr \
-subj "/CN=puppet.example.com"
# Sign the certificate
openssl x509 -req -in requests/puppetmaster.csr \
-CA certs/ca.pem \
-CAkey private_keys/ca.pem \
-CAcreateserial \
-out certs/puppetmaster.pem \
-days 365
In your puppet.conf
:
[master]
ssldir = /etc/puppetlabs/puppet/ssl
certname = puppet.example.com
ca_name = 'Puppet CA'
The error you encountered typically indicates a key/certificate mismatch. Verify with:
openssl rsa -noout -modulus -in private_keys/puppetmaster.pem | openssl md5
openssl x509 -noout -modulus -in certs/puppetmaster.pem | openssl md5
Both commands should output identical hash values.
For multiple Puppet masters, consider this bash script template:
#!/bin/bash
DOMAIN=$1
MASTER_NAME=$2
openssl genrsa -out ${MASTER_NAME}.pem 2048
openssl req -new -key ${MASTER_NAME}.pem \
-out ${MASTER_NAME}.csr \
-subj "/CN=${MASTER_NAME}.${DOMAIN}"
openssl x509 -req -in ${MASTER_NAME}.csr \
-CA ca.pem -CAkey ca.key \
-out ${MASTER_NAME}.crt -days 365
# Deploy to Puppet master
scp ${MASTER_NAME}.{pem,crt} puppet@${MASTER_NAME}:/etc/puppetlabs/puppet/ssl/
After deployment, verify the chain of trust:
openssl verify -CAfile /etc/puppetlabs/puppet/ssl/certs/ca.pem \
/etc/puppetlabs/puppet/ssl/certs/puppetmaster.pem