SlideShare a Scribd company logo
1 of 45
Download to read offline
RE-USEYOUR MODULES!
Techniques and Approaches to Modules Reusability
Puppet Camp 2010 San Francisco
Alessandro Franceschi
al@lab42.it
I have a dream
a small one
CrossVendor
Reusable
Plug & Play
Puppet
modules
CrossVendor
Reusable
Plug & Play
At the beginning...
class foo {
package { foo:
ensure => installed
}
service { foo:
ensure => running,
enable => true,
hasstatus => true,
require => Package[foo],
subscribe => File[foo.conf],
}
file { foo.conf:
ensure => present,
path => “/etc/foo.conf”,
mode => 644,
owner => root,
group => root,
source => “puppet:///foo/foo.conf”,
}
}
At the beginning
Facing Diversity
package { foo:
ensure => installed,
name => $operatingsystem ? {
debian => “food”,
default => “foo”,
},
}
service { foo:
ensure => running,
name => $operatingsystem ? {
debian => “food”,
default => “foo”,
},
enable => true,
hasstatus => true,
require => Package[foo],
subscribe => File[foo.conf],
}
file { foo.conf:
ensure => present,
path => $operatingsystem ? {
debian => “/etc/foo/foo.conf”,
default => “/etc/foo.conf”,
},
mode => 644,
Facing Diversity
ensure => installed
name => $operatingsystem ? {
debian => “food”,
default => “foo”,
}
}
service { foo:
ensure => running,
name => $operatingsystem ? {
debian => “food”,
default => “foo”,
},
enable => true,
hasstatus => $operatingsystem ? {
debian => false,
default => true,
},
pattern => “food”,
require => Package[foo],
subscribe => File[foo.conf],
}
file { foo.conf:
ensure => present,
path => $operatingsystem ? {
debian => “/etc/foo/foo.conf”,
Facing Diversity
debian => “food”,
ubuntu => “food”,
default => “foo”,
}
}
service { foo:
ensure => running,
name => $operatingsystem ? {
debian => “food”,
ubuntu => “food”,
default => “foo”,
},
enable => true,
hasstatus => $operatingsystem ? {
debian => false,
ubuntu => false,
default => true,
},
pattern => “food”,
require => Package[foo],
subscribe => File[foo.conf],
}
file { foo.conf:
ensure => present,
Facing Diversity
Centralized settings: foo::params
Qualified variables
OS dedicated classes
Facing Diversity
Centralized settings
class foo::params {
$packagename = $operatingsystem ? {
debian => “food”,
ubuntu => “food”
default => "foo",
}
$servicename = $operatingsystem ? {
debian => “food”,
ubuntu => “food”,
default => “foo”,
},
$processname = $operatingsystem ? {
default => "food",
}
$hasstatus = $operatingsystem ? {
debian => false,
ubuntu => false,
default => true,
}
$configfile = $operatingsystem ? {
freebsd => "/usr/local/etc/foo.conf",
ubuntu => “/etc/foo/foo.conf",
Facing Diversity
Qualified variables
class foo {
require foo::params
package { "foo":
name => "${foo::params::packagename}",
ensure => present,
}
service { "foo":
name => "${foo::params::servicename}",
ensure => running,
enable => true,
hasstatus => "${foo::params::hasstatus}",
pattern => "${foo::params::processname}",
require => Package["foo"],
subscribe => File["foo.conf"],
}
file { "foo.conf":
path => "${foo::params::configfile}",
mode => "${foo::params::configfile_mode}",
owner => "${foo::params::configfile_owner}",
group => "${foo::params::configfile_group}",
ensure => present,
require => Package["foo"],
Facing Diversity
OS dedicated classes
class foo {
[ ... ]
# Include OS specific subclasses, if necessary
# Note that they needn’t to inherit foo
case $operatingsystem {
debian: { include foo::debian }
ubuntu: { include foo::debian }
default: { }
}
}
Facing Diversity
Dealing with Users
# foo class needs users’ variables
# IE: $foo_server
class foo {
[ ... ]
file { foo.conf:
ensure => present,
path => $operatingsystem ? {
debian => “/etc/foo/foo.conf”,
default => “/etc/foo.conf”,
},
mode => 644,
content => template(“foo/foo.conf.erb”),
}
}
# foo/templates/foo.conf.erb is something like:
# File Managed by Puppet
server = <%= foo_server %>
# Plug & Play ?
Dealing with Users
Filtering user variables
Setting default values
Dealing with Users
Setting default values
class foo::params {
# Full hostname of foo server
$server = $foo_server ? {
'' => "foo.example42.com",
default => "${foo_server}",
}
# Foo DB management
$db_host = $foo_db_host ? {
'' => "localhost",
default => "${foo_db_host}",
}
$db_user = $foo_db_user ? {
'' => "root",
default => "${foo_db_user}",
}
$db_password = $foo_db_password ? {
'' => "",
default => "${foo_db_host}",
}
Dealing with Users
Setting default values
class foo {
include foo::params
[ ... ]
# ${foo_server} is user variable unfiltered
# ${foo::params::server} is user variable filtered
# You may want/need to reassign ${foo_server} value:
${foo_server} = ${foo::params::server}
}
In templates this fails:
server = <%= foo::params::server %>
This works (of course):
server = <%= foo_server %>
This works (even if variable is not set):
server = <%= scope.lookupvar('foo::params::server') %>
Dealing with Users
Adapt and Customize
debian => “food”,
ubuntu => “food”,
default => “foo”,
},
enable => true,
hasstatus => $operatingsystem ? {
debian => false,
ubuntu => false,
default => true,
},
require => Package[foo],
subscribe => File[foo.conf],
}
file { foo.conf:
ensure => present,
path => “/etc/foo.conf”,
mode => 644,
owner => root,
group => root,
source => [ “puppet:///foo/foo.conf-$hostname”,
“puppet:///foo/foo.conf-$my_role”,
“puppet:///foo/foo.conf” ],
}
}
Adapt and customize
}
file { foo.conf:
ensure => present,
path => “/etc/foo.conf”,
mode => 644,
owner => root,
group => root,
source => [ “puppet:///foo/foo.conf-$hostname”,
“puppet:///foo/foo.conf-$my_role”,
“puppet:///foo/foo.conf” ],
}
case $my_role {
mail: {
file { foo.conf-mail:
ensure => present,
path => “/etc/foo.conf.d/mail”,
mode => 644,
owner => root,
group => root,
source => [ “puppet:///foo/foo.conf-mail”,
}
}
default: { }
}
Adapt and customize
Isolation of diversity
Project classes || Project module
Adapt and Customize
Isolation of diversity
# Class foo::example42
#
# You can use your custom project class to modify
# the standard behavior of foo module
#
# You don't need to use class inheritance if you
# don't override or redefine resources in foo class
#
# You can add custom resources and are free to
# decide how to provide the contents of your files:
# - Via static sourced files ( source => ) according
# to the naming convention you need
# - Via custom templates ( content => )
# - Via some kind of infile line modification tools
# such as Augeas
#
class foo::example42 inherits foo {
File["foo.conf"] {
source => [ "puppet:///foo/foo.conf-$hostname",
"puppet:///foo/foo.conf-$role",
"puppet:///foo/foo.conf" ],
}
}
Adapt and Customize
Project Classes ||
Project Modules
class foo {
[ ... ]
# Include project specific class if $my_project is set
# The extra project class is by default looked in foo module
# If $my_project_onmodule == yes it's looked in your project
# module
if $my_project {
case $my_project_onmodule {
yes,true: { include "${my_project}::foo" }
default: { include "foo::${my_project}" }
}
}
}
Adapt and Customize
Control and monitor
service { foo:
ensure => running,
name => $operatingsystem ? {
debian => “food”,
ubuntu => “food”,
default => “foo”,
},
enable => true,
hasstatus => $operatingsystem ? {
debian => false,
ubuntu => false,
default => true,
},
pattern => “food”,
require => Package[foo],
subscribe => File[foo.conf],
}
! # Monitoring stuff: munin and nagios
! munin::plugin { "foo_processes":
! ! ! ensure => present,
! }
! nagios::service { "foo_${foo_port_real}":
! ! check_command => "tcp_port!${foo_port_real}"
! }
Control and Monitor
Monitoring abstraction
Monitor meta-module
Control and Monitor
Monitoring abstraction
class foo {
[ ... ]
# Include monitor classe if $monitor == yes
# Define the monitoring tools to use
# with the variables $monitor_tools (can be an array)
if $monitor == "yes" { include foo::monitor }
}
Control and Monitor
Monitoring abstraction
class foo::monitor {
include foo::params
monitor::port { "foo_${foo::params::protocol}_
${foo::params::port}":
protocol => "${foo::params::protocol}",
target => "${foo::params::monitor_target_real}",
port => "${foo::params::port}",
enable => "${foo::params::monitor_port_enable}",
tool => "${monitor_tool}",
}
monitor::process { "foo_process":
process => "${foo::params::processname}",
service => "${foo::params::servicename}",
pidfile => "${foo::params::pidfile}",
enable => "${foo::params::monitor_process_enable}",
tool => "${monitor_tool}",
}
[ ... ]
if $my_project {
case $my_project_onmodule {
yes,true: { include "${my_project}::foo::monitor" }
default: { include "foo::monitor::${my_project}" }
Control and Monitor
Monitor Meta-module
define monitor::process ( $process, $service,
$pidfile, $tool, $enable ) {
if ($enable != "false") and ($enable != "no") {
if ($tool =~ /munin/) { # TODO }
if ($tool =~ /collectd/) { # TODO }
if ($tool =~ /monit/) {
monitor::process::monit { "$name":
pidfile => "$pidfile",
process => "$process",
service => "$service",
}
}
if ($tool =~ /nagios/) {
monitor::process::nagios { "$name":
process => $process,
}
}
} # End if $enable
}
Control and Monitor
Monitor Meta-module
define monitor::process::monit (
$pidfile='',
$process='',
$service=''
) {
# Use for Example42 monit module
monit::checkpid { "${process}":
pidfile => "${pidfile}",
startprogram => "/etc/init.d/${service} start",
stopprogram => "/etc/init.d/${service} stop",
}
# Use for Camptocamp’s monit module (sample)
# monit::config { "${process}":
# ensure => present,
# content => template(“monit/checkprocess.erb”), # To create
# }
# Use for Monit recipe on Puppet’s wiki (sample)
# monit::package { "${process}": }
}
Control and Monitor
Coherent naming conventions
Predictable behaviors
A name for Everything
Naming conventions
include foo - Installs and runs foo service
# If foo can be client or server
include foo::server - Installs foo server
include foo::client - Installs foo client
# If foo is on every/many host either client or server:
if ($foo_server_local == true) or ($foo_server == "$fqdn") {
include puppet::server
} else {
include puppet::client
}
# If foo has to be disable or removed:
include foo::absent - Remove foo
include foo::disable - Disable foo service
include foo::disableboot - Disable foo service but
do not check if is running
A name for Everything
Quick cloning & customization
Coherent Modules Infrastructure
Modules Machine
Quick cloning
# Few seds for a script that clones foo module
example42_module_clone.sh
# Creates new module from foo template. Then you:
# - Edit params.pp
# - Add specific classes, defines, types, facts
# - Eventually define modules variables and templates
#
# - Everything else is ready out of the box
Modules Machine
Quick customization
# Script that adapts a module for a new project
example42_project_rename.sh
# Prepares custom classes for new project
# foo/manifests/my_project.pp
# foo/manifests/monitor/my_project.pp
# foo/manifests/backup/my_project.pp
#
# - Use the logic that works for your project
# - Choose how to provide your configuration files
Modules Machine
Coherent Infrastructure
# Clone is GOOD
# Modules are similar
# They share a coherent naming convention
# They have confined places where to apply
# custom logic
# Fixed files for fixes functions
# Common approach for the Puppet team members
# Reduced risks and better manageability
# Quick update to template improvements
# Could be more easily manageable/autogenerated
# by GUI tools
Modules Machine
Centralized settings:
foo::params
Qualified variables
Isolation of diversity
Project classes ||
Project module
Monitoring abstraction
Monitor meta-module
Filtering user variables
Setting default values
Coherent naming
conventions
Predictable behaviors
Quick cloning of foo
module
Quick customization
CrossVendor Reusable Plug & Play
Modules
Machine
A name for
Everything
Dealing
with Users
Control
and Monitor
Adapt and
Customize
Facing
Diversity
small dreams turn easier into reality
www.example42.com
github.com/example42/puppet-foo/
Questions?
(Please Loud & Clear, I’ve lost my Babelfish)

More Related Content

What's hot

News of the Symfony2 World
News of the Symfony2 WorldNews of the Symfony2 World
News of the Symfony2 WorldFabien Potencier
 
Doctrine MongoDB ODM (PDXPHP)
Doctrine MongoDB ODM (PDXPHP)Doctrine MongoDB ODM (PDXPHP)
Doctrine MongoDB ODM (PDXPHP)Kris Wallsmith
 
The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010Fabien Potencier
 
Dependency injection in PHP 5.3/5.4
Dependency injection in PHP 5.3/5.4Dependency injection in PHP 5.3/5.4
Dependency injection in PHP 5.3/5.4Fabien Potencier
 
Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2Fabien Potencier
 
Dependency Injection with PHP 5.3
Dependency Injection with PHP 5.3Dependency Injection with PHP 5.3
Dependency Injection with PHP 5.3Fabien Potencier
 
The symfony platform: Create your very own framework (PHP Quebec 2008)
The symfony platform: Create your very own framework (PHP Quebec 2008)The symfony platform: Create your very own framework (PHP Quebec 2008)
The symfony platform: Create your very own framework (PHP Quebec 2008)Fabien Potencier
 
Dependency injection-zendcon-2010
Dependency injection-zendcon-2010Dependency injection-zendcon-2010
Dependency injection-zendcon-2010Fabien Potencier
 
Corephpcomponentpresentation 1211425966721657-8
Corephpcomponentpresentation 1211425966721657-8Corephpcomponentpresentation 1211425966721657-8
Corephpcomponentpresentation 1211425966721657-8PrinceGuru MS
 
Hidden treasures of Ruby
Hidden treasures of RubyHidden treasures of Ruby
Hidden treasures of RubyTom Crinson
 
Introdução ao Perl 6
Introdução ao Perl 6Introdução ao Perl 6
Introdução ao Perl 6garux
 
Durian: a PHP 5.5 microframework with generator-style middleware
Durian: a PHP 5.5 microframework with generator-style middlewareDurian: a PHP 5.5 microframework with generator-style middleware
Durian: a PHP 5.5 microframework with generator-style middlewareKuan Yen Heng
 
The Origin of Lithium
The Origin of LithiumThe Origin of Lithium
The Origin of LithiumNate Abele
 
Nashvile Symfony Routes Presentation
Nashvile Symfony Routes PresentationNashvile Symfony Routes Presentation
Nashvile Symfony Routes PresentationBrent Shaffer
 
A Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP GeneratorsA Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP GeneratorsMark Baker
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of LithiumNate Abele
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium AppsNate Abele
 
Looping the Loop with SPL Iterators
Looping the Loop with SPL IteratorsLooping the Loop with SPL Iterators
Looping the Loop with SPL IteratorsMark Baker
 
Damn Fine CoffeeScript
Damn Fine CoffeeScriptDamn Fine CoffeeScript
Damn Fine CoffeeScriptniklal
 

What's hot (20)

News of the Symfony2 World
News of the Symfony2 WorldNews of the Symfony2 World
News of the Symfony2 World
 
Doctrine MongoDB ODM (PDXPHP)
Doctrine MongoDB ODM (PDXPHP)Doctrine MongoDB ODM (PDXPHP)
Doctrine MongoDB ODM (PDXPHP)
 
The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010
 
Dependency injection in PHP 5.3/5.4
Dependency injection in PHP 5.3/5.4Dependency injection in PHP 5.3/5.4
Dependency injection in PHP 5.3/5.4
 
Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2
 
Dependency Injection with PHP 5.3
Dependency Injection with PHP 5.3Dependency Injection with PHP 5.3
Dependency Injection with PHP 5.3
 
The symfony platform: Create your very own framework (PHP Quebec 2008)
The symfony platform: Create your very own framework (PHP Quebec 2008)The symfony platform: Create your very own framework (PHP Quebec 2008)
The symfony platform: Create your very own framework (PHP Quebec 2008)
 
Dependency injection-zendcon-2010
Dependency injection-zendcon-2010Dependency injection-zendcon-2010
Dependency injection-zendcon-2010
 
Corephpcomponentpresentation 1211425966721657-8
Corephpcomponentpresentation 1211425966721657-8Corephpcomponentpresentation 1211425966721657-8
Corephpcomponentpresentation 1211425966721657-8
 
Hidden treasures of Ruby
Hidden treasures of RubyHidden treasures of Ruby
Hidden treasures of Ruby
 
Introdução ao Perl 6
Introdução ao Perl 6Introdução ao Perl 6
Introdução ao Perl 6
 
Zero to SOLID
Zero to SOLIDZero to SOLID
Zero to SOLID
 
Durian: a PHP 5.5 microframework with generator-style middleware
Durian: a PHP 5.5 microframework with generator-style middlewareDurian: a PHP 5.5 microframework with generator-style middleware
Durian: a PHP 5.5 microframework with generator-style middleware
 
The Origin of Lithium
The Origin of LithiumThe Origin of Lithium
The Origin of Lithium
 
Nashvile Symfony Routes Presentation
Nashvile Symfony Routes PresentationNashvile Symfony Routes Presentation
Nashvile Symfony Routes Presentation
 
A Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP GeneratorsA Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP Generators
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of Lithium
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium Apps
 
Looping the Loop with SPL Iterators
Looping the Loop with SPL IteratorsLooping the Loop with SPL Iterators
Looping the Loop with SPL Iterators
 
Damn Fine CoffeeScript
Damn Fine CoffeeScriptDamn Fine CoffeeScript
Damn Fine CoffeeScript
 

Similar to Alessandro sf 2010

Puppet Camp LA 2015: Basic Puppet Module Design (Beginner)
Puppet Camp LA  2015: Basic Puppet Module Design (Beginner)Puppet Camp LA  2015: Basic Puppet Module Design (Beginner)
Puppet Camp LA 2015: Basic Puppet Module Design (Beginner)Puppet
 
Puppetcamp module design talk
Puppetcamp module design talkPuppetcamp module design talk
Puppetcamp module design talkJeremy Kitchen
 
Puppet: What _not_ to do
Puppet: What _not_ to doPuppet: What _not_ to do
Puppet: What _not_ to doPuppet
 
PuppetCamp Ghent - What Not to Do with Puppet
PuppetCamp Ghent - What Not to Do with PuppetPuppetCamp Ghent - What Not to Do with Puppet
PuppetCamp Ghent - What Not to Do with PuppetWalter Heck
 
PuppetCamp Ghent - What Not to Do with Puppet
PuppetCamp Ghent - What Not to Do with PuppetPuppetCamp Ghent - What Not to Do with Puppet
PuppetCamp Ghent - What Not to Do with PuppetOlinData
 
Puppet Modules for Fun and Profit
Puppet Modules for Fun and ProfitPuppet Modules for Fun and Profit
Puppet Modules for Fun and ProfitPuppet
 
Puppet for Java developers - JavaZone NO 2012
Puppet for Java developers - JavaZone NO 2012Puppet for Java developers - JavaZone NO 2012
Puppet for Java developers - JavaZone NO 2012Carlos Sanchez
 
Aura Project for PHP
Aura Project for PHPAura Project for PHP
Aura Project for PHPHari K T
 
Writing and Publishing Puppet Modules - PuppetConf 2014
Writing and Publishing Puppet Modules - PuppetConf 2014Writing and Publishing Puppet Modules - PuppetConf 2014
Writing and Publishing Puppet Modules - PuppetConf 2014Puppet
 
Does your configuration code smell?
Does your configuration code smell?Does your configuration code smell?
Does your configuration code smell?Tushar Sharma
 
PM : code faster
PM : code fasterPM : code faster
PM : code fasterPHPPRO
 
Forget about loops
Forget about loopsForget about loops
Forget about loopsDušan Kasan
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐいHisateru Tanaka
 
Doing the Refactor Dance - Making Your Puppet Modules More Modular - PuppetCo...
Doing the Refactor Dance - Making Your Puppet Modules More Modular - PuppetCo...Doing the Refactor Dance - Making Your Puppet Modules More Modular - PuppetCo...
Doing the Refactor Dance - Making Your Puppet Modules More Modular - PuppetCo...Puppet
 

Similar to Alessandro sf 2010 (20)

Puppet Camp LA 2015: Basic Puppet Module Design (Beginner)
Puppet Camp LA  2015: Basic Puppet Module Design (Beginner)Puppet Camp LA  2015: Basic Puppet Module Design (Beginner)
Puppet Camp LA 2015: Basic Puppet Module Design (Beginner)
 
Puppetcamp module design talk
Puppetcamp module design talkPuppetcamp module design talk
Puppetcamp module design talk
 
Puppet: What _not_ to do
Puppet: What _not_ to doPuppet: What _not_ to do
Puppet: What _not_ to do
 
PuppetCamp Ghent - What Not to Do with Puppet
PuppetCamp Ghent - What Not to Do with PuppetPuppetCamp Ghent - What Not to Do with Puppet
PuppetCamp Ghent - What Not to Do with Puppet
 
PuppetCamp Ghent - What Not to Do with Puppet
PuppetCamp Ghent - What Not to Do with PuppetPuppetCamp Ghent - What Not to Do with Puppet
PuppetCamp Ghent - What Not to Do with Puppet
 
Puppet fundamentals
Puppet fundamentalsPuppet fundamentals
Puppet fundamentals
 
Puppet modules for Fun and Profit
Puppet modules for Fun and ProfitPuppet modules for Fun and Profit
Puppet modules for Fun and Profit
 
Puppet Modules for Fun and Profit
Puppet Modules for Fun and ProfitPuppet Modules for Fun and Profit
Puppet Modules for Fun and Profit
 
Puppet for Java developers - JavaZone NO 2012
Puppet for Java developers - JavaZone NO 2012Puppet for Java developers - JavaZone NO 2012
Puppet for Java developers - JavaZone NO 2012
 
Feeds drupal cafe
Feeds drupal cafeFeeds drupal cafe
Feeds drupal cafe
 
Tutorial Puppet
Tutorial PuppetTutorial Puppet
Tutorial Puppet
 
Aura Project for PHP
Aura Project for PHPAura Project for PHP
Aura Project for PHP
 
Writing and Publishing Puppet Modules - PuppetConf 2014
Writing and Publishing Puppet Modules - PuppetConf 2014Writing and Publishing Puppet Modules - PuppetConf 2014
Writing and Publishing Puppet Modules - PuppetConf 2014
 
Does your configuration code smell?
Does your configuration code smell?Does your configuration code smell?
Does your configuration code smell?
 
Puppet
PuppetPuppet
Puppet
 
PM : code faster
PM : code fasterPM : code faster
PM : code faster
 
Puppet @ Seat
Puppet @ SeatPuppet @ Seat
Puppet @ Seat
 
Forget about loops
Forget about loopsForget about loops
Forget about loops
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
 
Doing the Refactor Dance - Making Your Puppet Modules More Modular - PuppetCo...
Doing the Refactor Dance - Making Your Puppet Modules More Modular - PuppetCo...Doing the Refactor Dance - Making Your Puppet Modules More Modular - PuppetCo...
Doing the Refactor Dance - Making Your Puppet Modules More Modular - PuppetCo...
 

More from Puppet

Puppet camp2021 testing modules and controlrepo
Puppet camp2021 testing modules and controlrepoPuppet camp2021 testing modules and controlrepo
Puppet camp2021 testing modules and controlrepoPuppet
 
Puppetcamp r10kyaml
Puppetcamp r10kyamlPuppetcamp r10kyaml
Puppetcamp r10kyamlPuppet
 
2021 04-15 operational verification (with notes)
2021 04-15 operational verification (with notes)2021 04-15 operational verification (with notes)
2021 04-15 operational verification (with notes)Puppet
 
Puppet camp vscode
Puppet camp vscodePuppet camp vscode
Puppet camp vscodePuppet
 
Modules of the twenties
Modules of the twentiesModules of the twenties
Modules of the twentiesPuppet
 
Applying Roles and Profiles method to compliance code
Applying Roles and Profiles method to compliance codeApplying Roles and Profiles method to compliance code
Applying Roles and Profiles method to compliance codePuppet
 
KGI compliance as-code approach
KGI compliance as-code approachKGI compliance as-code approach
KGI compliance as-code approachPuppet
 
Enforce compliance policy with model-driven automation
Enforce compliance policy with model-driven automationEnforce compliance policy with model-driven automation
Enforce compliance policy with model-driven automationPuppet
 
Keynote: Puppet camp compliance
Keynote: Puppet camp complianceKeynote: Puppet camp compliance
Keynote: Puppet camp compliancePuppet
 
Automating it management with Puppet + ServiceNow
Automating it management with Puppet + ServiceNowAutomating it management with Puppet + ServiceNow
Automating it management with Puppet + ServiceNowPuppet
 
Puppet: The best way to harden Windows
Puppet: The best way to harden WindowsPuppet: The best way to harden Windows
Puppet: The best way to harden WindowsPuppet
 
Simplified Patch Management with Puppet - Oct. 2020
Simplified Patch Management with Puppet - Oct. 2020Simplified Patch Management with Puppet - Oct. 2020
Simplified Patch Management with Puppet - Oct. 2020Puppet
 
Accelerating azure adoption with puppet
Accelerating azure adoption with puppetAccelerating azure adoption with puppet
Accelerating azure adoption with puppetPuppet
 
Puppet catalog Diff; Raphael Pinson
Puppet catalog Diff; Raphael PinsonPuppet catalog Diff; Raphael Pinson
Puppet catalog Diff; Raphael PinsonPuppet
 
ServiceNow and Puppet- better together, Kevin Reeuwijk
ServiceNow and Puppet- better together, Kevin ReeuwijkServiceNow and Puppet- better together, Kevin Reeuwijk
ServiceNow and Puppet- better together, Kevin ReeuwijkPuppet
 
Take control of your dev ops dumping ground
Take control of your  dev ops dumping groundTake control of your  dev ops dumping ground
Take control of your dev ops dumping groundPuppet
 
100% Puppet Cloud Deployment of Legacy Software
100% Puppet Cloud Deployment of Legacy Software100% Puppet Cloud Deployment of Legacy Software
100% Puppet Cloud Deployment of Legacy SoftwarePuppet
 
Puppet User Group
Puppet User GroupPuppet User Group
Puppet User GroupPuppet
 
Continuous Compliance and DevSecOps
Continuous Compliance and DevSecOpsContinuous Compliance and DevSecOps
Continuous Compliance and DevSecOpsPuppet
 
The Dynamic Duo of Puppet and Vault tame SSL Certificates, Nick Maludy
The Dynamic Duo of Puppet and Vault tame SSL Certificates, Nick MaludyThe Dynamic Duo of Puppet and Vault tame SSL Certificates, Nick Maludy
The Dynamic Duo of Puppet and Vault tame SSL Certificates, Nick MaludyPuppet
 

More from Puppet (20)

Puppet camp2021 testing modules and controlrepo
Puppet camp2021 testing modules and controlrepoPuppet camp2021 testing modules and controlrepo
Puppet camp2021 testing modules and controlrepo
 
Puppetcamp r10kyaml
Puppetcamp r10kyamlPuppetcamp r10kyaml
Puppetcamp r10kyaml
 
2021 04-15 operational verification (with notes)
2021 04-15 operational verification (with notes)2021 04-15 operational verification (with notes)
2021 04-15 operational verification (with notes)
 
Puppet camp vscode
Puppet camp vscodePuppet camp vscode
Puppet camp vscode
 
Modules of the twenties
Modules of the twentiesModules of the twenties
Modules of the twenties
 
Applying Roles and Profiles method to compliance code
Applying Roles and Profiles method to compliance codeApplying Roles and Profiles method to compliance code
Applying Roles and Profiles method to compliance code
 
KGI compliance as-code approach
KGI compliance as-code approachKGI compliance as-code approach
KGI compliance as-code approach
 
Enforce compliance policy with model-driven automation
Enforce compliance policy with model-driven automationEnforce compliance policy with model-driven automation
Enforce compliance policy with model-driven automation
 
Keynote: Puppet camp compliance
Keynote: Puppet camp complianceKeynote: Puppet camp compliance
Keynote: Puppet camp compliance
 
Automating it management with Puppet + ServiceNow
Automating it management with Puppet + ServiceNowAutomating it management with Puppet + ServiceNow
Automating it management with Puppet + ServiceNow
 
Puppet: The best way to harden Windows
Puppet: The best way to harden WindowsPuppet: The best way to harden Windows
Puppet: The best way to harden Windows
 
Simplified Patch Management with Puppet - Oct. 2020
Simplified Patch Management with Puppet - Oct. 2020Simplified Patch Management with Puppet - Oct. 2020
Simplified Patch Management with Puppet - Oct. 2020
 
Accelerating azure adoption with puppet
Accelerating azure adoption with puppetAccelerating azure adoption with puppet
Accelerating azure adoption with puppet
 
Puppet catalog Diff; Raphael Pinson
Puppet catalog Diff; Raphael PinsonPuppet catalog Diff; Raphael Pinson
Puppet catalog Diff; Raphael Pinson
 
ServiceNow and Puppet- better together, Kevin Reeuwijk
ServiceNow and Puppet- better together, Kevin ReeuwijkServiceNow and Puppet- better together, Kevin Reeuwijk
ServiceNow and Puppet- better together, Kevin Reeuwijk
 
Take control of your dev ops dumping ground
Take control of your  dev ops dumping groundTake control of your  dev ops dumping ground
Take control of your dev ops dumping ground
 
100% Puppet Cloud Deployment of Legacy Software
100% Puppet Cloud Deployment of Legacy Software100% Puppet Cloud Deployment of Legacy Software
100% Puppet Cloud Deployment of Legacy Software
 
Puppet User Group
Puppet User GroupPuppet User Group
Puppet User Group
 
Continuous Compliance and DevSecOps
Continuous Compliance and DevSecOpsContinuous Compliance and DevSecOps
Continuous Compliance and DevSecOps
 
The Dynamic Duo of Puppet and Vault tame SSL Certificates, Nick Maludy
The Dynamic Duo of Puppet and Vault tame SSL Certificates, Nick MaludyThe Dynamic Duo of Puppet and Vault tame SSL Certificates, Nick Maludy
The Dynamic Duo of Puppet and Vault tame SSL Certificates, Nick Maludy
 

Alessandro sf 2010

  • 1. RE-USEYOUR MODULES! Techniques and Approaches to Modules Reusability Puppet Camp 2010 San Francisco Alessandro Franceschi al@lab42.it
  • 2. I have a dream a small one
  • 9. class foo { package { foo: ensure => installed } service { foo: ensure => running, enable => true, hasstatus => true, require => Package[foo], subscribe => File[foo.conf], } file { foo.conf: ensure => present, path => “/etc/foo.conf”, mode => 644, owner => root, group => root, source => “puppet:///foo/foo.conf”, } } At the beginning
  • 11. package { foo: ensure => installed, name => $operatingsystem ? { debian => “food”, default => “foo”, }, } service { foo: ensure => running, name => $operatingsystem ? { debian => “food”, default => “foo”, }, enable => true, hasstatus => true, require => Package[foo], subscribe => File[foo.conf], } file { foo.conf: ensure => present, path => $operatingsystem ? { debian => “/etc/foo/foo.conf”, default => “/etc/foo.conf”, }, mode => 644, Facing Diversity
  • 12. ensure => installed name => $operatingsystem ? { debian => “food”, default => “foo”, } } service { foo: ensure => running, name => $operatingsystem ? { debian => “food”, default => “foo”, }, enable => true, hasstatus => $operatingsystem ? { debian => false, default => true, }, pattern => “food”, require => Package[foo], subscribe => File[foo.conf], } file { foo.conf: ensure => present, path => $operatingsystem ? { debian => “/etc/foo/foo.conf”, Facing Diversity
  • 13. debian => “food”, ubuntu => “food”, default => “foo”, } } service { foo: ensure => running, name => $operatingsystem ? { debian => “food”, ubuntu => “food”, default => “foo”, }, enable => true, hasstatus => $operatingsystem ? { debian => false, ubuntu => false, default => true, }, pattern => “food”, require => Package[foo], subscribe => File[foo.conf], } file { foo.conf: ensure => present, Facing Diversity
  • 14. Centralized settings: foo::params Qualified variables OS dedicated classes Facing Diversity
  • 15. Centralized settings class foo::params { $packagename = $operatingsystem ? { debian => “food”, ubuntu => “food” default => "foo", } $servicename = $operatingsystem ? { debian => “food”, ubuntu => “food”, default => “foo”, }, $processname = $operatingsystem ? { default => "food", } $hasstatus = $operatingsystem ? { debian => false, ubuntu => false, default => true, } $configfile = $operatingsystem ? { freebsd => "/usr/local/etc/foo.conf", ubuntu => “/etc/foo/foo.conf", Facing Diversity
  • 16. Qualified variables class foo { require foo::params package { "foo": name => "${foo::params::packagename}", ensure => present, } service { "foo": name => "${foo::params::servicename}", ensure => running, enable => true, hasstatus => "${foo::params::hasstatus}", pattern => "${foo::params::processname}", require => Package["foo"], subscribe => File["foo.conf"], } file { "foo.conf": path => "${foo::params::configfile}", mode => "${foo::params::configfile_mode}", owner => "${foo::params::configfile_owner}", group => "${foo::params::configfile_group}", ensure => present, require => Package["foo"], Facing Diversity
  • 17. OS dedicated classes class foo { [ ... ] # Include OS specific subclasses, if necessary # Note that they needn’t to inherit foo case $operatingsystem { debian: { include foo::debian } ubuntu: { include foo::debian } default: { } } } Facing Diversity
  • 19. # foo class needs users’ variables # IE: $foo_server class foo { [ ... ] file { foo.conf: ensure => present, path => $operatingsystem ? { debian => “/etc/foo/foo.conf”, default => “/etc/foo.conf”, }, mode => 644, content => template(“foo/foo.conf.erb”), } } # foo/templates/foo.conf.erb is something like: # File Managed by Puppet server = <%= foo_server %> # Plug & Play ? Dealing with Users
  • 20. Filtering user variables Setting default values Dealing with Users
  • 21. Setting default values class foo::params { # Full hostname of foo server $server = $foo_server ? { '' => "foo.example42.com", default => "${foo_server}", } # Foo DB management $db_host = $foo_db_host ? { '' => "localhost", default => "${foo_db_host}", } $db_user = $foo_db_user ? { '' => "root", default => "${foo_db_user}", } $db_password = $foo_db_password ? { '' => "", default => "${foo_db_host}", } Dealing with Users
  • 22. Setting default values class foo { include foo::params [ ... ] # ${foo_server} is user variable unfiltered # ${foo::params::server} is user variable filtered # You may want/need to reassign ${foo_server} value: ${foo_server} = ${foo::params::server} } In templates this fails: server = <%= foo::params::server %> This works (of course): server = <%= foo_server %> This works (even if variable is not set): server = <%= scope.lookupvar('foo::params::server') %> Dealing with Users
  • 24. debian => “food”, ubuntu => “food”, default => “foo”, }, enable => true, hasstatus => $operatingsystem ? { debian => false, ubuntu => false, default => true, }, require => Package[foo], subscribe => File[foo.conf], } file { foo.conf: ensure => present, path => “/etc/foo.conf”, mode => 644, owner => root, group => root, source => [ “puppet:///foo/foo.conf-$hostname”, “puppet:///foo/foo.conf-$my_role”, “puppet:///foo/foo.conf” ], } } Adapt and customize
  • 25. } file { foo.conf: ensure => present, path => “/etc/foo.conf”, mode => 644, owner => root, group => root, source => [ “puppet:///foo/foo.conf-$hostname”, “puppet:///foo/foo.conf-$my_role”, “puppet:///foo/foo.conf” ], } case $my_role { mail: { file { foo.conf-mail: ensure => present, path => “/etc/foo.conf.d/mail”, mode => 644, owner => root, group => root, source => [ “puppet:///foo/foo.conf-mail”, } } default: { } } Adapt and customize
  • 26. Isolation of diversity Project classes || Project module Adapt and Customize
  • 27. Isolation of diversity # Class foo::example42 # # You can use your custom project class to modify # the standard behavior of foo module # # You don't need to use class inheritance if you # don't override or redefine resources in foo class # # You can add custom resources and are free to # decide how to provide the contents of your files: # - Via static sourced files ( source => ) according # to the naming convention you need # - Via custom templates ( content => ) # - Via some kind of infile line modification tools # such as Augeas # class foo::example42 inherits foo { File["foo.conf"] { source => [ "puppet:///foo/foo.conf-$hostname", "puppet:///foo/foo.conf-$role", "puppet:///foo/foo.conf" ], } } Adapt and Customize
  • 28. Project Classes || Project Modules class foo { [ ... ] # Include project specific class if $my_project is set # The extra project class is by default looked in foo module # If $my_project_onmodule == yes it's looked in your project # module if $my_project { case $my_project_onmodule { yes,true: { include "${my_project}::foo" } default: { include "foo::${my_project}" } } } } Adapt and Customize
  • 30. service { foo: ensure => running, name => $operatingsystem ? { debian => “food”, ubuntu => “food”, default => “foo”, }, enable => true, hasstatus => $operatingsystem ? { debian => false, ubuntu => false, default => true, }, pattern => “food”, require => Package[foo], subscribe => File[foo.conf], } ! # Monitoring stuff: munin and nagios ! munin::plugin { "foo_processes": ! ! ! ensure => present, ! } ! nagios::service { "foo_${foo_port_real}": ! ! check_command => "tcp_port!${foo_port_real}" ! } Control and Monitor
  • 32. Monitoring abstraction class foo { [ ... ] # Include monitor classe if $monitor == yes # Define the monitoring tools to use # with the variables $monitor_tools (can be an array) if $monitor == "yes" { include foo::monitor } } Control and Monitor
  • 33. Monitoring abstraction class foo::monitor { include foo::params monitor::port { "foo_${foo::params::protocol}_ ${foo::params::port}": protocol => "${foo::params::protocol}", target => "${foo::params::monitor_target_real}", port => "${foo::params::port}", enable => "${foo::params::monitor_port_enable}", tool => "${monitor_tool}", } monitor::process { "foo_process": process => "${foo::params::processname}", service => "${foo::params::servicename}", pidfile => "${foo::params::pidfile}", enable => "${foo::params::monitor_process_enable}", tool => "${monitor_tool}", } [ ... ] if $my_project { case $my_project_onmodule { yes,true: { include "${my_project}::foo::monitor" } default: { include "foo::monitor::${my_project}" } Control and Monitor
  • 34. Monitor Meta-module define monitor::process ( $process, $service, $pidfile, $tool, $enable ) { if ($enable != "false") and ($enable != "no") { if ($tool =~ /munin/) { # TODO } if ($tool =~ /collectd/) { # TODO } if ($tool =~ /monit/) { monitor::process::monit { "$name": pidfile => "$pidfile", process => "$process", service => "$service", } } if ($tool =~ /nagios/) { monitor::process::nagios { "$name": process => $process, } } } # End if $enable } Control and Monitor
  • 35. Monitor Meta-module define monitor::process::monit ( $pidfile='', $process='', $service='' ) { # Use for Example42 monit module monit::checkpid { "${process}": pidfile => "${pidfile}", startprogram => "/etc/init.d/${service} start", stopprogram => "/etc/init.d/${service} stop", } # Use for Camptocamp’s monit module (sample) # monit::config { "${process}": # ensure => present, # content => template(“monit/checkprocess.erb”), # To create # } # Use for Monit recipe on Puppet’s wiki (sample) # monit::package { "${process}": } } Control and Monitor
  • 36. Coherent naming conventions Predictable behaviors A name for Everything
  • 37. Naming conventions include foo - Installs and runs foo service # If foo can be client or server include foo::server - Installs foo server include foo::client - Installs foo client # If foo is on every/many host either client or server: if ($foo_server_local == true) or ($foo_server == "$fqdn") { include puppet::server } else { include puppet::client } # If foo has to be disable or removed: include foo::absent - Remove foo include foo::disable - Disable foo service include foo::disableboot - Disable foo service but do not check if is running A name for Everything
  • 38. Quick cloning & customization Coherent Modules Infrastructure Modules Machine
  • 39. Quick cloning # Few seds for a script that clones foo module example42_module_clone.sh # Creates new module from foo template. Then you: # - Edit params.pp # - Add specific classes, defines, types, facts # - Eventually define modules variables and templates # # - Everything else is ready out of the box Modules Machine
  • 40. Quick customization # Script that adapts a module for a new project example42_project_rename.sh # Prepares custom classes for new project # foo/manifests/my_project.pp # foo/manifests/monitor/my_project.pp # foo/manifests/backup/my_project.pp # # - Use the logic that works for your project # - Choose how to provide your configuration files Modules Machine
  • 41. Coherent Infrastructure # Clone is GOOD # Modules are similar # They share a coherent naming convention # They have confined places where to apply # custom logic # Fixed files for fixes functions # Common approach for the Puppet team members # Reduced risks and better manageability # Quick update to template improvements # Could be more easily manageable/autogenerated # by GUI tools Modules Machine
  • 42.
  • 43. Centralized settings: foo::params Qualified variables Isolation of diversity Project classes || Project module Monitoring abstraction Monitor meta-module Filtering user variables Setting default values Coherent naming conventions Predictable behaviors Quick cloning of foo module Quick customization CrossVendor Reusable Plug & Play Modules Machine A name for Everything Dealing with Users Control and Monitor Adapt and Customize Facing Diversity small dreams turn easier into reality
  • 45. Questions? (Please Loud & Clear, I’ve lost my Babelfish)