SlideShare a Scribd company logo
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….
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….
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…
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
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/
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/
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….
Questions
Links
•   http://puppetlabs.com
•   http://puppetlabs.com/blog/design-pattern-for-dealing-with-data/
•   http://devopswire.com/patterns/environment-abstraction
•   http://subversion.apache.org
•   http://www.redmine.org
•   http://vagrantup.com
•   http://git-scm.com

More Related Content

What's hot

zookeeperProgrammers
zookeeperProgrammerszookeeperProgrammers
zookeeperProgrammers
Hiroshi Ono
 
Python Deployment with Fabric
Python Deployment with FabricPython Deployment with Fabric
Python Deployment with Fabric
andymccurdy
 

What's hot (20)

zookeeperProgrammers
zookeeperProgrammerszookeeperProgrammers
zookeeperProgrammers
 
PuppetCamp SEA 1 - Use of Puppet
PuppetCamp SEA 1 - Use of PuppetPuppetCamp SEA 1 - Use of Puppet
PuppetCamp SEA 1 - Use of Puppet
 
Running High Performance and Fault Tolerant Elasticsearch Clusters on Docker
Running High Performance and Fault Tolerant Elasticsearch Clusters on DockerRunning High Performance and Fault Tolerant Elasticsearch Clusters on Docker
Running High Performance and Fault Tolerant Elasticsearch Clusters on Docker
 
Puppet for dummies - ZendCon 2011 Edition
Puppet for dummies - ZendCon 2011 EditionPuppet for dummies - ZendCon 2011 Edition
Puppet for dummies - ZendCon 2011 Edition
 
Ansible 實戰:top down 觀點
Ansible 實戰:top down 觀點Ansible 實戰:top down 觀點
Ansible 實戰:top down 觀點
 
Getting started with Ansible
Getting started with AnsibleGetting started with Ansible
Getting started with Ansible
 
Ansible : what's ansible & use case by REX
Ansible :  what's ansible & use case by REXAnsible :  what's ansible & use case by REX
Ansible : what's ansible & use case by REX
 
Managing Puppet using MCollective
Managing Puppet using MCollectiveManaging Puppet using MCollective
Managing Puppet using MCollective
 
Python Deployment with Fabric
Python Deployment with FabricPython Deployment with Fabric
Python Deployment with Fabric
 
Vagrant for real codemotion (moar tips! ;-))
Vagrant for real codemotion (moar tips! ;-))Vagrant for real codemotion (moar tips! ;-))
Vagrant for real codemotion (moar tips! ;-))
 
Ansible not only for Dummies
Ansible not only for DummiesAnsible not only for Dummies
Ansible not only for Dummies
 
How to implement a gdpr solution in a cloudera architecture
How to implement a gdpr solution in a cloudera architectureHow to implement a gdpr solution in a cloudera architecture
How to implement a gdpr solution in a cloudera architecture
 
Puppet Camp DC 2014: Managing Puppet with MCollective
Puppet Camp DC 2014: Managing Puppet with MCollectivePuppet Camp DC 2014: Managing Puppet with MCollective
Puppet Camp DC 2014: Managing Puppet with MCollective
 
More tips n tricks
More tips n tricksMore tips n tricks
More tips n tricks
 
Incrementalism: An Industrial Strategy For Adopting Modern Automation
Incrementalism: An Industrial Strategy For Adopting Modern AutomationIncrementalism: An Industrial Strategy For Adopting Modern Automation
Incrementalism: An Industrial Strategy For Adopting Modern Automation
 
Hacking ansible
Hacking ansibleHacking ansible
Hacking ansible
 
Ansible leveraging 2.0
Ansible leveraging 2.0Ansible leveraging 2.0
Ansible leveraging 2.0
 
Modern tooling to assist with developing applications on FreeBSD
Modern tooling to assist with developing applications on FreeBSDModern tooling to assist with developing applications on FreeBSD
Modern tooling to assist with developing applications on FreeBSD
 
How to create a multi tenancy for an interactive data analysis
How to create a multi tenancy for an interactive data analysisHow to create a multi tenancy for an interactive data analysis
How to create a multi tenancy for an interactive data analysis
 
Ansible loves Python, Python Philadelphia meetup
Ansible loves Python, Python Philadelphia meetupAnsible loves Python, Python Philadelphia meetup
Ansible loves Python, Python Philadelphia meetup
 

Similar to Fixing Growing Pains With Puppet Data Patterns

Puppet atbazaarvoice
Puppet atbazaarvoicePuppet atbazaarvoice
Puppet atbazaarvoice
Dave Barcelo
 
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
Carlos Sanchez
 
Stack kicker devopsdays-london-2013
Stack kicker devopsdays-london-2013Stack kicker devopsdays-london-2013
Stack kicker devopsdays-london-2013
Simon McCartney
 
Puppetpreso
PuppetpresoPuppetpreso
Puppetpreso
ke4qqq
 
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
Carlos Sanchez
 

Similar to Fixing Growing Pains With Puppet Data Patterns (20)

Practical Chef and Capistrano for Your Rails App
Practical Chef and Capistrano for Your Rails AppPractical Chef and Capistrano for Your Rails App
Practical Chef and Capistrano for Your Rails App
 
Burn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websitesBurn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websites
 
Puppet atbazaarvoice
Puppet atbazaarvoicePuppet atbazaarvoice
Puppet atbazaarvoice
 
infra-as-code
infra-as-codeinfra-as-code
infra-as-code
 
Harmonious Development: Via Vagrant and Puppet
Harmonious Development: Via Vagrant and PuppetHarmonious Development: Via Vagrant and Puppet
Harmonious Development: Via Vagrant and Puppet
 
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
 
Puppet at Bazaarvoice
Puppet at BazaarvoicePuppet at Bazaarvoice
Puppet at Bazaarvoice
 
Stack kicker devopsdays-london-2013
Stack kicker devopsdays-london-2013Stack kicker devopsdays-london-2013
Stack kicker devopsdays-london-2013
 
From Dev to DevOps
From Dev to DevOpsFrom Dev to DevOps
From Dev to DevOps
 
Integrating icinga2 and the HashiCorp suite
Integrating icinga2 and the HashiCorp suiteIntegrating icinga2 and the HashiCorp suite
Integrating icinga2 and the HashiCorp suite
 
Puppet
PuppetPuppet
Puppet
 
Ruby For Startups
Ruby For StartupsRuby For Startups
Ruby For Startups
 
Our Puppet Story – Patterns and Learnings (sage@guug, March 2014)
Our Puppet Story – Patterns and Learnings (sage@guug, March 2014)Our Puppet Story – Patterns and Learnings (sage@guug, March 2014)
Our Puppet Story – Patterns and Learnings (sage@guug, March 2014)
 
How I hack on puppet modules
How I hack on puppet modulesHow I hack on puppet modules
How I hack on puppet modules
 
Beaker: Automated, Cloud-Based Acceptance Testing - PuppetConf 2014
Beaker: Automated, Cloud-Based Acceptance Testing - PuppetConf 2014Beaker: Automated, Cloud-Based Acceptance Testing - PuppetConf 2014
Beaker: Automated, Cloud-Based Acceptance Testing - PuppetConf 2014
 
EC2
EC2EC2
EC2
 
Infrastructure as code - Python Saati #36
Infrastructure as code - Python Saati #36Infrastructure as code - Python Saati #36
Infrastructure as code - Python Saati #36
 
Puppetpreso
PuppetpresoPuppetpreso
Puppetpreso
 
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
 
Our Puppet Story (Linuxtag 2014)
Our Puppet Story (Linuxtag 2014)Our Puppet Story (Linuxtag 2014)
Our Puppet Story (Linuxtag 2014)
 

Fixing Growing Pains With Puppet Data Patterns

  • 1.
  • 2.
  • 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….
  • 4.
  • 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….
  • 6.
  • 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…
  • 8.
  • 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
  • 10.
  • 11.
  • 12.
  • 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/
  • 15.
  • 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….
  • 17.
  • 19. Links • http://puppetlabs.com • http://puppetlabs.com/blog/design-pattern-for-dealing-with-data/ • http://devopswire.com/patterns/environment-abstraction • http://subversion.apache.org • http://www.redmine.org • http://vagrantup.com • http://git-scm.com