SlideShare uma empresa Scribd logo
1 de 45
Baixar para ler 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
class foo {
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
class foo {
package { foo:
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”,
default => “/etc/foo.conf”,
},
mode => 644,
Facing Diversity
package { foo:
ensure => installed
name => $operatingsystem ? {
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,
path => $operatingsystem ? {
debian => “/etc/foo/foo.conf”,
default => “/etc/foo.conf”,
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/
ReUse Your (Puppet) Modules!

Mais conteúdo relacionado

Mais procurados

DPC 2012 : PHP in the Dark Workshop
DPC 2012 : PHP in the Dark WorkshopDPC 2012 : PHP in the Dark Workshop
DPC 2012 : PHP in the Dark Workshop
Jeroen Keppens
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Development
jsmith92
 

Mais procurados (20)

Doing It Wrong with Puppet -
Doing It Wrong with Puppet - Doing It Wrong with Puppet -
Doing It Wrong with Puppet -
 
Dependency Injection with PHP 5.3
Dependency Injection with PHP 5.3Dependency Injection with PHP 5.3
Dependency Injection with PHP 5.3
 
The Puppet Debugging Kit: Building Blocks for Exploration and Problem Solving...
The Puppet Debugging Kit: Building Blocks for Exploration and Problem Solving...The Puppet Debugging Kit: Building Blocks for Exploration and Problem Solving...
The Puppet Debugging Kit: Building Blocks for Exploration and Problem Solving...
 
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
 
Spl in the wild
Spl in the wildSpl in the wild
Spl in the wild
 
DPC 2012 : PHP in the Dark Workshop
DPC 2012 : PHP in the Dark WorkshopDPC 2012 : PHP in the Dark Workshop
DPC 2012 : PHP in the Dark Workshop
 
Replacing "exec" with a type and provider: Return manifests to a declarative ...
Replacing "exec" with a type and provider: Return manifests to a declarative ...Replacing "exec" with a type and provider: Return manifests to a declarative ...
Replacing "exec" with a type and provider: Return manifests to a declarative ...
 
SPL to the Rescue - Tek 09
SPL to the Rescue - Tek 09SPL to the Rescue - Tek 09
SPL to the Rescue - Tek 09
 
Memory Manglement in Raku
Memory Manglement in RakuMemory Manglement in Raku
Memory Manglement in Raku
 
BSDM with BASH: Command Interpolation
BSDM with BASH: Command InterpolationBSDM with BASH: Command Interpolation
BSDM with BASH: Command Interpolation
 
BASH Variables Part 1: Basic Interpolation
BASH Variables Part 1: Basic InterpolationBASH Variables Part 1: Basic Interpolation
BASH Variables Part 1: Basic Interpolation
 
Perforce Object and Record Model
Perforce Object and Record Model  Perforce Object and Record Model
Perforce Object and Record Model
 
Php on the desktop and php gtk2
Php on the desktop and php gtk2Php on the desktop and php gtk2
Php on the desktop and php gtk2
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Development
 
Php on the Web and Desktop
Php on the Web and DesktopPhp on the Web and Desktop
Php on the Web and Desktop
 
Tutorial Puppet
Tutorial PuppetTutorial Puppet
Tutorial Puppet
 
Findbin libs
Findbin libsFindbin libs
Findbin libs
 
PECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life betterPECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life better
 
Working with databases in Perl
Working with databases in PerlWorking with databases in Perl
Working with databases in Perl
 

Semelhante a ReUse Your (Puppet) Modules!

Alessandro sf 2010
Alessandro sf 2010Alessandro sf 2010
Alessandro sf 2010
Puppet
 
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
Carlos Sanchez
 
20090514 Introducing Puppet To Sasag
20090514 Introducing Puppet To Sasag20090514 Introducing Puppet To Sasag
20090514 Introducing Puppet To Sasag
garrett honeycutt
 
Kansai.pm 10周年記念 Plack/PSGI 入門
Kansai.pm 10周年記念 Plack/PSGI 入門Kansai.pm 10周年記念 Plack/PSGI 入門
Kansai.pm 10周年記念 Plack/PSGI 入門
lestrrat
 
Puppet Camp Amsterdam 2015: Manifests of Future Past
Puppet Camp Amsterdam 2015: Manifests of Future PastPuppet Camp Amsterdam 2015: Manifests of Future Past
Puppet Camp Amsterdam 2015: Manifests of Future Past
Puppet
 

Semelhante a ReUse Your (Puppet) Modules! (20)

Alessandro sf 2010
Alessandro sf 2010Alessandro sf 2010
Alessandro sf 2010
 
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 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
PuppetPuppet
Puppet
 
Creating beautiful puppet modules with puppet-lint
Creating beautiful puppet modules with puppet-lintCreating beautiful puppet modules with puppet-lint
Creating beautiful puppet modules with puppet-lint
 
Puppet fundamentals
Puppet fundamentalsPuppet fundamentals
Puppet fundamentals
 
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
 
Puppet Modules for Fun and Profit
Puppet Modules for Fun and ProfitPuppet Modules for Fun and Profit
Puppet Modules for Fun and Profit
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony Techniques
 
20090514 Introducing Puppet To Sasag
20090514 Introducing Puppet To Sasag20090514 Introducing Puppet To Sasag
20090514 Introducing Puppet To Sasag
 
Feeds drupal cafe
Feeds drupal cafeFeeds drupal cafe
Feeds drupal cafe
 
Kansai.pm 10周年記念 Plack/PSGI 入門
Kansai.pm 10周年記念 Plack/PSGI 入門Kansai.pm 10周年記念 Plack/PSGI 入門
Kansai.pm 10周年記念 Plack/PSGI 入門
 
Filesystem abstractions and msg queue sergeev - symfony camp 2018
Filesystem abstractions and msg queue   sergeev - symfony camp 2018Filesystem abstractions and msg queue   sergeev - symfony camp 2018
Filesystem abstractions and msg queue sergeev - symfony camp 2018
 
How to simplify OSGi development using OBR - Peter Kriens
How to simplify OSGi development using OBR - Peter KriensHow to simplify OSGi development using OBR - Peter Kriens
How to simplify OSGi development using OBR - Peter Kriens
 
Puppet Camp Amsterdam 2015: Manifests of Future Past
Puppet Camp Amsterdam 2015: Manifests of Future PastPuppet Camp Amsterdam 2015: Manifests of Future Past
Puppet Camp Amsterdam 2015: Manifests of Future Past
 
Developing IT infrastructures with Puppet
Developing IT infrastructures with PuppetDeveloping IT infrastructures with Puppet
Developing IT infrastructures with Puppet
 
Puppet: Eclipsecon ALM 2013
Puppet: Eclipsecon ALM 2013Puppet: Eclipsecon ALM 2013
Puppet: Eclipsecon ALM 2013
 

Mais de Alessandro Franceschi

Mais de Alessandro Franceschi (16)

Strategies for Puppet code upgrade and refactoring
Strategies for Puppet code upgrade and refactoringStrategies for Puppet code upgrade and refactoring
Strategies for Puppet code upgrade and refactoring
 
DevOps - Evoluzione della specie - DevOps Heroes.pdf
DevOps - Evoluzione della specie - DevOps Heroes.pdfDevOps - Evoluzione della specie - DevOps Heroes.pdf
DevOps - Evoluzione della specie - DevOps Heroes.pdf
 
Tiny Puppet Can Install Everything. Prove me wrong!
Tiny Puppet Can Install Everything. Prove me wrong!Tiny Puppet Can Install Everything. Prove me wrong!
Tiny Puppet Can Install Everything. Prove me wrong!
 
Ten years of [Puppet] installations. What now?
Ten years of [Puppet] installations. What now?Ten years of [Puppet] installations. What now?
Ten years of [Puppet] installations. What now?
 
Puppet Systems Infrastructure Construction Kit
Puppet Systems Infrastructure Construction KitPuppet Systems Infrastructure Construction Kit
Puppet Systems Infrastructure Construction Kit
 
Puppet Continuous Integration with PE and GitLab
Puppet Continuous Integration with PE and GitLabPuppet Continuous Integration with PE and GitLab
Puppet Continuous Integration with PE and GitLab
 
Puppet control-repo 
to the next level
Puppet control-repo 
to the next levelPuppet control-repo 
to the next level
Puppet control-repo 
to the next level
 
Tp install anything
Tp install anythingTp install anything
Tp install anything
 
Puppet: From 0 to 100 in 30 minutes
Puppet: From 0 to 100 in 30 minutesPuppet: From 0 to 100 in 30 minutes
Puppet: From 0 to 100 in 30 minutes
 
Puppet evolutions
Puppet evolutionsPuppet evolutions
Puppet evolutions
 
Essential applications management with Tiny Puppet
Essential applications management with Tiny PuppetEssential applications management with Tiny Puppet
Essential applications management with Tiny Puppet
 
Raise the bar! Reloaded
Raise the bar! ReloadedRaise the bar! Reloaded
Raise the bar! Reloaded
 
Raise the bar!
Raise the bar!Raise the bar!
Raise the bar!
 
Puppet modules: A Holistic Approach - Geneva
Puppet modules: A Holistic Approach - GenevaPuppet modules: A Holistic Approach - Geneva
Puppet modules: A Holistic Approach - Geneva
 
Puppet modules: An Holistic Approach
Puppet modules: An Holistic ApproachPuppet modules: An Holistic Approach
Puppet modules: An Holistic Approach
 
Spaghetti devops
Spaghetti devopsSpaghetti devops
Spaghetti devops
 

Último

Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Victor Rentea
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Último (20)

Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 

ReUse Your (Puppet) Modules!

  • 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. class foo { 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. class foo { package { foo: 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”, default => “/etc/foo.conf”, }, mode => 644, Facing Diversity
  • 13. package { foo: ensure => installed name => $operatingsystem ? { 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, path => $operatingsystem ? { debian => “/etc/foo/foo.conf”, default => “/etc/foo.conf”, 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