Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
Less talk, more rock

Puppet
                ALM Connect 2013
deepak
giridharagopal
deepak@puppetlabs.com
@grim_radical [github twitter freenode]
Let’s talk about...
Puppet: Eclipsecon ALM 2013
Immutability
  is great!
Puppet: Eclipsecon ALM 2013
Classes should be immutable unless
there's a very good reason to make




                                       -- Joshua Bloch, “Effective Java”
them mutable....If a class cannot be
made immutable, limit its mutability
as much as possible.
Immutability allows
for invariants, which
help you reason about
correctness
Immutability prevents
spooky action at a
distance
Immutability fosters
modular, composable
abstractions
(this shouldn’t be
  a tough sell to
   developers)
That’s great for
develoment, but how
 about operations?
Immutability for
infrastructure?
Because operations is in the
same boat as development
Everyone who’s got
their app running on
a fleet of servers has
experienced spooky
action at a distance
Known, good state is
critical for reliable
upgrades
A lack of predictability
in your systems
ruins automation and
abstraction
Puppet: Eclipsecon ALM 2013
The problem is that:

         Systems are inherently
                       mutable!

But ideally:

      Systems should behave as
           though they weren’t!
façade of immutability. Immutability
Computer systems are in many ways
open systems, providing the keys to
the vault if one is so inclined to grab
them. But in order to foster an air of
immutability in our own systems,
it's of utmost importance to create a
façade of immutability. Immutability




                                          -- The Joy of Clojure
requires that we layer over and
abstract the parts of our system that
provide unrestrained mutability.
Puppet: Eclipsecon ALM 2013
Describe how you’d
like your systems to
look, and Puppet
does all the hard
work for you!
Example: Inquire
a simple service for
exposing system
metrics
Example: Inquire
http://box/inquire/disk_usage
install apache
   create apache user
create apache config file
   cgi script for “df -h”
 correct perms for script
       start apache
restart if config changes!
Once you’ve got a
spec for your service,
you can see if a given
machine is up to code
• Packages:                  • Data files:
    • apache                    • /var/www/cgi-bin/
• Users:                           disk_usage
    • apache                      • executable, owned
                                     by apache
• Config files:
    • apache’s httpd.conf         • does “df -h”
• Services:
    • apache should be
      running
    • restart if config file
      changes
class inquire_server {
  package { apache: ensure => installed }
  user     { apache: uid => 1000, shell => "/bin/false" }
  service { apache: ensure => running }
 
  file {
    "/etc/httpd/httpd.conf":
       owner => root,
       mode => 644,
       source => "puppet://master-server/httpd.conf",
       notify => Service[apache];
 
    "/var/www/cgi-bin/disk_usage.sh":
       owner => apache,
       mode => 755,
       content => "/usr/bin/df -h";
  }
}
class inquire_bootstrap {
  package { apache: ensure => installed }
  user     { apache: uid => 1000, shell => "/bin/false" }
  service { apache: ensure => running }
 
  file {
    "/etc/httpd/httpd.conf":
       owner => root,
       mode => 644,
       source => "puppet://master-server/httpd.conf",
       notify => Service[apache];
  }
}
 
class inquire_disk_usage {
  include inquire_bootstrap
  file {
    "/var/www/cgi-bin/disk_usage.sh":
       owner => apache,
       mode => 755,
       content => "/usr/bin/df -h";
  }
}
class inquire_bootstrap {
  package { apache: ensure => installed }
  user     { apache: uid => 1000, shell => "/bin/false" }
  service { apache: ensure => running }
 
  file {
    "/etc/httpd/httpd.conf":
       owner => root,
       mode => 644,
       source => "puppet://master-server/httpd.conf",
       notify => Service[apache];
  }
}
 
define inquiry($command) {
  include inquire_bootstrap
  file {
    "/var/www/cgi-bin/$name.sh":
       owner => apache,
       mode => 755,
       content => $command;
  }
}
node “appserver.mydomain.com”   {
  inquiry {
    "disk-usage": command =>    "df -h";
    "processes":   command =>   "ps aux";
    "kernel-info": command =>   "uname -a";
  }
}
node “appserver1.mydomain.com” {
  inquiry {
    "disk-usage": command => "df -h";
    "processes":   command => "ps aux";
    "kernel-info": command => "uname -a";
  }
}

node “appserver2.mydomain.com” {
  inquiry {
    "disk-usage": command => "df -h";
    "processes":   command => "ps aux";
    "kernel-info": command => "uname -a";
  }
}
class instrumentation {
  inquiry {
    "disk-usage": command => "df -h";
    "processes":   command => "ps aux";
    "kernel-info": command => "uname -a";
  }
}

node “appserver1.mydomain.com” {
  include instrumentation
}

node “appserver2.mydomain.com” {
  include instrumentation
}
Rich set of primitives,
and make your own.
Can use existing
modules and
abstractions, and
make your own.
Puppet: Eclipsecon ALM 2013
Puppet: Eclipsecon ALM 2013
Puppet: Eclipsecon ALM 2013
Puppet: Eclipsecon ALM 2013
netmask_lo: 255.0.0.0               ipaddress: 172.16.245.128
  augeasversion: 0.10.0               processor0: Intel(R) Core(TM)
  fqdn: pe-debian6.localdomain      i7-2635QM CPU @ 2.00GHz
  manufacturer: "VMware, Inc."        lsbdistrelease: 6.0.2
  processorcount: "1"                 uniqueid: 007f0101
  productname: VMware Virtual         hardwaremodel: i686
Platform                              kernelversion: 2.6.32
  physicalprocessorcount: 1           operatingsystem: Debian
  facterversion: 1.6.7                architecture: i386
  boardproductname: 440BX Desktop     lsbdistdescription: Debian GNU/
Reference Platform                  Linux 6.0.2 (squeeze)
  kernelmajversion: "2.6"             lsbmajdistrelease: "6"
  hardwareisa: unknown                interfaces: "eth0,lo"
  timezone: PDT                       ipaddress_lo: 127.0.0.1
  puppetversion: 2.7.12 (Puppet       uptime_days: 0
Enterprise 2.5.1)                     lsbdistid: Debian
  lsbdistcodename: squeeze            rubysitedir: /opt/puppet/lib/
  is_virtual: "true"                site_ruby/1.8
  operatingsystemrelease: 6.0.2       rubyversion: 1.8.7
  virtual: vmware                     osfamily: Debian
  type: Other                         memorytotal: &id001 502.57 MB
  domain: localdomain                 memorysize: *id001
  hostname: pe-debian6                boardmanufacturer: Intel
  selinux: "false"                  Corporation
  kernel: Linux                       path: /usr/local/sbin:/usr/
Puppet: Eclipsecon ALM 2013
Puppet: Eclipsecon ALM 2013
file { “/etc/issue”:
  content => “Got an issue? Here’s a tissue!”,
}

file { “/etc/motd”:
  content => template(“Welcome to $hostname!”),
}
file { "/etc/sudoers":
  owner => root,
  group => root,
  mode   => 440,
  source => "puppet:///modules/sudo/sudoers"
}
class ntp {
    package { 'ntp':
      ensure => installed,
    }

    service { 'ntpd':
      ensure    => running,
      enable    => true,
      subscribe => File['/etc/ntp.conf'],
    }

    file { '/etc/ntp.conf':
      ensure => file,
      require => Package['ntp'],
      source => "puppet:///modules/ntp/ntp.conf",
    }
}
node “webserver.mydomain.com” {
  include ntp
}

node “appserver.mydomain.com” {
  include ntp
}

node “database.mydomain.com” {
  include ntp
}
class ssh {

    @@sshkey { $hostname:
      type => dsa,
      key => $sshdsakey
    }

    Sshkey <<| |>>

}
Puppet: Eclipsecon ALM 2013
Puppet: Eclipsecon ALM 2013
File “/tmp/foo/bar”
   User “deepak”
   Dir “/tmp/foo”
    Dir “/tmp”
Dir “/tmp”    User “deepak”

      Dir “/tmp/foo”


   File “/tmp/foo/bar”
Dir “/tmp”    User “deepak”

      Dir “/tmp/foo”


   File “/tmp/foo/bar”
Puppet: Eclipsecon ALM 2013
Puppet: Eclipsecon ALM 2013
Puppet: Eclipsecon ALM 2013
Puppet: Eclipsecon ALM 2013
package { 'ntp':
  ensure => installed,
}

service { 'ntpd':
  ensure    => running,
  enable    => true,
  subscribe => File['/etc/ntp.conf'],
}

file { '/etc/ntp.conf':
  ensure => file,
  require => Package['ntp'],
  source => "puppet:///modules/ntp/ntp.conf",
}
package { 'ntp':
  ensure => installed,
}

service { 'ntpd':
  ensure    => running,
  enable    => true,
  subscribe => File['/etc/ntp.conf'],
}

file { '/etc/ntp.conf':
  ensure => file,
  require => Package['ntp'],
  source => "puppet:///modules/ntp/ntp.conf",
}
package { 'ntp':
  ensure => installed,
}

service { 'ntpd':
  ensure    => running,
  enable    => true,
  subscribe => File['/etc/ntp.conf'],
}

file { '/etc/ntp.conf':
  ensure => file,
  require => Package['ntp'],
  source => "puppet:///modules/ntp/ntp.conf",
}
package { 'ntp':
  ensure => installed,
}

service { 'ntpd':
  ensure    => running,
  enable    => true,
  subscribe => File['/etc/ntp.conf'],
}

file { '/etc/ntp.conf':
  ensure => file,
  require => Package['ntp'],
  source => "puppet:///modules/ntp/ntp.conf",
}
Puppet: Eclipsecon ALM 2013
Puppet: Eclipsecon ALM 2013
Puppet: Eclipsecon ALM 2013
Idempotent, and
only does what’s
necessary
Compensates for the
inherent mutability
of systems
Combats spooky
action at a distance
with automatic
repair
Brings predictability
to your systems
A foundation of
predictability and
reliability lets you
perform higher-level
operations on your
infrastructure
Code all the way down
Software-defined
infrastructure is...just
software.
Infrastructure as
code is...just code.
Thus, you can treat it
like the other code in
your application
Scary, but liberating!
Maintaining the
state of your systems
is the foundation
upon which
everything rests
Start small, and start
somewhere. :)
deepak
giridharagopal
deepak@puppetlabs.com
@grim_radical [github twitter freenode]


        We’re hiring!

More Related Content

Puppet: Eclipsecon ALM 2013

  • 1. Less talk, more rock Puppet ALM Connect 2013
  • 7. Classes should be immutable unless there's a very good reason to make -- Joshua Bloch, “Effective Java” them mutable....If a class cannot be made immutable, limit its mutability as much as possible.
  • 8. Immutability allows for invariants, which help you reason about correctness
  • 11. (this shouldn’t be a tough sell to developers)
  • 12. That’s great for develoment, but how about operations?
  • 13. Immutability for infrastructure? Because operations is in the same boat as development
  • 14. Everyone who’s got their app running on a fleet of servers has experienced spooky action at a distance
  • 15. Known, good state is critical for reliable upgrades
  • 16. A lack of predictability in your systems ruins automation and abstraction
  • 18. The problem is that: Systems are inherently mutable! But ideally: Systems should behave as though they weren’t!
  • 19. façade of immutability. Immutability
  • 20. Computer systems are in many ways open systems, providing the keys to the vault if one is so inclined to grab them. But in order to foster an air of immutability in our own systems, it's of utmost importance to create a façade of immutability. Immutability -- The Joy of Clojure requires that we layer over and abstract the parts of our system that provide unrestrained mutability.
  • 22. Describe how you’d like your systems to look, and Puppet does all the hard work for you!
  • 23. Example: Inquire a simple service for exposing system metrics
  • 25. install apache create apache user create apache config file cgi script for “df -h” correct perms for script start apache restart if config changes!
  • 26. Once you’ve got a spec for your service, you can see if a given machine is up to code
  • 27. • Packages: • Data files: • apache • /var/www/cgi-bin/ • Users: disk_usage • apache • executable, owned by apache • Config files: • apache’s httpd.conf • does “df -h” • Services: • apache should be running • restart if config file changes
  • 28. class inquire_server { package { apache: ensure => installed } user { apache: uid => 1000, shell => "/bin/false" } service { apache: ensure => running }   file { "/etc/httpd/httpd.conf": owner => root, mode => 644, source => "puppet://master-server/httpd.conf", notify => Service[apache];   "/var/www/cgi-bin/disk_usage.sh": owner => apache, mode => 755, content => "/usr/bin/df -h"; } }
  • 29. class inquire_bootstrap { package { apache: ensure => installed } user { apache: uid => 1000, shell => "/bin/false" } service { apache: ensure => running }   file { "/etc/httpd/httpd.conf": owner => root, mode => 644, source => "puppet://master-server/httpd.conf", notify => Service[apache]; } }   class inquire_disk_usage { include inquire_bootstrap file { "/var/www/cgi-bin/disk_usage.sh": owner => apache, mode => 755, content => "/usr/bin/df -h"; } }
  • 30. class inquire_bootstrap { package { apache: ensure => installed } user { apache: uid => 1000, shell => "/bin/false" } service { apache: ensure => running }   file { "/etc/httpd/httpd.conf": owner => root, mode => 644, source => "puppet://master-server/httpd.conf", notify => Service[apache]; } }   define inquiry($command) { include inquire_bootstrap file { "/var/www/cgi-bin/$name.sh": owner => apache, mode => 755, content => $command; } }
  • 31. node “appserver.mydomain.com” { inquiry { "disk-usage": command => "df -h"; "processes": command => "ps aux"; "kernel-info": command => "uname -a"; } }
  • 32. node “appserver1.mydomain.com” { inquiry { "disk-usage": command => "df -h"; "processes": command => "ps aux"; "kernel-info": command => "uname -a"; } } node “appserver2.mydomain.com” { inquiry { "disk-usage": command => "df -h"; "processes": command => "ps aux"; "kernel-info": command => "uname -a"; } }
  • 33. class instrumentation { inquiry { "disk-usage": command => "df -h"; "processes": command => "ps aux"; "kernel-info": command => "uname -a"; } } node “appserver1.mydomain.com” { include instrumentation } node “appserver2.mydomain.com” { include instrumentation }
  • 34. Rich set of primitives, and make your own. Can use existing modules and abstractions, and make your own.
  • 39. netmask_lo: 255.0.0.0 ipaddress: 172.16.245.128 augeasversion: 0.10.0 processor0: Intel(R) Core(TM) fqdn: pe-debian6.localdomain i7-2635QM CPU @ 2.00GHz manufacturer: "VMware, Inc." lsbdistrelease: 6.0.2 processorcount: "1" uniqueid: 007f0101 productname: VMware Virtual hardwaremodel: i686 Platform kernelversion: 2.6.32 physicalprocessorcount: 1 operatingsystem: Debian facterversion: 1.6.7 architecture: i386 boardproductname: 440BX Desktop lsbdistdescription: Debian GNU/ Reference Platform Linux 6.0.2 (squeeze) kernelmajversion: "2.6" lsbmajdistrelease: "6" hardwareisa: unknown interfaces: "eth0,lo" timezone: PDT ipaddress_lo: 127.0.0.1 puppetversion: 2.7.12 (Puppet uptime_days: 0 Enterprise 2.5.1) lsbdistid: Debian lsbdistcodename: squeeze rubysitedir: /opt/puppet/lib/ is_virtual: "true" site_ruby/1.8 operatingsystemrelease: 6.0.2 rubyversion: 1.8.7 virtual: vmware osfamily: Debian type: Other memorytotal: &id001 502.57 MB domain: localdomain memorysize: *id001 hostname: pe-debian6 boardmanufacturer: Intel selinux: "false" Corporation kernel: Linux path: /usr/local/sbin:/usr/
  • 42. file { “/etc/issue”: content => “Got an issue? Here’s a tissue!”, } file { “/etc/motd”: content => template(“Welcome to $hostname!”), }
  • 43. file { "/etc/sudoers": owner => root, group => root, mode => 440, source => "puppet:///modules/sudo/sudoers" }
  • 44. class ntp { package { 'ntp': ensure => installed, } service { 'ntpd': ensure => running, enable => true, subscribe => File['/etc/ntp.conf'], } file { '/etc/ntp.conf': ensure => file, require => Package['ntp'], source => "puppet:///modules/ntp/ntp.conf", } }
  • 45. node “webserver.mydomain.com” { include ntp } node “appserver.mydomain.com” { include ntp } node “database.mydomain.com” { include ntp }
  • 46. class ssh { @@sshkey { $hostname: type => dsa, key => $sshdsakey } Sshkey <<| |>> }
  • 49. File “/tmp/foo/bar” User “deepak” Dir “/tmp/foo” Dir “/tmp”
  • 50. Dir “/tmp” User “deepak” Dir “/tmp/foo” File “/tmp/foo/bar”
  • 51. Dir “/tmp” User “deepak” Dir “/tmp/foo” File “/tmp/foo/bar”
  • 56. package { 'ntp': ensure => installed, } service { 'ntpd': ensure => running, enable => true, subscribe => File['/etc/ntp.conf'], } file { '/etc/ntp.conf': ensure => file, require => Package['ntp'], source => "puppet:///modules/ntp/ntp.conf", }
  • 57. package { 'ntp': ensure => installed, } service { 'ntpd': ensure => running, enable => true, subscribe => File['/etc/ntp.conf'], } file { '/etc/ntp.conf': ensure => file, require => Package['ntp'], source => "puppet:///modules/ntp/ntp.conf", }
  • 58. package { 'ntp': ensure => installed, } service { 'ntpd': ensure => running, enable => true, subscribe => File['/etc/ntp.conf'], } file { '/etc/ntp.conf': ensure => file, require => Package['ntp'], source => "puppet:///modules/ntp/ntp.conf", }
  • 59. package { 'ntp': ensure => installed, } service { 'ntpd': ensure => running, enable => true, subscribe => File['/etc/ntp.conf'], } file { '/etc/ntp.conf': ensure => file, require => Package['ntp'], source => "puppet:///modules/ntp/ntp.conf", }
  • 63. Idempotent, and only does what’s necessary
  • 64. Compensates for the inherent mutability of systems
  • 65. Combats spooky action at a distance with automatic repair
  • 67. A foundation of predictability and reliability lets you perform higher-level operations on your infrastructure
  • 68. Code all the way down
  • 70. Thus, you can treat it like the other code in your application
  • 72. Maintaining the state of your systems is the foundation upon which everything rests
  • 73. Start small, and start somewhere. :)