The Setup: Managing an Army of Laptops with Puppet

The Setup: Managing an Army of Laptops with Puppet

As a rapidly growing company, GitHub's faced some challenges in how to make sure that everyone can get up and running on projects or continue to work on one of the dozens of existing projects if they've never set it up before. What a nightmare! That's what prompted @jbarnette and @wfarr to develop The Setup. The Setup aims to solve all the problems that used to plague on-boarding GitHubbers onto projects with a lot of automation and a case of the "It Just Works". This presentation talks about the history of The Setup, how it works, and some of the lessons learned along the way.

Cd839cc361ffa996be0cc8259f3d7555?s=128

Will Farrington

September 12, 2012
Tweet

Transcript

  1. Setup the

  2. managing an army of laptops ...with puppet

  3. hi, my name is will farrington but @wfarr is way

    shorter
  4. i work at a “little-known startup” called github

  5. I work on System operations System operations internal apps the

    setup
  6. why

  7. once upon a time

  8. there was a developer

  9. there was a designer

  10. oh man, this new macbook pro is sweet! let me

    run a bunch of stuff by hand so I can get some work done in about 6 to 8 hours, maybe. - some perfectly normal people
  11. once upon a time

  12. there was a crazy person

  13. oh man, this new macbook pro is sweet! let me

    run a bunch of stuff by hand so I can get some work done in about 6 to 8 hours, maybe. ~ crazy people
  14. None
  15. we made a HUGE mistake

  16. yep, it’s pretty bad

  17. i thought we cared about testing

  18. i thought we cared about repeatability

  19. i thought we cared about automation

  20. we say those things matter for software and they totally

    do
  21. we do not treat our laptops like they matter

  22. wtf is wrong with us

  23. wtf is wrong with us i mean srsly guise

  24. spock approves this message

  25. what

  26. a living, breathing software project that tests and automates every

    little bit of your machine with love
  27. @jbarnette

  28. about 6000 about 3600 1186 26 lines of Ruby (not

    incl. tests) lines of Puppet (not incl. tests) commits contributors some numbers
  29. chrome, colloquy, dropbox, elasticsearch, emacs, erlang, git, homebrew, hub, iterm2,

    java, macvim, memcache, mongodb, mysql, nginx, nodejs, nvm, 1passwd, personalization, postgresql, projects, python, qt, rbenv, rdio, redis, ruby, solr, sparrow, textmate, virtualbox, viscosity, wget, xcode, xquartz, zeromq, zsh, and more daily.
  30. less than 6 months

  31. a githubber’s first day in

  32. None
  33. hours of frustration getting github.com and other projects even working

    locally
  34. None
  35. a githubber’s first day now

  36. None
  37. None
  38. drink coffee for 20 minutes

  39. Text

  40. None
  41. The Command Line Interface

  42. » gh-setup --projects * github

  43. github » script/bootstrap github » script/server github » open github.dev

    # Ready to ship things!
  44. » gh-setup octostatus # sets it all up. boom.

  45. » gh-setup --stealth # development mode

  46. None
  47. The Puppet DSL

  48. The Puppet DSL is pretty easy actually

  49. Resources

  50. Resources are the basic unit of puppet

  51. package { ‘redis-server’: }

  52. file { ‘/etc/motd’: content => ‘Hello, world!’ }

  53. service { ‘riak’: ensure => running, subscribe => File[‘/etc/riak/vm.args’] }

    resource type
  54. service { ‘riak’: ensure => running, subscribe => File[‘/etc/riak/vm.args’] }

    resource name
  55. service { ‘riak’: ensure => running, subscribe => File[‘/etc/riak/vm.args’] }

    resource parameters
  56. service { ‘riak’: ensure => running, subscribe => File[‘/etc/riak/vm.args’] }

    metaparameter
  57. metaparameters work on every resource

  58. metaparameters describe relationships

  59. before require subscribe notify this resource must run before this

    resource must run after this resource runs after and watches this resource runs before and tells
  60. resources can have custom types

  61. define git::config::local($key, $value) { $safekey = shellquote($key) $safevalue = shellquote($value)

    $command = "git config --local ${safekey} ${safevalue}" exec { "${command} in ${name}": command => $command, cwd => $name, onlyif => 'test -d .git', unless => "git config --local ${safekey}", require => Package['git'] } }
  62. git::config::local { ‘~/github/hubot’: key => ‘heroku.account’, value => ‘work’ }

  63. Resources can be grouped with classes

  64. class redis { package { ‘redis-server’: } service { ‘redis’:

    require => Package[‘redis-server’] } }
  65. classes can mixin other classes

  66. classes can require other classes

  67. this matters a whole lot everybody

  68. Puppet has its own dsl for a couple reasons

  69. 1. puppet was designed for sysadmin-types

  70. 2. puppet has semantics about execution that would be confusing

    and unintuitive in ruby or python or most other languages
  71. puppet uses a DAG to apply resources

  72. a DAG is a directed, acyclic graph

  73. a DAG means relationships matter

  74. a DAG also means order of execution does not matter

  75. None
  76. The Setup as a standard library for puppet but designed

    for personal laptops
  77. class github::projects::octostatus { require redis ... }

  78. class github::projects::octostatus { ... $dir = "${github::config::srcdir}/octostatus" ... }

  79. class github::projects::octostatus { ... git::repo { $dir: source => 'github/octostatus'

    } ... }
  80. class github::projects::octostatus { ... ruby::local { $dir: version => '1.9.3-p194',

    require => Git::Repo[$dir] } }
  81. I like doing things my way

  82. class github::people::hubot { include github::projects::all }

  83. class github::people::keavy { require gitx require onepassword require sizeup require

    sparrow require textmate }
  84. class github::people::yossef { package { 'Alfred': provider => 'appdmg', source

    => $alfred_dmg_url; } }
  85. class github::people::yossef { setup::tarballed_app { 'Mailplane': source => $mailplane_url; }

    }
  86. class github::people::wfarr { git::config::global { 'alias.st': value => 'status'; 'alias.ci':

    value => 'commit'; } }
  87. class github::people::wfarr { file { '/Users/wfarr/.gitignore': ensure => present, content

    => '.DS_STORE' } }
  88. class github::people::wfarr { package { 'emacs': } git::repo { '/Users/wfarr/.emacs.d':

    source => 'wfarr/.emacs.d', submodules => true } }
  89. class github::people::wfarr { setup::osx_defaults { 'require password always': ensure =>

    present, domain => 'com.apple.screensaver', key => 'askForPassword', value => 1, user => 'wfarr' } }
  90. lessons

  91. puppeteer supportocat

  92. people will do crazy shit to it

  93. if it breaks it is your job to fix it

  94. if it breaks it is your job to fix it

    no matter what
  95. devs are really good at breaking things

  96. people report about 1% of issues they have

  97. people report about 1% of issues they have on a

    really good day
  98. None
  99. rapid iteration on bugs makes people happy

  100. avoiding more bugs makes us happy

  101. reduce potential for bugs by vendoring

  102. EVERYTHING

  103. None
  104. » du -sh /opt/github 3.8G /opt/github

  105. there’s

  106. None
  107. =(

  108. » env | grep GH_ | wc -l 24

  109. » env | grep GH_REDIS_PORT GH_REDIS_PORT=16379

  110. » env | grep GH_MYSQL_PORT GH_MYSQL_PORT=13306

  111. None
  112. people just will never remember to update

  113. tell people when they should update

  114. None
  115. omg sneak peek time

  116. => Installing qt...

  117. None
  118. None
  119. => Fetching snapshot... => Installing qt...

  120. => Fetching snapshot... => Installing ruby-1.9.3...

  121. => Fetching snapshot... => Installing node-0.6.8...

  122. we don't have the ability to mandate environments

  123. we have to provide something dramatically better than just doing

    it yourself
  124. prim donn

  125. the setup is not a tool for it administrators

  126. the setup is a tool for people to get stuff

    done
  127. the setup is extensible by users

  128. the setup is a stable framework for config

  129. the setup is about enabling good patterns

  130. the setup is not about dictating machine policy

  131. how do i get it

  132. you don’t =(

  133. ... yet

  134. we are working hard to open source it

  135. Soon!

  136. Setup the

  137. questions

  138. love ops? come work with us puppet, erlang, ruby, shell,

    c and all the graphs you can shake a stick at
  139. None
  140. thanks