I worked with puppet (< 0.25) back in 2008/2009. We were able to
deploy 200 servers from scratch and manage them. It worked fine.
I'm now with a new customer and I'm pushing Puppet (and I'm also back
to puppet on a side project).
We're considering Puppet 2.6 to manage RHEL/CentOS 5 or 6 hosts. I'm
"upgrading myself" to Puppet 2.6's new concepts and features.
Anyway consider this for the sake of argument:
- node server1.hostingcompanyAlpha.com
-- hosted on a dedicated server at provider Alpha
-- production
- node server2.hostingcompanyBeta.net
-- hosted on a dedicated server at provider Beta
-- production
- node staging.myprivatenetwork.priv
-- hosted on my customer's private network
-- staging/QA
- node dev.myprivatenetwork.priv
-- hosted on my customer's private network
-- development server
Those four nodes must host the same elements:
- Apache HTTPD with multiple VHosts
- PHP
- Extra software ...
There are a few differences between nodes:
- Servers don't have the same capabilities (CPU/Mem/bandwidth): we
need to tweak Apache's MaxClients settings on a per-host basis
- We need to tweak PHP : displaying errors on 'staging' and 'dev' but
hiding them on server1/server2 (ie: setting 'display_errors' to 'on'
or 'off' in php.ini)
- On development and staging/testing servers we need to change some of
the VHosts definitions: add extra serverAliases, etc ...
- server1, server2 and staging/dev must use different DNS servers (/
etc/resolv.conf) and RPM Mirrors (yumrepo{ })
I've read the following blog post:
http://puppetlabs.com/blog/the-problem-with-separating-data-from-puppet-code/
Back with puppet < 0.25, we'd use "global variables" (not even node
inheritance).
manifest/sites.pp had something like:
$envname = 'prod'
$envstr = ''
$dns_servers = [ '10.0.0.42', '10.10.1.42' ]
import "classes/*.pp"
node 'server1.hostingcompanyAlpha.com' {
$httpd_maxclients = 300
$yum_base = "http://mirrors.hostingcompanyAlpha.com/ftp.centos.org/"
$dns_servers = [ '1.2.3.4', '1.2.4.4' ] # Hosting Co.'s resolvers
include mywebserver
}
node 'server2.hostingcompanyBeta.net' {
$httpd_maxclients = 200
$yum_base = "http://repo.hostingcompanyBeta.net/centos/"
$dns_servers = [ '8.8.8.8.8' , '8.8.4.4' ]
include mywebserver
}
node 'staging.myprivatenetwork.priv' {
$httpd_maxclients = 50
$php_display_errors = 'on'
$envname = 'staging'
$envstr = 'stag'
include mywebserver
}
node 'dev.myprivatenetwork.priv' {
$httpd_maxclients = 20
$php_error_reporting = "E_ALL"
$php_display_errors = 'on'
$envname = 'dev'
$envstr = 'dev'
include mywebserver
}
manifests/classes/mywebserver.pp would contain somethine like this:
import "php"
import "httpd"
class mywebserver {
include centos # which would in turn include modules 'yum' and
'resolv'
include httpd
include php
include php::apc
define httpd::vhost { 'mysite' :
servername => "www.mysite.com",
documentroot => "/var/www/html/mysite.com",
}
}
modules/httpd/manifests/init.pp had:
# defaults
$httpd_maxclients = 150
$httpd_...
class httpd {
file { "/etc/httpd/conf/httpd.conf" :
content => template("httpd/httpd.conf.default.erb"); # which would
then use $httpd_maxclients
}
}
We also had a httpd::vhost($ip = "*", $port = 80, $servername,
$documentroot, ...) define which would write VHosts files based on the
following template:
<VirtualHost <%= ip %>:<%= port%>>
ServerName <%= servername %>
<% if envstr != '' -%>
ServerAlias <%= envstr %><%= servername %>
<% end -%>
<% if envname != 'prod' -%>
php_admin_value display_errors on
<% end -%>
...
</VirtualHost>
modules/yum/manifests/init.pp had:
# defaults
$yum_base = "http://myrepo.myprivatenetwork.priv/centos"
class yum {
yumrep { "os" :
baseurl = "${yum_base}/RPMS.os",
}
}
modules/php/manifests/init.pp:
php_memory_limit = "32M"
php_error_reporting = "..."
php_display_errors = "off"
and so on ... (huge list)
with php.ini.erb :
display_errors = <%= php_display_errors %>
error_reporting = <%= php_error_reporting %>
...
And so on ... If you haven't dozed off already, you get the idea. :-)
That way we could provide safe/sane default settings which could
easily be tweaked on a per-host or per-class basis.
Parameters were quite easy to track and were in the code (which is
stored in SVN). There might be some scoping problems from time to
time, I have to admit. But once we had our "pattern", things would be
smooth.
I do now have trouble understanding how I should proceed with Puppet
2.6 (and 2.7 in the future), if I'm to avoid global variables.
Parameterized class are seemingly not an option and, from what I
understand and read, are more of an alternative to class inheritance
(Nigel Kersten's comment on issue #13537): you don't need to inherit
from a parent class if you want to tweak some of the ressources, you
could just pass parameters to your class in the first place.
Indeed I do not see how parameterized classes would help me get such
flexibility. Or I'd have to "pass down" all the variables I need from
my node/host down to every class. Cumbersome, at best.
Parameterized class a good for "coarse grained" tuning, but not "per
host" tweaks" on a variety of items.
Next option is an External Node Classifier which I would have to
develop and maintain to fetch/rewrite/generate/whatever variables I
need. I could probably get what I want but I'd end up having an extra
tool to maintain (and train people to use).
A "middle of the road" option would be Hiera and create a hierarchy
base on the '$hostname' fact (yaml backed for 'custom' values, and
probably a puppet backed to fetch the defaults ? I see that you can
also pass a default value to hiera()) . I assume that's the way to go.
Well... I'm a bit puzzled by all this. :-)
I'd like some input from you guys (and gals !).
I'll try and install Hiera (nice, more stuff I need to package !)
anyway. By the way what's the target version (2.8 ?) for Hiera's
integration into Puppet ?
Thanks !
G.
--
You received this message because you are subscribed to the Google Groups "Puppet Users" group.
To post to this group, send email to puppet-users@googlegroups.com.
To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.