3. Life is was good…
• We started out using puppet and everything
was good:
– That Puppet, Redmine & Subversion stuff we put
in is Da Bomb!
• Create a Redmine ticket for each request
• Hack around in puppet
• Commit using Redmine tag
• Auditability and trace ability - who did what and why
– It was all good until….
5. Multiple Environments!
• We created multiple environments
– Development
– QA
– Integration
• All on the same network so no problem!
• Easily sorted with a little RegEx action
• Problem sorted, err well sort of until….
7. Disconnected Networks!
• Then we created multiple environments in different locations with no direct
network access between each, so things got a little tricky:
ssh env-1.jumphost.office
svn export puppet-module
scp -r puppet-module colo1-puppetmaster.colo1:.
ssh colo1-puppet.master
rsync -av puppet-module /etc/puppet/modules/
vi /etc/puppet/modules/puppet-module/manifest/init.pp #customise to env
vi /etc/puppet/manifest/nodes.pp #enable new module functionality
pushd /etc/puppet
svn ci -m "Feature #404 - New version of puppet-module installed“
• We did this up to a point until…
9. SYNCHRONIZATION PAIN!
• Keeping multiple puppet environments in sync was
becoming a serious pain:
Environment 1.
svn export code
tar code
copy code
untar code
rsync code to newcode location
edit code like crazy till it works
svn add code
svn commit code
Environment 2. Rinse and repeat
Environment X. Rinse and repeat
13. Puppet Common Data Pattern
class common{
include common::data
}
class common::data {
# ensure that the $env variable has been set
# valid values are: 'vagrant', 'development', 'qa', 'staging', 'integration',
'training', 'production'
if ! ( $env in [ 'vagrant', 'development', 'qa', 'staging', 'integration',
'training', 'production' ] ) {
fail("common::data env must be one of: 'vagrant', 'development',
'qa', 'staging', 'integration', 'training', 'production'")
}
# environment specific data
case $env {
'vagrant': {
$domainname = "uncommonsense.local"
$searchpath = ["uncommonsense.local"]
$nameservers = ["192.168.1.10", "192.168.20", "8.8.8.8", "8.8.4.4"]
$ntpServerList = [ '0.uk.pool.ntp.org', '1.uk.pool.ntp.org' ]
$ldap = {host => ‘ldap.uncommonsense.local', port => ‘3389', baseDN =>
'dc=uncommonsense,dc=bogus', adminDN => 'cn=ldapmeister,dc=uncommonsense,dc=bogus',
password => ‘myspoonistoobig'}
} # vagrant:
http://puppetlabs.com/blog/design-pattern-for-dealing-with-data/
14. Leveraging the Data Pattern
Nodes.pp:
Nodes.pp:
node ‘ldapserver.dev.uncommonsense.local’ {
$env = ‘development’
include common
include localenvironment
include openldap
include ldap::server
}
Openldap-common.pp
Openldap-common.pp:
$basedn = $common::data::ldap[baseDN]
$admindn = $common::data::ldap[adminDN]
$password = $common::data::ldap[password]
class openldap::common {
case $common::data::ldap[baseDN] {
"": { fail('$common::data::ldap[baseDN] not set for environment') }
}
case $common::data::ldap[adminDN] {
"": { fail('$common::data::ldap[adminDN] not set for environment') }
}
case $common::data::ldap[password] {
"": { fail('$common::data::ldap[password] not set for environment') }
}
}
http://puppetlabs.com/blog/design-pattern-for-dealing-with-data/
16. Common Code Base
• We picked a master and stuck with it (i.e. the one
attached to Redmine)
• All changes made and tracked within one
environment
• Other Environments refreshed as needed as a
complete replacement copy no more ad-hoc edits
• Bliss!
• But what about git? Doesn’t git make this is much
easier because it’s a DVCS? Unfortunately….