Puppet 3.5 Release Notes

This version of Puppet is not included in Puppet Enterprise. The latest version of PE includes Puppet 4.4. A newer version is available; see the version menu above for details.

This page tells the history of the Puppet 3.5 series. (Elsewhere: release notes for Puppet 3.0 – 3.4)

Puppet’s version numbers use the format X.Y.Z, where:

  • X must increase for major backwards-incompatible changes
  • Y may increase for backwards-compatible new functionality
  • Z may increase for bug fixes

How to Upgrade

If you’re upgrading from a 3.x version of Puppet, you can usually just go for it. Upgrade your puppet master servers before upgrading the agents they serve. (But do look at the table of contents above and see if there are any “Upgrade Warning” notes for the new version.)

If you’re upgrading from Puppet 2.x, please learn about major upgrades of Puppet first! We have important advice about upgrade plans and package management practices. The short version is: test first, roll out in stages, give yourself plenty of time to work with. Also, read the release notes for Puppet 3 for a list of all the breaking changes made between the 2.x and 3.x series.

Puppet 3.5.1

Released April 16, 2014. (RC1: April 10.)

3.5.1 is a backward-compatible features and fixes release in the Puppet 3 series. It fixes the problems that 3.5.0 caused with dynamic environments and the yumrepo provider, as well as a couple of smaller bugs.

Dynamic Environment Fixes

Puppet 3.5.0 introduced directory environments, which provide a simpler alternative to the very powerful dynamic environments pattern. Unfortunately, the added functionality conflicted pretty badly with old-style dynamic environments.

This release changes the behavior of directory environments so that they have to be enabled by a feature flag (the environmentpath setting) before they can be used. To enable directory environments, you can set environmentpath = $confdir/environments in the [main] section of puppet.conf.

See the reference page for directory environments for more details.

Related issue:

Yumrepo Fixes

Puppet 3.5.0 included some changes to the yumrepo resource type that inadvertently broke existing configurations. This release fixes the following issues:

Other Fixes

Puppet 3.5.0

Released April 3, 2014. (RC1: March 14. RC2: March 24. RC3: March 31.)

3.5.0 is a backward-compatible features and fixes release in the Puppet 3 series. The biggest things in this release are:

  • A new way to set up environments, which replaces the popular “dynamic environments” pattern
  • A cleaner replacement for the classic import nodes/*.pp pattern
  • Scriptable configuration with a new puppet config set command
  • A new global $facts hash
  • Early support for hashes and arrays in fact values
  • Improvements to the future parser
  • Support for RHEL 7, Ruby 2.1, and Facter 2.0

…along with many smaller improvements and bug fixes.

RECALLED on April 4, 2014

When 3.5.0 went final, users found breaking issues with the yumrepo resource type and with dynamic environments which hadn’t been uncovered in the release candidate period. (See the “UPGRADE WARNING” headers below.)

We decided these issues were annoying enough to cause a bad user experience, so:

  • We have pulled 3.5.0 from public repositories.
  • We recommend that users who have upgraded revert to Puppet 3.4.3 until we can address these issues.

Sorry about the inconvenience, and we’ll be issuing a 3.5.1 bugfix release very soon.

UPGRADE WARNING: Bugs With Old-Style Dynamic Environments

If you use dynamic environments — that is, if your puppet.conf file references the $environment variable — either wait for 3.5.1 or temporarily set the following in the [main] or [master] section of your puppet master’s puppet.conf:

environmentpath = $confdir/no_environments_here

If you just upgrade without doing that, your setup might break.

In more detail:

Most people who use dynamic environments put their environment data in $confdir/environments. This also happens to be the default home for the new-style directory environments, and Puppet will attempt to use your existing environments with the new conventions.

Unfortunately, there are some problems if your dynamic environments don’t work exactly like directory environments. PUP-2158 is the master ticket for working on these. A few of the more frustrating ones:

  • If your environments only include a modules directory and don’t reliably include a main mainfest, Puppet won’t fall back to your global main manifest; it’ll act like the main manifest is empty.
  • If your modulepath includes any directories other than $confdir/modules and $confdir/environments/$environment/modules, they won’t get used.

We want dynamic environment users to be able to transition smoothly, so we consider these to be bugs. We’re working on fixing them for 3.5.1. In the meantime, you have two options if you use dynamic environments and want to run 3.5.0:

  • Tell Puppet not to treat your dynamic environments like directory environments, by pointing the environmentpath setting at a dummy directory. Things will now work like they always did. (At some point you’ll want to reverse that, so make a note to yourself in the config file comments.)
  • Switch over to directory environments completely. You’ll need to add a manifests directory to each environment, and you may want to set the basemodulepath setting. See the page on directory environments for more details.


If you use the yumrepo type, don’t upgrade quite yet; wait for 3.5.1. If you already upgraded, you may need to downgrade to the latest 3.4 release.

We refactored the yumrepo resource type as part of this release, in order to improve the code quality, fix a few minor issues, and make it easier to fix future issues.

Unfortunately, this introduced new bugs, which break existing configurations. Our users discovered these after 3.5.0 went final:

  • PUP-2162 — If baseurl or gpgkey use multiple URLs, the resource will fail.
  • PUP-2150 — Setting attributes like baseurl => absent to suppress settings in the generated repo file is broken.

Sorry for the annoyance! We have fixes that will go into Puppet 3.5.1.

Directory Environments

Lots of people have been using dynamic environments based on VCS checkouts to test and roll out their Puppet code, as described in this classic blog post. That pattern is great, but it’s complicated to set up and it pretty much works by accident, so we wanted a better way to support it.

Now we have one! The new feature is called directory environments, to distinguish them from the older environments that had to be set in the config file.

The short version is:

  • Create a $confdir/environments directory on your puppet master.
  • Each new environment is a subdirectory of that directory. The name of the directory will become the name of the environment.
  • Each environment dir contains a modules directory and a manifests directory.
    • The modules directory will become the first directory in the modulepath (with the new basemodulepath setting providing a global list of other directories to use).
    • The manifests directory will be used as the manifest setting (see “Auto-Import” below).
  • No other configuration is needed. Puppet will automatically discover new environments.

The upshot is that you can do a git clone or git-new-workdir in your environments directory, and nodes can immediately start requesting catalogs in that environment.

This feature isn’t quite finished yet: it’s missing the ability to do complex edits to the modulepath or set the config_version setting per-environment, which didn’t make the release deadline. However, it should already be good enough for most users.

For full details, see:

Related issues:

Auto-Import (Use a Directory as Main Manifest)

You can now set the manifest setting to a directory instead of a single file. (E.g. manifest = $confdir/manifests) If you do, the puppet master will parse every .pp file in that directory in alphabetical order (without descending into subdirectories) and use the whole set as the site manifest. Similarly, you can give puppet apply a directory as its argument, and it’ll do the same thing.

We did this because:

  • import is horrible…
  • …but the import nodes/*.pp pattern is good.

Lots of people like to use node definitions and keep every node in a separate file. In Puppet 3.4 and earlier, this meant putting an import statement in puppet.conf and storing the node files in another directory. Now, you can just put all your nodes in the main manifest dir and point the manifest setting at it.

And since this was the last real reason to use import, we can deprecate it now! (See “Deprecations and Removals” below.)

See the page about the manifest directory for more details.

Related issues:

Scriptable Configuration (puppet config set)

You can now change Puppet’s settings without parsing the config file, using the puppet config set command. This is mostly useful for configuring Puppet as part of your provisioning process, but can be convenient for one-off changes as well. For details, see the page about changing settings on the command line.

Related issues:

Global $facts Hash

You have to manually enable this (along with the $trusted hash) by setting trusted_node_data = true in puppet.conf on your puppet master(s). It’ll be on by default in Puppet 4.

In addition to using $fact_name, you can now use $facts[fact_name] to get a fact value. The $facts hash is protected and can’t be overridden locally, so you won’t need the $:: idiom when using this.

Our hope is that this will visibly distinguish facts from normal variables, make Puppet code more readable, and eventually clean up the global variable namespace. (That’ll take a while, though — we probably won’t be able to disable $fact_name until, like, Puppet 5.)

Related issues:

Structured Facts (Early Version)

You have to manually enable this by setting stringify_facts = false in puppet.conf on your puppet agents. It’ll be enabled by default in Puppet 4.

In Facter 2.0 and later, fact values can be any data type, including hashes, arrays, and booleans. (This is a change from Facter 1.7, where facts could only be strings.) If you enable structured facts in Puppet, you can do more cool stuff in your manifests and templates with any facts that use this new feature.

These are the early days of structured facts support — they work in Puppet and Facter now, but none of the built-in facts use data structures yet, and external systems like PuppetDB haven’t yet been updated to take advantage of them. (Any structured facts will still get smooshed into strings when they’re sent to PuppetDB.) But if you have a use for hashes or arrays in your custom facts, turn this on and give it a try.

Future Parser is Faster and Better

We think the future parser is fast enough to use in a large environment now — we haven’t done extensive benchmarking with real-life manifests, but the testing we’ve done suggests it’s about on par with the default parser. So if you’ve been waiting to try it out, give it a spin and let us know how it goes.

It also has some new tricks in this release:

  • HEREDOCs are now allowed! This is a much more convenient way to handle large strings. See here for details.
  • A new template language was added, based on the Puppet language instead of on Ruby. See here for details.
  • There’s a new “future” evaluator that goes along with the future parser.

Related issues:

Platform Support Updates

Newly supported:

  • Puppet now supports RHEL 7, with packages and acceptance testing. This mostly involved cleaning up resource providers to handle things like systemd more cleanly.
  • We’re running acceptance tests on Fedora 19 and 20, now, too.
  • Facter 2.0.1 works with Puppet 3.5, including its new structured facts support (see above).
  • We have early support for Ruby 2.1. We’re running spec tests on it, so we think it works fine! But since none of our testing platforms ship with it, we aren’t running acceptance tests on it, which means there might be problems we don’t know about yet.

Newly abandoned:

  • Support for Fedora 18 is done, since it EOL-ed in January; no more acceptance tests or packages.
  • Facter 1.6 is no longer supported with Puppet 3.5.

Related issues:

Smaller New Features

In addition to the big-ticket improvements above, we added a lot of smaller features.

Misc features:

  • You can now put external facts in modules, and they will be synced to all agent nodes. This requires Facter 2.0.1 or later. To use this feature, put your external facts in a facts.d directory, which should exist at the top level of the module.
  • Certificate extensions will now appear in the $trusted hash.
  • There’s a new strict_variables setting; if set to true, it will throw parse errors when accessing undeclared variables. Right now, this will wreak havoc; eventually, it will make Puppet code easier to debug.
  • Related to the last: The defined function can now test whether a variable is defined. Note that you have to single-quote the variable name, like this: defined('$my_var') — otherwise, the function will receive the value of the variable instead of its name. Anyway, going forward, this will be a more accurate way to distinguish between false, undef, and uninitialized variables, especially if you’re using strict_variables = true.
  • The http report processor can use basic auth now when forwarding reports.
  • Puppet apply now has a --test option that acts much like puppet agent’s --test.
  • On Windows, the puppet agent service will now log activity using the Windows Event Log instead of a logfile.
  • Environment and transaction UUID information is now included when submitting facts to PuppetDB. (This will be used in a future version of PuppetDB.)

Type and provider features:

  • The ssh_authorized_key type can use ssh-ed25519 keys now.
  • When service resources fail to start or restart, they’ll log the exit code, stdin, and stderr text as Puppet errors to help with debugging.
  • The rpm package provider now accepts virtual packages.
  • The rpm package provider now supports uninstall_options.
  • The package type has a new package_settings attribute. This is a property that can be implemented differently per-provider; currently nothing uses it, but there are plans to make the FreeBSD provider use it for port options.
  • The user type now validates the shell attribute, to make sure it actually exists and is executable.
  • You can now use msgpack as the on-disk cache format for some of Puppet’s generated data types.
  • The file type has a new validate_cmd attribute that can help protect against accidentally writing broken config files.
  • The resources type has a new unless_uid attribute that acts like an improved version of the unless_system_user attribute — it lets you protect multiple UIDs and ranges of UIDs from deletion when purging user resources.
  • You can now purge unmanaged cron resources with the resources type.

Features for extension writers:

  • The Puppet::Util::Profiler#profile API is now public, and can be used by extensions like indirector termini and report handlers.
  • There’s a new v2.0 HTTP API, which doesn’t have to abide by the (sometimes inconsistent and weird) semantics of the main API. Right now, the only v2.0 endpoint is for getting information about environments via the API. See the developer documentation for details.

Related issues:

Deprecations and Removals

As we start to get ready for Puppet 4, we’re deprecating some features we’re hoping to remove or replace. (Be ready for more of these in Puppet 3.6, too.) Using deprecated features will cause warnings to be logged on the puppet master; these features will be removed in Puppet 4.

Deprecations in the Puppet language:

  • The import keyword is deprecated. Instead of importing, you should set your manifest setting to a directory of .pp files.
  • Modifying arrays and hashes in Puppet code or templates is deprecated. (This actually should never have been possible, but we can’t kill it in a minor version because it might break something.)

Deprecations in the type and provider API:

  • Using the :parent option when creating a type is deprecated. This actually hasn’t worked for a long while, but now it will warn you that it won’t do anything.


  • The experimental bindings-based Hiera2/data-in-modules code has been removed. We’re back to the drawing board on this.

Related issues:

Performance Improvements

3.5 is faster! We found a situation where defined types were a lot slower than they needed to be, some slow cases in puppet cert list and the module tool, and a few other performance wins.

Related issues:

Bug Fixes and Clean-Ups

We fixed a bunch of bugs in types and providers (including a big cleanup of the yumrepo type), improved standards-compliance in our use of certificates, fixed a bunch of Windows-specific problems, cleaned up some inconsistencies, and fixed some bugs that don’t fit in any particular bucket.

Type and provider bugs:

Windows-related bugs:

Standards compliance improvements:


General bugs:

Bugs introduced in 3.5 and fixed during the release candidate period:

Fixed in RC3:

Fixed in RC2:

All Resolved Issues for 3.5.0

Our ticket tracker has the list of all issues resolved in Puppet 3.5.0.

↑ Back to top