Slide 1

Slide 1 text

puppet in the trenches ™ guerrilla devops @

Slide 2

Slide 2 text

™ mission objective

Slide 3

Slide 3 text

— $ 1. 2.

Slide 4

Slide 4 text

$ dead simple

Slide 5

Slide 5 text

Slide 6

Slide 6 text

You ( )

Slide 7

Slide 7 text

Secure Storage Bank Integration Clean APIs

Slide 8

Slide 8 text

™ modern tech killer support rock-solid platform

Slide 9

Slide 9 text

why puppet?

Slide 10

Slide 10 text

a small startup...

Slide 11

Slide 11 text

...with a big job

Slide 12

Slide 12 text

...with a big job

Slide 13

Slide 13 text

Use what you've got <3

Slide 14

Slide 14 text

Use what you've got

Slide 15

Slide 15 text

automated consistency version controlled layer(s) of abstraction puppet

Slide 16

Slide 16 text

why puppet? ^ masterless

Slide 17

Slide 17 text

master puppet puppet master puppet agent puppet agent puppet agent who am i? a proxy server! a db box! an app node!

Slide 18

Slide 18 text

master puppet less you two: mongodb cluster! APP node ASAP!

Slide 19

Slide 19 text

master puppet less fine-grained control parallelization distributed (no S.P.O.F.)

Slide 20

Slide 20 text

supply_drop pitluga/supply_drop

Slide 21

Slide 21 text

supply_drop $ mkdir infrastructure && cd infrastructure [infrastructure] $ gem install supply_drop Successfully installed capistrano-2.13.4 Successfully installed supply_drop-0.11.1 [infrastructure] $ capify . [done] capified! [infrastructure] $ vim config/deploy.rb let's get

Slide 22

Slide 22 text

# config/deploy.rb require 'rubygems' require 'supply_drop' def tasks_for_datacenter(datacenter, servers) task(datacenter) do role :server, *servers end servers.each do |server| task(server) { role :server, server } end end supply_drop let's use

Slide 23

Slide 23 text

# ...config/deploy.rb tasks_for_datacenter :qa, %w( app01.qa db01.qa ) tasks_for_datacenter :production, %w( app01.prod db01.prod ) supply_drop let's use

Slide 24

Slide 24 text

# site.pp node 'app01.qa' { package { 'python': ensure => installed } } supply_drop let's use

Slide 25

Slide 25 text

supply_drop let's use [infrastructure] $ cap app01.qa puppet:noop ... notice: /Stage[main]/Package[python]/ensure: current_value absent, should be present (noop) [infrastructure] $ cap app01.qa puppet:apply ... notice: /Stage[main]/Package[python]/ensure: ensure changed ‘purged’ to ‘present’

Slide 26

Slide 26 text

cap tasks parallel rsync collision detection supply_drop

Slide 27

Slide 27 text

fine grained control $ cap db01.qa puppet:noop # single boxes $ cap app{01..05}.qa puppet:noop # classes of boxes $ cap qa puppet:noop # full environment $ git branch --list * master # maps to QA environments * staging # maps to pre-prod environments * production # maps to production environments we always read the diff

Slide 28

Slide 28 text

parallelization anybody using qa? working on a nagios check i'm tweaking the postgres configs, but we should be fine $ cap monitor01.qa puppet:noop $ cap monitor01.qa puppet:apply $ git pull --rebase $ git commit $ cap db01.qa puppet:noop $ cap db01.qa puppet:apply $ git pull --rebase $ git commit

Slide 29

Slide 29 text

parallelization Squad! Prepping a merge to staging! $ git co master && git pull $ git co staging && git pull $ git merge master $ git log origin/staging..HEAD $ git diff origin/staging..HEAD # review git log and diff $ cap staging puppet:noop # review puppet noop output $ cap db01.stg puppet:apply # selectively apply high-risk changes $ cap staging puppet:apply # flush out environment $ cap staging puppet:noop # double check "clean noop" $ git push roger! ten-four!

Slide 30

Slide 30 text

distributed by default well... thanks git!

Slide 31

Slide 31 text

putting it together

Slide 32

Slide 32 text

. ├── config # capistrano tasks & supply_drop config ├── datacenters # variable farms inherited by all nodes │ ├── qa.pp │ ├── staging.pp │ └── production.pp ├── manifests # legacy manifests; here be dragons ├── modules # new-style modules ├── nodes # node definitions │ ├── qa │ │ ├── app.pp # divided into per-class files │ │ ├── db.pp │ │ └── proxy.pp │ ├── staging │ └── production ├── puppet.pp # top-level puppet file ├── templates # legacy templates; here too be dragons └── vendor # vendored puppet pushed to machines ├── facter-1.6.4 ├── puppet-2.6.13 └── supply_drop-0.10.2

Slide 33

Slide 33 text

lessons learned and unanswered questions

Slide 34

Slide 34 text

puppet weapon is a dangerous

Slide 35

Slide 35 text

# apache2.conf.erb <% if rails_env == 'prod' -%> HostName www.example.com <% else -%> Hostname qa.example.com <% end -%> deceptively simple node "app1.qa" { $rails_env = "qa" include users include apache include rails } node "app1.prod" { $rails_env = "prod" include users include apache include rails }

Slide 36

Slide 36 text

mind your abstractions node "app1.qa" { include apache apache::site { 'example': hostname => 'qa.example.com' } } node "app1.prod" { include apache apache::site { 'example': hostname => 'www.example.com' } }

Slide 37

Slide 37 text

mind your abstractions 0..1 or 0..n? ☑ generic or unique? ☑ what changes? ☑ required variables ☑ optional variables ☑ defaults ☑

Slide 38

Slide 38 text

mind your abstractions modules. use them.

Slide 39

Slide 39 text

mind your scope watch your six! location node class/type template/file

Slide 40

Slide 40 text

truth

Slide 41

Slide 41 text

does not manage truth puppet maps truth to complexity puppet

Slide 42

Slide 42 text

how should we manage truth?

Slide 43

Slide 43 text

puppet in the trenches ™ guerrilla devops @