What is a reusable Puppet module? What are its requirements? Why does it matter and why it's not always the best choice? And, most of all, HOW do you make reusable modules? This session is all about this: How to make modules written in a way that you can use them in many different environments (also with different OS) without modifying them.
Alessandro Franceschi
Freelance Consultant, Lab42
Founded an Internet Service Provider in 1995. Founded a IT consulting firm in 1999. Decided that it was funnier to do technical stuff rather than to manage companies and became a freelance consultant in 2006. Discovered Puppet in 2007. Passed the last years pursuing an insane passion for fun and profit: Puppet consulting and modules development.
7. How do we use Puppet today
Include classes
manifests/
site.pp
Set Parameters / Variables
Integration logic
Resources
ENC HIERA
SITE
MODULES
SHARED
MODULES
BAD
EDGE
Configuration files
manifests/
site.pp
ENC HIERA
manifests/
site.pp
BAD?
BAD?
BAD
SITE
MODULES
SITE
MODULES
SHARED
MODULES
SITE
MODULES
SHARED
MODULES
manifests/
site.pp
BAD?
ENC
BAD?
Saturday, August 24, 13
16. THE PARAMETERS
DILEMMA
Managed resources attributes
Application specific config options
Application logic and behaviour
Integration with other modules
Saturday, August 24, 13
33.
Users
Everyone has his
own users...
Leave options to
decide
if, how and where to
manage the ones
the module requires.
Saturday, August 24, 13
34. Managing Users
elasticsearch/manifests/init.pp
class elasticsearch {
$ensure = 'present',
[...]
$user = 'elasticsearch',
$user_uid = undef,
$user_gid = undef,
$user_groups = undef,
$user_class = 'elasticsearch::user',
[...]
if $elasticsearch::user_class {
require $elasticsearch::user_class
}
elasticsearch/manifests/user.pp
class elasticsearch::user {
@user { $elasticsearch::user :
ensure = $elasticsearch::ensure,
comment = ${elasticsearch::user} user,
password = '!',
managehome = false,
uid = $elasticsearch::user_uid,
gid = $elasticsearch::user_gid,
groups = $elasticsearch::user_groups,
shell = '/bin/bash',
}
User | title == $elasticsearch::user |
}
Do not create the requested user
class { ‘elasticsearch’:
user_class = undef,
}
Provide the user in a different custom class
class { ‘elasticsearch’:
user_class = 'site::users',
}
Run elasticsearch with a different user
class { ‘elasticsearch’:
user = 'apache',
}
Saturday, August 24, 13
37. Extra Resources: Custom classes
elasticsearch/manifests/init.pp
class elasticsearch (
$dependency_class = 'elasticsearch::dependency',
$monitor_class = 'elasticsearch::monitor',
$firewall_class = 'elasticsearch::firewall',
$my_class = undef,
) {
[...]
if $elasticsearch::dependency_class {
include $elasticsearch::dependency_class
}
if $elasticsearch::monitor and $elasticsearch::monitor_class {
include $elasticsearch::monitor_class
}
if $elasticsearch::firewall and $elasticsearch::firewall_class {
include $elasticsearch::firewall_class
}
if $elasticsearch::my_class {
include $elasticsearch::my_class
}[...]
Provide the modules dependencies with a custom class
class { ‘elasticsearch’:
dependency_class = 'site::dep_elasticsearch',
}
Saturday, August 24, 13
38. Extra Resources: Resources Hash
elasticsearch/manifests/init.pp
class elasticsearch (
$create_resource = undef,
$resources_hash = undef,
) {
[...]
if $create_resource {
create_resources( $create_resource , $resources_hash )
}
Alternative: A single hash that includes resources and
resources_hash
Provide the modules dependencies with a custom class
class { ‘elasticsearch’:
create_resource = 'file',
resources_hash = {
path = '/etc/elasticsearch/my_file',
content = template('site/elasticsearch/my_file.erb),
mode = '0600',
},
}
Saturday, August 24, 13
46. hashes
Managing specific
application configs
parameters may get
out of control
A single config hash
to show them all
A custom template
to use them
Application specific configs
THE PARAMETERS
DILEMMA
Saturday, August 24, 13
47. Options Hash: Setup
openssh/manifests/init.pp
class openssh (
[...]
$file_template = undef,
$options_hash = undef,
site/templates/openssh/sshd_config.erb
# File Managed by Puppet
[...]
Port %= scope.function_options_lookup(['Port','22']) %
PermitRootLogin %= scope.function_options_lookup(['PermitRootLogin','yes']) %
UsePAM %= scope.function_options_lookup(['UsePAM','yes']) %
[...]
* Function options_lookup currently in Example42's Puppi module
Alternative site/templates/openssh/sshd_config.erb
Port %= scope.lookupvar('openssh::options_hash')['Port'] ||='22' %
PermitRootLogin %= scope.lookupvar('openssh::options_hash')['PermitRootLogin'] ||='yes' %
UsePAM %= scope.lookupvar('openssh::options_hash')['UsePAM'] ||='yes' %
[...]
Saturday, August 24, 13
53.
Standards
A blog post*
Some discussions on
Puppet-Users
github.com/stdmod
Naming standards
for modules
parameters
Community driven
(draft 0.0.2)
* http://www.example42.com/?q=The_handy_Grail_of_Modules_Standards
Saturday, August 24, 13
68. stack?
We always use
stacks.
We need them to
make something
useful with modules.
What about:
Sharing?
Best practices?
Standardization?
Saturday, August 24, 13
70. Stacks - A Simple Sample
[...]
if $syslog_server {
rsyslog::config { 'logstash_stack':
content = template($syslog_config_template),
}
}
if $install_logstash {
class { 'logstash':
template = $logstash_config_template,
}
}
if $install_elasticsearch {
class { 'elasticsearch':
java_opts = $elasticsearch_java_opts,
template = $elasticsearch_config_template,
}
}
[...]
Saturday, August 24, 13
71. Stacks - Usage
On any host:
stack::logs { 'central':
syslog_server = 'syslog.example42.com',
}
On the Logstash (syslog) server:
stack::logs { 'central':
syslog_server = 'syslog.example42.com',
install_logstash = true,
elasticsearch_server = 'el.example42.com',
}
On the Elasticsearch server(s), with a custom configuration file:
stack::logs { 'central':
syslog_server = 'syslog.example42.com',
install_elasticsearch = true,
elasticsearch_server = 'el.example42.com',
elasticsearch_config_template = 'site/logs/elasticsearch.yml.erb',
}
On the Kibana server:
stack::logs { 'central':
syslog_server = 'syslog.example42.com',
install_kibana = true,
elasticsearch_server = 'el.example42.com',
}
Saturday, August 24, 13
72. The
Stacks
Logic
Stacks are local
Modules are shared
Higher level
interface
Integrate different
set of modules
Preserve modules
local change
Saturday, August 24, 13
73. How do we use Puppet today
Include classes
manifests/
site.pp
Set Parameters / Variables
Integration logic
Resources
ENC HIERA
SITE
MODULES
SHARED
MODULES
BAD
EDGE
Configuration files
manifests/
site.pp
ENC HIERA
manifests/
site.pp
BAD?
BAD?
BAD
SITE
MODULES
SITE
MODULES
SHARED
MODULES
SITE
MODULES
SHARED
MODULES
manifests/
site.pp
BAD?
ENC
BAD?
STACKS
STACKS
STACKS
Saturday, August 24, 13