What we Learned Implementing Puppet at Backstop

96
Puppet at Backstop Learn from our mistakes (and a few wins along the way)

description

"What We Learned Implementing Puppet at Backstop" by Bill Weiss at Puppet Camp Chicago 2013. Learn about upcoming Puppet Camps at http://puppetlabs.com/community/puppet-camp/

Transcript of What we Learned Implementing Puppet at Backstop

Page 1: What we Learned Implementing Puppet at Backstop

Puppet  at  Backstop  

Learn  from  our  mistakes  (and  a  few  wins  along  the  way)  

Page 2: What we Learned Implementing Puppet at Backstop

Who  am  I?  

•  Bill  Weiss  <[email protected]>  •  @BillWeiss  

•  Wrote  a  bunch  of  the  coming  examples  of  what  not  to  do  here  

•  As  you  can  tell,  not  a  designer  

Page 3: What we Learned Implementing Puppet at Backstop

What  is  Backstop?  

I  promise  I’m  not  in  sales.  

Page 4: What we Learned Implementing Puppet at Backstop
Page 5: What we Learned Implementing Puppet at Backstop

 

Rack  picture  from  hIp://en.wikipedia.org/wiki/File:Datacenter-­‐telecom.jpg  .    The  rest  should  be  obvious  who  owns  them  

Page 6: What we Learned Implementing Puppet at Backstop

•  Same  places  and  infrastructure,  but:  

Page 7: What we Learned Implementing Puppet at Backstop

Where  we  came  from  

<@boss> Hey, we need another server to handle all these customers! <IT> Sure, we can just…

Page 8: What we Learned Implementing Puppet at Backstop
Page 9: What we Learned Implementing Puppet at Backstop
Page 10: What we Learned Implementing Puppet at Backstop
Page 11: What we Learned Implementing Puppet at Backstop
Page 12: What we Learned Implementing Puppet at Backstop

•  From  the  Dell  manual,  as  you  can  imagine  

Page 13: What we Learned Implementing Puppet at Backstop

•  hIp://www.centos.org/docs/5/html/5.2/InstallaAon_Guide/  

Page 14: What we Learned Implementing Puppet at Backstop

•  hIp://www.centos.org/docs/5/html/5.2/InstallaAon_Guide/s1-­‐diskpartsetup-­‐x86.html  

Page 15: What we Learned Implementing Puppet at Backstop

You  get  the  idea  

But  wait,  there’s  more!  

Page 16: What we Learned Implementing Puppet at Backstop

centos5.1-­‐a\erwork.txt  rpm --import http://dag.wieers.com/rpm/packages/RPM-GPG-KEY.dag.txt wget http://apt.sw.be/redhat/el5/en/x86_64/RPMS.dag/rpmforge-release-0.3.6-1.el5.rf.x86_64.rpm rpm -Uvh rpmforge-release-0.3.6-1.el5.rf.x86_64.rpm yum -y install mod_ssl gcc yum-priorities ncurses-devel httpd-devel apr-devel apr-util-devel apr-devel zlib-devel openssl-devel readline-devel ruby gcc-c++ postfix chkconfig iptables off chkconfig cups off chkconfig ip6tables off

Page 17: What we Learned Implementing Puppet at Backstop

I’m  not  showing  the  whole  file,  I  promise  

yum -y install ntp ntpdate 192.168.45.2 chkconfig ntpd on vi /etc/ntp.conf ############# Change server to (IP) if in the cage #################

Page 18: What we Learned Implementing Puppet at Backstop

wc  –l    ==  273  cd /usr/local/ scp -pr root@abe:/usr/local/instantclient-* . ln -s instantclient-10.2.0.4 instantclient cd instantclient ln -s libclntsh.so.10.1 libclntsh.so chmod 755 *.so* chmod 755 sqlplus chmod 755 genezi echo "/usr/local/instantclient" > /etc/ld.so.conf.d/oracle.conf ldconfig cd /root

Page 19: What we Learned Implementing Puppet at Backstop

So…  that’s  it,  right?  

•  Nope.    That’s  just  the  OS,  no  app.  •  Deploy  instrucAons  passed  down  from  developer  to  developer  as  lore  and  legend.  

Page 20: What we Learned Implementing Puppet at Backstop

So  it’s  really  

Page 21: What we Learned Implementing Puppet at Backstop

What  about  VMs?  

•  Obviously  no  rack-­‐and-­‐stack,  but  otherwise  the  same  

•  Sweet  master-­‐centos-­‐5.1-­‐java-­‐backstop.img  “gold”  file  

Page 22: What we Learned Implementing Puppet at Backstop

What  if  upstream  changes?  

•  We  lose  •  Massive  dri\  between  machines  

“Remember  that  bobo  is  slow  to  run  email  imports”  

 •  I’m  just  not  going  to  talk  about  patching  

Page 23: What we Learned Implementing Puppet at Backstop

What  if  we  need  to  update  a  package?  

$ for server in $(seq 1 254) ; do > ssh [email protected].$server \ > “yum update && yum upgrade thing”

> done

It’s  cool,  I’ll  just  type  that  password  a  lot…  (No  SSH  keys,  of  course)  

Page 24: What we Learned Implementing Puppet at Backstop

What  if  we  need  to  update  a  file?  

$ for server in $(seq 1 254) ; do > scp file \ > [email protected].$server:/some/where

> done

Hope  the  files  don’t  differ  between  machines.  (They  do)  

Page 25: What we Learned Implementing Puppet at Backstop

Honestly,  that’s  more  like  

$ for server in $(seq 1 254) ; do > ssh –t [email protected].$server \ > “vim /some/file”

> done My  escape  key  is  strangely  worn  smooth.  

Page 26: What we Learned Implementing Puppet at Backstop

My  reacAon  

•  Courtesy  THE  INTERNET  •  Specifically  hIp://www.reacAongifs.com/nope-­‐nope-­‐nope-­‐octopus/  

Page 27: What we Learned Implementing Puppet at Backstop

•  hIp://en.wikipedia.org/wiki/File:The_Scream.jpg  

Page 28: What we Learned Implementing Puppet at Backstop

I’ll  just  give  you  the  punchline  now  

•  SAll  have  to  order  and  wait  for  shipping,  Puppet  doesn’t  do  that  (yet)  

•  SAll  have  to  rack  the  silly  thing  •  PXE  boot  to  kickstart  •  Kickstart  installs  minimum  to  get  Puppet  running  

•  puppet agent –onetime --no-daemonize  on  boot  

Page 29: What we Learned Implementing Puppet at Backstop

•  Jenkins  logo,  of  course,  courtesy  hIps://wiki.jenkins-­‐ci.org/display/JENKINS/Logo  •  “Push  buIon”  image  courtesy  hIp://onemansblog.com/2007/11/29/reinterpreAng-­‐hand-­‐

dryer-­‐symbols/push-­‐buIon-­‐receive-­‐bacon-­‐2/  •  Horrible  ediAng  courtesy  OS  X  Preview’s  “Annotate”  funcAon  

Page 30: What we Learned Implementing Puppet at Backstop

How  did  we  get  there?  

•  ~5700  SVN  commits  $ (svn log old-puppet ; svn log puppet26/)| egrep \ '^r.*lines?$' | wc -l 5721

•  23  authors  $ (svn log old-puppet ; svn log puppet26/)| egrep \ '^r.*lines?$' | awk '{print $3}' | sort | uniq | wc –l 23

•  3  years,  1  month,  19  days  (as  of  March  13th)  

If  anyone  wants  to  do  shell  golf,  I  bet  I  could  combine  those  into  one  command  line  to  get  #  of  commits  and  #  of  disAnct  authors.  

Page 31: What we Learned Implementing Puppet at Backstop

Let’s  talk  about  what  we  learned  

Page 32: What we Learned Implementing Puppet at Backstop

☹  #1  –  Global  variables  

•  Once  we  started  configuring  Nagios  via  Puppet  (more  on  that  later),  we  needed  a  way  to  control  if  a  given  box  was  monitored.    Thus:  

 node /^ib3qa\d+\.investorbridge$/ { $servertype = 'IB3' $serverenv = 'qa' $serverrole = 'frontend' $monitor = false

Page 33: What we Learned Implementing Puppet at Backstop

☹  #1  –  Global  variables  

•  What’s  the  code  look  like  for  that?  if ($monitor == true) or ($monitor == 'true') or ($monitor == 'yes') or ($monitor == '') { class{ ‘bsgbase::monitor’: real_ensure => ‘present’, } } else { class{ ‘bsgbase::monitor’: real_ensure => ‘absent’, } }

Page 34: What we Learned Implementing Puppet at Backstop

☹  #1  –  Global  variables  

•  Ok,  just  set  $monitor  =  false  anywhere  you  don’t  want  to  monitor.    Sure.  

•  What  if  you  want  to  monitor  the  basic  stuff,  but  not  the  app  on  top  of  it?  (like  a  test  box)  

Page 35: What we Learned Implementing Puppet at Backstop

☹  #1  –  Global  variables  node /ib-test-\d+/ { (stuff) $monitor_ib = false }

Page 36: What we Learned Implementing Puppet at Backstop

☹  #1  –  Global  variables  

•  What  about  a  machine  that  you  don’t  care  about  load  average  on?  

node ‘superbusy’ { $monitor = ‘true’ $monitor_load = ‘false’ }

Page 37: What we Learned Implementing Puppet at Backstop

☹  #1  –  Global  variables  

•  Guess  what  that  code  looks  like?  

Page 38: What we Learned Implementing Puppet at Backstop

☹  #1  –  Global  variables  

•  I’ll  spare  you.    It  has  to  check  $monitor  and  $monitor_load  and  do  the  right  thing.  

•  Also,  it  didn’t  fit  in  a  slide.  

Page 39: What we Learned Implementing Puppet at Backstop

☹  #1  –  Global  variables  

Page 40: What we Learned Implementing Puppet at Backstop

☹  #1  –  Global  variables  

•  Seemed  like  a  good  idea  at  the  Ame.  •  How  do  we  get  rid  of  it?  •  Turns  out  Puppet  3  does  this  for  you!  

Page 41: What we Learned Implementing Puppet at Backstop

☺  #1  -­‐  Hiera  

•  Hiera  to  the  rescue.  •  Our  hierarchy  looks  like:  :hierarchy: - %{fqdn} - %{operatingsystem} - %{location}/%{servertype}/%{serverenv}/%{serverrole} - %{location}/%{servertype}/%{serverenv} - %{location}/%{servertype} - %{location} - common

Page 42: What we Learned Implementing Puppet at Backstop

☺  #1  -­‐  Hiera  

•  ProducAon  should  default  to  monitored,  but  other  locaAons  shouldn’t?  

$ grep monitor: common.yaml ch3.yaml common.yaml:monitor: 'absent' ch3.yaml:monitor: 'present'

Page 43: What we Learned Implementing Puppet at Backstop

☺  #1  -­‐  Hiera  

•  Developers  for  a  certain  app  don’t  want  load  monitoring?  

$ grep monitor ch3/docsvc.yaml monitor: 'present’ monitor_load: ‘absent’  

Page 44: What we Learned Implementing Puppet at Backstop

☺  #1  –  Hiera  

•  Anywhere  you’ve  got  $something  =  “something”  in  a  module,  think  about  if  it  needs  to  change  per-­‐environment.  

•  If  so,  in  Hiera  it  goes!  

Page 45: What we Learned Implementing Puppet at Backstop

☺  #1  –  Hiera  

•  Example  #2:  sshd_config  •  Most  machines  need  the  same  one,  but  a  few  get  something  radically  different.    How  do  you  include  a  different  file?  

Page 46: What we Learned Implementing Puppet at Backstop

☺  #1  –  Hiera  class ssh::install { $sshd_template = hiera('sshd_template', 'ssh/sshd_config.erb') file { '/etc/ssh/sshd_config': owner => 'root', group => 'root', mode => '0600', content => template($sshd_template), notify => Class['ssh::service'], } }

Page 47: What we Learned Implementing Puppet at Backstop

☺  #1  –  Hiera  

hieradata/ $ ack template . ch3/IT/production/sshjumphost.yaml 3:sshd_template: 'sshjumphost/sshd_config.erb'

Page 48: What we Learned Implementing Puppet at Backstop

☺  #1  –  Hiera  

•  The  more  you  wait  on  installing  it,  the  more  you’ll  have  to  migrate  in.  

•  Do  it  now,  even  if  not  everything  lives  in  there  day  one.  

Page 49: What we Learned Implementing Puppet at Backstop

☹  #2  –  Per-­‐something  files  •  Started  innocently  enough:    bweiss@rezal-evad-gib ~/repos/old-puppet $ svn diff -c 29 Index: manifests/nodes.pp ========================================================= --- manifests/nodes.pp (revision 28) +++ manifests/nodes.pp (revision 29) @@ -10,8 +9,14 @@ include rails include oracle include ib3 + $servertype = "IB3" + include sudo }

Page 50: What we Learned Implementing Puppet at Backstop

☹  #2  –  Per-­‐something  files  bweiss@rezal-evad-gib ~/repos/old-puppet $ svn diff -c 27 Index: modules/sudo/manifests/init.pp ========================================================= --- modules/sudo/manifests/init.pp (revision 26) +++ modules/sudo/manifests/init.pp (revision 27) @@ -1,7 +1,18 @@ class sudo { + case $servertype { + "IB3": { include sudo::ib3 } + "BB": { include sudo::bb } + default: { include sudo::default } + } +}

Page 51: What we Learned Implementing Puppet at Backstop

☹  #2  –  Per-­‐something  files  +class sudo::ib3 inherits sudo::common { + file { "/etc/sudoers": + owner => "root", + group => "root", + mode => 440, + source => "puppet:///modules/sudo/ib3-sudoers", + require => Package["sudo"], + } +}

Page 52: What we Learned Implementing Puppet at Backstop

☹  #2  –  Per-­‐something  files  

•  Yikes.    I  got  a  liIle  more  clever,  and  this  became:  

Page 53: What we Learned Implementing Puppet at Backstop

☹  #2  –  Per-­‐something  files  file { "/etc/sudoers": owner => "root", group => "root", mode => 0440, source => [ "puppet:///modules/sudo/sudoers.$fqdn", "puppet:///modules/sudo/sudoers.$servertype", "puppet:///modules/sudo/sudoers" ], require => Package["sudo"] }

Page 54: What we Learned Implementing Puppet at Backstop

☹  #2  –  Per-­‐something  files  

•  Well...  That’s  not  so  bad,  right?    

 modules/sudo/files $ ll | wc -l 20  

Page 55: What we Learned Implementing Puppet at Backstop

☹  #2  –  Per-­‐something  files  --------------------------------------------------------- r213 | bweiss | 2010-08-19 16:23:21 -0500 (Thu, 19 Aug 2010) | 1 line Added DevManager group to all systems

(cut:  adding  the  same  line  to  20  files)  

Page 56: What we Learned Implementing Puppet at Backstop

☹  #2  –  Per-­‐something  files  

•  No  global  “right”  answer.  •  For  this  specific  case,  please  go  download  Example42’s  sudo  module  from  the  Forge.  

Page 57: What we Learned Implementing Puppet at Backstop

☺  #2  –  Compose  those  files  

•  You’ll  have  lots  of  cases  where  you  need  to  add  to  a  file  from  other  modules  (or  per-­‐something).    Don’t  fall  into  the  trap  of  sudoers.${::fqdn}  

Page 58: What we Learned Implementing Puppet at Backstop

☺  #2  –  Compose  those  files  

•  Approach  #1:  foo.d  directories  •  Sudo  supports  this  at  the  boIom  of  your    /etc/sudoers/:  #includedir /etc/sudoers.d

•  Then  you  can  just  dump  config  snippets  in   /etc/sudoers.d/(whatever)  

Page 59: What we Learned Implementing Puppet at Backstop

☺  #2  –  Compose  those  files  

•  Approach  #2:  puppet-­‐concat  •  hIps://github.com/ripienaar/puppet-­‐concat  •  Lets  you  fake  the  foo.d  style  by  gluing  your  file  fragments  together  at  puppet  Ame.  

•  Used  like  this:  

Page 60: What we Learned Implementing Puppet at Backstop

☺  #2  –  Compose  those  files  

•  Set  up  the  file:  concat{ ‘/some/file’: }

•  Add  a  couple  of  blobs  concat::fragment{ ‘blob1’: target => ‘/some/file’, order => 5, content => “Yep, I’m #5”, }

Page 61: What we Learned Implementing Puppet at Backstop

☺  #2  –  Compose  those  files  concat::fragment{ ‘blob2’: target => ‘/some/file’, order => 10, source => ‘puppet:///(etc)/blob2’, }

•  That’s  it,  /some/file will  contain  all  those  blocks  in  the  order  you  asked  for.  

•  It  shouldn’t  be  your  first  stop,  but  it  works!  

Page 62: What we Learned Implementing Puppet at Backstop

☺  #2  –  Compose  those  files  

•  When  all  else  fails,  get  templaAng.  •  It’s  just  Ruby,  you  can  do  this.  

Page 63: What we Learned Implementing Puppet at Backstop

☺  #3  –  Stored  Configs  

•  These  look  super  confusing  at  first,  but  they’re  not  bad.  

•  On  the  source,  you  do:  @@my_type{‘whatever’: normal => arguments, tag => ‘something’, }

Page 64: What we Learned Implementing Puppet at Backstop

☺  #3  –  Stored  Configs  

•  Then,  wherever  you  need  those  resources  to  show  up,  you  do:  

My_type <<| tag == ‘something’ |>> { } •  That’s  it.    How  do  you  use  it?  

Page 65: What we Learned Implementing Puppet at Backstop

☺  #3  –  Stored  Configs  

•  The  fantasAc  built-­‐in  Nagios  types.  •  On  a  client:  @@nagios_service{“check_load_${::fqdn}”: ensure => ‘present’, (lots of parameters) tag => $::location, }

•  $::location  is  something  we  wrote  to  contain  what  datacenter  you’re  in.    Don’t  worry  about  that  part.

Page 66: What we Learned Implementing Puppet at Backstop

☺  #3  –  Stored  Configs  

•  On  the  Nagios  server:  Nagios_service <<| tag == $::location |>>{ notify => Class[‘nagios::service’], }

(that’s  just  this  side  of  boilerplate)  

Page 67: What we Learned Implementing Puppet at Backstop

☺  #3  –  Stored  Configs  

•  Once  the  client  checks  in,  and  then  the  Nagios  server  checks  in,  it’s  monitored.  

•  That’s  it.  •  You’ll  need  some  machinery  to  determine  when  to  monitor  what  machine,  of  course,  but  it’s  as  easy  as  that.  

Page 68: What we Learned Implementing Puppet at Backstop

☺  #3  –  Stored  Configs  

•  Big  wins  here.  •  Old  manually-­‐configured  Nagios:  ~600  services  

•  Puppet-­‐configured  Nagios:  ~800  services  •  I  wonder  what  we  were  missing?  

Page 69: What we Learned Implementing Puppet at Backstop

☺  #3  –  Stored  Configs  

•  We’re  working  on  code  to  configure  our  load  balancer  in  the  same  way.  

•  Client:  @@load_balance{ “servicename_${::fqdn}”: port => 443, external_name => ‘www.backstopsolutions.com’, }

Page 70: What we Learned Implementing Puppet at Backstop

☺  #3  –  Stored  Configs  

•  Then  the  load  balancer  can  just  grab  all  of  those  and  add  them  as  backends!  

Page 71: What we Learned Implementing Puppet at Backstop

☺  #3  –  Stored  Configs  

•  Gotchas:  – Resource  names  have  to  be  globally  unique.    Add  ${::fqdn}  everywhere.  

– You  have  to  have  a  database  to  dump  these  into.    Get  PuppetDB  running!  

– Be  willing  to  dig  in  the  database  to  debug  if  needed.  

Page 72: What we Learned Implementing Puppet at Backstop

☹  #3  –  Convergence  Ame  

•  Early  on,  we  decided  to  run  Puppet  only  once  daily,  during  a  Ame  clients  aren’t  using  a  server.  – Minimizes  the  chances  of  causing  an  outage.  

•  Remember  the  order  those  stored  configs  have  to  happen  in?  

Page 73: What we Learned Implementing Puppet at Backstop

☹  #3  –  Convergence  Ame  

•  Yep,  have  to  make  sure  all  clients  run  before  the  consumer  of  a  stored  config  does,  or  you’ll  be  out  of  sync.  

•  Try  to  run  as  o\en  as  possible.    This  reduces  the  amount  of  changes  to  make  per  run,  which  has  less  impact.  

Page 74: What we Learned Implementing Puppet at Backstop

☺  #4  -­‐  mcollecAve  

Original  image:  hIp://xkcd.com/353/  Cheapo  ediAng  again  courtesy  OS  X  Preview  “Annotate”  

Page 75: What we Learned Implementing Puppet at Backstop

☺  #4  -­‐  mcollecAve  

<dba> The app needs to be down in CH3 before we can do our DR test <IT> I can do that  

Page 76: What we Learned Implementing Puppet at Backstop

☺  #4  -­‐  mcollecAve  

It  would  have  been  $ for server in $(seq 1 254) ; do > ssh [email protected].$server \ > “/etc/init.d/jboss stop”

> done

•  Elapsed  Ame,  an  hour  (if  you  type  fast)  

Page 77: What we Learned Implementing Puppet at Backstop

☺  #4  -­‐  mcollecAve  

•  Instead:  $ mc-service –W jboss jboss stop  •  Elapsed  Ame:  0.34  seconds  –  I  tested  with  ‘status’,  not  ‘stop’,  to  get  that  number.    Don’t  worry,  it’s  async.  

Page 78: What we Learned Implementing Puppet at Backstop

☺  #4  -­‐  mcollecAve  

<IT_1> We added a new DNS server, and we need traffic to go to it ASAP. We don’t want to wait for the puppet run. <IT_2> Sure.

Page 79: What we Learned Implementing Puppet at Backstop

☺  #4  -­‐  mcollecAve  

It  would  have  been  •  Oh,  you  know.    Instead,  make  that  Puppet  change,  then:  

$ mc-puppetd runonce –f

Page 80: What we Learned Implementing Puppet at Backstop

☺  #4  -­‐  mcollecAve  

•  What  machine  has  MAC    90:B1:1C:04:44:3A?  It’s  generaAng  some  strange  traffic.  

$ mco find -W \ macaddress=90:B1:1C:04:44:3A

Page 81: What we Learned Implementing Puppet at Backstop

☺  #4  -­‐  mcollecAve  

<dev> Hey, now that VMs get spun up so quickly, I don’t know what all the machines I need to deploy to are. Can I get a list? $ mco find –W app1

Page 82: What we Learned Implementing Puppet at Backstop

☺  #4  -­‐  mcollecAve  

•  You’ll  keep  finding  places  to  use  it.  •  To  get  the  full  value,  you’ll  need  to  write  some  code  around  it.    Even  without  that,  it’ll  pay  off.  

Page 83: What we Learned Implementing Puppet at Backstop

☹  #4  -­‐  environments  

•  Sadly,  I  can  only  say  what  didn’t  work  here.  •  Puppet  config  is  in  svn  •  /etc/puppet/ is  a  checkout  of  that  on  each  Puppet  server  

•  No  branching  strategy,  all  in  trunk  

Page 84: What we Learned Implementing Puppet at Backstop

☹  #4  -­‐  environments  

•  Worked  at  first,  one  person  wriAng  manifests  •  Then,  two,  we  knew  what  the  other  person  was  working  on…  

•  10  commiIers  this  month,  with  185  commits  

Page 85: What we Learned Implementing Puppet at Backstop

☹  #4  -­‐  environments  

•  This  isn’t  a  new  problem.    If  you’re  at  a  development  shop,  you  probably  already  have  a  branching  strategy.    Do  that,  and  get  different  servers  into  different  environments.  

•  This  would  also  let  you  have  one  server  for  mulAple  uses.  

Page 86: What we Learned Implementing Puppet at Backstop

☺  #5  –  think  business  terms  

•  It’s  easy  to  do  the  normal  flow  in  Puppet  of  package  /  files  /  service.    That’s  useful.  

•  BeIer  yet,  talk  about  things  the  business  need  or  wants!  

•  Example:  

Page 87: What we Learned Implementing Puppet at Backstop

☺  #5  –  think  business  terms  

•  InvestorBridge  hosts  a  website  per  client.    They’re  of  the  form  www.(clientname).com,  and  include  SSL  certs,  an  apache  vhost,  (eventually)  load  balancer  config,  etc.    How’s  that  look  in  Puppet?  

Page 88: What we Learned Implementing Puppet at Backstop

☺  #5  –  think  business  terms   ib3r192::clientsite{ 'backstopadvisors': lastOctet => 199, clientFqdn => 'www.backstopadvisors.com', seconddn => 'backstopadvisors.com', }

•  A  liIle  ruby  could  clean  up  that  seconddn  part.    Eh.  

Page 89: What we Learned Implementing Puppet at Backstop

☺  #5  –  think  business  terms  

•  That’s  it.    That  configures:  –  IP  for  the  client’s  vhost  (need  an  IP  since  we  have  SSL  certs)  

– Apache  vhost.d  file  – SSL  cert  gets  dropped  in  the  right  place  –  (Soon)  Load  balancer  config  –  (Soon)  add  it  to  DNS  

•  On  mulAple  hosts!  This  works  if  we  have  one  server  or  ten.  

Page 90: What we Learned Implementing Puppet at Backstop

☺  #5  –  think  business  terms  

•  There’s  obviously  some  magic:  – SSL  cert  has  to  be  named  same  as  the  client  name  

•  And  a  bunch  of  code  – 6  Puppet  defines  back  there,  and  lots  of  built-­‐in  types  

– Stored  configs  for  the  load  balancer  and  DNS  

Page 91: What we Learned Implementing Puppet at Backstop

☺  #6  –Puppet  as  automaAon  glue  

•  We  have  a  fair  number  of  jobs  that  generate  a  file  that  needs  to  go  out  somewhere.  – DNS  zones  – O\-­‐menAoned  load  balancer  configs  

•  Instead  of  wriAng  deploy  jobs  for  each…  

Page 92: What we Learned Implementing Puppet at Backstop

☺  #6  –Puppet  as  automaAon  glue  

•  Write  the  files  into  the  puppet  repo  (checked  in)  and  let  it  drop  the  files.  

•  You  get  change  tracking  for  free,  and  can  build  all  the  usual  tools  around  it  – Restart  services  when  their  files  change  – Test  syntax  before  restarAng  services  

•  If  you’re  using  reports,  you’ll  even  find  out  if  things  go  wrong.  

Page 93: What we Learned Implementing Puppet at Backstop

☺  #7  –  VCS  pre-­‐commit  hooks  

•  Since  your  Puppet  manifests  are  in  some  VCS  (right?),  and  a  bunch  of  config  files  are  there  as  well,  why  not  test  them?  – SSL  certs  –  check  to  make  sure  keys  and  certs  match  

– Bind  files  –  check  that  serial  numbers  incremented  •  Heck,  run  named-­‐checkzone  against  them  

– Syntax  check  .pp  files!  – Syntax  check  .erb  files  

Page 94: What we Learned Implementing Puppet at Backstop

☺  #8  –  don’t  reinvent  the  wheel  

•  While  looking  for  code  to  put  in  this,  I  found  a  ton  of  modules  we  wrote  that  exist  in  the  Forge.  

•  Those  are  probably  beIer  wriIen.  •  Certainly  beIer  tested.  •  Don’t  be  afraid  to  throw  code  away.  

Page 95: What we Learned Implementing Puppet at Backstop

☺  #8  –  don’t  reinvent  the  wheel  

•  You  might  spend  some  Ame  digging  through  the  Forge  to  find  the  right  project.  

•  Consider  it  early  payment  for  not  having  to  maintain  the  module  by  yourself.  

Page 96: What we Learned Implementing Puppet at Backstop

QuesAons?