Over the course of the 3.x series, Puppet has included work-in-progress releases of a rewritten Puppet language, which can be enabled with a setting. This revised language includes significant breaking changes, major additions, and a new underlying implementation.
In Puppet 4.0, the rewritten language is the new normal; in this version of Puppet, it’s optional, and you can choose when and where to enable it.
As of Puppet 3.7.5, the future parser is functionally identical to the Puppet language in Puppet 4.0. It’s ready for real-world use, and it should be an important part of your migration to Puppet 4.
To enable the future parser, you need to set the parser
setting to future
. This setting is used by the Puppet master and Puppet apply applications.
There are three ways to change the parser:
parser = future
in the [main]
section of puppet.conf.parser = future
in that environment’s environment.conf file. This is only available in Puppet 3.7.5 and later.--parser future
on the command line when running Puppet apply.Note: If you installed Puppet with something other than the official packages, ensure that the rgen
gem is installed on your Puppet master(s) (or all nodes, if running Puppet apply).
Puppet now has iteration and looping features, which can help you write more succinct and readable code.
For an introduction, see the language page on iteration.
The revised language has a more consistent concept of data types now, and you can take advantage of it in several ways. It’s now easier to test what data type a value is and catch common errors early by restricting allowed values for class/defined type parameters.
For an introduction, see the language page on data types.
The frustrations of relative namespace lookup are gone. (Not actually fixed in 3.8.1; see PUP-4818.) Most expressions with values work the same now, so the weird rules about where you can use a variable but not a function call are gone. A lot of edge cases have been cleaned up, and everything is just a lot nicer.
The revised language includes breaking changes, and some of them might break your existing Puppet code or make it behave differently. Watch out for the following:
The rules for comparing values with the comparison operators have changed quite a bit, and some of the changes might reverse the results of comparisons in your code. So you’ll want to check your if
, unless
, case
, and selector expressions to see if you’re relying on changed behavior.
The most notable changes are:
in
operator now ignores case when comparing strings, same as the ==
operator."3" < 40
is now an error, because strings and numbers aren’t the same anymore.undef
converts to false
and all other non-boolean values convert to true
; in the 3.x parser, empty strings were also false.Look for any place in your code that either checks truth of a fact or makes a numerical comparison with a fact, and make sure they’re ready for Puppet 4.
This isn’t strictly part of the future parser, but it’s a related change that and can be enabled early with a setting.
Old versions of Facter returned all facts as strings, but modern versions can return facts of many data types. Puppet will use the real fact data types if the stringify_facts
setting is set to false
, which is the default in Puppet 4.0 and up.
This is generally good, but a lot of older code assumes that “boolean” facts like $is_virtual
are actually strings, using conditionals like if $is_virtual == "true"
. If you enable multi-type facts, any conditionals that treat booleans like strings will silently change their behavior, which is super bad. You’ll need to change these when migrating to the future parser.
Most people will want a period of overlap, where their code can work in both Puppet 4 and Puppet 3. The safe and compatible way to handle boolean facts is to:
"$is_virtual"
)…str2bool
function (str2bool("$is_virtual")
).This will behave identically in new and old Puppet versions.
Search your code for any use of the file
type’s mode
attribute, and make sure the mode is quoted. Unquoted numbers in the mode
attribute will cause compilation errors in Puppet 4 (and a deprecation warning in this version of Puppet).
We enabled integers in octal and hexidecimal bases as part of making data types more rigorous, and Puppet internally normalizes these numbers to decimal base. And since the mode
attribute is actually just a string that’s passed to the underlying operating system tools, a literal octal number would be converted into decimal before being converted to a string, which would result in something very unwanted. So Puppet 4 fails early if you do that, instead of doing anything weird.