Infrastructure as code
   with Puppet and
  Apache CloudStack
  David Nalley <david@gnsa.us> @ke4qqq
#whoami

• Recovering sysadmin
• Apache CloudStack Committer
• Designer of ugly slides
To set the stage...

• Apache CloudStack is...
 • an open source IaaS platform
 • proven in production at massive scale
 • awesome
Gorgeous UI
Decent API


• EC2 or native
•   http://incubator.apache.org/cloudstack/docs/api
So IaaS has several problems
         for puppet
People provision stuff


Often not ops folks
Often not intimately familiar with intricacies
Baseline is important; but...
Classification


Problem: We spin up, dynamically, 1-500 VMs at
 any given time - how do we decide what
 configurations apply.
Classification


The wrong way - dedicated images for each
 purpose
Classification
editing nodes.pp


node 'foo-356.cloud.com' {
 include httpd
}
Classification
globbing


node 'foo*' {
 include httpd
}
Classification
Everything is default


node 'default' {
 include httpd
}
Classification


External node classifier
Classification
Facts
class base {
 case $::fact {
   'httpd': {
     include httpd
    }
   'otherrole': {
     include nginx
   }
  }
 }
One solution

During instance provisioning define metadata.
Custom fact for that metadata
Case statement based on that fact
Example metadata

role=webserver
location=datacenter1
environment=production
Corresponding
class base {
             manifest
case $::fact {
  'webserver': {
    include httpd
   }
  'database': {
    include postgresql
  }
 }
}
Links, et al

Fact:
 http://s.apache.org/acs_userdata
Blog with details:
  http://s.apache.org/acs_userdata2
Video is here, go watch it


• I only have 45 minutes - so can't delve into
  everything, you should watch the video- it’s
  great.
• http://youtu.be/c8YWctfOpwo
And then there was a
              knife.....plugin

• So the folks at Edmunds.com wrote a knife
    plugin for CloudStack.
• The knife plugin had the ability to define an
    application stack, potentially hundreds of
    nodes, that are interrelated, and provision
    them with a single knife command.
•   https://github.com/cloudstack-extras/knife-cloudstack
Deploying a machine with knife



knife cs server create
"name": "hadoop_cluster_a",
"description": "A small hadoop cluster with hbase",
"version": "1.0",
"environment": "production",
"servers": [
  {
     "name": "zookeeper-a, zookeeper-b, zookeeper-c",
     "description": "Zookeeper nodes",
     "template": "rhel-5.6-base",
     "service": "small",
     "port_rules": "2181",
     "run_list": "role[cluster_a], role[zookeeper_server]",
     "actions": [
       { "knife_ssh": ["role:zookeeper_server", "sudo chef-client"] }
     ]
  },
  {
     "name": "hadoop-master",
     "description": "Hadoop master node",
     "template": "rhel-5.6-base",
     "service": "large",
     "networks": "app-net, storage-net",
     "port_rules": "50070, 50030, 60010",
     "run_list": "role[cluster_a], role[hadoop_master], role[hbase_master]"
  },
  {
     "name": "hadoop-worker-a hadoop-worker-b hadoop-worker-c",
     "description": "Hadoop worker nodes",
     "template": "rhel-5.6-base",
     "service": "medium",
     "port_rules": "50075, 50060, 60030",
     "run_list": "role[cluster_a], role[hadoop_worker], role[hbase_regionserver]",
     "actions": [
       { "knife_ssh": ["role:hadoop_master", "sudo chef-client"] },
       { "http_request": "http://${hadoop-master}:50070/index.jsp" }
     ]
  }
Deploy that with...

knife cs stack create hadoop_cluster_a
I was jealous...
Then at FOSDEM 2012

• CloudStack user shows me Puppet types
    and resources for OpenNebula.
•   https://puppetlabs.com/blog/puppetizing-opennebula/


• They indicated they wanted this
    awesomeness for CloudStack....
Why???
•   They wanted to define each of their application
    stacks in puppet, so that not only the
    configuration of software on the machine, but
    the machines themselves would be configured
    by Puppet.
•   Automated deployment of test environments
    that are exactly the same
•   Really gets outside of machine configuration to
    entire infrastructure configuration
...and then at
                PuppetConf
• There was Google Compute Engine types
    and resources for Puppet.
• Dan Bode gave a presentation showing off
    the work he had done... that presentation is
    worth seeing...
•   http://www.slideshare.net/bodepd/google-compute-presentation-puppet-conf
So then for Christmas...


• puppet types and providers arrived -
    courtesy of Dan Bode
•   https://github.com/bodepd/cloudstack_resources
So how does this work

cloudstack_instance { 'foo1':
  ensure   => present,
  flavor  => 'Small Instance',
  zone    => 'FMT-ACS-001',
  image    => 'CentOS 5.6(64-bit) no GUI (XenServer)',
  network => 'puppetlabs-network',
  # domain
  # account
  # hostname
  }
A simple stack
class my_web_stack {
  cloudstack_instance { 'foo4':
        ensure => present,
        group => 'role=apache',
     }
     cloudstack_instance { 'foo5':
        ensure => present,
        group => 'role=db',
     }
  }
Setting defaults
Cloudstack_instance {
     image => 'CentOS 6.3',
     flavor => 'M1.medium',
     zone => 'San Jose',
     network => 'davids_net',
     keypair => 'david_keys',
  }
  cloudstack_instance {
     ensure => $::ensure,
     group => 'role=db',
  }
Define all your
infrastructure
Resources/contact
Me: David Nalley <david@gnsa.us> @ke4qqq
CloudStack: http://cloudstack.org
  cloudstack-users@incubator.apache.org
cloudstack_resources:
 https://github.com/bodepd/cloudstack_resources

Jason Hancock Vids
   http://youtu.be/c8YWctfOpwo
   http://youtu.be/8W0BqCmNZQQ

Puppetpreso

  • 1.
    Infrastructure as code with Puppet and Apache CloudStack David Nalley <david@gnsa.us> @ke4qqq
  • 2.
    #whoami • Recovering sysadmin •Apache CloudStack Committer • Designer of ugly slides
  • 3.
    To set thestage... • Apache CloudStack is... • an open source IaaS platform • proven in production at massive scale • awesome
  • 4.
  • 5.
    Decent API • EC2or native • http://incubator.apache.org/cloudstack/docs/api
  • 6.
    So IaaS hasseveral problems for puppet
  • 7.
    People provision stuff Oftennot ops folks Often not intimately familiar with intricacies
  • 8.
  • 9.
    Classification Problem: We spinup, dynamically, 1-500 VMs at any given time - how do we decide what configurations apply.
  • 10.
    Classification The wrong way- dedicated images for each purpose
  • 11.
  • 12.
  • 13.
    Classification Everything is default node'default' { include httpd }
  • 14.
  • 15.
    Classification Facts class base { case $::fact { 'httpd': { include httpd } 'otherrole': { include nginx } } }
  • 16.
    One solution During instanceprovisioning define metadata. Custom fact for that metadata Case statement based on that fact
  • 17.
  • 18.
    Corresponding class base { manifest case $::fact { 'webserver': { include httpd } 'database': { include postgresql } } }
  • 19.
    Links, et al Fact: http://s.apache.org/acs_userdata Blog with details: http://s.apache.org/acs_userdata2
  • 20.
    Video is here,go watch it • I only have 45 minutes - so can't delve into everything, you should watch the video- it’s great. • http://youtu.be/c8YWctfOpwo
  • 21.
    And then therewas a knife.....plugin • So the folks at Edmunds.com wrote a knife plugin for CloudStack. • The knife plugin had the ability to define an application stack, potentially hundreds of nodes, that are interrelated, and provision them with a single knife command. • https://github.com/cloudstack-extras/knife-cloudstack
  • 22.
    Deploying a machinewith knife knife cs server create
  • 23.
    "name": "hadoop_cluster_a", "description": "Asmall hadoop cluster with hbase", "version": "1.0", "environment": "production", "servers": [ { "name": "zookeeper-a, zookeeper-b, zookeeper-c", "description": "Zookeeper nodes", "template": "rhel-5.6-base", "service": "small", "port_rules": "2181", "run_list": "role[cluster_a], role[zookeeper_server]", "actions": [ { "knife_ssh": ["role:zookeeper_server", "sudo chef-client"] } ] }, { "name": "hadoop-master", "description": "Hadoop master node", "template": "rhel-5.6-base", "service": "large", "networks": "app-net, storage-net", "port_rules": "50070, 50030, 60010", "run_list": "role[cluster_a], role[hadoop_master], role[hbase_master]" }, { "name": "hadoop-worker-a hadoop-worker-b hadoop-worker-c", "description": "Hadoop worker nodes", "template": "rhel-5.6-base", "service": "medium", "port_rules": "50075, 50060, 60030", "run_list": "role[cluster_a], role[hadoop_worker], role[hbase_regionserver]", "actions": [ { "knife_ssh": ["role:hadoop_master", "sudo chef-client"] }, { "http_request": "http://${hadoop-master}:50070/index.jsp" } ] }
  • 24.
    Deploy that with... knifecs stack create hadoop_cluster_a
  • 25.
  • 26.
    Then at FOSDEM2012 • CloudStack user shows me Puppet types and resources for OpenNebula. • https://puppetlabs.com/blog/puppetizing-opennebula/ • They indicated they wanted this awesomeness for CloudStack....
  • 27.
    Why??? • They wanted to define each of their application stacks in puppet, so that not only the configuration of software on the machine, but the machines themselves would be configured by Puppet. • Automated deployment of test environments that are exactly the same • Really gets outside of machine configuration to entire infrastructure configuration
  • 28.
    ...and then at PuppetConf • There was Google Compute Engine types and resources for Puppet. • Dan Bode gave a presentation showing off the work he had done... that presentation is worth seeing... • http://www.slideshare.net/bodepd/google-compute-presentation-puppet-conf
  • 30.
    So then forChristmas... • puppet types and providers arrived - courtesy of Dan Bode • https://github.com/bodepd/cloudstack_resources
  • 31.
    So how doesthis work cloudstack_instance { 'foo1': ensure => present, flavor => 'Small Instance', zone => 'FMT-ACS-001', image => 'CentOS 5.6(64-bit) no GUI (XenServer)', network => 'puppetlabs-network', # domain # account # hostname }
  • 32.
    A simple stack classmy_web_stack { cloudstack_instance { 'foo4': ensure => present, group => 'role=apache', } cloudstack_instance { 'foo5': ensure => present, group => 'role=db', } }
  • 33.
    Setting defaults Cloudstack_instance { image => 'CentOS 6.3', flavor => 'M1.medium', zone => 'San Jose', network => 'davids_net', keypair => 'david_keys', } cloudstack_instance { ensure => $::ensure, group => 'role=db', }
  • 34.
  • 35.
    Resources/contact Me: David Nalley<david@gnsa.us> @ke4qqq CloudStack: http://cloudstack.org cloudstack-users@incubator.apache.org cloudstack_resources: https://github.com/bodepd/cloudstack_resources Jason Hancock Vids http://youtu.be/c8YWctfOpwo http://youtu.be/8W0BqCmNZQQ