![Page 1: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/1.jpg)
puppetconf.com #puppetconf
![Page 2: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/2.jpg)
Loops and Unicorns Future of the Puppet Language Henrik Lindberg Consulting Engineer | Puppet Labs @hel
![Page 3: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/3.jpg)
puppetconf.com #puppetconf
• New parser • New Language Features • New approach – Opt in to New/Experimental Features – Maintaining Backwards Compatibility
Introduction
![Page 4: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/4.jpg)
New Parser The future is already here…
![Page 5: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/5.jpg)
puppetconf.com #puppetconf
• Rewritten from the ground up • Removes quirky grammar constraints • Improves error messages • Enabler for: – opt-in to new and experimental features – backwards compatibility
• Use on command line, or in settings
New Parser
puppet apply –-parser future ...
![Page 6: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/6.jpg)
puppetconf.com #puppetconf
De-Quirk
"This is a random number: ${fqdn_rand()}"
join([1,2,3])
$a = 0x0EH $b = 0778
Interpolation and functions work: Literal Array / Hash as argument in calls works: Numbers must now be valid:
![Page 7: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/7.jpg)
puppetconf.com #puppetconf
Array & Hash
$a = [1,2,3] $b = [4,5,6] $c = $a + $b
Concatenate Arrays: Append to Array: Merge Hash:
$d = $a << 4
$a = {name => 'mary'} $b = {has => 'a little lamb'} $c = $a + $b
![Page 8: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/8.jpg)
puppetconf.com #puppetconf
Misc
unless $something { . . .} else { . . . }
Unless Else: Assignment is an expression: Expression separator ';' :
$a = $b = 10 fqdn_rand($seed = 30)
$a = $x[1][1] $a = $x[1];[1]
![Page 9: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/9.jpg)
puppetconf.com #puppetconf
Error Reporting
Error: Could not parse for environment production: Syntax error at 'node' at line 1 on node kermit.example.com
puppet apply -e '$a = node "a+b" { }' Then: Now:
Error: Invalid use of expression. A Node Definition does not produce a value at line 1:6 Error: The hostname 'a+b' contains illegal characters (only letters, digits, '_', '-', and '.' are allowed) at line 1:11 Error: Classes, definitions, and nodes may only appear at toplevel or inside other classes at line 1:6 Error: Could not parse for environment production: Found 3 errors. Giving up on node kermit.example.com
![Page 10: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/10.jpg)
New Approach
![Page 11: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/11.jpg)
puppetconf.com #puppetconf
• Forgiving Grammar • Validation is separate – Can validate a particular language version – Language version != Puppet version
• Evaluation is separate – Can evaluate a particular language version way – Language version != Puppet version
Separation of Language Concerns
![Page 12: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/12.jpg)
New Language Features
![Page 13: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/13.jpg)
puppetconf.com #puppetconf
![Page 14: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/14.jpg)
puppetconf.com #puppetconf
![Page 15: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/15.jpg)
puppetconf.com #puppetconf
![Page 16: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/16.jpg)
puppetconf.com #puppetconf
![Page 17: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/17.jpg)
puppetconf.com #puppetconf
• Iteration & Lambdas • Puppet Bindings • Heredoc support • Puppet Templates
New Language Features
![Page 18: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/18.jpg)
Iteration & Lambdas
![Page 19: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/19.jpg)
puppetconf.com #puppetconf
Concepts
each($foo) |$x| { notice $x }
The lambda: Inline call:
$foo.each |$x| { notice $x } each($foo) |$x| { notice $x }
![Page 20: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/20.jpg)
puppetconf.com #puppetconf
• each • select – reject • collect • reduce • slice
Custom functions can take a lambda!
Iterating Functions
![Page 21: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/21.jpg)
puppetconf.com #puppetconf
Each - Array
$a = ['a', 'b', 'c'] $a.each |$value| { notice $value }
Iterating over an array: Produces:
Notice: Scope(Class[main]): a Notice: Scope(Class[main]): b Notice: Scope(Class[main]): c
![Page 22: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/22.jpg)
puppetconf.com #puppetconf
Each – Array (with index)
$a = ['a', 'b', 'c'] $a.each |$index, $value| { notice "$index = $value" }
Iterating over an array – with index: Produces:
Notice: Scope(Class[main]): 0 = a Notice: Scope(Class[main]): 1 = b Notice: Scope(Class[main]): 2 = c
![Page 23: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/23.jpg)
puppetconf.com #puppetconf
Each - Hash
$a = {a => 10, b => 20, c => 30} $a.each |$key, $value| { notice "$key = $value" }
Iterating over a hash – with key and value: Produces:
Notice: Scope(Class[main]): a = 10 Notice: Scope(Class[main]): b = 20 Notice: Scope(Class[main]): c = 30
![Page 24: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/24.jpg)
puppetconf.com #puppetconf
Each – Hash (elements)
$a = {a => 10, b => 20, c => 30} $a.each |$elem| { notice "${elem[0]} = ${elem[1]}" }
Iterating over a hash elements: Produces:
Notice: Scope(Class[main]): a = 10 Notice: Scope(Class[main]): b = 20 Notice: Scope(Class[main]): c = 30
![Page 25: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/25.jpg)
puppetconf.com #puppetconf
Select / Reject
$a = [1, 2, 3] notice $a.select |$value| { $v == 2 } notice $a.reject |$value| { $v == 2 }
Select and Reject elements: Produces:
Notice: Scope(Class[main]): 2 Notice: Scope(Class[main]): 1 3
![Page 26: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/26.jpg)
puppetconf.com #puppetconf
Collect
$a = [1, 2, 3] notice $a.collect |$value| { $v * 10 }
Transform each element with collect: Produces:
Notice: Scope(Class[main]): 10 20 30
![Page 27: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/27.jpg)
puppetconf.com #puppetconf
Reduce
$a = [1, 2, 3] notice $a.reduce |$memo, $value| { $memo + $value }
Reduce all elements into one: Produces:
Notice: Scope(Class[main]): 6
![Page 28: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/28.jpg)
puppetconf.com #puppetconf
Examples
$usernames.each |$x| { file { "/home/$x/.somerc": owner => $x } }
Set ownership of some "rc-file" for each user: Setting 'owner' and 'mode' from a Hash:
$users_with_mode = ['fred' => 0666, 'mary' => 0777 ] $users_with_mode.each |$user, $mode| { file {"/home/$user/.somerc": owner => $user, mode => $mode } }
![Page 29: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/29.jpg)
puppetconf.com #puppetconf
Examples
$a.select |$x| { $x =~ /com$/ }.each |$x| { file { "/somewhere/$x": owner => $x } }
Filter and create resources: Include classes based on array of roles:
$roles.each |$x| { include "role_$x" }
![Page 30: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/30.jpg)
puppetconf.com #puppetconf
Custom Function (Ruby)
pp_block = args[-1]
Lambda always last argument: Was it given? Call it:
pp_block.is_a? Puppet::Parser::AST::Lambda
# in a custom function, self is scope) pp_block.call(self, 'hello', 'world')
![Page 31: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/31.jpg)
puppetconf.com #puppetconf
• http://links.puppetlabs.com/arm2-iteration • http://links.puppetlabs.com/arm2-examples
ARM 2 - Iteration
![Page 32: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/32.jpg)
Heredoc
Not yet on master branch https://github.com/puppetlabs/puppet/pull/1659
![Page 33: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/33.jpg)
puppetconf.com #puppetconf
Heredoc - Syntax
@( ["]<endtag>["] [:<syntax>] [/<escapes>] ) <text> [|][-] <endtag>
ENDS-‐HERE anything not in <text> "ENDS-‐HERE" with interpola2on
:json syntax check result
/tsrn$L turns on escape / turns on all
| set le7 margin
-‐ trim trailing
t tab s space r return n new-‐line $ $ L <end of line>
![Page 34: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/34.jpg)
puppetconf.com #puppetconf
Heredoc – example Example:
#.........1.........2.........3.........4.........5.... $a = @(END) This is indented 2 spaces in the source, but produces a result flush left with the initial 'T' This line is thus indented 2 spaces. | END
![Page 35: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/35.jpg)
puppetconf.com #puppetconf
Heredoc – example multiple on same line:
#.........1.........2.........3.........4.........5.... foo(@(FIRST), @(SECOND)) This is the text for the first heredoc FIRST This is the text for the second SECOND
![Page 36: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/36.jpg)
puppetconf.com #puppetconf
For more examples and details • http://links.puppetlabs.com/arm4-heredoc
ARM-4 Heredoc
![Page 37: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/37.jpg)
Puppet Templates
Not yet on master branch https://github.com/puppetlabs/puppet/pull/1660
![Page 38: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/38.jpg)
puppetconf.com #puppetconf
• Embedded Puppet (EPP) - like ERB • Same tags
§ <%, <%=, <%-, <%%, <%# § %>, -%>
• Expressions are Puppet DSL • Parameterized • .epp file extension (by convention)
Puppet Templates
![Page 39: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/39.jpg)
puppetconf.com #puppetconf
Use by calling epptemplate(<name> [,<params_hash>]) inline_epptemplate(<text>[,<params_hash>])
Puppet Templates
$x = 'human' inline_epptemplate('This is not the <%= $x %> you are looking for.', { 'x' => 'droid'}) # => 'This is not the droid you are looking for.'
![Page 40: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/40.jpg)
puppetconf.com #puppetconf
• Parameterized – declare parameters – set default values – parameter without value and no default = error
Puppet Templates
<%- ($x = 'human') -%> This is not the <%= $x %> you are looking for.
![Page 41: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/41.jpg)
puppetconf.com #puppetconf
For more examples and details • http://links.puppetlabs.com/arm3-
puppet_templates
ARM-3 Puppet Templates
![Page 42: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/42.jpg)
Puppet Bindings / Data in Modules
![Page 43: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/43.jpg)
puppetconf.com #puppetconf
• More powerful data bindings • For both Data, and Puppet Extensions • Composes Hiera2 data in modules and
environment + Hiera1 • Bindings in Ruby • Opt in on command line or in settings
Puppet Binder
puppet apply --binder puppet apply –-parser future ...
![Page 44: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/44.jpg)
puppetconf.com #puppetconf
• Default: – All hiera-2 data (in default location) and all
(default) ruby bindings from all modules on module path composed
– Site level hiera-2 data and ruby bindings override contributions from modules.
• Customize – include alternatives, exclude bindings – add / reorganize overriding "layers"
Configuration
![Page 45: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/45.jpg)
puppetconf.com #puppetconf
• Composable • Interpolation using Puppet DSL expressions • Changed hiera.yaml syntax (for version 2)
Hiera 2
![Page 46: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/46.jpg)
puppetconf.com #puppetconf
Minimal opt-in (in a module)
--- version: 2
hiera.yaml: data/common.yaml: data/${osfamily}.yaml:
--- myclass::myparam: '1.2.3'
--- myclass::myparam: '2.4.6'
![Page 47: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/47.jpg)
puppetconf.com #puppetconf
For more examples and details • http://links.puppetlabs.com/arm8-
puppet_bindings • http://links.puppetlabs.com/arm9-
data_in_modules
ARM-8 & 9
![Page 48: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/48.jpg)
![Page 49: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/49.jpg)
Thank You Henrik Lindberg Consulting Engineer | Puppet Labs @hel
Collaborate. Automate. Ship.
![Page 50: Loops and Unicorns - The Future of the Puppet Language - PuppetConf 2013](https://reader033.vdocuments.us/reader033/viewer/2022052823/554f5d7fb4c905b9508b5539/html5/thumbnails/50.jpg)
Follow us on Twitter @puppetlabs youtube.com/puppetlabsinc slideshare.net/puppetlabs
Collaborate. Automate. Ship.