adventures in infrastructure as code
DESCRIPTION
We're all developers now. Infrastructure as code is a new art and science, and we'd all better learn to get past hello world.TRANSCRIPT
![Page 1: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/1.jpg)
We’re all developers now
Adventures in Infrastructure as Code
Julian Simpson, The Build Doctor Ltd
![Page 2: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/2.jpg)
Before we begin
•For gory detail, talk to me at the drinks
•Examples: http://github.com/builddoctor/infrastructure-as-code
•You can ask questions
![Page 3: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/3.jpg)
Poll
•Are you using Puppet or Chef?
•What about Vagrant?
•Do you hate Ruby on Rails?
•Do you hate Apache Ant/NAnt?
![Page 4: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/4.jpg)
Demo
QuickTime™ and aH.264 decompressor
are needed to see this picture.
![Page 5: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/5.jpg)
What just happened?
•We spawned a fresh Ubuntu machine
•and mounted Puppet code
•and executed it
•and tested the desired state of the machine
![Page 6: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/6.jpg)
Vagrant
![Page 7: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/7.jpg)
Examples
![Page 8: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/8.jpg)
![Page 9: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/9.jpg)
Hello Puppet
1 #!/usr/bin/env puppet apply2 3file {4 '/tmp/PuppetHelloWorld':5
content => 'Hello Yow!\n'6 }
![Page 10: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/10.jpg)
Hello Puppet
knox:puppet jsimpson$ ./manifests/classes/01_hello_world.pp warning: Could not retrieve fact fqdnnotice: /Stage[main]//File[/tmp/PuppetHelloWorld]/ensure: defined content as '{md5}54393566ca75844a50baf0c6bccd84b5'notice: Finished catalog run in 0.16 secondsknox:puppet jsimpson$ cat /tmp/PuppetHelloWorld Hello Yow!knox:puppet jsimpson$
![Page 11: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/11.jpg)
Hello Chef
cat -n chef-repo/cookbooks/hello/recipes/default.rb 1 file "/tmp/Chef_Hello_World" do2 content "Hello, world!"3 end
![Page 12: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/12.jpg)
Hello Chef
knox:chef-repo jsimpson$ ./go [Thu, 01 Dec 2011 14:26:46 +1100] INFO: *** Chef 0.10.4 ***[Thu, 01 Dec 2011 14:26:46 +1100] INFO: Setting the run_list to ["recipe[hello]"] from JSON[Thu, 01 Dec 2011 14:26:46 +1100] INFO: Run List is [recipe[hello]][Thu, 01 Dec 2011 14:26:46 +1100] INFO: Run List expands to [hello][Thu, 01 Dec 2011 14:26:46 +1100] INFO: Starting Chef Run for knox[Thu, 01 Dec 2011 14:26:46 +1100] INFO: Processing file[/tmp/Chef_Hello_World] action create (hello::default line 1)[Thu, 01 Dec 2011 14:26:47 +1100] INFO: file[/tmp/Chef_Hello_World] created file /tmp/Chef_Hello_World[Thu, 01 Dec 2011 14:26:47 +1100] INFO: Chef Run complete in 0.084655 seconds[Thu, 01 Dec 2011 14:26:47 +1100] INFO: Running report handlers[Thu, 01 Dec 2011 14:26:47 +1100] INFO: Report handlers complete
![Page 13: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/13.jpg)
1 class nginx::install {2 3 package {4 'nginx':5 ensure => present;6 }7 8 file {9 'default web page':10 path => '/var/www/nginx-default/index.html',11 content => 'This page, courtesy of puppet',12 require => Package['nginx'];13 }14 15 service {16 'nginx':17 ensure => running,18 enable => true,19 hasstatus => true,20 require => [Package['nginx'], File['default web page']];21 }22 23 }24 25 node default {26 include nginx::install27 }
![Page 14: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/14.jpg)
cat -n recipes/default.rb 1 require_recipe "apt"23 package "nginx" do4 action :install5 end6 7 service "nginx" do8 action [:enable, :start]9 end
cat -n config/node.json 1 {2 "run_list": [ 3 "recipe[nginx]"4 ]5 }6
![Page 15: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/15.jpg)
30 class jetty::install {31 include ubuntu::common3233 package {34 'jetty':35 ensure => present,36 require => Class['ubuntu::common'];37 }3839 service {40 'jetty':41 ensure => running,42 enable => true,43 hasstatus => true,44 require => [Package['jetty'], File['/etc/default/jetty']];45 }4647 file {48 '/etc/default/jetty':49 ensure => present,50 content => "51 NO_START=052 VERBOSE=yes53 "54 }55 }
![Page 16: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/16.jpg)
1 require_recipe "apt"2 3 package "jetty" do4 action :install5 end6 7 service "jetty" do8 action [:enable]9 end10 11 file "/etc/default/jetty" do12 mode "0644"13 content "NO_START=0\nVERBOSE=yes\n"14 notifies :restart, resources(:service => "jetty")15 end
![Page 17: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/17.jpg)
1 class corporateapp::install {2 include jetty::install3 include nginx::install4 file {5 'corporate app':6 ensure => file,7 path => '/usr/share/jetty/webapps/app.war',8 source => 'puppet:///modules/corporateapp/app.war',9 require => [Class['jetty::install'], Class['nginx::install']],
notify => Exec['restart jetty'];10 }11 }
![Page 18: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/18.jpg)
1 include_recipe "jetty"2 3 # We do it like this for the example...4 cookbook_file "/usr/share/jetty/webapps/app.war" do5 source "app.war"6 mode "0644"7 end8 9 # In real life I'd do something like...10 #remote_file "/usr/share/jetty/webapps/app.war" do11 # source node[:jetty][:deploy][:source]12 # checksum node[:jetty][:deploy][:checksum] if node[:jetty][:deploy][:checksum]13 # notifies :restart, "service[jetty]"14 #end
![Page 19: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/19.jpg)
├── Gemfile├── Gemfile.lock├── Rakefile├── TODO├── Vagrantfile├── manifests│ ├── classes│ │ ├── 01_hello_world.pp│ │ ├── 02_installed_app_on_nginx.pp│ │ └── 03_installed_app_on_nginx_and_jetty.pp│ └── site.pp└── modules ├── corporateapp │ ├── files │ │ └── app.war │ └── manifests │ └── install.pp ├── jetty │ └── manifests │ └── install.pp ├── nginx │ ├── files │ │ └── nginx_www.corporateapp.com │ └── manifests │ └── install.pp ├── puppet │ └── manifests │ └── fudge.pp └── ubuntu └── manifests └── common.pp15 directories, 16 files
![Page 20: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/20.jpg)
![Page 21: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/21.jpg)
├── config│ ├── node.json│ └── solo.rb├── cookbooks│ ├── apt│ │ └── recipes│ │ └── default.rb│ ├── hello│ │ └── recipes│ │ └── default.rb│ ├── jetty│ │ ├── files│ │ │ └── default│ │ │ └── app.war│ │ └── recipes│ │ ├── default.rb│ │ └── deploy.rb│ └── nginx│ ├── attributes│ │ └── default.rb│ ├── recipes│ │ ├── default.rb│ │ └── loadbalancer.rb│ └── templates│ └── default│ └── lb.erb├── go└── roles └── corporateapp.rb
![Page 22: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/22.jpg)
1 name "corporateapp"2 description "Corporate App Server"3 run_list(4 "recipe[jetty]", 5 "recipe[jetty::deploy]", 6 "recipe[nginx::loadbalancer]"7 )8 9override_attributes(10 "nginx" => {11 "loadbalancer" => {12 "name" => "corporateapp",13 "source" => "http://localhost:8080"14 }15 }, 16 "jetty" => {17 "deploy" => {18 "source" => "http://build-repository/build-number/app.war"19 }20 } 21 )22
![Page 23: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/23.jpg)
History
![Page 24: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/24.jpg)
This isn’t new
![Page 25: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/25.jpg)
domain = ( sequenceapp.com )actionsequence = ( tidy disable resolve filesdirectories copy shellcommands linkseditfiles processes)################################################################################tidy:################################################################################$(sequenceetc) pattern=*.cfsaved age=0!cfmaster::# stops cfservd running on everything except master server/etc/rc2.d/ pattern=S97cfservd age=0# get rid of any hosts.equiv/etc pattern=hosts.equiv age=0 recurse=0homedirs::# no .rhosts files!Hr00::/export/home pattern=.rhosts age=0 recurse=inf
![Page 26: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/26.jpg)
Overview
http://verticalsysadmin.com/blog/uncategorized/relative-origins-of-cfengine-chef-and-puppet
![Page 27: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/27.jpg)
Differences
![Page 28: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/28.jpg)
PuppetPuppet ChefChef
Ruby DSL Ruby DSL
Parsed Internal
Declarative* Imperative*
Configuration Convention
Convergent Congruent
Sysadmins* Developers*
*IMHO
![Page 29: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/29.jpg)
Convergent vs Congruent
![Page 30: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/30.jpg)
“if you want a tool to be congruent, you really have to never re-write history. You have to constantly apply every byte-for-byte change in the same order, on every system you build. Skip a step in history, and everything goes off-kilter”Adam Jacob, 4 Dec
![Page 31: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/31.jpg)
Luke Kanies is here to present on “Essential Incompleteness in Program Modeling”, and starts by getting right into Godel’s Incompleteness Theorem. [it] says that for any system that attempts to model reality (“any sufficiently complex system”), it can never be both consistent and complete.
![Page 32: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/32.jpg)
Declarativevs Imperative
• Declarative programming is a programming paradigm that expresses the logic of a computation without describing its control flow.
• Imperative programming is a programming paradigm that describes computation in terms of statements that change a program state ... imperative programs define sequences of commands for the computer to perform.
![Page 33: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/33.jpg)
Cluster-wide facts
•Chef recipes can access attributes of other nodes
•Puppet can collect node info with stored config
•but ...
![Page 34: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/34.jpg)
Nothing beats realtime
![Page 35: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/35.jpg)
What about ...
![Page 36: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/36.jpg)
Windows?ResourceResource PuppetPuppet ChefChef
File ✔ ✔User ✔ ✔
Group ✔ ✔Scheduled
Task✔ ✔
Service ✔ ✔Exec ✔ ✔Host ✔ ✔
Package(MSI)
✔ ✘
Powershell ✘ ✔
![Page 37: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/37.jpg)
Testing?
•https://github.com/nistude/cucumber-puppet
•https://github.com/Atalanta/cucumber-chef
•https://github.com/gregretkowski/vmth/
•https://github.com/rodjek/puppet-lint
•http://cloudsmith.github.com/geppetto/
![Page 38: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/38.jpg)
Validating
task :parse_pp do file = File.open("parseonly.pp","w+") Dir.glob('etc/puppet/**/*.pp').each do |manifest| file << "import '#{manifest}'\n"
end sh "bundle exec puppet parser validate parseonly.pp" end
![Page 39: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/39.jpg)
Poll Results
•You might prefer Chef if you get annoyed by Ant’s ‘depends’ model
•You might prefer Puppet if you despise the magic of Ruby on Rails
![Page 40: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/40.jpg)
Disclaimer
•I don’t endorse either tool - you’ll need to make your own decision
•You can really, really screw things up with these tools. Test twice, run once.
![Page 41: Adventures in infrastructure as code](https://reader033.vdocuments.us/reader033/viewer/2022051513/5477167eb4af9fe7248b4a8c/html5/thumbnails/41.jpg)
Thank you - questions?
•http://github.com/builddoctor/infrastructure-as-code
•@builddoctor
•Much thanks to @cread, @tastapod, @adamgibbins, @puppetmasterd, @adamhjk