SlideShare a Scribd company logo
1 of 46
Download to read offline
Modules: Reuse, Reduce, Recycle
Puppet Camp Denver 2015
by daniel kendrick
1 / 46
mod·ule
(mŏj′o͞ol) n.
1. A standardized, often interchangeable component of a system or
construction that is designed for easy assembly or flexible use
2 / 46
Flexibility
Give that man a straw!
3 / 46
Trifecta Package: Managing a package by enforcing it's state
File: Managing a configuration file or it's content
Service: Managing a service or daemon
Where We Typically Start
4 / 46
Example NTP
#/root/examples/modules1-ntp1.pp
classntp{
case$operatingsystem{
centos,redhat:{
$service_name='ntpd'
$conf_file ='ntp.conf.el'
}
debian,ubuntu:{
$service_name='ntp'
$conf_file ='ntp.conf.debian'
}
}
package{'ntp':
ensure=>installed,
}
file{'ntp.conf':
path =>'/etc/ntp.conf',
ensure =>file,
require=>Package['ntp'],
source =>"/root/examples/answers/${conf_file}"
}
service{'ntp':
name =>$service_name,
ensure =>running,
enable =>true,
subscribe=>File['ntp.conf'],
}
}
The Trifecta at Work
it's doing exactly what it's told, and only what it's told
5 / 46
Trifecta: Not a very good implementation
#ntpmodule
classntp::present{
package{'ntp':
ensure=>present,
}
}
classntp::config{
file{"/etc/ntp.conf":
owner=>"root",
group=>"root",
mode=>0644,
# source=>"puppet://$puppetserver/modules/ntp/etc/ntp.conf",
content=>template("ntp/etc/ntp.conf.erb"),
require=>Class["ntp::present"],
notify=>Class["ntp::service"],
}
}
classntp::service{
service{"ntp":
ensure=>running,
hasstatus=>true,
hasrestart=>true,
enable=>true,
require=>Class["ntp::config"],
}
}
classntp::absent{
package{'ntp':
ensure=>absent,
}
}
classntp{
if$is_virtual=='false' {
notify{"puppet:ntp:$hostnameisphysical":}
includentp::present,ntp::config,ntp::service
}
else{
notify{"puppet:ntp:$hostnameisvirtual":}
includentp::absent
}
}
My GOD Mojo, what have they done to you?!
6 / 46
Trifecta: Not a very good implementation
#ntpmodule
classntp::present{
package{'ntp':
ensure=>present,
}
}
classntp::config{
file{"/etc/ntp.conf":
owner=>"root",
group=>"root",
mode=>0644,
# source=>"puppet://$puppetserver/modules/ntp/etc/ntp.conf",
content=>template("ntp/etc/ntp.conf.erb"),
require=>Class["ntp::present"],
notify=>Class["ntp::service"],
}
}
classntp::service{
service{"ntp":
ensure=>running,
hasstatus=>true,
hasrestart=>true,
enable=>true,
require=>Class["ntp::config"],
}
}
classntp::absent{
package{'ntp':
ensure=>absent,
}
}
classntp{
if$is_virtual=='false' {
notify{"puppet:ntp:$hostnameisphysical":}
includentp::present,ntp::config,ntp::service
}
else{
notify{"puppet:ntp:$hostnameisvirtual":}
includentp::absent
}
}
My GOD Mojo, what have they done to you?!
7 / 46
Example NTP
#/root/examples/modules1-ntp1.pp
classntp{
case$operatingsystem{
centos,redhat:{
$service_name='ntpd'
$conf_file ='ntp.conf.el'
}
debian,ubuntu:{
$service_name='ntp'
$conf_file ='ntp.conf.debian'
}
}
package{'ntp':
ensure=>installed,
}
file{'ntp.conf':
path =>'/etc/ntp.conf',
ensure =>file,
require=>Package['ntp'],
source =>"/root/examples/answers/${conf_file}"
}
service{'ntp':
name =>$service_name,
ensure =>running,
enable =>true,
subscribe=>File['ntp.conf'],
}
}
Managing State
8 / 46
Parameters
classntp(
$conf_file =$ntp::params::conf_file,
$service_name=$ntp::params::service_name,
)inheritsntp::params{
package{'ntp':
ensure=>installed,
}
file{'ntp.conf':
path =>'/etc/ntp.conf',
ensure =>file,
require=>Package['ntp'],
source =>$ntp::conf_file,
}
service{'ntp':
name =>$ntp::service_name,
ensure =>running,
enable =>true,
subscribe=>File['ntp.conf'],
}
}
classntp::params{
$conf_file=$::operatingsystem?{
/(?i:RedHat|CentOS)/ =>'puppet:///modules/ntp/etc/ntp.conf.el',
/(?i:Debian|Ubuntu)/ =>'puppet:///modules/ntp/etc/ntp.conf.debian',
default =>'puppet:///modules/ntp/etc/ntp.conf',
}
$service_name=$::operatingsystem?{
/(?i:RedHat|CentOS)/ =>'ntp',
/(?i:Debian|Ubuntu)/ =>'ntpd',
default =>'ntp',
}
}
A bit of Flexibility
9 / 46
Parameters
classntp(
$conf_file =$ntp::params::conf_file,
$service_name=$ntp::params::service_name,
)inheritsntp::params{
package{'ntp':
ensure=>installed,
}
file{'ntp.conf':
path =>'/etc/ntp.conf',
ensure =>file,
require=>Package['ntp'],
source =>$ntp::conf_file,
}
service{'ntp':
name =>$ntp::service_name,
ensure =>running,
enable =>true,
subscribe=>File['ntp.conf'],
}
}
classntp::params{
$conf_file=$::operatingsystem?{
/(?i:RedHat|CentOS)/ =>'puppet:///modules/ntp/etc/ntp.conf.el',
/(?i:Debian|Ubuntu)/ =>'puppet:///modules/ntp/etc/ntp.conf.debian',
default =>'puppet:///modules/ntp/etc/ntp.conf',
}
$service_name=$::operatingsystem?{
/(?i:RedHat|CentOS)/ =>'ntp',
/(?i:Debian|Ubuntu)/ =>'ntpd',
default =>'ntp',
}
}
A bit of Flexibility
Called as a Parameterized Class
class{'ntp':
conf_file=>'puppet:///modules/my-site/etc/ntp.conf'
}
10 / 46
Foobar Module
classfoobar{
package{'foobar.package':
ensure=>present,
name =>'foobar',
}
file{'foobar.conf':
ensure =>file,
path =>'/etc/foobar/foobar.conf',
require=>Package['foobar.package'],
source =>'puppet:///modules/foobar/foobar.conf',
notify =>Service['foobar.service'],
}
service{'foobar.service':
ensure =>running,
name =>'foobard',
enable =>true,
}
}
11 / 46
Foobar Module
Identifying Candidates
classfoobar{
package{'foobar.package':
ensure=>present,
name =>'foobar',
}
file{'foobar.conf':
ensure =>file,
path =>'/etc/foobar/foobar.conf',
require=>Package['foobar.package'],
source =>'puppet:///modules/foobar/foobar.conf',
notify =>Service['foobar.service'],
}
service{'foobar.service':
ensure =>running,
name =>'foobard',
enable =>true,
}
}
12 / 46
Foobar Module
How it could look
classfoobar(
$package_name =$foobar::params::package_name,
$package_ensure =$foobar::params::package_ensure,
$service_name =$foobar::params::service_name,
$service_ensure =$foobar::params::service_ensure,
$service_enable =$foobar::params::service_enable,
$config_file_path =$foobar::params::config_file_path,
$config_file_source =$foobar::params::config_file_source,
)inheritsfoobar::params{
'validationandlogichere..'
package{'foobar.package':
ensure=>$foobar::package_ensure,
name =>$foobar::package_name,
}
file{'foobar.conf':
ensure =>$foobar::config_file_ensure,
path =>$foobar::config_file_path,
require=>Package['foobar.package'],
source =>$foobar::config_file_source,
notify =>Service['foobar.service'],
}
service{'foobar.service':
ensure =>$foobar::service_ensure,
name =>$foobar::service_name,
enable =>$foobar::service_enable,
}
}
13 / 46
Too Much?
classfoobar(
$package_name =$foobar::params::package_name,
$package_ensure =$foobar::params::package_ensure,
$service_name =$foobar::params::service_name,
$service_ensure =$foobar::params::service_ensure,
$service_enable =$foobar::params::service_enable,
$config_file_path =$foobar::params::config_file_path,
$config_file_owner =$foobar::params::config_file_owner,
$config_file_group =$foobar::params::config_file_group,
$config_file_mode =$foobar::params::config_file_mode,
$config_file_source =$foobar::params::config_file_source,
$config_file_template =$foobar::params::config_file_template,
$unicorn_config_file_path=$unicorn::unicorn_config_file_path,
$config_ru_template =$unicorn::config_ru_template,
$unicorn_working_dir =$unicorn::unicorn_working_dir,
$unicorn_init_file_path =$unicorn::unicorn_init_file_path,
$use_nginx =true,
$use_apache =false,
$nginx_config_file_path =$nginx::config_file_path,
$apache_config_file_path =$apache::config_file_path,
)inheritsfoobar::params{
SuperCoolPuppetCodeHere...
}
flexibility means more options for the user, but where is the line drawn?
14 / 46
Too Much?
Just Enough
classfoobar(
$package_name =$foobar::params::package_name,
$package_ensure =$foobar::params::package_ensure,
$package_version =$foobar::params::package_version,
$service_name =$foobar::params::service_name,
$service_ensure =$foobar::params::service_ensure,
$service_enable =$foobar::params::service_enable,
$config_file_path =$foobar::params::config_file_path,
$config_file_owner =$foobar::params::config_file_owner,
$config_file_group =$foobar::params::config_file_group,
$config_file_mode =$foobar::params::config_file_mode,
$config_file_source =$foobar::params::config_file_source,
$config_file_template =$foobar::params::config_file_template,
$config_dir_path =$foobar::params::config_dir_path,
$config_dir_source =$foobar::params::config_dir_source,
$config_dir_purge =$foobar::params::config_dir_purge,
$config_dir_recurse =$foobar::params::config_dir_recurse,
)inheritsfoobar::params{
}
a perfectly sane food to eat
15 / 46
Too Much?
Just Enough
classfoobar(
$package_name =$foobar::params::package_name,
$package_ensure =$foobar::params::package_ensure,
$package_version =$foobar::params::package_version,
$service_name =$foobar::params::service_name,
$service_ensure =$foobar::params::service_ensure,
$service_enable =$foobar::params::service_enable,
$config_file_path =$foobar::params::config_file_path,
$config_file_owner =$foobar::params::config_file_owner,
$config_file_group =$foobar::params::config_file_group,
$config_file_mode =$foobar::params::config_file_mode,
$config_file_source =$foobar::params::config_file_source,
$config_file_template =$foobar::params::config_file_template,
$config_dir_path =$foobar::params::config_dir_path,
$config_dir_source =$foobar::params::config_dir_source,
$config_dir_purge =$foobar::params::config_dir_purge,
$config_dir_recurse =$foobar::params::config_dir_recurse,
)inheritsfoobar::params{
#$config_dir_pathcanberecursivelyoverwrittenby$config_dir_source
if$foobar::config_dir_source{
file{'foobar.dir':
ensure =>directory,
path =>$foobar::config_dir_path,
source =>$foobar::config_dir_source,
recurse=>$foobar::config_dir_recurse,
purge =>$foobar::config_dir_purge,
force =>$foobar::config_dir_purge,
notify =>Service['foobar.service'],
require=>Package['foobar.package'],
}
}
}
a perfectly sane food to eat
16 / 46
Too Much?
Just Enough
classfoobar(
$package_name =$foobar::params::package_name,
$package_ensure =$foobar::params::package_ensure,
$package_version =$foobar::params::package_version,
$service_name =$foobar::params::service_name,
$service_ensure =$foobar::params::service_ensure,
$service_enable =$foobar::params::service_enable,
$config_file_path =$foobar::params::config_file_path,
$config_file_owner =$foobar::params::config_file_owner,
$config_file_group =$foobar::params::config_file_group,
$config_file_mode =$foobar::params::config_file_mode,
$config_file_source =$foobar::params::config_file_source,
$config_file_template =$foobar::params::config_file_template,
$config_dir_path =$foobar::params::config_dir_path,
$config_dir_source =$foobar::params::config_dir_source,
$config_dir_purge =$foobar::params::config_dir_purge,
$config_dir_recurse =$foobar::params::config_dir_recurse,
)inheritsfoobar::params{
#$config_dir_pathcanberecursivelyoverwrittenby$config_dir_source
if$foobar::config_dir_source{
file{'foobar.dir':
ensure =>directory,
path =>$foobar::config_dir_path,
source =>$foobar::config_dir_source,
recurse=>$foobar::config_dir_recurse,
purge =>$foobar::config_dir_purge,
force =>$foobar::config_dir_purge,
notify =>Service['foobar.service'],
require=>Package['foobar.package'],
}
}
}
a perfectly sane food to eat
Called as a Parameterized Class
class{'foobar':
config_dir_source=>'puppet:///modules/my-site/foobar/',
}
17 / 46
Too Much?
Just Enough
classfoobar(
$package_name =$foobar::params::package_name,
$package_ensure =$foobar::params::package_ensure,
$package_version =$foobar::params::package_version,
$service_name =$foobar::params::service_name,
$service_ensure =$foobar::params::service_ensure,
$service_enable =$foobar::params::service_enable,
$config_file_path =$foobar::params::config_file_path,
$config_file_owner =$foobar::params::config_file_owner,
$config_file_group =$foobar::params::config_file_group,
$config_file_mode =$foobar::params::config_file_mode,
$config_file_source =$foobar::params::config_file_source,
$config_file_template =$foobar::params::config_file_template,
$config_dir_path =$foobar::params::config_dir_path,
$config_dir_source =$foobar::params::config_dir_source,
$config_dir_purge =$foobar::params::config_dir_purge,
$config_dir_recurse =$foobar::params::config_dir_recurse,
)inheritsfoobar::params{
#$config_dir_pathcanberecursivelyoverwrittenby$config_dir_source
if$foobar::config_dir_source{
file{'foobar.dir':
ensure =>directory,
path =>$foobar::config_dir_path,
source =>$foobar::config_dir_source,
recurse=>$foobar::config_dir_recurse,
purge =>$foobar::config_dir_purge,
force =>$foobar::config_dir_purge,
notify =>Service['foobar.service'],
require=>Package['foobar.package'],
}
}
}
a perfectly sane food to eat
Called as a Parameterized Class
class{'foobar':
config_dir_source=>'puppet:///modules/my-site/foobar/',
}
Called as a Parameterized Class
class{'foobar':
config_dir_source=>'puppet:///modules/my-site/foobar/',
config_dir_purge =>true,
}
18 / 46
Too Much?
Just Enough
classfoobar(
$package_name =$foobar::params::package_name,
$package_ensure =$foobar::params::package_ensure,
$package_version =$foobar::params::package_version,
$service_name =$foobar::params::service_name,
$service_ensure =$foobar::params::service_ensure,
$service_enable =$foobar::params::service_enable,
$config_file_path =$foobar::params::config_file_path,
$config_file_owner =$foobar::params::config_file_owner,
$config_file_group =$foobar::params::config_file_group,
$config_file_mode =$foobar::params::config_file_mode,
$config_file_source =$foobar::params::config_file_source,
$config_file_template =$foobar::params::config_file_template,
$config_dir_path =$foobar::params::config_dir_path,
$config_dir_source =$foobar::params::config_dir_source,
$config_dir_purge =$foobar::params::config_dir_purge,
$config_dir_recurse =$foobar::params::config_dir_recurse,
)inheritsfoobar::params{
#$config_dir_pathcanberecursivelyoverwrittenby$config_dir_source
if$foobar::config_dir_source{
file{'foobar.dir':
ensure =>directory,
path =>$foobar::config_dir_path,
source =>$foobar::config_dir_source,
recurse=>$foobar::config_dir_recurse,
purge =>$foobar::config_dir_purge,
force =>$foobar::config_dir_purge,
notify =>Service['foobar.service'],
require=>Package['foobar.package'],
}
}
}
a perfectly sane food to eat
Called as a Parameterized Class
class{'foobar':
config_dir_source=>'puppet:///modules/my-site/foobar/',
}
Called as a Parameterized Class
class{'foobar':
config_dir_source=>'puppet:///modules/my-site/foobar/',
config_dir_purge =>true,
}
Called as a Parameterized Class
class{'foobar':
config_dir_source =>'puppet:///modules/my-site/foobar/',
config_dir_purge =>true,
config_dir_recurse=>true,
}
19 / 46
Flexibility Zealot with Metaparameters
notify, require, subscribe, noop
What?! Another Parameter?!....sigh... Alright
https://docs.puppetlabs.com/references/latest/metaparameter.html
20 / 46
noop
notify
require
classfoobar(
$noop =$foobar::params::noop,
$package_name =$foobar::params::package_name,
$package_ensure =$foobar::params::package_ensure,
$package_version =$foobar::params::package_version,
$service_name =$foobar::params::service_name,
$service_ensure =$foobar::params::service_ensure,
$service_enable =$foobar::params::service_enable,
$config_file_path =$foobar::params::config_file_path,
$config_file_owner =$foobar::params::config_file_owner,
$config_file_group =$foobar::params::config_file_group,
$config_file_mode =$foobar::params::config_file_mode,
$config_file_source =$foobar::params::config_file_source,
$config_file_template =$foobar::params::config_file_template,
$config_file_require =$foobar::params::config_file_require,
$config_file_notify =$foobar::params::config_file_notify,
$config_dir_path =$foobar::params::config_dir_path,
$config_dir_source =$foobar::params::config_dir_source,
$config_dir_purge =$foobar::params::config_dir_purge,
$config_dir_recurse =$foobar::params::config_dir_recurse,
)inheritsfoobar::params{
package{'foobar.package':
ensure=>$foobar::package_ensure,
name =>$foobar::package_name,
noop =>$foobar::noop,
}
file{'foobar.conf':
ensure =>$foobar::config_file_ensure,
path =>$foobar::config_file_path,
require=>$foobar::config_file_require,
source =>$foobar::config_file_source,
notify =>$foobar::config_file_notify,
noop =>$foobar::noop,
}
service{'foobar.service':
ensure=>$foobar::service_ensure,
name =>$foobar::service_name,
enable=>$foobar::service_enable,
noop =>$foobar::noop,
}
}
Notice: /Stage[main]/Foobar/File[foobar.conf]/ensure: current_value absent, should
be present (noop)
21 / 46
Validation of Parameters
validate the parameters, but remain flexible
22 / 46
Functions validate_absolute_path.rb
validate_array.rb
validate_augeas.rb
validate_bool.rb
validate_cmd.rb
validate_hash.rb
validate_ipv4_address.rb
validate_ipv6_address.rb
validate_re.rb
validate_slength.rb
validate_string.rb
Example Usage
#Classvariablesvalidationandmanagement
validate_absolute_path($config_dir_path)
validate_bool($service_enable)
validate_string($config_file_mode)
PuppetLabs StdLib
https://forge.puppetlabs.com/puppetlabs/stdlib
23 / 46
Functions
Be Flexible
human boolean
class{'foobar':
service_enable='t',
}
Error: Could not retrieve catalog from remote server: Error 400 on SERVER: "t" is not
a boolean. It looks to be a String
str2bool.rb
#Strict
validate_bool($service_enable)
#Relaxed
$bool_service_enable=str2bool($service_enable)
str2bool converts human booleans
when/^(1|t|y|true|yes)$/ thentrue
when/^(0|f|n|false|no)$/ thenfalse
PuppetLabs StdLib
https://forge.puppetlabs.com/puppetlabs/stdlib
24 / 46
Functions
Be Flexible
human boolean
class{'foobar':
service_enable='t',
}
Error: Could not retrieve catalog from remote server: Error 400 on SERVER: "t" is not
a boolean. It looks to be a String
str2bool.rb
#Strict
validate_bool($service_enable)
#Relaxed
$bool_service_enable=str2bool($service_enable)
str2bool converts human booleans
when/^(1|t|y|true|yes)$/ thentrue
when/^(0|f|n|false|no)$/ thenfalse
PuppetLabs StdLib
https://forge.puppetlabs.com/puppetlabs/stdlib
###ValidationofParameters
validate_absolute_path($standardFu::config_file_path)
validate_absolute_path($standardFu::config_dir_path)
validate_string($standardFu::config_file_owner)
validate_string($standardFu::config_file_group)
validate_string($standardFu::config_file_mode)
#SanitizeBooleans
$bool_config_dir_purge=str2bool($standardFu::config_dir_purge)
$bool_service_enable =str2bool($standardFu::service_enable)
25 / 46
Method I
#Classfoobar::params
#
#Thisclassonlyprovidessanedefaultsforthefoobarmodule,and
#shouldnotbecalledasis.Thisclassshouldbecalledfromfoobar.
#
classfoobar::params{
case$::osfamily{
'Debian':{
$package_name ='foobar'
$config_file_path='/etc/foobar/foobar.conf'
$service_name ='foobard'
}
'RedHat':{
$package_name ='foobar'
$config_file_path='/etc/foobar.conf'
$service_name ='foobar'
}
default:{
fail("FAIL:${::operatingsystem}is_NOT_supported.")
}
}
}
Operating System Validation
26 / 46
Method I
Method II
#Classfoobar::params
classfoobar::params{
$supported_os=$::osfamily?{
/(?i:RedHat)/ =>true,
/(?i:Debian)/ =>true,
default =>false
}
}
#Classfoobar
classfoobar(
$package_name =$foobar::params::package_name,
$package_ensure =$foobar::params::package_ensure,
$package_version =$foobar::params::package_version,
$service_name =$foobar::params::service_name,
$service_ensure =$foobar::params::service_ensure,
$service_enable =$foobar::params::service_enable,
$config_file_path =$foobar::params::config_file_path,
$config_file_owner =$foobar::params::config_file_owner,
$config_file_group =$foobar::params::config_file_group,
$config_file_mode =$foobar::params::config_file_mode,
$config_file_notify =$foobar::params::config_file_notify,
$config_file_source =$foobar::params::config_file_source,
$config_file_template =$foobar::params::config_file_template,
$config_dir_path =$foobar::params::config_dir_path,
$config_dir_source =$foobar::params::config_dir_source,
$config_dir_purge =$foobar::params::config_dir_purge,
$config_dir_recurse =$foobar::params::config_dir_recurse,
)inheritsfoobar::params{
if$foobar::params::supported_os==true{
#ParameterValidationandModuleResourcesHere
}else{
#NoticeKeepsGoing.FailStops.Uptoyou
notice("INFO:${::operatingsystem}is_NOT_supported.")
fail("FAIL:${::operatingsystem}is_NOT_supported.")
}
}
Operating System Validation
27 / 46
Public and Private Classes
what's the deal, and who cares
PuppetLabs StdLib 2014-11-10 - Supported Release 4.4.0
28 / 46
private('msg')
#/etc/puppet/modules/foobar/manifests/server.pp
classfoobar::server{
private('INFO:classfoobar::serverisprivate,consultdocumentation.')
}
#/etc/puppet/manifests/site.pp
node'foobar-server.shellfu.lab.com'{
includefoobar::server
}
Error: Could not retrieve catalog from remote server: Error 400 on SERVER: INFO:
class mysql::server is private, please consult module documentation for usage at
/etc/puppet/modules/mysql/manifests/server.pp on node shellfu.lab.com Warning:
Not using cache on failed catalog Error: Could not retrieve catalog; skipping run
Public and Private Classes
what's the deal, and who cares
PuppetLabs StdLib 2014-11-10 - Supported Release 4.4.0
The Entrance is over there.
29 / 46
Standardization
How can something be Interchangeable if it is not Standardized?
30 / 46
Semantic Versioning
Given a version number MAJOR.MINOR.PATCH, increment the:
MAJOR version when you make incompatible API changes,
MINOR version when you add functionality in a backwards-compatible
manner, and
PATCH version when you make backwards-compatible bug fixes.
Additional labels for pre-release and build metadata are available as
extensions to the MAJOR.MINOR.PATCH format.
http://www.semver.org
31 / 46
Puppet Labs Style Guide
https://docs.puppetlabs.com/guides/style_guide.html
32 / 46
Puppet-Lint: Check your style
~$puppet-lint/path/to/module/init.pp
WARNING:doublequotedstringcontainingnovariablesonline203
WARNING:linehasmorethan80charactersonline192
WARNING:indentationof=>isnotproperlyalignedonline248
WARNING:indentationof=>isnotproperlyalignedonline251
http://puppet-lint.com/
33 / 46
Module Documentation
puppet doc /path/to/module/init.pp
#[*config_file_path*]
# Mainconfigurationfilepath
# Canbedefinedalsobythe(classscope)variable$foobar::config_file
#
#[*config_file_mode*]
# Mainconfigurationfilepathmode
# Canbedefinedalsobythe(classscope)variable$foobar::config_file_mode
#
#[*config_file_owner*]
# Mainconfigurationfilepathowner
# Canbedefinedalsobythe(classscope)variable$foobar::config_file_owner
#
#[*config_file_group*]
# Mainconfigurationfilepathgroup
# Canbedefinedalsobythe(classscope)variable$foobar::config_file_group
https://docs.puppetlabs.com/puppet/latest/reference/modules_documentation.html
34 / 46
The Proposed Convention
prefix_resource-type_resource-attribute
Examples:
Config_File_Path
Package_Name
Server_Package_Name
Client_Config_File_Path
StdMod
https://github.com/stdmod
easy to read, is easy to understand
easy to understand, is easy to remember
35 / 46
skeletons stdmod/puppet-module-skeleton
garethr/puppet-module-skeleton
spiette/puppet-module-skeleton
Module Skeletons
~/.puppet/var/puppet-module/skeleton
36 / 46
skeletons
generate
stdmod/puppet-module-skeleton
garethr/puppet-module-skeleton
spiette/puppet-module-skeleton
puppetmodulegenerateexample-module
Notice:Generatingmoduleat/home/shellfu/example-newmodule...
Notice:Populatingtemplates...
Finished;modulegeneratedinexample-newmodule.
example-newmodule/tests
example-newmodule/tests/init.pp
example-newmodule/Rakefile
example-newmodule/spec
example-newmodule/spec/classes
example-newmodule/spec/classes/init_spec.rb
example-newmodule/spec/spec_helper.rb
example-newmodule/Gemfile
example-newmodule/manifests
example-newmodule/manifests/init.pp
example-newmodule/manifests/params.pp
example-newmodule/metadata.json
example-newmodule/README.md
Module Skeletons
~/.puppet/var/puppet-module/skeleton
37 / 46
Basic Foobar: What we changed
38 / 46
Basic Foobar: What we changed
Module Documentation
39 / 46
Basic Foobar: What we changed
Module Documentation
Standard Naming Convention
40 / 46
Basic Foobar: What we changed
Module Documentation
Standard Naming Convention
Data Separation
41 / 46
Basic Foobar: What we changed
Module Documentation
Standard Naming Convention
Data Separation
Choices in how to manage module resources
42 / 46
Basic Foobar: What we changed
Module Documentation
Standard Naming Convention
Data Separation
Choices in how to manage module resources
Decommissioning of Single Resources
43 / 46
Basic Foobar: What we changed
Module Documentation
Standard Naming Convention
Data Separation
Choices in how to manage module resources
Decommissioning of Single Resources
Decommissioning of the Entire module
44 / 46
Basic Foobar: What we changed
Module Documentation
Standard Naming Convention
Data Separation
Choices in how to manage module resources
Decommissioning of Single Resources
Decommissioning of the Entire module
Dry Run support
45 / 46
Thank You For Listening
Questions?
please see vendor for rotten throwing tomatoes!
46 / 46

More Related Content

What's hot

APC & Memcache the High Performance Duo
APC & Memcache the High Performance DuoAPC & Memcache the High Performance Duo
APC & Memcache the High Performance DuoAnis Berejeb
 
Barcelona apc mem2010
Barcelona apc mem2010Barcelona apc mem2010
Barcelona apc mem2010isnull
 
PuppetCamp SEA 1 - Version Control with Puppet
PuppetCamp SEA 1 - Version Control with PuppetPuppetCamp SEA 1 - Version Control with Puppet
PuppetCamp SEA 1 - Version Control with PuppetWalter Heck
 
PuppetCamp SEA 1 - Use of Puppet
PuppetCamp SEA 1 - Use of PuppetPuppetCamp SEA 1 - Use of Puppet
PuppetCamp SEA 1 - Use of PuppetWalter Heck
 
The Ring programming language version 1.10 book - Part 92 of 212
The Ring programming language version 1.10 book - Part 92 of 212The Ring programming language version 1.10 book - Part 92 of 212
The Ring programming language version 1.10 book - Part 92 of 212Mahmoud Samir Fayed
 
OpenStack Swift Command Line Reference Diablo v1.2
OpenStack Swift Command Line Reference Diablo v1.2OpenStack Swift Command Line Reference Diablo v1.2
OpenStack Swift Command Line Reference Diablo v1.2Amar Kapadia
 
From Dev to DevOps - Codemotion ES 2012
From Dev to DevOps - Codemotion ES 2012From Dev to DevOps - Codemotion ES 2012
From Dev to DevOps - Codemotion ES 2012Carlos Sanchez
 
An example Hadoop Install
An example Hadoop InstallAn example Hadoop Install
An example Hadoop InstallMike Frampton
 
Single node hadoop cluster installation
Single node hadoop cluster installation Single node hadoop cluster installation
Single node hadoop cluster installation Mahantesh Angadi
 
Bpug mcollective 20140624
Bpug mcollective 20140624Bpug mcollective 20140624
Bpug mcollective 20140624Johan De Wit
 
Puppet at Opera Sofware - PuppetCamp Oslo 2013
Puppet at Opera Sofware - PuppetCamp Oslo 2013Puppet at Opera Sofware - PuppetCamp Oslo 2013
Puppet at Opera Sofware - PuppetCamp Oslo 2013Cosimo Streppone
 
Running hadoop on ubuntu linux
Running hadoop on ubuntu linuxRunning hadoop on ubuntu linux
Running hadoop on ubuntu linuxTRCK
 
PuppetConf 2016: Nano Server, Puppet, and DSC
PuppetConf 2016: Nano Server, Puppet, and DSCPuppetConf 2016: Nano Server, Puppet, and DSC
PuppetConf 2016: Nano Server, Puppet, and DSCMichael Smith
 
Red hat lvm cheatsheet
Red hat   lvm cheatsheetRed hat   lvm cheatsheet
Red hat lvm cheatsheetPrakash Ghosh
 
Nuxeo5 - Continuous Integration
Nuxeo5 - Continuous IntegrationNuxeo5 - Continuous Integration
Nuxeo5 - Continuous IntegrationPASCAL Jean Marie
 
Using puppet
Using puppetUsing puppet
Using puppetAlex Su
 
Docker & CoreOS at Utah Gophers
Docker & CoreOS at Utah GophersDocker & CoreOS at Utah Gophers
Docker & CoreOS at Utah GophersJosh Braegger
 
Do more than one thing at the same time, the Python way
Do more than one thing at the same time, the Python wayDo more than one thing at the same time, the Python way
Do more than one thing at the same time, the Python wayJaime Buelta
 

What's hot (20)

Puppet fundamentals
Puppet fundamentalsPuppet fundamentals
Puppet fundamentals
 
APC & Memcache the High Performance Duo
APC & Memcache the High Performance DuoAPC & Memcache the High Performance Duo
APC & Memcache the High Performance Duo
 
Barcelona apc mem2010
Barcelona apc mem2010Barcelona apc mem2010
Barcelona apc mem2010
 
PuppetCamp SEA 1 - Version Control with Puppet
PuppetCamp SEA 1 - Version Control with PuppetPuppetCamp SEA 1 - Version Control with Puppet
PuppetCamp SEA 1 - Version Control with Puppet
 
PuppetCamp SEA 1 - Use of Puppet
PuppetCamp SEA 1 - Use of PuppetPuppetCamp SEA 1 - Use of Puppet
PuppetCamp SEA 1 - Use of Puppet
 
The Ring programming language version 1.10 book - Part 92 of 212
The Ring programming language version 1.10 book - Part 92 of 212The Ring programming language version 1.10 book - Part 92 of 212
The Ring programming language version 1.10 book - Part 92 of 212
 
OpenStack Swift Command Line Reference Diablo v1.2
OpenStack Swift Command Line Reference Diablo v1.2OpenStack Swift Command Line Reference Diablo v1.2
OpenStack Swift Command Line Reference Diablo v1.2
 
From Dev to DevOps - Codemotion ES 2012
From Dev to DevOps - Codemotion ES 2012From Dev to DevOps - Codemotion ES 2012
From Dev to DevOps - Codemotion ES 2012
 
Hadoop Installation
Hadoop InstallationHadoop Installation
Hadoop Installation
 
An example Hadoop Install
An example Hadoop InstallAn example Hadoop Install
An example Hadoop Install
 
Single node hadoop cluster installation
Single node hadoop cluster installation Single node hadoop cluster installation
Single node hadoop cluster installation
 
Bpug mcollective 20140624
Bpug mcollective 20140624Bpug mcollective 20140624
Bpug mcollective 20140624
 
Puppet at Opera Sofware - PuppetCamp Oslo 2013
Puppet at Opera Sofware - PuppetCamp Oslo 2013Puppet at Opera Sofware - PuppetCamp Oslo 2013
Puppet at Opera Sofware - PuppetCamp Oslo 2013
 
Running hadoop on ubuntu linux
Running hadoop on ubuntu linuxRunning hadoop on ubuntu linux
Running hadoop on ubuntu linux
 
PuppetConf 2016: Nano Server, Puppet, and DSC
PuppetConf 2016: Nano Server, Puppet, and DSCPuppetConf 2016: Nano Server, Puppet, and DSC
PuppetConf 2016: Nano Server, Puppet, and DSC
 
Red hat lvm cheatsheet
Red hat   lvm cheatsheetRed hat   lvm cheatsheet
Red hat lvm cheatsheet
 
Nuxeo5 - Continuous Integration
Nuxeo5 - Continuous IntegrationNuxeo5 - Continuous Integration
Nuxeo5 - Continuous Integration
 
Using puppet
Using puppetUsing puppet
Using puppet
 
Docker & CoreOS at Utah Gophers
Docker & CoreOS at Utah GophersDocker & CoreOS at Utah Gophers
Docker & CoreOS at Utah Gophers
 
Do more than one thing at the same time, the Python way
Do more than one thing at the same time, the Python wayDo more than one thing at the same time, the Python way
Do more than one thing at the same time, the Python way
 

Viewers also liked

A Brief Introduction to Writing and Understanding Puppet Modules
A Brief Introduction to Writing and Understanding Puppet ModulesA Brief Introduction to Writing and Understanding Puppet Modules
A Brief Introduction to Writing and Understanding Puppet ModulesDavid Phillips
 
Little Puppet Tools To Make Your Life Better
Little Puppet Tools To Make Your Life BetterLittle Puppet Tools To Make Your Life Better
Little Puppet Tools To Make Your Life BetterPeter Souter
 
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-lintSpencer Owen
 
Puppet module anti patterns
Puppet module anti patternsPuppet module anti patterns
Puppet module anti patternsPeter Souter
 
Home searchapplicationform ga3_a1_l1_2
Home searchapplicationform ga3_a1_l1_2Home searchapplicationform ga3_a1_l1_2
Home searchapplicationform ga3_a1_l1_2Paula Tatiana
 
Final RKIC CaseStudy Presentation
Final  RKIC CaseStudy PresentationFinal  RKIC CaseStudy Presentation
Final RKIC CaseStudy PresentationSanford Terrance
 
Puppet for Developers
Puppet for DevelopersPuppet for Developers
Puppet for Developerssagarhere4u
 
Using vagrant for developing and testing puppet modules
Using vagrant for developing and testing puppet modulesUsing vagrant for developing and testing puppet modules
Using vagrant for developing and testing puppet modulesKristian Houlberg Øllegaard
 
Puppet | Custom Modules & Using the Forge
Puppet | Custom Modules & Using the ForgePuppet | Custom Modules & Using the Forge
Puppet | Custom Modules & Using the ForgeAaron Bernstein
 
Nginx + Tornado = 17k req/s
Nginx + Tornado = 17k req/sNginx + Tornado = 17k req/s
Nginx + Tornado = 17k req/smoret1979
 
Generations_in_the_Workforce 97-2003
Generations_in_the_Workforce 97-2003Generations_in_the_Workforce 97-2003
Generations_in_the_Workforce 97-2003Sanford Terrance
 
INSTALACIONES SANITARIAS
INSTALACIONES SANITARIASINSTALACIONES SANITARIAS
INSTALACIONES SANITARIASGelito Melito
 
Struktur pasar modal indonesia
Struktur pasar modal indonesiaStruktur pasar modal indonesia
Struktur pasar modal indonesiamutiarahikmatul
 
What you need to know about ceph
What you need to know about cephWhat you need to know about ceph
What you need to know about cephEmma Haruka Iwao
 
Build an High-Performance and High-Durable Block Storage Service Based on Ceph
Build an High-Performance and High-Durable Block Storage Service Based on CephBuild an High-Performance and High-Durable Block Storage Service Based on Ceph
Build an High-Performance and High-Durable Block Storage Service Based on CephRongze Zhu
 

Viewers also liked (20)

A Brief Introduction to Writing and Understanding Puppet Modules
A Brief Introduction to Writing and Understanding Puppet ModulesA Brief Introduction to Writing and Understanding Puppet Modules
A Brief Introduction to Writing and Understanding Puppet Modules
 
Little Puppet Tools To Make Your Life Better
Little Puppet Tools To Make Your Life BetterLittle Puppet Tools To Make Your Life Better
Little Puppet Tools To Make Your Life Better
 
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 module anti patterns
Puppet module anti patternsPuppet module anti patterns
Puppet module anti patterns
 
Home searchapplicationform ga3_a1_l1_2
Home searchapplicationform ga3_a1_l1_2Home searchapplicationform ga3_a1_l1_2
Home searchapplicationform ga3_a1_l1_2
 
Solicitud
SolicitudSolicitud
Solicitud
 
Agency Creds_2014_Lara
Agency Creds_2014_LaraAgency Creds_2014_Lara
Agency Creds_2014_Lara
 
Final RKIC CaseStudy Presentation
Final  RKIC CaseStudy PresentationFinal  RKIC CaseStudy Presentation
Final RKIC CaseStudy Presentation
 
Movinf to new place
Movinf to new placeMovinf to new place
Movinf to new place
 
Puppet for Developers
Puppet for DevelopersPuppet for Developers
Puppet for Developers
 
Using vagrant for developing and testing puppet modules
Using vagrant for developing and testing puppet modulesUsing vagrant for developing and testing puppet modules
Using vagrant for developing and testing puppet modules
 
Resume
ResumeResume
Resume
 
Puppet | Custom Modules & Using the Forge
Puppet | Custom Modules & Using the ForgePuppet | Custom Modules & Using the Forge
Puppet | Custom Modules & Using the Forge
 
Nginx + Tornado = 17k req/s
Nginx + Tornado = 17k req/sNginx + Tornado = 17k req/s
Nginx + Tornado = 17k req/s
 
Power of Puppet 4
Power of Puppet 4Power of Puppet 4
Power of Puppet 4
 
Generations_in_the_Workforce 97-2003
Generations_in_the_Workforce 97-2003Generations_in_the_Workforce 97-2003
Generations_in_the_Workforce 97-2003
 
INSTALACIONES SANITARIAS
INSTALACIONES SANITARIASINSTALACIONES SANITARIAS
INSTALACIONES SANITARIAS
 
Struktur pasar modal indonesia
Struktur pasar modal indonesiaStruktur pasar modal indonesia
Struktur pasar modal indonesia
 
What you need to know about ceph
What you need to know about cephWhat you need to know about ceph
What you need to know about ceph
 
Build an High-Performance and High-Durable Block Storage Service Based on Ceph
Build an High-Performance and High-Durable Block Storage Service Based on CephBuild an High-Performance and High-Durable Block Storage Service Based on Ceph
Build an High-Performance and High-Durable Block Storage Service Based on Ceph
 

Similar to Modules reduce reuse_recycle

Luc Suryo - Puppet on EC2
Luc Suryo - Puppet on EC2Luc Suryo - Puppet on EC2
Luc Suryo - Puppet on EC2Puppet
 
Learning Puppet basic thing
Learning Puppet basic thing Learning Puppet basic thing
Learning Puppet basic thing DaeHyung Lee
 
Linux Troubleshooting
Linux TroubleshootingLinux Troubleshooting
Linux TroubleshootingKeith Wright
 
Developing IT infrastructures with Puppet
Developing IT infrastructures with PuppetDeveloping IT infrastructures with Puppet
Developing IT infrastructures with PuppetAlessandro Franceschi
 
Puppet overview
Puppet overviewPuppet overview
Puppet overviewMike_Foto
 
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
 
Tame your Infrastructure with Puppet
Tame your Infrastructure with PuppetTame your Infrastructure with Puppet
Tame your Infrastructure with Puppetdelimiter
 
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
 
PuppetCamp SEA 1 - Puppet Deployment at OnApp
PuppetCamp SEA 1 - Puppet Deployment  at OnAppPuppetCamp SEA 1 - Puppet Deployment  at OnApp
PuppetCamp SEA 1 - Puppet Deployment at OnAppOlinData
 
PuppetCamp SEA 1 - Puppet Deployment at OnApp
PuppetCamp SEA 1 - Puppet Deployment  at OnAppPuppetCamp SEA 1 - Puppet Deployment  at OnApp
PuppetCamp SEA 1 - Puppet Deployment at OnAppWalter Heck
 
Puppet Deployment at OnApp
Puppet Deployment at OnApp Puppet Deployment at OnApp
Puppet Deployment at OnApp Puppet
 
From Dev to DevOps
From Dev to DevOpsFrom Dev to DevOps
From Dev to DevOpsAgile Spain
 
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
 
Automatic systems installations and change management wit FAI - Talk for Netw...
Automatic systems installations and change management wit FAI - Talk for Netw...Automatic systems installations and change management wit FAI - Talk for Netw...
Automatic systems installations and change management wit FAI - Talk for Netw...Henning Sprang
 
Building Docker images with Puppet
Building Docker images with PuppetBuilding Docker images with Puppet
Building Docker images with PuppetNick Jones
 

Similar to Modules reduce reuse_recycle (20)

Luc Suryo - Puppet on EC2
Luc Suryo - Puppet on EC2Luc Suryo - Puppet on EC2
Luc Suryo - Puppet on EC2
 
Learning Puppet basic thing
Learning Puppet basic thing Learning Puppet basic thing
Learning Puppet basic thing
 
Puppet
PuppetPuppet
Puppet
 
Linux Troubleshooting
Linux TroubleshootingLinux Troubleshooting
Linux Troubleshooting
 
Developing IT infrastructures with Puppet
Developing IT infrastructures with PuppetDeveloping IT infrastructures with Puppet
Developing IT infrastructures with Puppet
 
Puppet overview
Puppet overviewPuppet overview
Puppet overview
 
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
 
Tame your Infrastructure with Puppet
Tame your Infrastructure with PuppetTame your Infrastructure with Puppet
Tame your Infrastructure with 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
 
PuppetCamp SEA 1 - Puppet Deployment at OnApp
PuppetCamp SEA 1 - Puppet Deployment  at OnAppPuppetCamp SEA 1 - Puppet Deployment  at OnApp
PuppetCamp SEA 1 - Puppet Deployment at OnApp
 
PuppetCamp SEA 1 - Puppet Deployment at OnApp
PuppetCamp SEA 1 - Puppet Deployment  at OnAppPuppetCamp SEA 1 - Puppet Deployment  at OnApp
PuppetCamp SEA 1 - Puppet Deployment at OnApp
 
Puppet Deployment at OnApp
Puppet Deployment at OnApp Puppet Deployment at OnApp
Puppet Deployment at OnApp
 
Puppet
PuppetPuppet
Puppet
 
From Dev to DevOps
From Dev to DevOpsFrom Dev to DevOps
From Dev to DevOps
 
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
 
Automatic systems installations and change management wit FAI - Talk for Netw...
Automatic systems installations and change management wit FAI - Talk for Netw...Automatic systems installations and change management wit FAI - Talk for Netw...
Automatic systems installations and change management wit FAI - Talk for Netw...
 
Building Docker images with Puppet
Building Docker images with PuppetBuilding Docker images with Puppet
Building Docker images with Puppet
 
Puppet quick start guide
Puppet quick start guidePuppet quick start guide
Puppet quick start guide
 

Recently uploaded

Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxRemote DBA Services
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdfSandro Moreira
 
Less Is More: Utilizing Ballerina to Architect a Cloud Data Platform
Less Is More: Utilizing Ballerina to Architect a Cloud Data PlatformLess Is More: Utilizing Ballerina to Architect a Cloud Data Platform
Less Is More: Utilizing Ballerina to Architect a Cloud Data PlatformWSO2
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2
 
Decarbonising Commercial Real Estate: The Role of Operational Performance
Decarbonising Commercial Real Estate: The Role of Operational PerformanceDecarbonising Commercial Real Estate: The Role of Operational Performance
Decarbonising Commercial Real Estate: The Role of Operational PerformanceIES VE
 
Design and Development of a Provenance Capture Platform for Data Science
Design and Development of a Provenance Capture Platform for Data ScienceDesign and Development of a Provenance Capture Platform for Data Science
Design and Development of a Provenance Capture Platform for Data SciencePaolo Missier
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
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.pdfOrbitshub
 
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.pptxRustici Software
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityWSO2
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Orbitshub
 
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 2024Victor Rentea
 
JavaScript Usage Statistics 2024 - The Ultimate Guide
JavaScript Usage Statistics 2024 - The Ultimate GuideJavaScript Usage Statistics 2024 - The Ultimate Guide
JavaScript Usage Statistics 2024 - The Ultimate GuidePixlogix Infotech
 
"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 ...Zilliz
 
Stronger Together: Developing an Organizational Strategy for Accessible Desig...
Stronger Together: Developing an Organizational Strategy for Accessible Desig...Stronger Together: Developing an Organizational Strategy for Accessible Desig...
Stronger Together: Developing an Organizational Strategy for Accessible Desig...caitlingebhard1
 
Simplifying Mobile A11y Presentation.pptx
Simplifying Mobile A11y Presentation.pptxSimplifying Mobile A11y Presentation.pptx
Simplifying Mobile A11y Presentation.pptxMarkSteadman7
 
Choreo: Empowering the Future of Enterprise Software Engineering
Choreo: Empowering the Future of Enterprise Software EngineeringChoreo: Empowering the Future of Enterprise Software Engineering
Choreo: Empowering the Future of Enterprise Software EngineeringWSO2
 
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)Samir Dash
 
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 TerraformAndrey Devyatkin
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamUiPathCommunity
 

Recently uploaded (20)

Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Less Is More: Utilizing Ballerina to Architect a Cloud Data Platform
Less Is More: Utilizing Ballerina to Architect a Cloud Data PlatformLess Is More: Utilizing Ballerina to Architect a Cloud Data Platform
Less Is More: Utilizing Ballerina to Architect a Cloud Data Platform
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
Decarbonising Commercial Real Estate: The Role of Operational Performance
Decarbonising Commercial Real Estate: The Role of Operational PerformanceDecarbonising Commercial Real Estate: The Role of Operational Performance
Decarbonising Commercial Real Estate: The Role of Operational Performance
 
Design and Development of a Provenance Capture Platform for Data Science
Design and Development of a Provenance Capture Platform for Data ScienceDesign and Development of a Provenance Capture Platform for Data Science
Design and Development of a Provenance Capture Platform for Data Science
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
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
 
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
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
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
 
JavaScript Usage Statistics 2024 - The Ultimate Guide
JavaScript Usage Statistics 2024 - The Ultimate GuideJavaScript Usage Statistics 2024 - The Ultimate Guide
JavaScript Usage Statistics 2024 - The Ultimate Guide
 
"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 ...
 
Stronger Together: Developing an Organizational Strategy for Accessible Desig...
Stronger Together: Developing an Organizational Strategy for Accessible Desig...Stronger Together: Developing an Organizational Strategy for Accessible Desig...
Stronger Together: Developing an Organizational Strategy for Accessible Desig...
 
Simplifying Mobile A11y Presentation.pptx
Simplifying Mobile A11y Presentation.pptxSimplifying Mobile A11y Presentation.pptx
Simplifying Mobile A11y Presentation.pptx
 
Choreo: Empowering the Future of Enterprise Software Engineering
Choreo: Empowering the Future of Enterprise Software EngineeringChoreo: Empowering the Future of Enterprise Software Engineering
Choreo: Empowering the Future of Enterprise Software Engineering
 
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
 
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
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 

Modules reduce reuse_recycle

  • 1. Modules: Reuse, Reduce, Recycle Puppet Camp Denver 2015 by daniel kendrick 1 / 46
  • 2. mod·ule (mŏj′o͞ol) n. 1. A standardized, often interchangeable component of a system or construction that is designed for easy assembly or flexible use 2 / 46
  • 3. Flexibility Give that man a straw! 3 / 46
  • 4. Trifecta Package: Managing a package by enforcing it's state File: Managing a configuration file or it's content Service: Managing a service or daemon Where We Typically Start 4 / 46
  • 5. Example NTP #/root/examples/modules1-ntp1.pp classntp{ case$operatingsystem{ centos,redhat:{ $service_name='ntpd' $conf_file ='ntp.conf.el' } debian,ubuntu:{ $service_name='ntp' $conf_file ='ntp.conf.debian' } } package{'ntp': ensure=>installed, } file{'ntp.conf': path =>'/etc/ntp.conf', ensure =>file, require=>Package['ntp'], source =>"/root/examples/answers/${conf_file}" } service{'ntp': name =>$service_name, ensure =>running, enable =>true, subscribe=>File['ntp.conf'], } } The Trifecta at Work it's doing exactly what it's told, and only what it's told 5 / 46
  • 6. Trifecta: Not a very good implementation #ntpmodule classntp::present{ package{'ntp': ensure=>present, } } classntp::config{ file{"/etc/ntp.conf": owner=>"root", group=>"root", mode=>0644, # source=>"puppet://$puppetserver/modules/ntp/etc/ntp.conf", content=>template("ntp/etc/ntp.conf.erb"), require=>Class["ntp::present"], notify=>Class["ntp::service"], } } classntp::service{ service{"ntp": ensure=>running, hasstatus=>true, hasrestart=>true, enable=>true, require=>Class["ntp::config"], } } classntp::absent{ package{'ntp': ensure=>absent, } } classntp{ if$is_virtual=='false' { notify{"puppet:ntp:$hostnameisphysical":} includentp::present,ntp::config,ntp::service } else{ notify{"puppet:ntp:$hostnameisvirtual":} includentp::absent } } My GOD Mojo, what have they done to you?! 6 / 46
  • 7. Trifecta: Not a very good implementation #ntpmodule classntp::present{ package{'ntp': ensure=>present, } } classntp::config{ file{"/etc/ntp.conf": owner=>"root", group=>"root", mode=>0644, # source=>"puppet://$puppetserver/modules/ntp/etc/ntp.conf", content=>template("ntp/etc/ntp.conf.erb"), require=>Class["ntp::present"], notify=>Class["ntp::service"], } } classntp::service{ service{"ntp": ensure=>running, hasstatus=>true, hasrestart=>true, enable=>true, require=>Class["ntp::config"], } } classntp::absent{ package{'ntp': ensure=>absent, } } classntp{ if$is_virtual=='false' { notify{"puppet:ntp:$hostnameisphysical":} includentp::present,ntp::config,ntp::service } else{ notify{"puppet:ntp:$hostnameisvirtual":} includentp::absent } } My GOD Mojo, what have they done to you?! 7 / 46
  • 8. Example NTP #/root/examples/modules1-ntp1.pp classntp{ case$operatingsystem{ centos,redhat:{ $service_name='ntpd' $conf_file ='ntp.conf.el' } debian,ubuntu:{ $service_name='ntp' $conf_file ='ntp.conf.debian' } } package{'ntp': ensure=>installed, } file{'ntp.conf': path =>'/etc/ntp.conf', ensure =>file, require=>Package['ntp'], source =>"/root/examples/answers/${conf_file}" } service{'ntp': name =>$service_name, ensure =>running, enable =>true, subscribe=>File['ntp.conf'], } } Managing State 8 / 46
  • 9. Parameters classntp( $conf_file =$ntp::params::conf_file, $service_name=$ntp::params::service_name, )inheritsntp::params{ package{'ntp': ensure=>installed, } file{'ntp.conf': path =>'/etc/ntp.conf', ensure =>file, require=>Package['ntp'], source =>$ntp::conf_file, } service{'ntp': name =>$ntp::service_name, ensure =>running, enable =>true, subscribe=>File['ntp.conf'], } } classntp::params{ $conf_file=$::operatingsystem?{ /(?i:RedHat|CentOS)/ =>'puppet:///modules/ntp/etc/ntp.conf.el', /(?i:Debian|Ubuntu)/ =>'puppet:///modules/ntp/etc/ntp.conf.debian', default =>'puppet:///modules/ntp/etc/ntp.conf', } $service_name=$::operatingsystem?{ /(?i:RedHat|CentOS)/ =>'ntp', /(?i:Debian|Ubuntu)/ =>'ntpd', default =>'ntp', } } A bit of Flexibility 9 / 46
  • 10. Parameters classntp( $conf_file =$ntp::params::conf_file, $service_name=$ntp::params::service_name, )inheritsntp::params{ package{'ntp': ensure=>installed, } file{'ntp.conf': path =>'/etc/ntp.conf', ensure =>file, require=>Package['ntp'], source =>$ntp::conf_file, } service{'ntp': name =>$ntp::service_name, ensure =>running, enable =>true, subscribe=>File['ntp.conf'], } } classntp::params{ $conf_file=$::operatingsystem?{ /(?i:RedHat|CentOS)/ =>'puppet:///modules/ntp/etc/ntp.conf.el', /(?i:Debian|Ubuntu)/ =>'puppet:///modules/ntp/etc/ntp.conf.debian', default =>'puppet:///modules/ntp/etc/ntp.conf', } $service_name=$::operatingsystem?{ /(?i:RedHat|CentOS)/ =>'ntp', /(?i:Debian|Ubuntu)/ =>'ntpd', default =>'ntp', } } A bit of Flexibility Called as a Parameterized Class class{'ntp': conf_file=>'puppet:///modules/my-site/etc/ntp.conf' } 10 / 46
  • 11. Foobar Module classfoobar{ package{'foobar.package': ensure=>present, name =>'foobar', } file{'foobar.conf': ensure =>file, path =>'/etc/foobar/foobar.conf', require=>Package['foobar.package'], source =>'puppet:///modules/foobar/foobar.conf', notify =>Service['foobar.service'], } service{'foobar.service': ensure =>running, name =>'foobard', enable =>true, } } 11 / 46
  • 12. Foobar Module Identifying Candidates classfoobar{ package{'foobar.package': ensure=>present, name =>'foobar', } file{'foobar.conf': ensure =>file, path =>'/etc/foobar/foobar.conf', require=>Package['foobar.package'], source =>'puppet:///modules/foobar/foobar.conf', notify =>Service['foobar.service'], } service{'foobar.service': ensure =>running, name =>'foobard', enable =>true, } } 12 / 46
  • 13. Foobar Module How it could look classfoobar( $package_name =$foobar::params::package_name, $package_ensure =$foobar::params::package_ensure, $service_name =$foobar::params::service_name, $service_ensure =$foobar::params::service_ensure, $service_enable =$foobar::params::service_enable, $config_file_path =$foobar::params::config_file_path, $config_file_source =$foobar::params::config_file_source, )inheritsfoobar::params{ 'validationandlogichere..' package{'foobar.package': ensure=>$foobar::package_ensure, name =>$foobar::package_name, } file{'foobar.conf': ensure =>$foobar::config_file_ensure, path =>$foobar::config_file_path, require=>Package['foobar.package'], source =>$foobar::config_file_source, notify =>Service['foobar.service'], } service{'foobar.service': ensure =>$foobar::service_ensure, name =>$foobar::service_name, enable =>$foobar::service_enable, } } 13 / 46
  • 14. Too Much? classfoobar( $package_name =$foobar::params::package_name, $package_ensure =$foobar::params::package_ensure, $service_name =$foobar::params::service_name, $service_ensure =$foobar::params::service_ensure, $service_enable =$foobar::params::service_enable, $config_file_path =$foobar::params::config_file_path, $config_file_owner =$foobar::params::config_file_owner, $config_file_group =$foobar::params::config_file_group, $config_file_mode =$foobar::params::config_file_mode, $config_file_source =$foobar::params::config_file_source, $config_file_template =$foobar::params::config_file_template, $unicorn_config_file_path=$unicorn::unicorn_config_file_path, $config_ru_template =$unicorn::config_ru_template, $unicorn_working_dir =$unicorn::unicorn_working_dir, $unicorn_init_file_path =$unicorn::unicorn_init_file_path, $use_nginx =true, $use_apache =false, $nginx_config_file_path =$nginx::config_file_path, $apache_config_file_path =$apache::config_file_path, )inheritsfoobar::params{ SuperCoolPuppetCodeHere... } flexibility means more options for the user, but where is the line drawn? 14 / 46
  • 15. Too Much? Just Enough classfoobar( $package_name =$foobar::params::package_name, $package_ensure =$foobar::params::package_ensure, $package_version =$foobar::params::package_version, $service_name =$foobar::params::service_name, $service_ensure =$foobar::params::service_ensure, $service_enable =$foobar::params::service_enable, $config_file_path =$foobar::params::config_file_path, $config_file_owner =$foobar::params::config_file_owner, $config_file_group =$foobar::params::config_file_group, $config_file_mode =$foobar::params::config_file_mode, $config_file_source =$foobar::params::config_file_source, $config_file_template =$foobar::params::config_file_template, $config_dir_path =$foobar::params::config_dir_path, $config_dir_source =$foobar::params::config_dir_source, $config_dir_purge =$foobar::params::config_dir_purge, $config_dir_recurse =$foobar::params::config_dir_recurse, )inheritsfoobar::params{ } a perfectly sane food to eat 15 / 46
  • 16. Too Much? Just Enough classfoobar( $package_name =$foobar::params::package_name, $package_ensure =$foobar::params::package_ensure, $package_version =$foobar::params::package_version, $service_name =$foobar::params::service_name, $service_ensure =$foobar::params::service_ensure, $service_enable =$foobar::params::service_enable, $config_file_path =$foobar::params::config_file_path, $config_file_owner =$foobar::params::config_file_owner, $config_file_group =$foobar::params::config_file_group, $config_file_mode =$foobar::params::config_file_mode, $config_file_source =$foobar::params::config_file_source, $config_file_template =$foobar::params::config_file_template, $config_dir_path =$foobar::params::config_dir_path, $config_dir_source =$foobar::params::config_dir_source, $config_dir_purge =$foobar::params::config_dir_purge, $config_dir_recurse =$foobar::params::config_dir_recurse, )inheritsfoobar::params{ #$config_dir_pathcanberecursivelyoverwrittenby$config_dir_source if$foobar::config_dir_source{ file{'foobar.dir': ensure =>directory, path =>$foobar::config_dir_path, source =>$foobar::config_dir_source, recurse=>$foobar::config_dir_recurse, purge =>$foobar::config_dir_purge, force =>$foobar::config_dir_purge, notify =>Service['foobar.service'], require=>Package['foobar.package'], } } } a perfectly sane food to eat 16 / 46
  • 17. Too Much? Just Enough classfoobar( $package_name =$foobar::params::package_name, $package_ensure =$foobar::params::package_ensure, $package_version =$foobar::params::package_version, $service_name =$foobar::params::service_name, $service_ensure =$foobar::params::service_ensure, $service_enable =$foobar::params::service_enable, $config_file_path =$foobar::params::config_file_path, $config_file_owner =$foobar::params::config_file_owner, $config_file_group =$foobar::params::config_file_group, $config_file_mode =$foobar::params::config_file_mode, $config_file_source =$foobar::params::config_file_source, $config_file_template =$foobar::params::config_file_template, $config_dir_path =$foobar::params::config_dir_path, $config_dir_source =$foobar::params::config_dir_source, $config_dir_purge =$foobar::params::config_dir_purge, $config_dir_recurse =$foobar::params::config_dir_recurse, )inheritsfoobar::params{ #$config_dir_pathcanberecursivelyoverwrittenby$config_dir_source if$foobar::config_dir_source{ file{'foobar.dir': ensure =>directory, path =>$foobar::config_dir_path, source =>$foobar::config_dir_source, recurse=>$foobar::config_dir_recurse, purge =>$foobar::config_dir_purge, force =>$foobar::config_dir_purge, notify =>Service['foobar.service'], require=>Package['foobar.package'], } } } a perfectly sane food to eat Called as a Parameterized Class class{'foobar': config_dir_source=>'puppet:///modules/my-site/foobar/', } 17 / 46
  • 18. Too Much? Just Enough classfoobar( $package_name =$foobar::params::package_name, $package_ensure =$foobar::params::package_ensure, $package_version =$foobar::params::package_version, $service_name =$foobar::params::service_name, $service_ensure =$foobar::params::service_ensure, $service_enable =$foobar::params::service_enable, $config_file_path =$foobar::params::config_file_path, $config_file_owner =$foobar::params::config_file_owner, $config_file_group =$foobar::params::config_file_group, $config_file_mode =$foobar::params::config_file_mode, $config_file_source =$foobar::params::config_file_source, $config_file_template =$foobar::params::config_file_template, $config_dir_path =$foobar::params::config_dir_path, $config_dir_source =$foobar::params::config_dir_source, $config_dir_purge =$foobar::params::config_dir_purge, $config_dir_recurse =$foobar::params::config_dir_recurse, )inheritsfoobar::params{ #$config_dir_pathcanberecursivelyoverwrittenby$config_dir_source if$foobar::config_dir_source{ file{'foobar.dir': ensure =>directory, path =>$foobar::config_dir_path, source =>$foobar::config_dir_source, recurse=>$foobar::config_dir_recurse, purge =>$foobar::config_dir_purge, force =>$foobar::config_dir_purge, notify =>Service['foobar.service'], require=>Package['foobar.package'], } } } a perfectly sane food to eat Called as a Parameterized Class class{'foobar': config_dir_source=>'puppet:///modules/my-site/foobar/', } Called as a Parameterized Class class{'foobar': config_dir_source=>'puppet:///modules/my-site/foobar/', config_dir_purge =>true, } 18 / 46
  • 19. Too Much? Just Enough classfoobar( $package_name =$foobar::params::package_name, $package_ensure =$foobar::params::package_ensure, $package_version =$foobar::params::package_version, $service_name =$foobar::params::service_name, $service_ensure =$foobar::params::service_ensure, $service_enable =$foobar::params::service_enable, $config_file_path =$foobar::params::config_file_path, $config_file_owner =$foobar::params::config_file_owner, $config_file_group =$foobar::params::config_file_group, $config_file_mode =$foobar::params::config_file_mode, $config_file_source =$foobar::params::config_file_source, $config_file_template =$foobar::params::config_file_template, $config_dir_path =$foobar::params::config_dir_path, $config_dir_source =$foobar::params::config_dir_source, $config_dir_purge =$foobar::params::config_dir_purge, $config_dir_recurse =$foobar::params::config_dir_recurse, )inheritsfoobar::params{ #$config_dir_pathcanberecursivelyoverwrittenby$config_dir_source if$foobar::config_dir_source{ file{'foobar.dir': ensure =>directory, path =>$foobar::config_dir_path, source =>$foobar::config_dir_source, recurse=>$foobar::config_dir_recurse, purge =>$foobar::config_dir_purge, force =>$foobar::config_dir_purge, notify =>Service['foobar.service'], require=>Package['foobar.package'], } } } a perfectly sane food to eat Called as a Parameterized Class class{'foobar': config_dir_source=>'puppet:///modules/my-site/foobar/', } Called as a Parameterized Class class{'foobar': config_dir_source=>'puppet:///modules/my-site/foobar/', config_dir_purge =>true, } Called as a Parameterized Class class{'foobar': config_dir_source =>'puppet:///modules/my-site/foobar/', config_dir_purge =>true, config_dir_recurse=>true, } 19 / 46
  • 20. Flexibility Zealot with Metaparameters notify, require, subscribe, noop What?! Another Parameter?!....sigh... Alright https://docs.puppetlabs.com/references/latest/metaparameter.html 20 / 46
  • 21. noop notify require classfoobar( $noop =$foobar::params::noop, $package_name =$foobar::params::package_name, $package_ensure =$foobar::params::package_ensure, $package_version =$foobar::params::package_version, $service_name =$foobar::params::service_name, $service_ensure =$foobar::params::service_ensure, $service_enable =$foobar::params::service_enable, $config_file_path =$foobar::params::config_file_path, $config_file_owner =$foobar::params::config_file_owner, $config_file_group =$foobar::params::config_file_group, $config_file_mode =$foobar::params::config_file_mode, $config_file_source =$foobar::params::config_file_source, $config_file_template =$foobar::params::config_file_template, $config_file_require =$foobar::params::config_file_require, $config_file_notify =$foobar::params::config_file_notify, $config_dir_path =$foobar::params::config_dir_path, $config_dir_source =$foobar::params::config_dir_source, $config_dir_purge =$foobar::params::config_dir_purge, $config_dir_recurse =$foobar::params::config_dir_recurse, )inheritsfoobar::params{ package{'foobar.package': ensure=>$foobar::package_ensure, name =>$foobar::package_name, noop =>$foobar::noop, } file{'foobar.conf': ensure =>$foobar::config_file_ensure, path =>$foobar::config_file_path, require=>$foobar::config_file_require, source =>$foobar::config_file_source, notify =>$foobar::config_file_notify, noop =>$foobar::noop, } service{'foobar.service': ensure=>$foobar::service_ensure, name =>$foobar::service_name, enable=>$foobar::service_enable, noop =>$foobar::noop, } } Notice: /Stage[main]/Foobar/File[foobar.conf]/ensure: current_value absent, should be present (noop) 21 / 46
  • 22. Validation of Parameters validate the parameters, but remain flexible 22 / 46
  • 24. Functions Be Flexible human boolean class{'foobar': service_enable='t', } Error: Could not retrieve catalog from remote server: Error 400 on SERVER: "t" is not a boolean. It looks to be a String str2bool.rb #Strict validate_bool($service_enable) #Relaxed $bool_service_enable=str2bool($service_enable) str2bool converts human booleans when/^(1|t|y|true|yes)$/ thentrue when/^(0|f|n|false|no)$/ thenfalse PuppetLabs StdLib https://forge.puppetlabs.com/puppetlabs/stdlib 24 / 46
  • 25. Functions Be Flexible human boolean class{'foobar': service_enable='t', } Error: Could not retrieve catalog from remote server: Error 400 on SERVER: "t" is not a boolean. It looks to be a String str2bool.rb #Strict validate_bool($service_enable) #Relaxed $bool_service_enable=str2bool($service_enable) str2bool converts human booleans when/^(1|t|y|true|yes)$/ thentrue when/^(0|f|n|false|no)$/ thenfalse PuppetLabs StdLib https://forge.puppetlabs.com/puppetlabs/stdlib ###ValidationofParameters validate_absolute_path($standardFu::config_file_path) validate_absolute_path($standardFu::config_dir_path) validate_string($standardFu::config_file_owner) validate_string($standardFu::config_file_group) validate_string($standardFu::config_file_mode) #SanitizeBooleans $bool_config_dir_purge=str2bool($standardFu::config_dir_purge) $bool_service_enable =str2bool($standardFu::service_enable) 25 / 46
  • 26. Method I #Classfoobar::params # #Thisclassonlyprovidessanedefaultsforthefoobarmodule,and #shouldnotbecalledasis.Thisclassshouldbecalledfromfoobar. # classfoobar::params{ case$::osfamily{ 'Debian':{ $package_name ='foobar' $config_file_path='/etc/foobar/foobar.conf' $service_name ='foobard' } 'RedHat':{ $package_name ='foobar' $config_file_path='/etc/foobar.conf' $service_name ='foobar' } default:{ fail("FAIL:${::operatingsystem}is_NOT_supported.") } } } Operating System Validation 26 / 46
  • 27. Method I Method II #Classfoobar::params classfoobar::params{ $supported_os=$::osfamily?{ /(?i:RedHat)/ =>true, /(?i:Debian)/ =>true, default =>false } } #Classfoobar classfoobar( $package_name =$foobar::params::package_name, $package_ensure =$foobar::params::package_ensure, $package_version =$foobar::params::package_version, $service_name =$foobar::params::service_name, $service_ensure =$foobar::params::service_ensure, $service_enable =$foobar::params::service_enable, $config_file_path =$foobar::params::config_file_path, $config_file_owner =$foobar::params::config_file_owner, $config_file_group =$foobar::params::config_file_group, $config_file_mode =$foobar::params::config_file_mode, $config_file_notify =$foobar::params::config_file_notify, $config_file_source =$foobar::params::config_file_source, $config_file_template =$foobar::params::config_file_template, $config_dir_path =$foobar::params::config_dir_path, $config_dir_source =$foobar::params::config_dir_source, $config_dir_purge =$foobar::params::config_dir_purge, $config_dir_recurse =$foobar::params::config_dir_recurse, )inheritsfoobar::params{ if$foobar::params::supported_os==true{ #ParameterValidationandModuleResourcesHere }else{ #NoticeKeepsGoing.FailStops.Uptoyou notice("INFO:${::operatingsystem}is_NOT_supported.") fail("FAIL:${::operatingsystem}is_NOT_supported.") } } Operating System Validation 27 / 46
  • 28. Public and Private Classes what's the deal, and who cares PuppetLabs StdLib 2014-11-10 - Supported Release 4.4.0 28 / 46
  • 29. private('msg') #/etc/puppet/modules/foobar/manifests/server.pp classfoobar::server{ private('INFO:classfoobar::serverisprivate,consultdocumentation.') } #/etc/puppet/manifests/site.pp node'foobar-server.shellfu.lab.com'{ includefoobar::server } Error: Could not retrieve catalog from remote server: Error 400 on SERVER: INFO: class mysql::server is private, please consult module documentation for usage at /etc/puppet/modules/mysql/manifests/server.pp on node shellfu.lab.com Warning: Not using cache on failed catalog Error: Could not retrieve catalog; skipping run Public and Private Classes what's the deal, and who cares PuppetLabs StdLib 2014-11-10 - Supported Release 4.4.0 The Entrance is over there. 29 / 46
  • 30. Standardization How can something be Interchangeable if it is not Standardized? 30 / 46
  • 31. Semantic Versioning Given a version number MAJOR.MINOR.PATCH, increment the: MAJOR version when you make incompatible API changes, MINOR version when you add functionality in a backwards-compatible manner, and PATCH version when you make backwards-compatible bug fixes. Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format. http://www.semver.org 31 / 46
  • 32. Puppet Labs Style Guide https://docs.puppetlabs.com/guides/style_guide.html 32 / 46
  • 33. Puppet-Lint: Check your style ~$puppet-lint/path/to/module/init.pp WARNING:doublequotedstringcontainingnovariablesonline203 WARNING:linehasmorethan80charactersonline192 WARNING:indentationof=>isnotproperlyalignedonline248 WARNING:indentationof=>isnotproperlyalignedonline251 http://puppet-lint.com/ 33 / 46
  • 34. Module Documentation puppet doc /path/to/module/init.pp #[*config_file_path*] # Mainconfigurationfilepath # Canbedefinedalsobythe(classscope)variable$foobar::config_file # #[*config_file_mode*] # Mainconfigurationfilepathmode # Canbedefinedalsobythe(classscope)variable$foobar::config_file_mode # #[*config_file_owner*] # Mainconfigurationfilepathowner # Canbedefinedalsobythe(classscope)variable$foobar::config_file_owner # #[*config_file_group*] # Mainconfigurationfilepathgroup # Canbedefinedalsobythe(classscope)variable$foobar::config_file_group https://docs.puppetlabs.com/puppet/latest/reference/modules_documentation.html 34 / 46
  • 38. Basic Foobar: What we changed 38 / 46
  • 39. Basic Foobar: What we changed Module Documentation 39 / 46
  • 40. Basic Foobar: What we changed Module Documentation Standard Naming Convention 40 / 46
  • 41. Basic Foobar: What we changed Module Documentation Standard Naming Convention Data Separation 41 / 46
  • 42. Basic Foobar: What we changed Module Documentation Standard Naming Convention Data Separation Choices in how to manage module resources 42 / 46
  • 43. Basic Foobar: What we changed Module Documentation Standard Naming Convention Data Separation Choices in how to manage module resources Decommissioning of Single Resources 43 / 46
  • 44. Basic Foobar: What we changed Module Documentation Standard Naming Convention Data Separation Choices in how to manage module resources Decommissioning of Single Resources Decommissioning of the Entire module 44 / 46
  • 45. Basic Foobar: What we changed Module Documentation Standard Naming Convention Data Separation Choices in how to manage module resources Decommissioning of Single Resources Decommissioning of the Entire module Dry Run support 45 / 46
  • 46. Thank You For Listening Questions? please see vendor for rotten throwing tomatoes! 46 / 46