dive into puppet 4

84
Dive into Puppet 4 Dive into Puppet 4 Dive into Puppet 4 Dive into Puppet 4 Dive into Puppet 4 Dive into Puppet 4 Dive into Puppet 4 Dive into Puppet 4 Dive into Puppet 4 Dive into Puppet 4 Dive into Puppet 4 Dive into Puppet 4 Dive into Puppet 4 Dive into Puppet 4 Dive into Puppet 4 Dive into Puppet 4 Dive into Puppet 4 A new way to puppetize A new way to puppetize A new way to puppetize A new way to puppetize A new way to puppetize A new way to puppetize A new way to puppetize A new way to puppetize A new way to puppetize A new way to puppetize A new way to puppetize A new way to puppetize A new way to puppetize A new way to puppetize A new way to puppetize A new way to puppetize A new way to puppetize Julien Pivotto Julien Pivotto Julien Pivotto Julien Pivotto Julien Pivotto Julien Pivotto Julien Pivotto Julien Pivotto Julien Pivotto Julien Pivotto Julien Pivotto Julien Pivotto Julien Pivotto Julien Pivotto Julien Pivotto Julien Pivotto Julien Pivotto Belgian Puppet User Group Belgian Puppet User Group Belgian Puppet User Group Belgian Puppet User Group Belgian Puppet User Group Belgian Puppet User Group Belgian Puppet User Group Belgian Puppet User Group Belgian Puppet User Group Belgian Puppet User Group Belgian Puppet User Group Belgian Puppet User Group Belgian Puppet User Group Belgian Puppet User Group Belgian Puppet User Group Belgian Puppet User Group Belgian Puppet User Group September 10, 2015 September 10, 2015 September 10, 2015 September 10, 2015 September 10, 2015 September 10, 2015 September 10, 2015 September 10, 2015 September 10, 2015 September 10, 2015 September 10, 2015 September 10, 2015 September 10, 2015 September 10, 2015 September 10, 2015 September 10, 2015 September 10, 2015

Upload: julien-pivotto

Post on 11-Jan-2017

1.569 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: Dive into Puppet 4

Dive into Puppet 4Dive into Puppet 4Dive into Puppet 4Dive into Puppet 4Dive into Puppet 4Dive into Puppet 4Dive into Puppet 4Dive into Puppet 4Dive into Puppet 4Dive into Puppet 4Dive into Puppet 4Dive into Puppet 4Dive into Puppet 4Dive into Puppet 4Dive into Puppet 4Dive into Puppet 4Dive into Puppet 4

A new way to puppetizeA new way to puppetizeA new way to puppetizeA new way to puppetizeA new way to puppetizeA new way to puppetizeA new way to puppetizeA new way to puppetizeA new way to puppetizeA new way to puppetizeA new way to puppetizeA new way to puppetizeA new way to puppetizeA new way to puppetizeA new way to puppetizeA new way to puppetizeA new way to puppetize

Julien PivottoJulien PivottoJulien PivottoJulien PivottoJulien PivottoJulien PivottoJulien PivottoJulien PivottoJulien PivottoJulien PivottoJulien PivottoJulien PivottoJulien PivottoJulien PivottoJulien PivottoJulien PivottoJulien Pivotto

Belgian Puppet User GroupBelgian Puppet User GroupBelgian Puppet User GroupBelgian Puppet User GroupBelgian Puppet User GroupBelgian Puppet User GroupBelgian Puppet User GroupBelgian Puppet User GroupBelgian Puppet User GroupBelgian Puppet User GroupBelgian Puppet User GroupBelgian Puppet User GroupBelgian Puppet User GroupBelgian Puppet User GroupBelgian Puppet User GroupBelgian Puppet User GroupBelgian Puppet User GroupSeptember 10, 2015September 10, 2015September 10, 2015September 10, 2015September 10, 2015September 10, 2015September 10, 2015September 10, 2015September 10, 2015September 10, 2015September 10, 2015September 10, 2015September 10, 2015September 10, 2015September 10, 2015September 10, 2015September 10, 2015

Page 2: Dive into Puppet 4

$::user$::user$::user$::user$::user$::user$::user$::user$::user$::user$::user$::user$::user$::user$::user$::user$::userJulien PivottoJulien PivottoJulien PivottoJulien PivottoJulien PivottoJulien PivottoJulien PivottoJulien PivottoJulien PivottoJulien PivottoJulien PivottoJulien PivottoJulien PivottoJulien PivottoJulien PivottoJulien PivottoJulien Pivotto

• Open-Source consultant at inuits.euOpen-Source consultant at inuits.euOpen-Source consultant at inuits.euOpen-Source consultant at inuits.euOpen-Source consultant at inuits.euOpen-Source consultant at inuits.euOpen-Source consultant at inuits.euOpen-Source consultant at inuits.euOpen-Source consultant at inuits.euOpen-Source consultant at inuits.euOpen-Source consultant at inuits.euOpen-Source consultant at inuits.euOpen-Source consultant at inuits.euOpen-Source consultant at inuits.euOpen-Source consultant at inuits.euOpen-Source consultant at inuits.euOpen-Source consultant at inuits.eu

• Puppet User since 2011Puppet User since 2011Puppet User since 2011Puppet User since 2011Puppet User since 2011Puppet User since 2011Puppet User since 2011Puppet User since 2011Puppet User since 2011Puppet User since 2011Puppet User since 2011Puppet User since 2011Puppet User since 2011Puppet User since 2011Puppet User since 2011Puppet User since 2011Puppet User since 2011• Speaker/attendee at PuppetcampsSpeaker/attendee at PuppetcampsSpeaker/attendee at PuppetcampsSpeaker/attendee at PuppetcampsSpeaker/attendee at PuppetcampsSpeaker/attendee at PuppetcampsSpeaker/attendee at PuppetcampsSpeaker/attendee at PuppetcampsSpeaker/attendee at PuppetcampsSpeaker/attendee at PuppetcampsSpeaker/attendee at PuppetcampsSpeaker/attendee at PuppetcampsSpeaker/attendee at PuppetcampsSpeaker/attendee at PuppetcampsSpeaker/attendee at PuppetcampsSpeaker/attendee at PuppetcampsSpeaker/attendee at Puppetcamps• Member of the Belgian PUGMember of the Belgian PUGMember of the Belgian PUGMember of the Belgian PUGMember of the Belgian PUGMember of the Belgian PUGMember of the Belgian PUGMember of the Belgian PUGMember of the Belgian PUGMember of the Belgian PUGMember of the Belgian PUGMember of the Belgian PUGMember of the Belgian PUGMember of the Belgian PUGMember of the Belgian PUGMember of the Belgian PUGMember of the Belgian PUG• Puppet core contributorPuppet core contributorPuppet core contributorPuppet core contributorPuppet core contributorPuppet core contributorPuppet core contributorPuppet core contributorPuppet core contributorPuppet core contributorPuppet core contributorPuppet core contributorPuppet core contributorPuppet core contributorPuppet core contributorPuppet core contributorPuppet core contributor• Puppet(labs) modules contributorPuppet(labs) modules contributorPuppet(labs) modules contributorPuppet(labs) modules contributorPuppet(labs) modules contributorPuppet(labs) modules contributorPuppet(labs) modules contributorPuppet(labs) modules contributorPuppet(labs) modules contributorPuppet(labs) modules contributorPuppet(labs) modules contributorPuppet(labs) modules contributorPuppet(labs) modules contributorPuppet(labs) modules contributorPuppet(labs) modules contributorPuppet(labs) modules contributorPuppet(labs) modules contributor• @roidelapluie@roidelapluie@roidelapluie@roidelapluie@roidelapluie@roidelapluie@roidelapluie@roidelapluie@roidelapluie@roidelapluie@roidelapluie@roidelapluie@roidelapluie@roidelapluie@roidelapluie@roidelapluie@roidelapluie on irc/twitter/githubon irc/twitter/githubon irc/twitter/githubon irc/twitter/githubon irc/twitter/githubon irc/twitter/githubon irc/twitter/githubon irc/twitter/githubon irc/twitter/githubon irc/twitter/githubon irc/twitter/githubon irc/twitter/githubon irc/twitter/githubon irc/twitter/githubon irc/twitter/githubon irc/twitter/githubon irc/twitter/github

Page 3: Dive into Puppet 4

inuits.eu

Page 4: Dive into Puppet 4

IntroductionIntroductionIntroductionIntroductionIntroductionIntroductionIntroductionIntroductionIntroductionIntroductionIntroductionIntroductionIntroductionIntroductionIntroductionIntroductionIntroduction

Page 5: Dive into Puppet 4

Puppetmaster since 2011Puppetmaster since 2011Puppetmaster since 2011Puppetmaster since 2011Puppetmaster since 2011Puppetmaster since 2011Puppetmaster since 2011Puppetmaster since 2011Puppetmaster since 2011Puppetmaster since 2011Puppetmaster since 2011Puppetmaster since 2011Puppetmaster since 2011Puppetmaster since 2011Puppetmaster since 2011Puppetmaster since 2011Puppetmaster since 2011

• PPPPPPPPPPPPPPPPPuppet 2.6/2.7• RRRRRRRRRRRRRRRRReports stored with activerecord• PPPPPPPPPPPPPPPPPuppet Dashboard• NNNNNNNNNNNNNNNNNo hiera• NNNNNNNNNNNNNNNNNo PuppetDB

Page 6: Dive into Puppet 4

Puppet 2.7 - June 2011Puppet 2.7 - June 2011Puppet 2.7 - June 2011Puppet 2.7 - June 2011Puppet 2.7 - June 2011Puppet 2.7 - June 2011Puppet 2.7 - June 2011Puppet 2.7 - June 2011Puppet 2.7 - June 2011Puppet 2.7 - June 2011Puppet 2.7 - June 2011Puppet 2.7 - June 2011Puppet 2.7 - June 2011Puppet 2.7 - June 2011Puppet 2.7 - June 2011Puppet 2.7 - June 2011Puppet 2.7 - June 2011

• RRRRRRRRRRRRRRRRRuby 1.9 support• AAAAAAAAAAAAAAAAApache 2.0 Licence• TTTTTTTTTTTTTTTTThe end of "random" catalog order• SSSSSSSSSSSSSSSSSupport for network devices• DDDDDDDDDDDDDDDDDeprecation of dynamic variables

Page 7: Dive into Puppet 4

Puppet 3.0.0 - October 2012Puppet 3.0.0 - October 2012Puppet 3.0.0 - October 2012Puppet 3.0.0 - October 2012Puppet 3.0.0 - October 2012Puppet 3.0.0 - October 2012Puppet 3.0.0 - October 2012Puppet 3.0.0 - October 2012Puppet 3.0.0 - October 2012Puppet 3.0.0 - October 2012Puppet 3.0.0 - October 2012Puppet 3.0.0 - October 2012Puppet 3.0.0 - October 2012Puppet 3.0.0 - October 2012Puppet 3.0.0 - October 2012Puppet 3.0.0 - October 2012Puppet 3.0.0 - October 2012

• SSSSSSSSSSSSSSSSSupport for 3rd parties gems• NNNNNNNNNNNNNNNNNative hiera support• AAAAAAAAAAAAAAAAAutomatic hiera lookups• RRRRRRRRRRRRRRRRRemove dynamic scope lookup• SSSSSSSSSSSSSSSSSemantic versioning

Page 8: Dive into Puppet 4

Puppet 3.x seriesPuppet 3.x seriesPuppet 3.x seriesPuppet 3.x seriesPuppet 3.x seriesPuppet 3.x seriesPuppet 3.x seriesPuppet 3.x seriesPuppet 3.x seriesPuppet 3.x seriesPuppet 3.x seriesPuppet 3.x seriesPuppet 3.x seriesPuppet 3.x seriesPuppet 3.x seriesPuppet 3.x seriesPuppet 3.x series

• FFFFFFFFFFFFFFFFFuture parser (3.2.0)• """""""""""""""""contain" keyword (3.4.0)• dddddddddddddddddirectory environments (3.5.0)

Page 9: Dive into Puppet 4

Puppet 4Puppet 4Puppet 4Puppet 4Puppet 4Puppet 4Puppet 4Puppet 4Puppet 4Puppet 4Puppet 4Puppet 4Puppet 4Puppet 4Puppet 4Puppet 4Puppet 4Licensed under a Creative Commons Attribution 2.0 License

https://www.flickr.com/photos/mujitra/4421810399

Page 10: Dive into Puppet 4

The big pictureThe big pictureThe big pictureThe big pictureThe big pictureThe big pictureThe big pictureThe big pictureThe big pictureThe big pictureThe big pictureThe big pictureThe big pictureThe big pictureThe big pictureThe big pictureThe big picture

• NNNNNNNNNNNNNNNNNew DSL language• AAAAAAAAAAAAAAAAAll-in-one Package• PPPPPPPPPPPPPPPPPuppetserver

Page 11: Dive into Puppet 4

A new DSLA new DSLA new DSLA new DSLA new DSLA new DSLA new DSLA new DSLA new DSLA new DSLA new DSLA new DSLA new DSLA new DSLA new DSLA new DSLA new DSLApache 2.0 License

https://github.com/ke4qqq/puppet-cloudstack

Page 12: Dive into Puppet 4

Domain Specific LanguageDomain Specific LanguageDomain Specific LanguageDomain Specific LanguageDomain Specific LanguageDomain Specific LanguageDomain Specific LanguageDomain Specific LanguageDomain Specific LanguageDomain Specific LanguageDomain Specific LanguageDomain Specific LanguageDomain Specific LanguageDomain Specific LanguageDomain Specific LanguageDomain Specific LanguageDomain Specific Language

The goal of the Puppet DSL staysthe same: describe the final state of

your infrastructure.

Page 13: Dive into Puppet 4

The new DSL gets closer to otherprogramming languages: types,iterations, predictive ordering…

Page 14: Dive into Puppet 4

OrderingOrderingOrderingOrderingOrderingOrderingOrderingOrderingOrderingOrderingOrderingOrderingOrderingOrderingOrderingOrderingOrderingLicensed under a Creative Commons Attribution-ShareAlike 2.0 License

https://www.flickr.com/photos/lambertclement/19543885696

Page 15: Dive into Puppet 4

order.pporder.pporder.pporder.pporder.pporder.pporder.pporder.pporder.pporder.pporder.pporder.pporder.pporder.pporder.pporder.pporder.pp

n o t i f y { ’ B e l g i a n ’ : }n o t i f y { ’ Puppet ’ : }n o t i f y { ’ U s e r ’ : }n o t i f y { ’ Group ’ : }

Page 16: Dive into Puppet 4

Puppet 3.xPuppet 3.xPuppet 3.xPuppet 3.xPuppet 3.xPuppet 3.xPuppet 3.xPuppet 3.xPuppet 3.xPuppet 3.xPuppet 3.xPuppet 3.xPuppet 3.xPuppet 3.xPuppet 3.xPuppet 3.xPuppet 3.x

Notice: Compiled catalog for nitrogen in environmentproduction in 0.02 seconds

Notice: UserNotice: /Stage[main]/Main/Notify[User]/message: defined

'message ' as 'User'Notice: BelgianNotice: /Stage[main]/Main/Notify[Belgian]/message:

defined 'message ' as 'Belgian 'Notice: GroupNotice: /Stage[main]/Main/Notify[Group]/message: defined

'message ' as 'Group 'Notice: PuppetNotice: /Stage[main]/Main/Notify[Puppet]/message:

defined 'message ' as 'Puppet 'Notice: Finished catalog run in 0.02 seconds

Page 17: Dive into Puppet 4

Puppet 4.xPuppet 4.xPuppet 4.xPuppet 4.xPuppet 4.xPuppet 4.xPuppet 4.xPuppet 4.xPuppet 4.xPuppet 4.xPuppet 4.xPuppet 4.xPuppet 4.xPuppet 4.xPuppet 4.xPuppet 4.xPuppet 4.x

Notice: Compiled catalog for nitrogen in environmentproduction in 0.23 seconds

Notice: BelgianNotice: /Stage[main]/Main/Notify[Belgian]/message:

defined 'message ' as 'Belgian 'Notice: PuppetNotice: /Stage[main]/Main/Notify[Puppet]/message:

defined 'message ' as 'Puppet 'Notice: UserNotice: /Stage[main]/Main/Notify[User]/message: defined

'message ' as 'User'Notice: GroupNotice: /Stage[main]/Main/Notify[Group]/message: defined

'message ' as 'Group 'Notice: Applied catalog in 0.01 seconds

Page 18: Dive into Puppet 4

OrderingOrderingOrderingOrderingOrderingOrderingOrderingOrderingOrderingOrderingOrderingOrderingOrderingOrderingOrderingOrderingOrdering

• AAAAAAAAAAAAAAAAAlways the same order• PPPPPPPPPPPPPPPPPuppet 3.x: based on title-hash• PPPPPPPPPPPPPPPPPuppet 4.x: order seen in the manifest

Page 19: Dive into Puppet 4

Puppet 4 orderingPuppet 4 orderingPuppet 4 orderingPuppet 4 orderingPuppet 4 orderingPuppet 4 orderingPuppet 4 orderingPuppet 4 orderingPuppet 4 orderingPuppet 4 orderingPuppet 4 orderingPuppet 4 orderingPuppet 4 orderingPuppet 4 orderingPuppet 4 orderingPuppet 4 orderingPuppet 4 ordering

• TTTTTTTTTTTTTTTTTime saver• """""""""""""""""Hides" complexity• AAAAAAAAAAAAAAAAAlign with other languages• SSSSSSSSSSSSSSSSStill supports Require, Notify, …• """""""""""""""""real" dependencies should still beexplicitely set (e.g cron job only installed ifpackages is installed)

Page 20: Dive into Puppet 4

(Native) Data Types(Native) Data Types(Native) Data Types(Native) Data Types(Native) Data Types(Native) Data Types(Native) Data Types(Native) Data Types(Native) Data Types(Native) Data Types(Native) Data Types(Native) Data Types(Native) Data Types(Native) Data Types(Native) Data Types(Native) Data Types(Native) Data TypesLicensed under a Creative Commons Attribution 2.0 License

https://www.flickr.com/photos/ionics/6338281766

Page 21: Dive into Puppet 4

Data types are not newData types are not newData types are not newData types are not newData types are not newData types are not newData types are not newData types are not newData types are not newData types are not newData types are not newData types are not newData types are not newData types are not newData types are not newData types are not newData types are not new

• PPPPPPPPPPPPPPPPPreviously included in stdlib, 3rd partymodule

• ssssssssssssssssstdlib contains functions to convert datatypes, check data types

• NNNNNNNNNNNNNNNNNothing in Puppet Core• DDDDDDDDDDDDDDDDDifficult to check the type of all theparameters

Page 22: Dive into Puppet 4

Data TypesData TypesData TypesData TypesData TypesData TypesData TypesData TypesData TypesData TypesData TypesData TypesData TypesData TypesData TypesData TypesData Types

StringNumeric: Integer, Float

BooleanArrayHash

RegexpUndef

Catalogentry: Class, Resource

Page 23: Dive into Puppet 4

StringStringStringStringStringStringStringStringStringStringStringStringStringStringStringStringString

String Any stringString[2] Any string with at least 2 characters

String[0,2] A string with at most 2 charactersString[4,6] A string with at least 4 and at most 6 charactersString[5,5] A string with 5 characters

Convert to string with: "${myvariable}"

Page 24: Dive into Puppet 4

NumericNumericNumericNumericNumericNumericNumericNumericNumericNumericNumericNumericNumericNumericNumericNumericNumeric

Numeric Float or integerNumeric[-1,1] Float or Integer between -1 and 1 (incl)

Integer Any integer (from −∞ to ∞)Integer[0] Positive Integer

Integer[default, 0] Negative IntegerInteger[-1,1] Integer between -1 and 1 (incl)

Float Floating point numberFloat[-3,3.14] Float between -3 and 3.14 (incl)

Convert to Integer with the scanf function or 0+$variable

Page 25: Dive into Puppet 4

HashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHashHash

A Hash (key, value pairs)

Hash[String, String]Hash with String as keys and values

Hash[String, Integer]String as keys, Integer as values

Hash[String, Integer, 1]Non empty hash

Hash[String, Integer, default, 5]Hash with at most 5 entries

Page 26: Dive into Puppet 4

ArrayArrayArrayArrayArrayArrayArrayArrayArrayArrayArrayArrayArrayArrayArrayArrayArray

ArrayAn array (list)

Array[String]Array with String

Array[String, 1]Non empty Array

Array[String, default, 5]Array with at most 5 entries

Page 27: Dive into Puppet 4

UndefUndefUndefUndefUndefUndefUndefUndefUndefUndefUndefUndefUndefUndefUndefUndefUndef

Eventually! A clear type for Undef (was veryconfusing in the past: nil? string? symbol?)

Page 28: Dive into Puppet 4

Abstract Data TypesAbstract Data TypesAbstract Data TypesAbstract Data TypesAbstract Data TypesAbstract Data TypesAbstract Data TypesAbstract Data TypesAbstract Data TypesAbstract Data TypesAbstract Data TypesAbstract Data TypesAbstract Data TypesAbstract Data TypesAbstract Data TypesAbstract Data TypesAbstract Data TypesLicensed under a Creative Commons Attribution 2.0 License

https://www.flickr.com/photos/webtreatsetc/4666231979

Page 29: Dive into Puppet 4

OptionalOptionalOptionalOptionalOptionalOptionalOptionalOptionalOptionalOptionalOptionalOptionalOptionalOptionalOptionalOptionalOptional

Optional[String]: String or UndefOptional[Integer]: Integer or Undef

Page 30: Dive into Puppet 4

NotUndefNotUndefNotUndefNotUndefNotUndefNotUndefNotUndefNotUndefNotUndefNotUndefNotUndefNotUndefNotUndefNotUndefNotUndefNotUndefNotUndef

Everything but Undef.NotUndef[Data]: Anything that matches

Data but not Undef.Example: [Undef]

Page 31: Dive into Puppet 4

VariantVariantVariantVariantVariantVariantVariantVariantVariantVariantVariantVariantVariantVariantVariantVariantVariant

Variant[Integer, String]: AnInteger or a String

Page 32: Dive into Puppet 4

PatternPatternPatternPatternPatternPatternPatternPatternPatternPatternPatternPatternPatternPatternPatternPatternPattern

Pattern[Regex, Regex]: Strings matchregexes

Page 33: Dive into Puppet 4

EnumEnumEnumEnumEnumEnumEnumEnumEnumEnumEnumEnumEnumEnumEnumEnumEnum

Enum["true", "false"]: "true" or"false" (strings)

Page 34: Dive into Puppet 4

TupleTupleTupleTupleTupleTupleTupleTupleTupleTupleTupleTupleTupleTupleTupleTupleTuple

Tuple[Integer, String]: An arraylike [1, "a"]

Page 35: Dive into Puppet 4

StructStructStructStructStructStructStructStructStructStructStructStructStructStructStructStructStruct

Advanced hash.Struct[{"username" => String,

"uid" => Integer[0]}]Matches {"username" => "tux", "uid"

=> 1}

Page 36: Dive into Puppet 4

ScalarScalarScalarScalarScalarScalarScalarScalarScalarScalarScalarScalarScalarScalarScalarScalarScalar

Same as Variant[Numeric, String,Boolean, Regex]

Page 37: Dive into Puppet 4

DataDataDataDataDataDataDataDataDataDataDataDataDataDataDataDataData

Same as Variant[Scalar, Undef,Array[Data], Hash[Scalar,

Variant[Data]]

Page 38: Dive into Puppet 4

AnyAnyAnyAnyAnyAnyAnyAnyAnyAnyAnyAnyAnyAnyAnyAnyAny

Anything

Page 39: Dive into Puppet 4

Playing with typesPlaying with typesPlaying with typesPlaying with typesPlaying with typesPlaying with typesPlaying with typesPlaying with typesPlaying with typesPlaying with typesPlaying with typesPlaying with typesPlaying with typesPlaying with typesPlaying with typesPlaying with typesPlaying with typesLicensed under a Creative Commons Attribution 2.0 License

https://www.flickr.com/photos/jdhancock/7439512656

Page 40: Dive into Puppet 4

Types in conditionsTypes in conditionsTypes in conditionsTypes in conditionsTypes in conditionsTypes in conditionsTypes in conditionsTypes in conditionsTypes in conditionsTypes in conditionsTypes in conditionsTypes in conditionsTypes in conditionsTypes in conditionsTypes in conditionsTypes in conditionsTypes in conditions

# Compar i soni f $m =~ Boo lean {

$manage = $m} e l s i f $m !~ Enum [ ’ t r u e ’ , ’ f a l s e ’ ] {

f a i l ( ’ Bad v a l u e ’ )}

Page 41: Dive into Puppet 4

Types in case statementsTypes in case statementsTypes in case statementsTypes in case statementsTypes in case statementsTypes in case statementsTypes in case statementsTypes in case statementsTypes in case statementsTypes in case statementsTypes in case statementsTypes in case statementsTypes in case statementsTypes in case statementsTypes in case statementsTypes in case statementsTypes in case statements

c a s e $ u s e r {I n t e g e r : { $u i d = $ u s e r }Boo lean : { $ c r e a t e = $ u s e r }d e f a u l t : { f a i l ( ’ Bad Data Type ’ ) }

}

Page 42: Dive into Puppet 4

Types in parametersTypes in parametersTypes in parametersTypes in parametersTypes in parametersTypes in parametersTypes in parametersTypes in parametersTypes in parametersTypes in parametersTypes in parametersTypes in parametersTypes in parametersTypes in parametersTypes in parametersTypes in parametersTypes in parameters

c l a s s p r o f i l e _ m y s q l (Boo lean $manage_s e r v i c e ,Enum [ ’ mysq l ’ , ’ mar iadb ’ ] $ s e r v i c e _ n a m e ,O p t i o n a l [ S t r i n g [ 8 ] ] $ r o o t_pa s swo r d ,

) {

}

Page 43: Dive into Puppet 4

Type checkingType checkingType checkingType checkingType checkingType checkingType checkingType checkingType checkingType checkingType checkingType checkingType checkingType checkingType checkingType checkingType checking

# NOT CORRECT:S t r i n g $runmode = $ f a c t s [ ’ runmode ’ ]

# C o r r e c t :$runmode = a s s e r t _ t y p e ( S t r i n g , $ f a c t s [ ’

runmode ’ ] )

Page 44: Dive into Puppet 4

Array, Hash mergeArray, Hash mergeArray, Hash mergeArray, Hash mergeArray, Hash mergeArray, Hash mergeArray, Hash mergeArray, Hash mergeArray, Hash mergeArray, Hash mergeArray, Hash mergeArray, Hash mergeArray, Hash mergeArray, Hash mergeArray, Hash mergeArray, Hash mergeArray, Hash mergeLicensed under a Creative Commons Attribution 2.0 License

https://www.flickr.com/photos/willmx/2295022876

Page 45: Dive into Puppet 4

HashesHashesHashesHashesHashesHashesHashesHashesHashesHashesHashesHashesHashesHashesHashesHashesHashes

$mascot1 = { ’ l i n u x ’ => ’ tux ’ }$mascot2 = { ’ bsd ’ => ’ b e a s t i e ’ }$mascots = $mascot1 + $mascot2# { ’ l i n u x ’ => ’ tux ’ , ’ bsd ’ => ’ b e a s t i e ’ }

Page 46: Dive into Puppet 4

ArraysArraysArraysArraysArraysArraysArraysArraysArraysArraysArraysArraysArraysArraysArraysArraysArrays

$ d i s t r o = [ ’ L a r r y ’ , ’ Geeko ’ ]$misc = [ ’ b l i n k y ’ , ’ f r e d ’ ]$ a l l = $ d i s t r o + $misc

# [ ’ L a r r y ’ , ’ Geeko ’ , ’ b l i n k y ’ , ’ f r e d ’ ]

Page 47: Dive into Puppet 4

MergesMergesMergesMergesMergesMergesMergesMergesMergesMergesMergesMergesMergesMergesMergesMergesMerges

• NNNNNNNNNNNNNNNNNo more need for stdlib• CCCCCCCCCCCCCCCCCleaner code

Page 48: Dive into Puppet 4

FunctionsFunctionsFunctionsFunctionsFunctionsFunctionsFunctionsFunctionsFunctionsFunctionsFunctionsFunctionsFunctionsFunctionsFunctionsFunctionsFunctionsLicensed under a Creative Commons Attribution 2.0 License

https://www.flickr.com/photos/zzpza/3269784239

Page 49: Dive into Puppet 4

Puppet 4 FunctionPuppet 4 FunctionPuppet 4 FunctionPuppet 4 FunctionPuppet 4 FunctionPuppet 4 FunctionPuppet 4 FunctionPuppet 4 FunctionPuppet 4 FunctionPuppet 4 FunctionPuppet 4 FunctionPuppet 4 FunctionPuppet 4 FunctionPuppet 4 FunctionPuppet 4 FunctionPuppet 4 FunctionPuppet 4 Function

# http :// puppet−on−the−edge . blogspot . sePuppet : : F u n c t i o n s . c r e a t e _ f u n c t i o n ( : min ) do

d i s p a t c h : min doparam ’ Numer ic ’ , : aparam ’ Numer ic ’ , : b

end

def min ( x , y )x <= y ? x : y

endend

Page 50: Dive into Puppet 4

Puppet 4 FunctionPuppet 4 FunctionPuppet 4 FunctionPuppet 4 FunctionPuppet 4 FunctionPuppet 4 FunctionPuppet 4 FunctionPuppet 4 FunctionPuppet 4 FunctionPuppet 4 FunctionPuppet 4 FunctionPuppet 4 FunctionPuppet 4 FunctionPuppet 4 FunctionPuppet 4 FunctionPuppet 4 FunctionPuppet 4 Function

# http :// puppet−on−the−edge . blogspot . sePuppet : : Funct ions . c reate_funct ion ( : min) do

d i spatch : min doparam ’ Numeric ’ , : aparam ’ Numeric ’ , : b

end

d i spatch : min_s doparam ’ St r i ng ’ , : s1param ’ St r i ng ’ , : s2

end

def min(x , y )x <= y ? x : y

end

def min_s(x , y )cmp = ( x . downcase <=> y . downcase )cmp <= 0 ? x : y

endend

Page 51: Dive into Puppet 4

Loops and new built-in functionsLoops and new built-in functionsLoops and new built-in functionsLoops and new built-in functionsLoops and new built-in functionsLoops and new built-in functionsLoops and new built-in functionsLoops and new built-in functionsLoops and new built-in functionsLoops and new built-in functionsLoops and new built-in functionsLoops and new built-in functionsLoops and new built-in functionsLoops and new built-in functionsLoops and new built-in functionsLoops and new built-in functionsLoops and new built-in functionsLicensed under a Creative Commons Attribution-ShareAlike 2.0 License

https://www.flickr.com/photos/squeaks2569/8114399667

Page 52: Dive into Puppet 4

Loops: ArrayLoops: ArrayLoops: ArrayLoops: ArrayLoops: ArrayLoops: ArrayLoops: ArrayLoops: ArrayLoops: ArrayLoops: ArrayLoops: ArrayLoops: ArrayLoops: ArrayLoops: ArrayLoops: ArrayLoops: ArrayLoops: Array

c l a s s v h o s t s ( A r r ay [ S t r i n g ] $ p a c k a g e s , ) {$package s . each | S t r i n g $package | {

package {” vhos t−${package} ” :

e n s u r e => p r e s e n t ,}

}}

Page 53: Dive into Puppet 4

Loops: HashLoops: HashLoops: HashLoops: HashLoops: HashLoops: HashLoops: HashLoops: HashLoops: HashLoops: HashLoops: HashLoops: HashLoops: HashLoops: HashLoops: HashLoops: HashLoops: Hash

class vhosts (Hash[String, String] $packages,){$packages.each | String $package, String $version | {

package {"vhost−${package}":

ensure => $version,}

}}

Page 54: Dive into Puppet 4

Loops: reduceLoops: reduceLoops: reduceLoops: reduceLoops: reduceLoops: reduceLoops: reduceLoops: reduceLoops: reduceLoops: reduceLoops: reduceLoops: reduceLoops: reduceLoops: reduceLoops: reduceLoops: reduceLoops: reduce

$total = reduce([1,2,3]) |$result, $value| {$result + $value

}# $total = 6

Page 55: Dive into Puppet 4

with: "private" scopewith: "private" scopewith: "private" scopewith: "private" scopewith: "private" scopewith: "private" scopewith: "private" scopewith: "private" scopewith: "private" scopewith: "private" scopewith: "private" scopewith: "private" scopewith: "private" scopewith: "private" scopewith: "private" scopewith: "private" scopewith: "private" scope

# ’ p r i v a t e ’ v a r i a b l e swi th ( ’ l d ap ’ , ’ s e c r e t ’ ) | $ u s e r , $pas sword | {

f i l e {’ / e t c / s e c r e t s ’ :

c o n t e n t => ” ${u s e r } : $ { s e c r e t } ” ,}

}

Page 56: Dive into Puppet 4

filterfilterfilterfilterfilterfilterfilterfilterfilterfilterfilterfilterfilterfilterfilterfilterfilter

class vhosts (Hash[String, String] $packages,){$packages.filter | String $package, String $version |

{$version != 'latest'

}.each | String $package, String $version | {package {

"vhost−${package}":ensure => $version,

}}

}

Page 57: Dive into Puppet 4

access resource parametersaccess resource parametersaccess resource parametersaccess resource parametersaccess resource parametersaccess resource parametersaccess resource parametersaccess resource parametersaccess resource parametersaccess resource parametersaccess resource parametersaccess resource parametersaccess resource parametersaccess resource parametersaccess resource parametersaccess resource parametersaccess resource parameters

class vhosts (Hash[String, String] $packages,){$packages.filter | String $package, String $version |

{$version != 'latest'

}.each | String $package, String $version | {package {

"vhost−${package}":ensure => $version,

}}$foo_version = Package["foo"]["version"]

}

Page 58: Dive into Puppet 4

ruby-style . syntax (chaining)ruby-style . syntax (chaining)ruby-style . syntax (chaining)ruby-style . syntax (chaining)ruby-style . syntax (chaining)ruby-style . syntax (chaining)ruby-style . syntax (chaining)ruby-style . syntax (chaining)ruby-style . syntax (chaining)ruby-style . syntax (chaining)ruby-style . syntax (chaining)ruby-style . syntax (chaining)ruby-style . syntax (chaining)ruby-style . syntax (chaining)ruby-style . syntax (chaining)ruby-style . syntax (chaining)ruby-style . syntax (chaining)

$a = join(['foo', 'bar'], ',')$b = ['foo', 'bar'].join(',')

Page 59: Dive into Puppet 4

HEREDOCHEREDOCHEREDOCHEREDOCHEREDOCHEREDOCHEREDOCHEREDOCHEREDOCHEREDOCHEREDOCHEREDOCHEREDOCHEREDOCHEREDOCHEREDOCHEREDOC# HEREDOC$longstring = @(EOM)

This item is managed by PuppetEOM

# Remove tabs$longstring_notabs = @(EOM)

This item is managed by Puppet| EOM

# Remove new lines + trailing line$longstring_nonewline = @(EOM)

This item is managed by \Puppet|− EOM

# Syntax check$longstring_nonewline = @(EOM:json)

["This item is managed by Puppet"]|− EOM

Page 60: Dive into Puppet 4

TemplatesTemplatesTemplatesTemplatesTemplatesTemplatesTemplatesTemplatesTemplatesTemplatesTemplatesTemplatesTemplatesTemplatesTemplatesTemplatesTemplatesLicensed under a Creative Commons Attribution 2.0 License

https://www.flickr.com/photos/mrbill/3267227227

Page 61: Dive into Puppet 4

TemplatesTemplatesTemplatesTemplatesTemplatesTemplatesTemplatesTemplatesTemplatesTemplatesTemplatesTemplatesTemplatesTemplatesTemplatesTemplatesTemplates

• CCCCCCCCCCCCCCCCCan be written in Puppet Code (EPP)• GGGGGGGGGGGGGGGGGets their own variables• OOOOOOOOOOOOOOOOOnly useful since the new DSL• fffffffffffffffffunction epp and inline_epp

Page 62: Dive into Puppet 4

EPP templatesEPP templatesEPP templatesEPP templatesEPP templatesEPP templatesEPP templatesEPP templatesEPP templatesEPP templatesEPP templatesEPP templatesEPP templatesEPP templatesEPP templatesEPP templatesEPP templates

f i l e {’ pt−he a r t b e a t−c o n f i g ’ :

s h ow_d i f f => f a l s e ,c o n t e n t => epp ( ’ pth / pth . epp ’ , {

da t aba s e => $ d a t a b a s e ,s o c k e t => $ s o c k e t ,u s e r => $ u s e r ,pas sword => $pa s swo rd ,

} ) ,}

Page 63: Dive into Puppet 4

EPP templatesEPP templatesEPP templatesEPP templatesEPP templatesEPP templatesEPP templatesEPP templatesEPP templatesEPP templatesEPP templatesEPP templatesEPP templatesEPP templatesEPP templatesEPP templatesEPP templates

<%− |S t r i n g $database ,S t r i n g $password ,S t r i n g $ socke t ,S t r i n g $use r ,

| −%>u s e r=<%= $ u s e r %>password=<%= $password %>s o c k e t=<%= $ s o c k e t %>da taba s e=<%= $da taba s e %>hos t=l o c a l h o s tc r e a t e −t a b l e

Page 64: Dive into Puppet 4

All-in-One packageAll-in-One packageAll-in-One packageAll-in-One packageAll-in-One packageAll-in-One packageAll-in-One packageAll-in-One packageAll-in-One packageAll-in-One packageAll-in-One packageAll-in-One packageAll-in-One packageAll-in-One packageAll-in-One packageAll-in-One packageAll-in-One packageLicensed under a Creative Commons Attribution 2.0 Licensehttps://www.flickr.com/photos/creative_tools/5299374697

Page 65: Dive into Puppet 4

All-in-One package: FactsAll-in-One package: FactsAll-in-One package: FactsAll-in-One package: FactsAll-in-One package: FactsAll-in-One package: FactsAll-in-One package: FactsAll-in-One package: FactsAll-in-One package: FactsAll-in-One package: FactsAll-in-One package: FactsAll-in-One package: FactsAll-in-One package: FactsAll-in-One package: FactsAll-in-One package: FactsAll-in-One package: FactsAll-in-One package: Facts

• AAAAAAAAAAAAAAAAAll the client is in one RPM• RRRRRRRRRRRRRRRRRepository is called PC1• PPPPPPPPPPPPPPPPPuppet Collection 1• pppppppppppppppppuppet-agent RPM contains ruby and all thedeps

• EEEEEEEEEEEEEEEEEverything is under /etc/puppetlabs,/opt/puppetlabs, …

Page 66: Dive into Puppet 4

All-in-One package: ProsAll-in-One package: ProsAll-in-One package: ProsAll-in-One package: ProsAll-in-One package: ProsAll-in-One package: ProsAll-in-One package: ProsAll-in-One package: ProsAll-in-One package: ProsAll-in-One package: ProsAll-in-One package: ProsAll-in-One package: ProsAll-in-One package: ProsAll-in-One package: ProsAll-in-One package: ProsAll-in-One package: ProsAll-in-One package: Pros

• EEEEEEEEEEEEEEEEEveryone gets the same ruby version• OOOOOOOOOOOOOOOOOne RPM, one repository• EEEEEEEEEEEEEEEEEverything can be optimized• OOOOOOOOOOOOOOOOOnly one version to check for consistency

Page 67: Dive into Puppet 4

All-in-One package: Cons (1/2)All-in-One package: Cons (1/2)All-in-One package: Cons (1/2)All-in-One package: Cons (1/2)All-in-One package: Cons (1/2)All-in-One package: Cons (1/2)All-in-One package: Cons (1/2)All-in-One package: Cons (1/2)All-in-One package: Cons (1/2)All-in-One package: Cons (1/2)All-in-One package: Cons (1/2)All-in-One package: Cons (1/2)All-in-One package: Cons (1/2)All-in-One package: Cons (1/2)All-in-One package: Cons (1/2)All-in-One package: Cons (1/2)All-in-One package: Cons (1/2)• NNNNNNNNNNNNNNNNNot rebuildable (toolchain(ezbake/vanagon) not released/notopen-source)

• PPPPPPPPPPPPPPPPPL can patch Ruby, preventing people thatuse other methods to get the samebehaviour

• WWWWWWWWWWWWWWWWWe are dependent on PL for updates (e.gOpenSSL)

• HHHHHHHHHHHHHHHHHidden version numbers (Puppet-agentversion is semantic but abstract)

• NNNNNNNNNNNNNNNNNot reusing shared libs

Page 68: Dive into Puppet 4

All-in-One package: Cons (2/2)All-in-One package: Cons (2/2)All-in-One package: Cons (2/2)All-in-One package: Cons (2/2)All-in-One package: Cons (2/2)All-in-One package: Cons (2/2)All-in-One package: Cons (2/2)All-in-One package: Cons (2/2)All-in-One package: Cons (2/2)All-in-One package: Cons (2/2)All-in-One package: Cons (2/2)All-in-One package: Cons (2/2)All-in-One package: Cons (2/2)All-in-One package: Cons (2/2)All-in-One package: Cons (2/2)All-in-One package: Cons (2/2)All-in-One package: Cons (2/2)

• HHHHHHHHHHHHHHHHHow can we guess such paths?/opt/puppetlabs/puppet/cache shouldhave been at least/var/opt/puppetlabs/puppet

Page 69: Dive into Puppet 4

Batteries includedBatteries includedBatteries includedBatteries includedBatteries includedBatteries includedBatteries includedBatteries includedBatteries includedBatteries includedBatteries includedBatteries includedBatteries includedBatteries includedBatteries includedBatteries includedBatteries included

• HHHHHHHHHHHHHHHHHiera, Augeas• FFFFFFFFFFFFFFFFFacter, CFacter• MMMMMMMMMMMMMMMMMcollective• OOOOOOOOOOOOOOOOOpenSSL• RRRRRRRRRRRRRRRRRuby and gem dependencies

Page 70: Dive into Puppet 4

The case of FedoraThe case of FedoraThe case of FedoraThe case of FedoraThe case of FedoraThe case of FedoraThe case of FedoraThe case of FedoraThe case of FedoraThe case of FedoraThe case of FedoraThe case of FedoraThe case of FedoraThe case of FedoraThe case of FedoraThe case of FedoraThe case of Fedora

• FFFFFFFFFFFFFFFFFedora 23 ships Puppet 4• NNNNNNNNNNNNNNNNNOT using the AIO package• MMMMMMMMMMMMMMMMMight be rebuilt one day for EL

Page 71: Dive into Puppet 4

Migration and stuffMigration and stuffMigration and stuffMigration and stuffMigration and stuffMigration and stuffMigration and stuffMigration and stuffMigration and stuffMigration and stuffMigration and stuffMigration and stuffMigration and stuffMigration and stuffMigration and stuffMigration and stuffMigration and stuffLicensed under a Creative Commons Attribution-ShareAlike 2.0 License

https://www.flickr.com/photos/photos/26116471@N03/6362329323

Page 72: Dive into Puppet 4

PuppetserverPuppetserverPuppetserverPuppetserverPuppetserverPuppetserverPuppetserverPuppetserverPuppetserverPuppetserverPuppetserverPuppetserverPuppetserverPuppetserverPuppetserverPuppetserverPuppetserver

• AAAAAAAAAAAAAAAAA Puppet master written in clojure• RRRRRRRRRRRRRRRRRuns on top of a jvm• PPPPPPPPPPPPPPPPPut it behind a reverse proxy• SSSSSSSSSSSSSSSSSlow start but better performances• NNNNNNNNNNNNNNNNNot much to say, it stays out of my way soit's good

• PPPPPPPPPPPPPPPPPuppetserver 2.1 is compatible with Puppet3 and 4 clients

Page 73: Dive into Puppet 4

Prepare yourselfPrepare yourselfPrepare yourselfPrepare yourselfPrepare yourselfPrepare yourselfPrepare yourselfPrepare yourselfPrepare yourselfPrepare yourselfPrepare yourselfPrepare yourselfPrepare yourselfPrepare yourselfPrepare yourselfPrepare yourselfPrepare yourself

• UUUUUUUUUUUUUUUUUpdate to latest Puppet 3.x• UUUUUUUUUUUUUUUUUse the Future parser• UUUUUUUUUUUUUUUUUpdate to latest Puppetserver

Page 74: Dive into Puppet 4

Update your clientsUpdate your clientsUpdate your clientsUpdate your clientsUpdate your clientsUpdate your clientsUpdate your clientsUpdate your clientsUpdate your clientsUpdate your clientsUpdate your clientsUpdate your clientsUpdate your clientsUpdate your clientsUpdate your clientsUpdate your clientsUpdate your clients

• hhhhhhhhhhhhhhhhhttps://github.com/puppetlabs/puppetlabs-puppet_agent

• DDDDDDDDDDDDDDDDDo not forget to edit your cronjobs (changePATH to /usr/bin:/opt/puppetlabs/bin)

• pppppppppppppppppuppet will be in /opt/puppetlabs/bin

Page 75: Dive into Puppet 4

Everything is not there yetEverything is not there yetEverything is not there yetEverything is not there yetEverything is not there yetEverything is not there yetEverything is not there yetEverything is not there yetEverything is not there yetEverything is not there yetEverything is not there yetEverything is not there yetEverything is not there yetEverything is not there yetEverything is not there yetEverything is not there yetEverything is not there yet

• PPPPPPPPPPPPPPPPPuppetboard and Foreman does not workyet (new PuppetDB API)

• GGGGGGGGGGGGGGGGGood news: Puppetexplorer does (I have nottested)

Page 76: Dive into Puppet 4

ConclusionConclusionConclusionConclusionConclusionConclusionConclusionConclusionConclusionConclusionConclusionConclusionConclusionConclusionConclusionConclusionConclusionLicensed under a Creative Commons Attribution-ShareAlike 2.0 License

https://www.flickr.com/photos/olivierpechenet/19824185788

Page 77: Dive into Puppet 4

Good job :-)Good job :-)Good job :-)Good job :-)Good job :-)Good job :-)Good job :-)Good job :-)Good job :-)Good job :-)Good job :-)Good job :-)Good job :-)Good job :-)Good job :-)Good job :-)Good job :-)

• GGGGGGGGGGGGGGGGGood job, Puppetlabs (and community)• TTTTTTTTTTTTTTTTThe new DSL was a hard work• IIIIIIIIIIIIIIIIIt works well• IIIIIIIIIIIIIIIII have seen only minor bugs• IIIIIIIIIIIIIIIIIt is still a lot backward-compatible (withclean code…)

• PPPPPPPPPPPPPPPPPlease open-source the toolchain

Page 78: Dive into Puppet 4

Regarding the new DSLRegarding the new DSLRegarding the new DSLRegarding the new DSLRegarding the new DSLRegarding the new DSLRegarding the new DSLRegarding the new DSLRegarding the new DSLRegarding the new DSLRegarding the new DSLRegarding the new DSLRegarding the new DSLRegarding the new DSLRegarding the new DSLRegarding the new DSLRegarding the new DSL

• AAAAAAAAAAAAAAAAA lot of new powers• IIIIIIIIIIIIIIIIIt's a language• TTTTTTTTTTTTTTTTTime to write new recommendations, bestpractices

• IIIIIIIIIIIIIIIIIt can look awesome or horrible• PPPPPPPPPPPPPPPPPuppet lint and code review to the rescue!

Page 79: Dive into Puppet 4

Is it time to move?Is it time to move?Is it time to move?Is it time to move?Is it time to move?Is it time to move?Is it time to move?Is it time to move?Is it time to move?Is it time to move?Is it time to move?Is it time to move?Is it time to move?Is it time to move?Is it time to move?Is it time to move?Is it time to move?

• IIIIIIIIIIIIIIIIIf you have a test environment, yes• OOOOOOOOOOOOOOOOOtherwise I would still wait for morebugfixes

• BBBBBBBBBBBBBBBBBut we are already at 4.2.1• YYYYYYYYYYYYYYYYYou should a least prepare yourself• IIIIIIIIIIIIIIIII recommendgithub.com/theforeman/puppet-puppet tomanage puppet

Page 80: Dive into Puppet 4

The new DSLThe new DSLThe new DSLThe new DSLThe new DSLThe new DSLThe new DSLThe new DSLThe new DSLThe new DSLThe new DSLThe new DSLThe new DSLThe new DSLThe new DSLThe new DSLThe new DSL

• WWWWWWWWWWWWWWWWWill not be everywhere• AAAAAAAAAAAAAAAAA lot of stuff could be done with stdlib• FFFFFFFFFFFFFFFFFirst in roles, profiles, node manifests• WWWWWWWWWWWWWWWWWaiting for PL to decomission 3.x for therest

• MMMMMMMMMMMMMMMMMaybe we will see puppet4-only modules(but is that what we want?)

Page 81: Dive into Puppet 4

Puppet 4Puppet 4Puppet 4Puppet 4Puppet 4Puppet 4Puppet 4Puppet 4Puppet 4Puppet 4Puppet 4Puppet 4Puppet 4Puppet 4Puppet 4Puppet 4Puppet 4

• FFFFFFFFFFFFFFFFFull of new features• NNNNNNNNNNNNNNNNNow has a powerful DSL• SSSSSSSSSSSSSSSSStays declarative• IIIIIIIIIIIIIIIIIs more predictive

Page 82: Dive into Puppet 4

Any Question?Any Question?Any Question?Any Question?Any Question?Any Question?Any Question?Any Question?Any Question?Any Question?Any Question?Any Question?Any Question?Any Question?Any Question?Any Question?Any Question?

Page 83: Dive into Puppet 4

BioBioBioBioBioBioBioBioBioBioBioBioBioBioBioBioBio

• hhhhhhhhhhhhhhhhhttp://puppet-on-the-edge.blogspot.com/• hhhhhhhhhhhhhhhhhttps://www.devco.net/• hhhhhhhhhhhhhhhhhttp://docs.puppetlabs.com/

Page 84: Dive into Puppet 4

ContactContactContactContactContactContactContactContactContactContactContactContactContactContactContactContactContact

Julien PivottoJulien PivottoJulien PivottoJulien PivottoJulien PivottoJulien PivottoJulien PivottoJulien PivottoJulien PivottoJulien PivottoJulien PivottoJulien PivottoJulien PivottoJulien PivottoJulien PivottoJulien PivottoJulien [email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected]@roidelapluie@roidelapluie@roidelapluie@roidelapluie@roidelapluie@roidelapluie@roidelapluie@roidelapluie@roidelapluie@roidelapluie@roidelapluie@roidelapluie@roidelapluie@roidelapluie@roidelapluie@roidelapluie@roidelapluie

inuitsinuitsinuitsinuitsinuitsinuitsinuitsinuitsinuitsinuitsinuitsinuitsinuitsinuitsinuitsinuitsinuitshttps://inuits.euhttps://inuits.euhttps://inuits.euhttps://inuits.euhttps://inuits.euhttps://inuits.euhttps://inuits.euhttps://inuits.euhttps://inuits.euhttps://inuits.euhttps://inuits.euhttps://inuits.euhttps://inuits.euhttps://inuits.euhttps://inuits.euhttps://inuits.euhttps://inuits.eu

[email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected]+32 473 441 636+32 473 441 636+32 473 441 636+32 473 441 636+32 473 441 636+32 473 441 636+32 473 441 636+32 473 441 636+32 473 441 636+32 473 441 636+32 473 441 636+32 473 441 636+32 473 441 636+32 473 441 636+32 473 441 636+32 473 441 636+32 473 441 636