Slide 1

Slide 1 text

Treat your servers like your Ruby App: Infrastructure as Code 2015 March 27-28 Allan Espinosa Platform as a Service Team Global Operations Department Rakuten, Inc. http://www.rakuten.co.jp/

Slide 2

Slide 2 text

About me  Allan Espinosa  Technology Background  Language Polyglot: Ruby, Node.js, Java, .NET  Systems Polyglot: Docker, VMWare  Automation Junkie: Chef, Jenkins  Job Background  “Private Heroku”  Senior Systems Developer Platform as a Service Team Global Operations Department @AllanEspinosa

Slide 3

Slide 3 text

Rakuten, Inc.

Slide 4

Slide 4 text

Agenda  Audience Demographics  Typical App TDD  Introduction to Configuration Management  Infrastructure as Code  Evolved App and Infrastructure TDD  Wrap-up

Slide 5

Slide 5 text

Audience Demographics  Web application developers?  Infrastructure engineers?  Fullstack engineers?  Unit Tests?  Test Driven Development?  Automated/ Push-button deployments?  Post-deployment end-to-end tests?

Slide 6

Slide 6 text

Infrastructure as Code  Reproducable servers  Bring up a lot of servers  Programmatically add servers to monitor/ load balancer Server as cattle not pets Reference: Test Driven Infrastructure with Chef

Slide 7

Slide 7 text

Unmaintained Infrastructure Code  Where did I install ruby-2.0.0-p589 to?  Which machines upgraded to ruby-2.1.1-p589?  Have I upgraded libxml2 for nokogiri?  Why is database.yml pointing to staging????  Test and software engineering practices still relevant! # FIXME: … # TODO: …

Slide 8

Slide 8 text

Typical TDD Cycle Make the test pass Refactor Write a failing test Application Ref: K. Beck, Test Driven Development by Example, 2003.

Slide 9

Slide 9 text

Extended TDD with Acceptance Tests Pass the unit test Refactor Write a failing unit test Write Failing Acceptance Test Application Capybara.current_driver = :selenium Capybara.app_host = ‘http://localhost:8000’ G. Adzic, Specification by Example, 2011.

Slide 10

Slide 10 text

Apply to your Infrastructure Pass the unit test Refactor Write a failing unit test Write Failing Acceptance Test Application + Servers Capybara.current_driver = :selenium Capybara.app_host = ‘http://actual-production.domain

Slide 11

Slide 11 text

Build our infrastructure! .kitchen.yml --- provisioner: chef_zero platforms: - freebsd-10.1 suites: - name: app  Write a failing test  Test-kitchen  Plain Minitest  Make the test pass  Chef Recipe  Refactor  Repeat!  Roll out to servers  Pass acceptance test! test/integration/app/minitest/test_app.rb class TestApp < Minitest::Unit::TestCase def test_ruby_is_installed assert File.exists ‘/usr/local/bin/ruby’, ‘Ruby should be installed’ end end

Slide 12

Slide 12 text

Failing Test! -----> Running minitest test suite /opt/chef/embedded/bin/ruby -I"/opt/chef/embedded/lib/ruby/2.1.0" "/opt/chef/embedded/lib/ruby/2.1.0/rake/rake_test_loader.rb" "/tmp/busser/suites/minitest/test_app.rb" Run options: --seed 48374 # Running tests: F Finished tests in 0.001660s, 602.4866 tests/s, 602.4866 assertions/s. 1) Failure: AppTest#test_ruby_should_be_installed [/tmp/busser/suites/minitest/test_app.rb:5]: ruby is not installed 1 tests, 1 assertions, 1 failures, 0 errors, 0 skips /opt/chef/embedded/lib/ruby/2.1.0/rake/testtask.rb:106:in `block (3 levels) in define': Command failed with status (1): [ruby -I"/opt/chef/embedded/lib/ruby/2.1.0" "/opt/che f/embedded/lib/ruby/2.1.0/rake/rake_test_loader.rb" "/tmp/busser/suites/minitest/test_app.rb" ] (RuntimeError)

Slide 13

Slide 13 text

Build our infrastructure! .kitchen.yml --- provisioner: chef_zero platforms: - freebsd-10.1 suites: - name: app run_list: - recipe[todo::app]  Write a failing test  Test-kitchen  Plain Minitest  Make the test pass  Chef Recipe  Refactor  Repeat!  Roll out to servers  Pass acceptance test!

Slide 14

Slide 14 text

Build our infrastructure! recipes/app.rb execute ‘pkg update’ package ‘ruby’ do action :install end metadata.rb name ‘todo’  Write a failing test  Test-kitchen  Plain Minitest  Make the test pass  Chef Recipe  Refactor  Repeat!  Roll out to servers  Pass acceptance test!

Slide 15

Slide 15 text

Make the test pass resolving cookbooks for run list: ["todo::app"] Synchronizing Cookbooks: - todo Compiling Cookbooks... Converging 2 resources Recipe: todo::app * execute[pkg update] action run - execute pkg update * package[ruby] action install - install version 2.0.0.598_2,1 of package ruby Running handlers: Running handlers complete Chef Client finished, 2/2 resources updated in 47.595913304 seconds Finished converging (0m55.78s).

Slide 16

Slide 16 text

GREEN! Make the test pass Run options: --seed 4256 # Running tests: . Finished tests in 0.001526s, 655.4072 tests/s, 655.4072 assertions/s. 1 tests, 1 assertions, 0 failures, 0 errors, 0 skips Finished verifying (0m2.59s).

Slide 17

Slide 17 text

Conclusion  Infrastructure express in code  Leapfrog on software engineering disciplines

Slide 18

Slide 18 text

We’re Hiring! Search for “Platform as a Service” http://global.rakuten.com/corp/careers/engineering/

Slide 19

Slide 19 text

Thank you! Questions?