Designing a production-ready Puppet architecture: Puppet Server with high availability, PuppetDB on PostgreSQL, Code Manager and r10k, thousands of agent nodes, a CI/CD pipeline from PDK to canary environments, plus PuppetDB and server monitoring and backup.

In episode 20 you got to know the latest features in Puppet 8 and Puppet Enterprise 2025.1, including Security Compliance Management and role-based node management. Now it's time to bring it all together into one big picture: what a Puppet architecture actually looks like in a production environment at the thousand-node scale.
In a local lab, a single Puppet server serving a few nodes feels simple. In production, there are many new questions: how do you keep the server available when one of them dies? How do you make sure deployed code is always consistent across all compilers? How do you prevent slow agent runs from overloading the whole pipeline? This episode answers those questions.
We'll cover the production Puppet architecture — Puppet Server with high availability, PuppetDB on PostgreSQL, Code Manager and r10k, and centralized reporting — then connect it to a complete CI/CD pipeline from PDK and rspec-puppet to canary environments, and close with monitoring and backup practices that keep the whole system healthy.
A mature production Puppet architecture consists of several components, each with a role:
| Component | Main Role |
|---|---|
| Puppet Server primary | Catalog compiler, CA, agent endpoint |
| Puppet Server replica | Backup compiler when the primary is down |
| PuppetDB | Stores facts, catalogs, and reports |
| PostgreSQL | Database behind PuppetDB |
| Code Manager or r10k | Deploys code from Git to environments |
| PE Console | UI for classification, reports, RBAC |
| Thousands of agent nodes | Run catalogs periodically |
The logical flow goes roughly like this: agents talk to Puppet Server, the server calls hiera and the classifier for compilation, the result is sent to the agent, the agent applies it and sends a report, the report goes into PuppetDB, and the console and dashboards read from PuppetDB.
The most critical component is Puppet Server. If it goes down, every node loses the ability to run. A common HA strategy is placing a replica as a backup compiler: environments, modules, and hiera are synced from the primary to the replica periodically.
To make agents automatically fail over to the replica when the primary fails, use the server_list setting on agents:
puppet config set server puppet-primary.example.net
puppet config set server_list puppet-primary.example.net:8140,puppet-replica.example.net:8140With server_list, the agent tries the first server, then moves to the next one if it fails. This is far more resilient than relying on a single server address. Remember that the Certificate Authority should stay on the primary so certificate signing isn't split across servers.
PuppetDB stores all operational data: facts, catalogs, and reports. Everything is stored in PostgreSQL. Because the data volume is large, there are a few important practices:
report-ttl, node-ttl, and node-purge-ttl limit data growth as in episode 19.A quick query to check database size:
SELECT datname, pg_size_pretty(pg_database_size(datname))
FROM pg_database ORDER BY pg_database_size(datname) DESC;A healthy PostgreSQL keeps PQL queries and the console dashboard responsive. If PuppetDB's report processing queue builds up, add threads or move the database to its own machine.
In production, code must not be edited directly on the server. The correct flow: code lives in Git, then is distributed by r10k or Code Manager to Puppet environments. A common control repository structure:
production/
hieradata/
manifests/
modules/
site/
PuppetfileThe Puppetfile declares modules from the Forge or Git with pinned versions:
forge 'https://forge.puppet.com'
mod 'puppetlabs/stdlib', '9.4.0'
mod 'puppetlabs/nginx', '5.2.0'
mod 'company-role-web',
git: 'https://git.company.net/puppet/role-web.git',
ref: 'main'Deployment is done with the following commands, and Code Manager keeps reproducibility by deploying to a specific commit:
puppet code deploy production --wait
puppet code deploy production --version <commit-sha> --waitA healthy production pipeline connects the testing from episode 18 with deployment. The flow looks roughly like this:
feature branch -> pdk validate + lint + unit test -> pull request -> main
main -> puppet code deploy production -> canary group -> full rolloutThe stages:
puppet code deploy production --version <previous-commit> --waitThe canary principle matters because a catalog that passes unit tests isn't necessarily correct in production — production hiera, real facts, and network conditions can only be tested on actual nodes.
Tip
Use run reports and the Code Manager API to compare canary results against the whole fleet. If the canary shows many failed resources or unexpected corrective changes, cancel the rollout before it spreads to all nodes.
All agent reports gather in PuppetDB, and from there they're consumed by various consumers: dashboards to see the percentage of nodes that are noop, unchanged, failed, or corrective; alerting systems for key metrics; and Grafana reading PuppetDB metrics.
Minimum monitoring practices to maintain:
| Metric | Watch Threshold |
|---|---|
| Catalog compilation over 5 seconds | Happening repeatedly on many nodes |
| Report delay over 2x runinterval | Slow agent or overloaded server |
| Full JRuby queue | Server needs tuning or scale-out |
| PuppetDB storage piling up | TTL not right or disk almost full |
Backup is half of a production architecture. Components that must be backed up:
tar -czf puppetserver-backup.tar.gz \
/etc/puppetlabs/puppet/ssl \
/etc/puppetlabs/code \
/etc/puppetlabs/puppetserver/conf.d
pg_dump -Fc puppetdb > puppetdb.dumpMinimum backup contents: the CA keys and certificates in /etc/puppetlabs/puppet/ssl, the control repo and hiera in /etc/puppetlabs/code, the server configuration, and a PuppetDB database dump. Store backups in a separate location and test restoration periodically — a backup that's never tested is a backup that doesn't exist.
Important
The CA keys are the most valuable asset. If they're lost, every agent certificate must be recreated and all nodes need their certificates cleaned. Keep a copy of the CA keys in a safe place, separate from the primary server, and restrict access to them.
In this episode we designed a production-ready Puppet architecture: Puppet Server with high availability and failover via server_list, PuppetDB on PostgreSQL with TTL management, Code Manager and r10k as the single code source, agents across thousands of nodes, and centralized reporting and monitoring. We also built a CI/CD pipeline from PDK and rspec-puppet to canary environments, and made sure PuppetDB and CA key backups aren't forgotten.
Key takeaways:
In episode 22 — the final episode of this series — we'll step back and look at the ecosystem: comparing Puppet with Ansible, Chef, SaltStack, and Pulumi/Terraform, then summarizing the whole journey from episode 0 to 21. See you there!