Let’s get this straight before we start: a Puppet 7-to-8 upgrade is not a package update. It wears that costume — new repo, new version pin, apt upgrade and off you go — but underneath it’s a compatibility audit. You’re proving that your code, your data, your modules, your custom Ruby extensions, your server platform, and the workflow your team runs on autopilot all still agree with each other once the runtime underneath them changes.
Ruby moves. OpenSSL moves. Strict mode flips on whether you asked for it or not. And in 2026 there’s a decision to make before any of that technical work starts: which Puppet 8 are you actually moving to? Open-source Puppet 8.10 was the last release Perforce maintained. Puppet Core continues from 8.11 as a commercial product. Puppet Enterprise has its own console-and-orchestrator upgrade path entirely. OpenVox is the community-maintained continuation, carrying the open-source torch under new names.
Choose the target first. Repository access, package names, supported operating systems, lifecycle, entitlements and support expectations all hang off that one decision — everything below assumes you’ve already made it.
The four target paths
Open-source Puppet 8.10
Still installable, still runs. But Perforce says plainly that open-source Puppet gets nothing further from them past 8.10. Freezing here can be a legitimate, temporary compatibility step. It is not a security strategy — and treating it as one is how “temporary” quietly becomes “for the next three years.” See the Puppet Core 8.11 announcement.
Puppet Core 8
The Perforce-maintained platform, built from the open-source tree, distributed through protected repositories that require actual entitlements — no more anonymous apt-get install. Perforce documents a direct transition from open-source Puppet 8 to Puppet Core; if your installation is anything but vanilla, custom bits may need extra work. See Upgrading from open-source Puppet to Puppet Core.
Puppet Enterprise
PE bundles the platform with its console, orchestrator, classifiers and deployment tooling — and its own supported upgrade procedure, full stop. Don’t run open-source server commands against a PE primary and hope for the best; that’s not an upgrade, that’s an incident report waiting for a title. Follow the PE version-specific path instead. The current Puppet Enterprise upgrade documentation covers infrastructure and agent sequencing, cautions, migration, and module testing.
OpenVox 8
The community-maintained open-source implementation. Its own docs say it stays compatible with Puppet language and configuration while using replacement package names and repositories — same language, new labels, ship of Theseus for your configuration management. Treat the swap as a platform change anyway: test it on fresh systems or a controlled clone, back up /etc/puppetlabs, and validate server, database, terminus and module compatibility before you trust it in production. See the OpenVox installation and migration guidance.
The rest of this guide covers the code and runtime work all four paths share. Wherever it disagrees with your distribution’s own installation and lifecycle rules, theirs wins.
Breaking changes that deserve attention
Perforce’s own Puppet 7-to-8 upgrade notes lay out the real compatibility boundaries. Four of them will actually bite.
Ruby 3.2
Puppet 8 agents vendor MRI Ruby 3.2. Puppet Server 8 runs on JRuby 9.4, which implements most — not all — of the Ruby 3.1 interface. Plain Puppet DSL code barely notices. Your Ruby extensions will.
Inventory all of these before you touch a package manager:
- Custom facts.
- Ruby functions.
- Types and providers.
- Report processors.
- Indirector termini.
- Face, application, and plugin code.
- Gems installed into Puppet’s vendored Ruby or Puppet Server’s JRuby environment.
Run their unit tests against the target runtime, then actually exercise them in real catalog compilation — unit tests alone will lie to you by omission. Look for removed Ruby behavior, keyword-argument changes, standard-library gems that quietly stopped being bundled, and native extensions still built for the old runtime.
OpenSSL 3
Puppet 8 agents vendor OpenSSL 3. Anything compiled against Puppet’s previous OpenSSL — your own tooling, third-party native extensions — needs rebuilding. Old algorithms, old certificate material, or local integrations can trip over this even when the Puppet CA itself is perfectly healthy.
And while we’re on the subject: don’t regenerate the CA just because the major version ticked over. Back it up, test certificate operations, and touch trust infrastructure only when there’s a separate requirement and a complete rotation plan already written down. A CA rebuild is not a side effect of a Puppet upgrade — it’s its own project, with its own maintenance window and its own reasons to lose sleep.
Strict mode by default
Puppet 8 turns strict mode on by default. Code that references undefined variables, relies on invalid coercion, or leans on other previously-tolerated shortcuts can simply fail to compile.
There are compatibility settings that dial strictness back down. Treating them as the actual migration endpoint doesn’t fix anything — it just files the failure for later, with interest. Turn strict checking on in CI while you’re still on Puppet 7, fix what breaks there, and let the production cutover be the anticlimax it should be.
Legacy facts are no longer collected by default
$::osfamily and $facts['osfamily'] both need to become $facts['os']['family'] or the equivalent structured fact. Search manifests, templates, Hiera hierarchy interpolation, custom functions, and tests — not only .pp files. Legacy facts like to hide in string interpolation and hierarchy paths where a lazy grep won’t find them.
Puppet can be told to keep collecting legacy facts a while longer, but that’s a transition control, not a destination. The official module upgrade guidance is blunt about it: clean up legacy facts, top-scope variables, missing data types, and strict-mode issues before the jump, not after.
Hiera 3 backends
The Hiera 3 component is gone. Dropped. Deceased. Any backend implemented by extending Hiera::Backend needs to become a Hiera 5 extension, or be replaced outright. Ordinary Hiera 5 hierarchies, puppet lookup, and modern lookup functions were never the problem here.
Find custom backends early. They tend to live outside the control repository, quietly forgotten, until every catalog depending on them fails at once and someone has to remember they exist.
Phase 1: inventory the real platform
Capture versions and ownership for:
- Puppet agent, Puppet Server, PuppetDB, termini, and PostgreSQL.
- Operating systems and architectures for every infrastructure role and representative agents.
- Java and JVM configuration on Puppet Server and PuppetDB nodes.
- Control repositories, environments, deployment tooling, and CI images.
- Every module and its dependency constraints from the Puppetfile.
- Locally developed modules and all custom Ruby extensions.
- Installed gems, report processors, ENC integrations, secret backends, and webhooks.
- Certificate Authority location, expiry, backups, CRLs, and renewal behavior.
- External consoles, dashboards, orchestrators, and API consumers.
Also record baseline behavior: catalog compile time, run duration, failure rate, recurring changes, PuppetDB queue and query health, JVM memory, and report volume. Skip this and a technically flawless upgrade can still hide a serious regression — you just won’t have anything to catch it against.
Phase 2: make Puppet 7 behave like the target
Close the compatibility gap before you change a single package.
- Enable strict checks in development and CI.
- Replace legacy and top-scope fact access with structured facts.
- Add data types to public class parameters where practical.
- Remove deprecated language constructs and suppressed lint warnings.
- Move Hiera 3 backends and obsolete hierarchy patterns to Hiera 5.
- Update modules to releases declaring Puppet 8 support.
- Test custom Ruby code under Ruby 3.2 and the target Puppet Server runtime.
Useful checks include:
puppet parser validate manifests/site.pp
puppet epp validate templates/example.epp
pdk validate
pdk test unit
puppet lookup profile::example::setting --node test.example.com --explain
Run these through CI, with the same module and gem dependency resolution production will actually use. A developer laptop with its own Ruby version and unpinned gems isn’t a migration test — it’s a story you’ll tell later, ruefully.
Phase 3: prove catalog compatibility
Unit tests catch module behavior in isolation. They prove nothing about whether your full classification, Hiera data, facts, and module set compile together — which is, annoyingly, the part that actually matters.
Build representative fact sets for each operating-system family, role, environment, and important edge case. Compile catalogs on Puppet 7 and on the target Puppet 8 stack. Compare:
- Compilation success and warnings.
- Resource counts and types.
- Removed or newly managed resources.
- Dependency edges that affect ordering.
- File content and sensitive-data handling.
- Exported-resource and PuppetDB-dependent behavior.
- Compile time and memory use.
Then apply target catalogs to disposable or restored test nodes. Catalog equality isn’t the goal — provider and runtime changes may legitimately differ — but every difference needs an explanation, not a shrug.
Phase 4: rehearse the infrastructure upgrade
Clone or rebuild a representative non-production stack. Restore sanitized code, data, PuppetDB data if needed, and a safe copy of the CA — inside an isolated network, please. Exercise:
- Server startup and full catalog compilation.
- Certificate signing, renewal, revocation, and CRL distribution.
- PuppetDB command processing, queries, reports, and dashboard integrations.
- Code deployment and environment cache behavior.
- Backup and restore procedures.
- Monitoring, alerting, log collection, and service restart behavior.
- Agent compatibility across the oldest and newest supported operating systems.
Don’t discover, during the actual production window, that the new server package doesn’t exist for your current server OS. Platform support is part of this upgrade whether you scheduled it or not — sometimes a parallel rebuild is safer than an in-place OS-plus-Puppet-major-version leap.
Phase 5: upgrade infrastructure before agents
Puppet’s own agent upgrade guidance isn’t negotiable on this point: the server goes first. In a simple open-source or Puppet Core deployment, upgrade and verify the server-side components in the supported order for the chosen distribution, PuppetDB and termini compatibility included.
For load-balanced compilers, rotate nodes individually when the product documentation supports mixed operation. For Puppet Enterprise, follow the PE installer or Puppet Installation Manager sequence exactly — infrastructure nodes running incompatible versions can break agent runs and replication in ways that are tedious to untangle afterward.
After each infrastructure step, verify:
- Status endpoints and service health.
- Catalog compilation for representative nodes.
- PuppetDB command queues and query results.
- A controlled Puppet 7 agent run against the upgraded server.
- Report ingestion and external integrations.
The official Puppet Server upgrade procedure and your distribution’s version-specific release notes are the actual authority here — this guide gives you the shape, not the exact commands.
Phase 6: canary Puppet 8 agents
Start with nodes that are representative, observable, and recoverable — not just the handful of empty test machines nobody would miss. Include:
- Each supported operating-system family and major version.
- Nodes using custom facts, providers, or native extensions.
- High-resource catalogs and unusual Hiera paths.
- Systems with security hardening or restricted networking.
- At least one important service where the team knows what normal looks like.
For each canary:
- Back up configuration and record the installed package state.
- Run the last Puppet 7 catalog and keep its report.
- Upgrade the agent through the supported repository and package path.
- Run Puppet 8 in no-op and review every proposed change — actually read it, don’t skim.
- Apply only after the output is understood.
- Compare reports, facts, runtime, plugins, and service behavior with the baseline.
- Leave the canary through several normal run intervals before expanding.
Roll out in bounded cohorts. Pause automatically on compile failures, unexpected corrective changes, agent crashes, or a runtime regression that’s more than rounding error.
Rollback is a designed path
Downgrading the package is the easy part of rollback. Decide, before production, how you’d recover:
- Server packages and configuration.
- PuppetDB and PostgreSQL data.
- CA files and certificate state.
- Code and Hiera data deployments.
- Agent package repositories and pinned versions.
- Ruby gems and native extensions.
- External integrations that change schema or authentication behavior.
Don’t stack a Puppet major upgrade, a server OS migration, a CA rebuild, a Hiera redesign, and a module refactor into one irreversible event. Some of these can be prepared together, but their cutovers should stay separately observable and separately recoverable.
What “done” looks like
The migration is complete when:
- All production platforms use a supported target distribution and version.
- Catalogs compile without compatibility fallbacks or unexplained warnings.
- Legacy facts and Hiera 3 dependencies are gone, not just muted.
- Custom Ruby extensions are tested on the target runtimes.
- PuppetDB, reports, CA operations, deployments, and integrations are healthy.
- Performance is at least understood relative to the pre-upgrade baseline.
- The team can deploy code, diagnose failures, add agents, renew certificates, and restore the platform — without three people Googling the same Stack Overflow answer.
- Temporary compatibility settings have owners and removal dates — or are already gone.
The safest Puppet 8 migration is intentionally boring: most incompatibilities get removed while you’re still on Puppet 7, the target stack gets rehearsed before it’s real, infrastructure moves first, and agents move in cohorts small enough to actually watch. No fireworks. That’s the whole point.
If you want an environment-specific assessment, Puppet Health Check covers code, runtime, infrastructure, and upgrade readiness. For implementation and rollout, there’s Smart Puppet Support. [Shameless plug].
Alvabot
