SlideShare ist ein Scribd-Unternehmen logo
1 von 64
Downloaden Sie, um offline zu lesen
PUPPET DESIGN PATTERNS
David Danzilio
Kovarus, Inc.
➤ Cloud Architect at Kovarus
➤ Previously at Constant Contact, Sandia
National Laboratories, and a few other
places you’ve never heard of
➤ Operations background, but more of a
developer these days
➤ Member of Vox Pupuli
➤ Organizer of the Boston Puppet User
Group
ABOUT ME
CONTACT INFO
➤ @djdanzilio on Twitter
➤ danzilio on Freenode and Slack (you can
usually find me in #voxpupuli, #puppet-
dev, and #puppet)
➤ danzilio on GitHub and The Forge
➤ ddanzilio (at) kovarus (dot) com
➤ blog.danzil.io
➤ www.kovarus.com
ACKNOWLEDGEMENTS
➤ Daniele Sluijters, Spotify
➤ David Schmitt, Puppet
➤ Rob Nelson, AT&T
➤ Will Tome, EchoStor
ABOUT DESIGN PATTERNS
GANG OF FOUR
➤ Gang of Four (GoF) book introduced the
concept for Object Oriented
programming
➤ 23 patterns with examples written in
C++ and SmallTalk
➤ Published in 1994, more than 500,000
copies sold
➤ One of the best selling software
engineering books in history
➤ Influenced an entire generation of
developers, languages, and tools
DESIGN PATTERNS
➤ Can be highly contextual and language dependent, but a lot can be learned from all
of them
➤ The GoF focused on statically-typed, object oriented, compiled languages
➤ Some languages have implemented primitives for these patterns
➤ Not many of the GoF patterns directly apply to Puppet
➤ All of the GoF patterns focus on reinforcing a set of design principles
WHY DESIGN PATTERNS?
DESIGN PRINCIPLES
SEPARATE THINGS
THAT CHANGE
Minimize risk when making changes
LOOSE COUPLING
Reduce dependencies, increase
modularity
SEPARATION OF
CONCERNS
Divide your application into distinct
features
SINGLE
RESPONSIBILITY
Do one thing well
LEAST
KNOWLEDGE
Components should know as little as
possible about their neighbors
DON’T REPEAT
YOURSELF
DRY, because we’re lazy
PROGRAM TO AN
INTERFACE
Interfaces are more stable than the
implementation
SIX PATTERNS
SIX PATTERNS
➤ Resource Wrapper: adding functionality to code you don’t own
➤ Package, File, Service: breaking up monolithic classes
➤ Params: delegating parameter defaults
➤ Strategy: doing the same thing differently
➤ Roles and Profiles: organizing your code for modularity
➤ Factory: creating resources on the fly
THE RESOURCE
WRAPPER
PATTERN
Extending existing resources
ABOUT THE WRAPPER PATTERN
➤ Problem: resources you don’t own are missing some functionality or feature
necessary to implement your requirements
➤ Solution: use composition to add your required functionality without modifying the
code you don’t own
ABOUT THE WRAPPER PATTERN
➤ Use the resource wrapper pattern when you need to add functionality to an
existing resource
➤ When you feel the need to write your own resources, or to make changes to Forge
modules, think about whether you should really be using the wrapper pattern
➤ You can do this in Puppet 3 and Puppet 4, but it’s much cleaner in Puppet 4
➤ This pattern forms the basis of many other patterns you’ll see today
EXAMPLE: MANAGING USERS
➤ We want to manage our employee user accounts
➤ Requirements:
➤ The user’s UID should be set to their employee ID
➤ All employees need to be members of the ‘employees’ group
➤ We should manage a user’s bash profile by default, but users may opt out of this
upon request
EXAMPLE: MANAGING USERS
define mycompany::user (
$employee_id,
$gid,
$groups = ['employees'],
$username = $title,
$manage_profile = true,
) {
if $manage_profile {
file { "/home/${username}/.bash_profile":
ensure => file,
owner => $username,
require => User[$username],
}
}
user { $username:
uid => $employee_id,
gid => $gid,
groups => $groups,
}
}
All employees should be in the ‘employees’ group
Employee ID is used for the user ID
Feature flag to manage your user’s bash profile
Manage ~/.bash_profile with a file resource
Pass your parameters to the user resource
EXAMPLE: MANAGING USERS
mycompany::user { 'bob':
employee_id => '1093',
gid => 'wheel',
manage_profile => false,
}
“We have a new employee
named Bob. He’s employee
1093 and he needs to be a
member of the wheel group so
he can sudo. He wants to
manage his own bash
profile.”
EXAMPLE: MANAGING USERS
“Hey, I’d like to have my
shell set to /bin/zsh, can you
do that for me?”
mycompany::user { 'bob':
employee_id => '1093',
gid => 'wheel',
shell => '/bin/zsh',
manage_profile => false,
}
Could not retrieve catalog:
Invalid parameter ‘shell’ for
type ‘mycompany::user’
EXAMPLE: MANAGING USERS define mycompany::user (
$employee_id,
$gid,
$groups = ['employees'],
$username = $title,
$manage_profile = true,
) {
if $manage_profile {
file { "/home/${username}/.bash_profile":
ensure => file,
owner => $username,
require => User[$username],
}
}
user { $username:
uid => $employee_id,
gid => $gid,
groups => $groups,
}
}
Problem
You must maintain these parameters.
EXAMPLE: MANAGING USERS (PUPPET 3)
define mycompany::user (
$username = $title,
$manage_profile = true,
$user = {}
) {
if $manage_profile {
file { "/home/${username}/.bash_profile":
ensure => file,
owner => $username,
require => User[$username],
}
}
$user_defaults = { ‘groups’ => [‘employees’] }
$user_params = merge($user, $user_defaults)
create_resources(‘user’, $username, $user_params)
}
Much more flexible interface
Enforce business rules
Create the user resource by passing
the hash to create_resources
EXAMPLE: MANAGING USERS (PUPPET 4)
define mycompany::user (
String $username = $title,
Boolean $manage_profile = true,
Hash $user = {}
) {
if $manage_profile {
file { "/home/${username}/.bash_profile":
ensure => file,
owner => $username,
require => User[$username],
}
}
$user_defaults = { 'groups' => [‘employees’] }
user { $username:
* => $user_defaults + $user,
}
}
Much more flexible interface
Enforce business rules
Use splat operator to pass hash keys
as parameters to the user resource
EXAMPLE: MANAGING USERS
mycompany::user { 'bob':
employee_id => '1093',
gid => 'wheel',
manage_profile => false,
}
“Hey, I’d like to have my
shell set to /bin/zsh, can you
do that for me?”
mycompany::user { 'bob':
manage_profile => false,
user => {
'uid' => '1093',
'gid' => 'wheel',
}
}
EXAMPLE: MANAGING USERS
mycompany::user { 'bob':
employee_id => '1093',
gid => 'wheel',
manage_profile => false,
}
mycompany::user { 'bob':
manage_profile => false,
user => {
'uid' => '1093',
'gid' => 'wheel',
'shell' => '/bin/zsh',
}
}
“Hey, I’d like to have my
shell set to /bin/zsh, can you
do that for me?”
THE PACKAGE/
FILE/SERVICE
PATTERN
Assembling complex behavior
ABOUT THE PACKAGE/FILE/SERVICE PATTERN
➤ Problem: your module’s init.pp is getting too cluttered because all of your code’s
functionality (concerns) live in that one file
➤ Solution: break out the basic functions of your module into separate classes, usually
into a package, config, and service class
ABOUT THE PACKAGE/FILE/SERVICE PATTERN
➤ This is one of the first patterns you see when learning Puppet
➤ This is the embodiment of the Single Responsibility and Separation of Concerns
principles
➤ Most modules can be broken down into some form of Package, Config File, and
Service management
➤ Use this specific pattern any time you write a module that manages these things
➤ Keep the spirit of this pattern in mind whenever you write a module that is more
than a few lines long
➤ This has the added benefit of allowing us to utilize class containment for cleaner
resource ordering
EXAMPLE: NTP
class ntp {
case $::osfamily {
'Solaris': {
$package_name = ['SUNWntpr', 'SUNWntpu']
$config_file = '/etc/inet/ntp.conf'
$service_name = 'network/ntp'
}
'RedHat': {
$package_name = 'ntp'
$config_file = '/etc/ntp.conf'
$service_name = 'ntpd'
}
}
package { $package_name:
ensure => installed,
}
file { $config_file:
ensure => file,
content => template('ntp/ntpd.conf.erb'),
require => Package[$package_name],
notify => Service[$service_name],
}
service { $service_name:
ensure => running
}
}
Installs the ntp package for that platform
Places the ntp config file
Ensures that the package is installed first
Notifies the ntp service of changes to the file
Manages the ntp service
Set some variables based on the osfamily fact
class ntp {
case $osfamily {
'Solaris': {
$package_name = ['SUNWntpr', 'SUNWntpu']
$config_file = '/etc/inet/ntp.conf'
$service_name = 'network/ntp'
}
'RedHat': {
$package_name = 'ntp'
$config_file = '/etc/ntp.conf'
$service_name = 'ntpd'
}
}
class { 'ntp::install': } ->
class { 'ntp::config': } ~>
class { 'ntp::service': }
}
EXAMPLE: NTP
Installs the ntp package
Places the ntp config file
Package is installed first
Manages the ntp service
Notifies the service of changes
class ntp::install {
package { $ntp::package_name:
ensure => installed,
}
}
class ntp::config {
file { $ntp::config_file:
ensure => file,
content => template('ntp/ntpd.conf.erb'),
}
}
class ntp::service {
service { $ntp::service_name:
ensure => running,
}
}
EXAMPLE: NTP
THE PARAMS
PATTERN
Separating out your data
ABOUT THE PARAMS PATTERN
➤ Problem: hard-coded data makes modules fragile, verbose parameter default and
variable setting logic make classes hard to read
➤ Solution: convert embedded data to parameters and move that data to a separate
class where it can be used as parameter defaults
ABOUT THE PARAMS PATTERN
➤ The params pattern breaks out your variable assignment and parameter defaults
into a separate class, typically named params
➤ Makes classes easier to read by moving the default setting logic into a purpose-built
class
➤ Delegates responsibility for setting defaults to the params class
➤ Module data is a new feature designed to eliminate the params pattern by moving
this logic into Hiera
➤ Until module data becomes ubiquitous, you’ll see params in use in almost every
module
➤ Use this pattern any time you have data that must live in your module
EXAMPLE: NTP
Problems
Only supports Solaris and RedHat
~70% of this class is devoted to data
class ntp {
case $osfamily {
'Solaris': {
$package_name = ['SUNWntpr', 'SUNWntpu']
$config_file = '/etc/inet/ntp.conf'
$service_name = 'network/ntp'
}
'RedHat': {
$package_name = 'ntp'
$config_file = '/etc/ntp.conf'
$service_name = 'ntpd'
}
}
class { 'ntp::install': } ->
class { 'ntp::config': } ~>
class { 'ntp::service': }
}
EXAMPLE: NTP
class ntp::params {
case $::osfamily {
'Solaris': {
$package_name = ['SUNWntpr', 'SUNWntpu']
$config_file = '/etc/inet/ntp.conf'
$service_name = 'network/ntp'
}
'RedHat': {
$package_name = 'ntp'
$config_file = '/etc/ntp.conf'
$service_name = 'ntpd'
}
}
}
Create a purpose-built class
to store your module’s data
These variables become the default
values for your class parameters
EXAMPLE: NTP
class ntp (
$package_name = $ntp::params::package_name,
$config_file = $ntp::params::config_file,
$service_name = $ntp::params::service_name,
) inherits ntp::params {
class { 'ntp::install': } ->
class { 'ntp::config': } ~>
class { 'ntp::service': }
}
Inheriting the params class ensures
that it is evaluated first
Convert the variables to parameters, and set
their defaults to the corresponding variables
in the params class
THE STRATEGY
PATTERN
Varying the algorithm
ABOUT THE STRATEGY PATTERN
➤ Problem: you have multiple ways to achieve basically the same thing in your
module, but you need to choose one way based on some criteria (usually a fact)
➤ Solution: break each approach into separate classes and let your caller decide which
to include
ABOUT THE STRATEGY PATTERN
➤ This is a GoF pattern
➤ Use this pattern when you have lots of logic doing effectively the same thing but
with different details under certain conditions
➤ The Strategy Pattern uses composition to assemble complex behavior from smaller
classes
EXAMPLE: MYSQL
class mysql {
...
case $::osfamily {
'Debian': {
apt::source { 'mysql':
comment => 'MySQL Community APT repository',
location => "http://repo.mysql.com/apt/${::operatingsystem}",
release => $::lsbdistcodename,
repos => 'mysql-5.7',
include => { src => false },
}
}
'RedHat': {
yumrepo { 'mysql':
descr => 'MySQL Community YUM repository',
baseurl => "http://repo.mysql.com/yum/mysql-5.7-community/el/${::lsbmajdistrelease}/${::architecture}",
enabled => true,
}
}
}
...
}
Both managing a package repository
EXAMPLE: MYSQL
class mysql::repo::redhat {
yumrepo { 'mysql':
descr => 'MySQL Community YUM repository',
baseurl => "http://repo.mysql.com/yum/mysql-5.7-community/el/${::lsbmajdistrelease}/${::architecture}",
enabled => true,
}
}
class mysql::repo::debian {
apt::source { 'mysql':
comment => 'MySQL Community APT repository',
location => "http://repo.mysql.com/apt/${::operatingsystem}",
release => $::lsbdistcodename,
repos => 'mysql-5.7',
include => { src => false },
}
}
Strategy Classes
EXAMPLE: MYSQL
class mysql {
...
case $::osfamily {
'Debian': { include mysql::repo::debian }
'RedHat': { include mysql::repo::redhat }
}
...
}
Context Class
Case statement determines
which strategy class to include
THE ROLES AND
PROFILES
PATTERN
Organizing your code for modularity
ABOUT THE ROLES AND PROFILES PATTERN
➤ Problem: large node statements with many classes, lots of inherited node
statements, difficulty identifying what a server’s purpose is in your environment
➤ Solution: add an extra layer of abstraction between your node and your modules
ABOUT THE ROLES AND PROFILES PATTERN
➤ The Roles and Profiles pattern was described by Craig Dunn in his blog post
Designing Puppet - Roles and Profiles
➤ This is one of the most comprehensive design patterns for Puppet
➤ It is the “official” way to structure your Puppet code
➤ You should always use Roles and Profiles
➤ Craig does an excellent job describing these concepts in depth, you should read his
blog post here: http://www.craigdunn.org/2012/05/239/
WITHOUT ROLES AND PROFILES node base {
include mycompany::settings
}
node www inherits base {
include apache
include mysql
include php
include nagios::web_server
}
node ns1 inherits base {
include bind
include nagios::bind
bind::zone { ‘example.com': type => master }
}
node ns2 inherits base {
include bind
include nagios::bind
bind::zone { ‘example.com': type => slave }
}
Base node includes common modules
Nodes inherit the base to get common functionality
More specific functionality is added in each node statement
Problems
This file can get really long, really fast
Can violate DRY when you have lots of similar nodes
Edge cases are hard to manage
Node ModulesModules ResourcesResources
ROLES AND PROFILES TERMINOLOGY
➤ Module: implements one piece of software or functionality
➤ Profile: combines modules to implement a stack (i.e. “A LAMP stack includes the
apache, mysql, and php modules”)
➤ Role: combine profiles to implement your business rules (i.e. “This server is a web
server”)
➤ A node can only ever include one role
➤ If you think you need to include two roles, you’ve probably just identified another
role
Node ModulesModules ResourcesResourcesRole ModulesProfiles
CONVERTING TO ROLES AND PROFILES
class roles::base {
include profiles::base
}
class roles::web_server {
include profiles::base
include profiles::lamp
}
class roles::nameserver::master inherits roles::base {
include profiles::bind::master
}
class roles::nameserver::slave inherits roles::base {
include profiles::bind::slave
}
class profiles::base {
include mycompany::settings
}
class profiles::lamp {
include apache
include mysql
include php
include nagios::web_server
}
class profiles::bind ($type = master) {
include bind
bind::zone { 'example.com':
type => $type,
}
}
class profiles::bind::master {
include profiles::bind
}
class profiles::bind::slave {
class { 'profiles::bind':
type => slave,
}
}
CONVERTING TO ROLES AND PROFILES
node www {
include roles::web_server
}
node ns1 {
include roles::nameserver::master
}
node ns2 {
include roles::nameserver::slave
}
node base {
include mycompany::settings
}
node www inherits base {
include apache
include mysql
include php
include nagios::web_server
}
node ns1 inherits base {
include bind
include nagios::bind
bind::zone { ‘example.com': type => master }
}
node ns2 inherits base {
include bind
include nagios::bind
bind::zone { ‘example.com': type => slave }
}
THE FACTORY
PATTERN
Creating resources in your classes
ABOUT THE FACTORY PATTERN
➤ Problem: your module has to create a lot of resources of the same type, or you want
to control how resources are created with your module
➤ Solution: create the resources in your class based on data passed to your parameters
ABOUT THE FACTORY PATTERN
➤ This is also known as the create_resources pattern
➤ Emerged early on as crude iteration support in older Puppet versions
➤ We already saw this in action in the Resource Wrapper Pattern example
➤ Use this pattern when you want your module to have a single entry point, even for
creating your own resources
EXAMPLE: MANAGING CONFIGURATION WITH INI_SETTING
class puppet (
$ca_server = 'puppet-ca.example.com',
$master = 'puppet.example.com',
$pluginsync = true,
$noop = false,
) {
$defaults = { 'path' => '/etc/puppet/puppet.conf' }
$main_section = {
'main/ca_server' => { 'setting' => 'ca_server', 'value' => $ca_server },
'main/server' => { 'setting' => 'server', 'value' => $master },
}
$agent_section = {
'agent/pluginsync' => { 'setting' => 'pluginsync', 'value' => $pluginsync },
'agent/noop' => { 'setting' => 'noop', 'value' => $noop },
}
create_resources('ini_setting', $main_section, merge($defaults, { section => 'main' }))
create_resources('ini_setting', $agent_section, merge($defaults, { section => 'agent' }))
}
Get data from params
Organize the data so
we can consume it
with create_resources
Pass the munged data
to create_resources
EXAMPLE: MANAGING CONFIGURATION WITH INI_SETTING (PUPPET 4)
class puppet (
String $path = '/etc/puppet/puppet.conf',
Hash $main_section = {
'ca_server' => 'puppet-ca.example.com',
'server' => 'puppet.example.com'
},
Hash $agent_section = {
'pluginsync' => true,
'noop' => false,
},
) {
['agent', 'main'].each |$section| {
$data = getvar("${section}_section")
$data.each |$key,$val| {
ini_setting { "${section}/${key}":
path => $path,
section => $section,
setting => $key,
value => $val,
}
}
}
}
Pass a hash for each section
Iterate over each section name
Fetch the variable that holds that section’s data
Iterate over that data, passing it to an
ini_setting resource
THE END
STAY TUNED FOR MORE PATTERNS
CONTACT INFO
➤ @djdanzilio on Twitter
➤ danzilio on Freenode and Slack (you can
usually find me in #voxpupuli, #puppet-
dev, and #puppet)
➤ danzilio on GitHub and The Forge
➤ ddanzilio (at) kovarus (dot) com
➤ blog.danzil.io
➤ www.kovarus.com

Weitere ähnliche Inhalte

Was ist angesagt?

8 things to know about theming in drupal 8
8 things to know about theming in drupal 88 things to know about theming in drupal 8
8 things to know about theming in drupal 8Logan Farr
 
Cloud, Cache, and Configs
Cloud, Cache, and ConfigsCloud, Cache, and Configs
Cloud, Cache, and ConfigsScott Taylor
 
Rails' Next Top Model
Rails' Next Top ModelRails' Next Top Model
Rails' Next Top ModelAdam Keys
 
Czym jest webpack i dlaczego chcesz go używać?
Czym jest webpack i dlaczego chcesz go używać?Czym jest webpack i dlaczego chcesz go używać?
Czym jest webpack i dlaczego chcesz go używać?Marcin Gajda
 
Sergei Stryukov.Drush.Why it should be used.DrupalCamp Kyiv 2011
Sergei Stryukov.Drush.Why it should be used.DrupalCamp Kyiv 2011Sergei Stryukov.Drush.Why it should be used.DrupalCamp Kyiv 2011
Sergei Stryukov.Drush.Why it should be used.DrupalCamp Kyiv 2011camp_drupal_ua
 
Building a Custom Theme in Drupal 8
Building a Custom Theme in Drupal 8Building a Custom Theme in Drupal 8
Building a Custom Theme in Drupal 8Anne Tomasevich
 
Drupal theming - a practical approach (European Drupal Days 2015)
Drupal theming - a practical approach (European Drupal Days 2015)Drupal theming - a practical approach (European Drupal Days 2015)
Drupal theming - a practical approach (European Drupal Days 2015)Eugenio Minardi
 
Cooking 5 Star Infrastructure with Chef
Cooking 5 Star Infrastructure with ChefCooking 5 Star Infrastructure with Chef
Cooking 5 Star Infrastructure with ChefG. Ryan Fawcett
 
Hadoop installation on windows
Hadoop installation on windows Hadoop installation on windows
Hadoop installation on windows habeebulla g
 
CapitalCamp Features
CapitalCamp FeaturesCapitalCamp Features
CapitalCamp FeaturesPhase2
 
Ansible : what's ansible & use case by REX
Ansible :  what's ansible & use case by REXAnsible :  what's ansible & use case by REX
Ansible : what's ansible & use case by REXSaewoong Lee
 
Drupal 8 templating with twig
Drupal 8 templating with twigDrupal 8 templating with twig
Drupal 8 templating with twigTaras Omelianenko
 

Was ist angesagt? (16)

8 things to know about theming in drupal 8
8 things to know about theming in drupal 88 things to know about theming in drupal 8
8 things to know about theming in drupal 8
 
Cloud, Cache, and Configs
Cloud, Cache, and ConfigsCloud, Cache, and Configs
Cloud, Cache, and Configs
 
Rails' Next Top Model
Rails' Next Top ModelRails' Next Top Model
Rails' Next Top Model
 
Czym jest webpack i dlaczego chcesz go używać?
Czym jest webpack i dlaczego chcesz go używać?Czym jest webpack i dlaczego chcesz go używać?
Czym jest webpack i dlaczego chcesz go używać?
 
Sergei Stryukov.Drush.Why it should be used.DrupalCamp Kyiv 2011
Sergei Stryukov.Drush.Why it should be used.DrupalCamp Kyiv 2011Sergei Stryukov.Drush.Why it should be used.DrupalCamp Kyiv 2011
Sergei Stryukov.Drush.Why it should be used.DrupalCamp Kyiv 2011
 
Building a Custom Theme in Drupal 8
Building a Custom Theme in Drupal 8Building a Custom Theme in Drupal 8
Building a Custom Theme in Drupal 8
 
Drupal theming - a practical approach (European Drupal Days 2015)
Drupal theming - a practical approach (European Drupal Days 2015)Drupal theming - a practical approach (European Drupal Days 2015)
Drupal theming - a practical approach (European Drupal Days 2015)
 
Cooking 5 Star Infrastructure with Chef
Cooking 5 Star Infrastructure with ChefCooking 5 Star Infrastructure with Chef
Cooking 5 Star Infrastructure with Chef
 
Puppet fundamentals
Puppet fundamentalsPuppet fundamentals
Puppet fundamentals
 
Hadoop installation on windows
Hadoop installation on windows Hadoop installation on windows
Hadoop installation on windows
 
CapitalCamp Features
CapitalCamp FeaturesCapitalCamp Features
CapitalCamp Features
 
Ansible : what's ansible & use case by REX
Ansible :  what's ansible & use case by REXAnsible :  what's ansible & use case by REX
Ansible : what's ansible & use case by REX
 
RuHL
RuHLRuHL
RuHL
 
Drupal 8 templating with twig
Drupal 8 templating with twigDrupal 8 templating with twig
Drupal 8 templating with twig
 
Php on Windows
Php on WindowsPhp on Windows
Php on Windows
 
Dc kyiv2010 jun_08
Dc kyiv2010 jun_08Dc kyiv2010 jun_08
Dc kyiv2010 jun_08
 

Andere mochten auch

Enjoying the Journey from Puppet 3.x to Puppet 4.x (PuppetConf 2016)
Enjoying the Journey from Puppet 3.x to Puppet 4.x (PuppetConf 2016)Enjoying the Journey from Puppet 3.x to Puppet 4.x (PuppetConf 2016)
Enjoying the Journey from Puppet 3.x to Puppet 4.x (PuppetConf 2016)Robert Nelson
 
Test Driven Development with Puppet - PuppetConf 2014
Test Driven Development with Puppet - PuppetConf 2014Test Driven Development with Puppet - PuppetConf 2014
Test Driven Development with Puppet - PuppetConf 2014Puppet
 
PuppetConf 2016: The Challenges with Container Configuration – David Lutterko...
PuppetConf 2016: The Challenges with Container Configuration – David Lutterko...PuppetConf 2016: The Challenges with Container Configuration – David Lutterko...
PuppetConf 2016: The Challenges with Container Configuration – David Lutterko...Puppet
 
Apresentação atmo letpp
Apresentação atmo letppApresentação atmo letpp
Apresentação atmo letppAtmo Hazmat
 
Data Science (Informatics) Programs at GMU - Kirk Borne - RDAP12
Data Science (Informatics) Programs at GMU - Kirk Borne - RDAP12Data Science (Informatics) Programs at GMU - Kirk Borne - RDAP12
Data Science (Informatics) Programs at GMU - Kirk Borne - RDAP12ASIS&T
 
Beste Nederlandse dividendaandeel
Beste Nederlandse dividendaandeelBeste Nederlandse dividendaandeel
Beste Nederlandse dividendaandeelKarel Mercx
 
10 Good Reasons - NetApp for Healthcare
10 Good Reasons - NetApp for Healthcare10 Good Reasons - NetApp for Healthcare
10 Good Reasons - NetApp for HealthcareNetAppUK
 
S and OP - Interview Series - Supply Chain Trend - Nov-2016 - Jim Biel
S and OP - Interview Series - Supply Chain Trend - Nov-2016 - Jim BielS and OP - Interview Series - Supply Chain Trend - Nov-2016 - Jim Biel
S and OP - Interview Series - Supply Chain Trend - Nov-2016 - Jim BielJim Biel
 
Instrumen & indikator pasar uang
Instrumen & indikator pasar uangInstrumen & indikator pasar uang
Instrumen & indikator pasar uangWahono Diphayana
 
What challenges will health insurance face? By Rafael Senen CEO at COVERONTRI...
What challenges will health insurance face? By Rafael Senen CEO at COVERONTRI...What challenges will health insurance face? By Rafael Senen CEO at COVERONTRI...
What challenges will health insurance face? By Rafael Senen CEO at COVERONTRI...COVERONTRIP ® DIGITAL INSURANCE
 
MDR aspects for the sterilisation industry
MDR aspects for the sterilisation industryMDR aspects for the sterilisation industry
MDR aspects for the sterilisation industryErik Vollebregt
 
Candidatos para comisionados presentados por universidades
Candidatos para comisionados presentados por universidadesCandidatos para comisionados presentados por universidades
Candidatos para comisionados presentados por universidadesGrupo Promotor LAIP
 
Cultivating Wonder: Using Picture Books to Explore STEAM Concepts
Cultivating Wonder: Using Picture Books to Explore STEAM ConceptsCultivating Wonder: Using Picture Books to Explore STEAM Concepts
Cultivating Wonder: Using Picture Books to Explore STEAM ConceptsRobin L. Gibson
 
Por qué dalas es gilipollas
Por qué dalas es gilipollasPor qué dalas es gilipollas
Por qué dalas es gilipollasWamiba
 
7.14.2 Решения по управлению агрегатами HVAC и холодильными машинами HVAC M168
7.14.2 Решения по управлению агрегатами HVAC и холодильными машинами HVAC M1687.14.2 Решения по управлению агрегатами HVAC и холодильными машинами HVAC M168
7.14.2 Решения по управлению агрегатами HVAC и холодильными машинами HVAC M168Igor Golovin
 

Andere mochten auch (18)

Enjoying the Journey from Puppet 3.x to Puppet 4.x (PuppetConf 2016)
Enjoying the Journey from Puppet 3.x to Puppet 4.x (PuppetConf 2016)Enjoying the Journey from Puppet 3.x to Puppet 4.x (PuppetConf 2016)
Enjoying the Journey from Puppet 3.x to Puppet 4.x (PuppetConf 2016)
 
Test Driven Development with Puppet - PuppetConf 2014
Test Driven Development with Puppet - PuppetConf 2014Test Driven Development with Puppet - PuppetConf 2014
Test Driven Development with Puppet - PuppetConf 2014
 
PuppetConf 2016: The Challenges with Container Configuration – David Lutterko...
PuppetConf 2016: The Challenges with Container Configuration – David Lutterko...PuppetConf 2016: The Challenges with Container Configuration – David Lutterko...
PuppetConf 2016: The Challenges with Container Configuration – David Lutterko...
 
Triple filter
Triple filterTriple filter
Triple filter
 
Apresentação atmo letpp
Apresentação atmo letppApresentação atmo letpp
Apresentação atmo letpp
 
Data Science (Informatics) Programs at GMU - Kirk Borne - RDAP12
Data Science (Informatics) Programs at GMU - Kirk Borne - RDAP12Data Science (Informatics) Programs at GMU - Kirk Borne - RDAP12
Data Science (Informatics) Programs at GMU - Kirk Borne - RDAP12
 
Beste Nederlandse dividendaandeel
Beste Nederlandse dividendaandeelBeste Nederlandse dividendaandeel
Beste Nederlandse dividendaandeel
 
10 Good Reasons - NetApp for Healthcare
10 Good Reasons - NetApp for Healthcare10 Good Reasons - NetApp for Healthcare
10 Good Reasons - NetApp for Healthcare
 
S and OP - Interview Series - Supply Chain Trend - Nov-2016 - Jim Biel
S and OP - Interview Series - Supply Chain Trend - Nov-2016 - Jim BielS and OP - Interview Series - Supply Chain Trend - Nov-2016 - Jim Biel
S and OP - Interview Series - Supply Chain Trend - Nov-2016 - Jim Biel
 
Instrumen & indikator pasar uang
Instrumen & indikator pasar uangInstrumen & indikator pasar uang
Instrumen & indikator pasar uang
 
What challenges will health insurance face? By Rafael Senen CEO at COVERONTRI...
What challenges will health insurance face? By Rafael Senen CEO at COVERONTRI...What challenges will health insurance face? By Rafael Senen CEO at COVERONTRI...
What challenges will health insurance face? By Rafael Senen CEO at COVERONTRI...
 
Docker & Azure
Docker & AzureDocker & Azure
Docker & Azure
 
MDR aspects for the sterilisation industry
MDR aspects for the sterilisation industryMDR aspects for the sterilisation industry
MDR aspects for the sterilisation industry
 
topographie Exercice 2
topographie Exercice 2topographie Exercice 2
topographie Exercice 2
 
Candidatos para comisionados presentados por universidades
Candidatos para comisionados presentados por universidadesCandidatos para comisionados presentados por universidades
Candidatos para comisionados presentados por universidades
 
Cultivating Wonder: Using Picture Books to Explore STEAM Concepts
Cultivating Wonder: Using Picture Books to Explore STEAM ConceptsCultivating Wonder: Using Picture Books to Explore STEAM Concepts
Cultivating Wonder: Using Picture Books to Explore STEAM Concepts
 
Por qué dalas es gilipollas
Por qué dalas es gilipollasPor qué dalas es gilipollas
Por qué dalas es gilipollas
 
7.14.2 Решения по управлению агрегатами HVAC и холодильными машинами HVAC M168
7.14.2 Решения по управлению агрегатами HVAC и холодильными машинами HVAC M1687.14.2 Решения по управлению агрегатами HVAC и холодильными машинами HVAC M168
7.14.2 Решения по управлению агрегатами HVAC и холодильными машинами HVAC M168
 

Ähnlich wie Puppet Design Patterns - PuppetConf

modern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet Campmodern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet CampPuppet
 
Drupal vs WordPress
Drupal vs WordPressDrupal vs WordPress
Drupal vs WordPressWalter Ebert
 
Ansible with oci
Ansible with ociAnsible with oci
Ansible with ociDonghuKIM2
 
Building and Maintaining a Distribution in Drupal 7 with Features
Building and Maintaining a  Distribution in Drupal 7 with FeaturesBuilding and Maintaining a  Distribution in Drupal 7 with Features
Building and Maintaining a Distribution in Drupal 7 with FeaturesNuvole
 
Puppetpreso
PuppetpresoPuppetpreso
Puppetpresoke4qqq
 
Puppet | Custom Modules & Using the Forge
Puppet | Custom Modules & Using the ForgePuppet | Custom Modules & Using the Forge
Puppet | Custom Modules & Using the ForgeAaron Bernstein
 
Decoupling Drupal mit dem Lupus Nuxt.js Drupal Stack
Decoupling Drupal mit dem Lupus Nuxt.js Drupal StackDecoupling Drupal mit dem Lupus Nuxt.js Drupal Stack
Decoupling Drupal mit dem Lupus Nuxt.js Drupal Stacknuppla
 
From Dev to DevOps - ApacheCON NA 2011
From Dev to DevOps - ApacheCON NA 2011From Dev to DevOps - ApacheCON NA 2011
From Dev to DevOps - ApacheCON NA 2011Carlos Sanchez
 
Drupal Day 2012 - Automating Drupal Development: Make!les, Features and Beyond
Drupal Day 2012 - Automating Drupal Development: Make!les, Features and BeyondDrupal Day 2012 - Automating Drupal Development: Make!les, Features and Beyond
Drupal Day 2012 - Automating Drupal Development: Make!les, Features and BeyondDrupalDay
 
Ansible new paradigms for orchestration
Ansible new paradigms for orchestrationAnsible new paradigms for orchestration
Ansible new paradigms for orchestrationPaolo Tonin
 
From Dev to DevOps
From Dev to DevOpsFrom Dev to DevOps
From Dev to DevOpsAgile Spain
 
Puppet and Apache CloudStack
Puppet and Apache CloudStackPuppet and Apache CloudStack
Puppet and Apache CloudStackPuppet
 
Infrastructure as code with Puppet and Apache CloudStack
Infrastructure as code with Puppet and Apache CloudStackInfrastructure as code with Puppet and Apache CloudStack
Infrastructure as code with Puppet and Apache CloudStackke4qqq
 
Puppet and CloudStack
Puppet and CloudStackPuppet and CloudStack
Puppet and CloudStackke4qqq
 
Debugging in drupal 8
Debugging in drupal 8Debugging in drupal 8
Debugging in drupal 8Allie Jones
 
Using Document Databases with TYPO3 Flow
Using Document Databases with TYPO3 FlowUsing Document Databases with TYPO3 Flow
Using Document Databases with TYPO3 FlowKarsten Dambekalns
 
Practical Chef and Capistrano for Your Rails App
Practical Chef and Capistrano for Your Rails AppPractical Chef and Capistrano for Your Rails App
Practical Chef and Capistrano for Your Rails AppSmartLogic
 
Drupal Module Development - OSI Days 2010
Drupal Module Development - OSI Days 2010Drupal Module Development - OSI Days 2010
Drupal Module Development - OSI Days 2010Siva Epari
 
Drupal Module Development
Drupal Module DevelopmentDrupal Module Development
Drupal Module Developmentipsitamishra
 

Ähnlich wie Puppet Design Patterns - PuppetConf (20)

modern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet Campmodern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet Camp
 
Drupal vs WordPress
Drupal vs WordPressDrupal vs WordPress
Drupal vs WordPress
 
Ansible with oci
Ansible with ociAnsible with oci
Ansible with oci
 
Building and Maintaining a Distribution in Drupal 7 with Features
Building and Maintaining a  Distribution in Drupal 7 with FeaturesBuilding and Maintaining a  Distribution in Drupal 7 with Features
Building and Maintaining a Distribution in Drupal 7 with Features
 
Puppetpreso
PuppetpresoPuppetpreso
Puppetpreso
 
Puppet | Custom Modules & Using the Forge
Puppet | Custom Modules & Using the ForgePuppet | Custom Modules & Using the Forge
Puppet | Custom Modules & Using the Forge
 
Decoupling Drupal mit dem Lupus Nuxt.js Drupal Stack
Decoupling Drupal mit dem Lupus Nuxt.js Drupal StackDecoupling Drupal mit dem Lupus Nuxt.js Drupal Stack
Decoupling Drupal mit dem Lupus Nuxt.js Drupal Stack
 
From Dev to DevOps - ApacheCON NA 2011
From Dev to DevOps - ApacheCON NA 2011From Dev to DevOps - ApacheCON NA 2011
From Dev to DevOps - ApacheCON NA 2011
 
Drupal Day 2012 - Automating Drupal Development: Make!les, Features and Beyond
Drupal Day 2012 - Automating Drupal Development: Make!les, Features and BeyondDrupal Day 2012 - Automating Drupal Development: Make!les, Features and Beyond
Drupal Day 2012 - Automating Drupal Development: Make!les, Features and Beyond
 
Ansible new paradigms for orchestration
Ansible new paradigms for orchestrationAnsible new paradigms for orchestration
Ansible new paradigms for orchestration
 
From Dev to DevOps
From Dev to DevOpsFrom Dev to DevOps
From Dev to DevOps
 
Puppet and Apache CloudStack
Puppet and Apache CloudStackPuppet and Apache CloudStack
Puppet and Apache CloudStack
 
Infrastructure as code with Puppet and Apache CloudStack
Infrastructure as code with Puppet and Apache CloudStackInfrastructure as code with Puppet and Apache CloudStack
Infrastructure as code with Puppet and Apache CloudStack
 
Puppet and CloudStack
Puppet and CloudStackPuppet and CloudStack
Puppet and CloudStack
 
Debugging in drupal 8
Debugging in drupal 8Debugging in drupal 8
Debugging in drupal 8
 
Using Document Databases with TYPO3 Flow
Using Document Databases with TYPO3 FlowUsing Document Databases with TYPO3 Flow
Using Document Databases with TYPO3 Flow
 
Welcome aboard the team
Welcome aboard the teamWelcome aboard the team
Welcome aboard the team
 
Practical Chef and Capistrano for Your Rails App
Practical Chef and Capistrano for Your Rails AppPractical Chef and Capistrano for Your Rails App
Practical Chef and Capistrano for Your Rails App
 
Drupal Module Development - OSI Days 2010
Drupal Module Development - OSI Days 2010Drupal Module Development - OSI Days 2010
Drupal Module Development - OSI Days 2010
 
Drupal Module Development
Drupal Module DevelopmentDrupal Module Development
Drupal Module Development
 

Kürzlich hochgeladen

Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comFatema Valibhai
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...OnePlan Solutions
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...Health
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AIABDERRAOUF MEHENNI
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️anilsa9823
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 

Kürzlich hochgeladen (20)

Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 

Puppet Design Patterns - PuppetConf

  • 1. PUPPET DESIGN PATTERNS David Danzilio Kovarus, Inc.
  • 2. ➤ Cloud Architect at Kovarus ➤ Previously at Constant Contact, Sandia National Laboratories, and a few other places you’ve never heard of ➤ Operations background, but more of a developer these days ➤ Member of Vox Pupuli ➤ Organizer of the Boston Puppet User Group ABOUT ME
  • 3.
  • 4. CONTACT INFO ➤ @djdanzilio on Twitter ➤ danzilio on Freenode and Slack (you can usually find me in #voxpupuli, #puppet- dev, and #puppet) ➤ danzilio on GitHub and The Forge ➤ ddanzilio (at) kovarus (dot) com ➤ blog.danzil.io ➤ www.kovarus.com
  • 5. ACKNOWLEDGEMENTS ➤ Daniele Sluijters, Spotify ➤ David Schmitt, Puppet ➤ Rob Nelson, AT&T ➤ Will Tome, EchoStor
  • 7. GANG OF FOUR ➤ Gang of Four (GoF) book introduced the concept for Object Oriented programming ➤ 23 patterns with examples written in C++ and SmallTalk ➤ Published in 1994, more than 500,000 copies sold ➤ One of the best selling software engineering books in history ➤ Influenced an entire generation of developers, languages, and tools
  • 8. DESIGN PATTERNS ➤ Can be highly contextual and language dependent, but a lot can be learned from all of them ➤ The GoF focused on statically-typed, object oriented, compiled languages ➤ Some languages have implemented primitives for these patterns ➤ Not many of the GoF patterns directly apply to Puppet ➤ All of the GoF patterns focus on reinforcing a set of design principles
  • 11. SEPARATE THINGS THAT CHANGE Minimize risk when making changes
  • 12. LOOSE COUPLING Reduce dependencies, increase modularity
  • 13. SEPARATION OF CONCERNS Divide your application into distinct features
  • 15. LEAST KNOWLEDGE Components should know as little as possible about their neighbors
  • 17. PROGRAM TO AN INTERFACE Interfaces are more stable than the implementation
  • 19. SIX PATTERNS ➤ Resource Wrapper: adding functionality to code you don’t own ➤ Package, File, Service: breaking up monolithic classes ➤ Params: delegating parameter defaults ➤ Strategy: doing the same thing differently ➤ Roles and Profiles: organizing your code for modularity ➤ Factory: creating resources on the fly
  • 21. ABOUT THE WRAPPER PATTERN ➤ Problem: resources you don’t own are missing some functionality or feature necessary to implement your requirements ➤ Solution: use composition to add your required functionality without modifying the code you don’t own
  • 22. ABOUT THE WRAPPER PATTERN ➤ Use the resource wrapper pattern when you need to add functionality to an existing resource ➤ When you feel the need to write your own resources, or to make changes to Forge modules, think about whether you should really be using the wrapper pattern ➤ You can do this in Puppet 3 and Puppet 4, but it’s much cleaner in Puppet 4 ➤ This pattern forms the basis of many other patterns you’ll see today
  • 23. EXAMPLE: MANAGING USERS ➤ We want to manage our employee user accounts ➤ Requirements: ➤ The user’s UID should be set to their employee ID ➤ All employees need to be members of the ‘employees’ group ➤ We should manage a user’s bash profile by default, but users may opt out of this upon request
  • 24. EXAMPLE: MANAGING USERS define mycompany::user ( $employee_id, $gid, $groups = ['employees'], $username = $title, $manage_profile = true, ) { if $manage_profile { file { "/home/${username}/.bash_profile": ensure => file, owner => $username, require => User[$username], } } user { $username: uid => $employee_id, gid => $gid, groups => $groups, } } All employees should be in the ‘employees’ group Employee ID is used for the user ID Feature flag to manage your user’s bash profile Manage ~/.bash_profile with a file resource Pass your parameters to the user resource
  • 25. EXAMPLE: MANAGING USERS mycompany::user { 'bob': employee_id => '1093', gid => 'wheel', manage_profile => false, } “We have a new employee named Bob. He’s employee 1093 and he needs to be a member of the wheel group so he can sudo. He wants to manage his own bash profile.”
  • 26. EXAMPLE: MANAGING USERS “Hey, I’d like to have my shell set to /bin/zsh, can you do that for me?” mycompany::user { 'bob': employee_id => '1093', gid => 'wheel', shell => '/bin/zsh', manage_profile => false, } Could not retrieve catalog: Invalid parameter ‘shell’ for type ‘mycompany::user’
  • 27. EXAMPLE: MANAGING USERS define mycompany::user ( $employee_id, $gid, $groups = ['employees'], $username = $title, $manage_profile = true, ) { if $manage_profile { file { "/home/${username}/.bash_profile": ensure => file, owner => $username, require => User[$username], } } user { $username: uid => $employee_id, gid => $gid, groups => $groups, } } Problem You must maintain these parameters.
  • 28. EXAMPLE: MANAGING USERS (PUPPET 3) define mycompany::user ( $username = $title, $manage_profile = true, $user = {} ) { if $manage_profile { file { "/home/${username}/.bash_profile": ensure => file, owner => $username, require => User[$username], } } $user_defaults = { ‘groups’ => [‘employees’] } $user_params = merge($user, $user_defaults) create_resources(‘user’, $username, $user_params) } Much more flexible interface Enforce business rules Create the user resource by passing the hash to create_resources
  • 29. EXAMPLE: MANAGING USERS (PUPPET 4) define mycompany::user ( String $username = $title, Boolean $manage_profile = true, Hash $user = {} ) { if $manage_profile { file { "/home/${username}/.bash_profile": ensure => file, owner => $username, require => User[$username], } } $user_defaults = { 'groups' => [‘employees’] } user { $username: * => $user_defaults + $user, } } Much more flexible interface Enforce business rules Use splat operator to pass hash keys as parameters to the user resource
  • 30. EXAMPLE: MANAGING USERS mycompany::user { 'bob': employee_id => '1093', gid => 'wheel', manage_profile => false, } “Hey, I’d like to have my shell set to /bin/zsh, can you do that for me?” mycompany::user { 'bob': manage_profile => false, user => { 'uid' => '1093', 'gid' => 'wheel', } }
  • 31. EXAMPLE: MANAGING USERS mycompany::user { 'bob': employee_id => '1093', gid => 'wheel', manage_profile => false, } mycompany::user { 'bob': manage_profile => false, user => { 'uid' => '1093', 'gid' => 'wheel', 'shell' => '/bin/zsh', } } “Hey, I’d like to have my shell set to /bin/zsh, can you do that for me?”
  • 33. ABOUT THE PACKAGE/FILE/SERVICE PATTERN ➤ Problem: your module’s init.pp is getting too cluttered because all of your code’s functionality (concerns) live in that one file ➤ Solution: break out the basic functions of your module into separate classes, usually into a package, config, and service class
  • 34. ABOUT THE PACKAGE/FILE/SERVICE PATTERN ➤ This is one of the first patterns you see when learning Puppet ➤ This is the embodiment of the Single Responsibility and Separation of Concerns principles ➤ Most modules can be broken down into some form of Package, Config File, and Service management ➤ Use this specific pattern any time you write a module that manages these things ➤ Keep the spirit of this pattern in mind whenever you write a module that is more than a few lines long ➤ This has the added benefit of allowing us to utilize class containment for cleaner resource ordering
  • 35. EXAMPLE: NTP class ntp { case $::osfamily { 'Solaris': { $package_name = ['SUNWntpr', 'SUNWntpu'] $config_file = '/etc/inet/ntp.conf' $service_name = 'network/ntp' } 'RedHat': { $package_name = 'ntp' $config_file = '/etc/ntp.conf' $service_name = 'ntpd' } } package { $package_name: ensure => installed, } file { $config_file: ensure => file, content => template('ntp/ntpd.conf.erb'), require => Package[$package_name], notify => Service[$service_name], } service { $service_name: ensure => running } } Installs the ntp package for that platform Places the ntp config file Ensures that the package is installed first Notifies the ntp service of changes to the file Manages the ntp service Set some variables based on the osfamily fact
  • 36. class ntp { case $osfamily { 'Solaris': { $package_name = ['SUNWntpr', 'SUNWntpu'] $config_file = '/etc/inet/ntp.conf' $service_name = 'network/ntp' } 'RedHat': { $package_name = 'ntp' $config_file = '/etc/ntp.conf' $service_name = 'ntpd' } } class { 'ntp::install': } -> class { 'ntp::config': } ~> class { 'ntp::service': } } EXAMPLE: NTP Installs the ntp package Places the ntp config file Package is installed first Manages the ntp service Notifies the service of changes
  • 37. class ntp::install { package { $ntp::package_name: ensure => installed, } } class ntp::config { file { $ntp::config_file: ensure => file, content => template('ntp/ntpd.conf.erb'), } } class ntp::service { service { $ntp::service_name: ensure => running, } } EXAMPLE: NTP
  • 39. ABOUT THE PARAMS PATTERN ➤ Problem: hard-coded data makes modules fragile, verbose parameter default and variable setting logic make classes hard to read ➤ Solution: convert embedded data to parameters and move that data to a separate class where it can be used as parameter defaults
  • 40. ABOUT THE PARAMS PATTERN ➤ The params pattern breaks out your variable assignment and parameter defaults into a separate class, typically named params ➤ Makes classes easier to read by moving the default setting logic into a purpose-built class ➤ Delegates responsibility for setting defaults to the params class ➤ Module data is a new feature designed to eliminate the params pattern by moving this logic into Hiera ➤ Until module data becomes ubiquitous, you’ll see params in use in almost every module ➤ Use this pattern any time you have data that must live in your module
  • 41. EXAMPLE: NTP Problems Only supports Solaris and RedHat ~70% of this class is devoted to data class ntp { case $osfamily { 'Solaris': { $package_name = ['SUNWntpr', 'SUNWntpu'] $config_file = '/etc/inet/ntp.conf' $service_name = 'network/ntp' } 'RedHat': { $package_name = 'ntp' $config_file = '/etc/ntp.conf' $service_name = 'ntpd' } } class { 'ntp::install': } -> class { 'ntp::config': } ~> class { 'ntp::service': } }
  • 42. EXAMPLE: NTP class ntp::params { case $::osfamily { 'Solaris': { $package_name = ['SUNWntpr', 'SUNWntpu'] $config_file = '/etc/inet/ntp.conf' $service_name = 'network/ntp' } 'RedHat': { $package_name = 'ntp' $config_file = '/etc/ntp.conf' $service_name = 'ntpd' } } } Create a purpose-built class to store your module’s data These variables become the default values for your class parameters
  • 43. EXAMPLE: NTP class ntp ( $package_name = $ntp::params::package_name, $config_file = $ntp::params::config_file, $service_name = $ntp::params::service_name, ) inherits ntp::params { class { 'ntp::install': } -> class { 'ntp::config': } ~> class { 'ntp::service': } } Inheriting the params class ensures that it is evaluated first Convert the variables to parameters, and set their defaults to the corresponding variables in the params class
  • 45. ABOUT THE STRATEGY PATTERN ➤ Problem: you have multiple ways to achieve basically the same thing in your module, but you need to choose one way based on some criteria (usually a fact) ➤ Solution: break each approach into separate classes and let your caller decide which to include
  • 46. ABOUT THE STRATEGY PATTERN ➤ This is a GoF pattern ➤ Use this pattern when you have lots of logic doing effectively the same thing but with different details under certain conditions ➤ The Strategy Pattern uses composition to assemble complex behavior from smaller classes
  • 47. EXAMPLE: MYSQL class mysql { ... case $::osfamily { 'Debian': { apt::source { 'mysql': comment => 'MySQL Community APT repository', location => "http://repo.mysql.com/apt/${::operatingsystem}", release => $::lsbdistcodename, repos => 'mysql-5.7', include => { src => false }, } } 'RedHat': { yumrepo { 'mysql': descr => 'MySQL Community YUM repository', baseurl => "http://repo.mysql.com/yum/mysql-5.7-community/el/${::lsbmajdistrelease}/${::architecture}", enabled => true, } } } ... } Both managing a package repository
  • 48. EXAMPLE: MYSQL class mysql::repo::redhat { yumrepo { 'mysql': descr => 'MySQL Community YUM repository', baseurl => "http://repo.mysql.com/yum/mysql-5.7-community/el/${::lsbmajdistrelease}/${::architecture}", enabled => true, } } class mysql::repo::debian { apt::source { 'mysql': comment => 'MySQL Community APT repository', location => "http://repo.mysql.com/apt/${::operatingsystem}", release => $::lsbdistcodename, repos => 'mysql-5.7', include => { src => false }, } } Strategy Classes
  • 49. EXAMPLE: MYSQL class mysql { ... case $::osfamily { 'Debian': { include mysql::repo::debian } 'RedHat': { include mysql::repo::redhat } } ... } Context Class Case statement determines which strategy class to include
  • 50. THE ROLES AND PROFILES PATTERN Organizing your code for modularity
  • 51. ABOUT THE ROLES AND PROFILES PATTERN ➤ Problem: large node statements with many classes, lots of inherited node statements, difficulty identifying what a server’s purpose is in your environment ➤ Solution: add an extra layer of abstraction between your node and your modules
  • 52. ABOUT THE ROLES AND PROFILES PATTERN ➤ The Roles and Profiles pattern was described by Craig Dunn in his blog post Designing Puppet - Roles and Profiles ➤ This is one of the most comprehensive design patterns for Puppet ➤ It is the “official” way to structure your Puppet code ➤ You should always use Roles and Profiles ➤ Craig does an excellent job describing these concepts in depth, you should read his blog post here: http://www.craigdunn.org/2012/05/239/
  • 53. WITHOUT ROLES AND PROFILES node base { include mycompany::settings } node www inherits base { include apache include mysql include php include nagios::web_server } node ns1 inherits base { include bind include nagios::bind bind::zone { ‘example.com': type => master } } node ns2 inherits base { include bind include nagios::bind bind::zone { ‘example.com': type => slave } } Base node includes common modules Nodes inherit the base to get common functionality More specific functionality is added in each node statement Problems This file can get really long, really fast Can violate DRY when you have lots of similar nodes Edge cases are hard to manage Node ModulesModules ResourcesResources
  • 54. ROLES AND PROFILES TERMINOLOGY ➤ Module: implements one piece of software or functionality ➤ Profile: combines modules to implement a stack (i.e. “A LAMP stack includes the apache, mysql, and php modules”) ➤ Role: combine profiles to implement your business rules (i.e. “This server is a web server”) ➤ A node can only ever include one role ➤ If you think you need to include two roles, you’ve probably just identified another role Node ModulesModules ResourcesResourcesRole ModulesProfiles
  • 55. CONVERTING TO ROLES AND PROFILES class roles::base { include profiles::base } class roles::web_server { include profiles::base include profiles::lamp } class roles::nameserver::master inherits roles::base { include profiles::bind::master } class roles::nameserver::slave inherits roles::base { include profiles::bind::slave } class profiles::base { include mycompany::settings } class profiles::lamp { include apache include mysql include php include nagios::web_server } class profiles::bind ($type = master) { include bind bind::zone { 'example.com': type => $type, } } class profiles::bind::master { include profiles::bind } class profiles::bind::slave { class { 'profiles::bind': type => slave, } }
  • 56. CONVERTING TO ROLES AND PROFILES node www { include roles::web_server } node ns1 { include roles::nameserver::master } node ns2 { include roles::nameserver::slave } node base { include mycompany::settings } node www inherits base { include apache include mysql include php include nagios::web_server } node ns1 inherits base { include bind include nagios::bind bind::zone { ‘example.com': type => master } } node ns2 inherits base { include bind include nagios::bind bind::zone { ‘example.com': type => slave } }
  • 58. ABOUT THE FACTORY PATTERN ➤ Problem: your module has to create a lot of resources of the same type, or you want to control how resources are created with your module ➤ Solution: create the resources in your class based on data passed to your parameters
  • 59. ABOUT THE FACTORY PATTERN ➤ This is also known as the create_resources pattern ➤ Emerged early on as crude iteration support in older Puppet versions ➤ We already saw this in action in the Resource Wrapper Pattern example ➤ Use this pattern when you want your module to have a single entry point, even for creating your own resources
  • 60. EXAMPLE: MANAGING CONFIGURATION WITH INI_SETTING class puppet ( $ca_server = 'puppet-ca.example.com', $master = 'puppet.example.com', $pluginsync = true, $noop = false, ) { $defaults = { 'path' => '/etc/puppet/puppet.conf' } $main_section = { 'main/ca_server' => { 'setting' => 'ca_server', 'value' => $ca_server }, 'main/server' => { 'setting' => 'server', 'value' => $master }, } $agent_section = { 'agent/pluginsync' => { 'setting' => 'pluginsync', 'value' => $pluginsync }, 'agent/noop' => { 'setting' => 'noop', 'value' => $noop }, } create_resources('ini_setting', $main_section, merge($defaults, { section => 'main' })) create_resources('ini_setting', $agent_section, merge($defaults, { section => 'agent' })) } Get data from params Organize the data so we can consume it with create_resources Pass the munged data to create_resources
  • 61. EXAMPLE: MANAGING CONFIGURATION WITH INI_SETTING (PUPPET 4) class puppet ( String $path = '/etc/puppet/puppet.conf', Hash $main_section = { 'ca_server' => 'puppet-ca.example.com', 'server' => 'puppet.example.com' }, Hash $agent_section = { 'pluginsync' => true, 'noop' => false, }, ) { ['agent', 'main'].each |$section| { $data = getvar("${section}_section") $data.each |$key,$val| { ini_setting { "${section}/${key}": path => $path, section => $section, setting => $key, value => $val, } } } } Pass a hash for each section Iterate over each section name Fetch the variable that holds that section’s data Iterate over that data, passing it to an ini_setting resource
  • 63. STAY TUNED FOR MORE PATTERNS
  • 64. CONTACT INFO ➤ @djdanzilio on Twitter ➤ danzilio on Freenode and Slack (you can usually find me in #voxpupuli, #puppet- dev, and #puppet) ➤ danzilio on GitHub and The Forge ➤ ddanzilio (at) kovarus (dot) com ➤ blog.danzil.io ➤ www.kovarus.com