Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Test-Driven Infrastructure with Puppet, Test Kitchen, Serverspec and RSpec

5,276 views

Published on

The goal of Continuous Delivery is, briefly, to get features into your users' or customers' hands as quickly and confidently as possible. In order to succeed, Development and Operations teams need to align and come up with both working and deployable software in short, regular intervals. Chef, Puppet, Ansible & Co. enable teams to code up application runtime environments, but alone do not allow for building quality into their processes. In this presentation I will show how you can apply the "Red, Green, Refactor Cycle" of Test-Driven Development and combine it with your configuration management or orchestration tool of choice in order to come up with better infrastructure that can automatically be tested using Puppet, Test Kitchen, Docker, Serverspec and RSpec.

Published in: Technology

Test-Driven Infrastructure with Puppet, Test Kitchen, Serverspec and RSpec

  1. 1. 1 #Dynatrace with Test Kitchen, Serverspec and RSpec Test-Driven Infrastructure Puppet Meetup
  2. 2. 2 #Dynatrace Insert image here Martin Etmajer Senior Technology Strategist at Dynatrace martin.etmajer@dynatrace.com @metmajer
  3. 3. 3 #Dynatrace Why Continuous Delivery?
  4. 4. 4 #Dynatrace Why Continuous Delivery?
  5. 5. 5 #Dynatrace Utmost Goal: Minimize Cycle Time feature cycle time time Customer Users
  6. 6. 6 #Dynatrace Utmost Goal: Minimize Cycle Time feature cycle time time Customer minimize Users
  7. 7. 7 #Dynatrace Utmost Goal: Minimize Cycle Time feature cycle time time Customer This is when you create value! minimize
  8. 8. 8 #Dynatrace Utmost Goal: Minimize Cycle Time feature cycle time time Customer You This is when you create value! minimize
  9. 9. 9 #Dynatrace Utmost Goal: Minimize Cycle Time feature cycle time time Customer You minimize It’s about getting your features into your user’s hands as quickly and confidently as possible!
  10. 10. 10 #Dynatrace Align Development and IT Operations IT OPERATIONS DEVELOPMENT time
  11. 11. 11 #Dynatrace Align Development and IT Operations IT OPERATIONS DEVELOPMENT current iteration (e.g. 2 weeks) time
  12. 12. 12 #Dynatrace Align Development and IT Operations IT OPERATIONS DEVELOPMENT current iteration (e.g. 2 weeks) time Planning
  13. 13. 13 #Dynatrace Align Development and IT Operations IT OPERATIONS DEVELOPMENT current iteration (e.g. 2 weeks) time Planning Implementing and testing
  14. 14. 14 #Dynatrace Align Development and IT Operations IT OPERATIONS DEVELOPMENT current iteration (e.g. 2 weeks) time Planning Implementing and testing Working and deployable code
  15. 15. 15 #Dynatrace Why Test-Driven Infrastructure?
  16. 16. 16 #Dynatrace You write code!
  17. 17. 17 #Dynatrace “Make it work. Make it right. Make it fast.” Kent Beck, Creator of Extreme Programming and Test-Driven Development Get the code to operate correctly Make the code clear, enforce good design Optimize
  18. 18. 18 #Dynatrace The Red, Green, Refactor Cycle of TDD Write a Failing Test Make the Test PassClean Up your Code Small increments Able to return to known working code Designed and tested code Protects against regressions
  19. 19. 19 #Dynatrace Test Kitchen Key Concepts Pluggable Architecture
  20. 20. 20 #Dynatrace » Drivers » Platforms » Provisioners » Test Suites Key Concepts
  21. 21. 21 #Dynatrace » Drivers » Platforms » Provisioners » Test Suites Key Concepts
  22. 22. 22 #Dynatrace Drivers let you run your code on various... Cloud Providers » Azure, Cloud Stack, EC2, Digital Ocean, GCE, Rackspace,... Virtualization Technologies » Vagrant, Docker, LXC Test Kitchen: Drivers
  23. 23. 23 #Dynatrace » Drivers » Platforms » Provisioners » Test Suites Key Concepts
  24. 24. 24 #Dynatrace Platforms are the Operating Systems you want to run on. Platforms » Linux- or Windows-based (since Test Kitchen 1.4.0) How to manage dependencies? » Automatically resolved when using Docker or Vagrant » Build your own and link them in the configuration file Test Kitchen: Platforms
  25. 25. 25 #Dynatrace » Drivers » Platforms » Provisioners » Test Suites Key Concepts
  26. 26. 26 #Dynatrace Provisioners are the tools used to converge the environment. Provisioners » Ansible, Chef, CFEngine, Puppet, SaltStack Why cool? » Useful if you need to support multiple of these tools Test Kitchen: Provisioners
  27. 27. 27 #Dynatrace » Drivers » Platforms » Provisioners » Test Suites Key Concepts
  28. 28. 28 #Dynatrace Test Suites define the tests to run against each platform. Test Frameworks » Bash, Bats, Cucumber, RSpec, Serverspec Test Kitchen: Test Suites
  29. 29. 29 #Dynatrace Test Kitchen Installation
  30. 30. 30 #Dynatrace Installation Ready? $ gem install test-kitchen kitchen-docker kitchen-puppet Test Kitchen: Installation $ kitchen version Test Kitchen version 1.4.2
  31. 31. 31 #Dynatrace Test Kitchen Configuration
  32. 32. 32 #Dynatrace Create a Puppet Module Initialize Test Kitchen $ mkdir –p my-puppet-module $ cd my-puppet-module Test Kitchen: Testing a Puppet Module $ kitchen init --driver=docker --provisioner=puppet_apply create .kitchen.yml create test/integration/default Configuration goes here! Tests go here!
  33. 33. 33 #Dynatrace .kitchen.yml (as provided via `kitchen init`) --- driver: name: docker provisioner: name: puppet_apply platforms: - name: ubuntu-14.04 - name: centos-7.1 suites: - name: default run_list: attributes: Test Kitchen: Testing a Puppet Module Names resolve to Docker Images on the Docker Hub
  34. 34. 34 #Dynatrace .kitchen.yml (slightly adjusted) --- driver: name: docker provisioner: name: puppet_apply puppet_version: latest files_path: files manifests_path: test/integration manifest: default/init.pp puppet_verbose: true puppet_debug: false Test Kitchen: Testing a Puppet Module platforms: - name: ubuntu-14.04 - name: centos-7.1 suites: - name: default
  35. 35. 35 #Dynatrace $ kitchen list Instance Driver Provisioner Transport Last Action default-ubuntu-1404 Docker PuppetApply Ssh <Not Created> default-centos-71 Docker PuppetApply Ssh <Not Created> `kitchen list`: List Test Kitchen Instances Test Kitchen: Installation This will change...Test Suite Platform
  36. 36. 36 #Dynatrace Test Kitchen Write an Integration Test
  37. 37. 37 #Dynatrace Create a Puppet Manifest for Test Suite ‘default’ Test Kitchen: Testing a Puppet Module $ kitchen init --driver=docker --provisioner=puppet_apply create .kitchen.yml create test/integration/default Configuration goes here! Tests go here!
  38. 38. 38 #Dynatrace test/integration/default/init.pp class { ‘foo’: } class { ‘bar‘: bar_param => ..., require => Class[‘foo’] } class { ‘baz’: baz_param => .., require => Class[‘bar’] } ... Test Kitchen: Testing a Puppet Module Create your environment Puppet Manifest Test Suite
  39. 39. 39 #Dynatrace Serverspec and RSpec A Short Primer
  40. 40. 40 #Dynatrace RSpec is a TDD tool for Ruby programmers. RSpec require ‘foo’ describe Foo do before do @foo = Foo.new end it ‘method #bar does something useful’ do @foo.bar.should eq ‘something useful’ end end
  41. 41. 41 #Dynatrace Serverspec is RSpec for your infrastructure. Serverspec require ‘serverspec’ describe user(‘foo’) do it { should exist } it { should belong_to_group ‘foo’ } end describe file(‘/opt/bar’) do it { should be_directory } it { should be_mode 777 } it { should be_owned_by ‘foo’ } it { should be_grouped_into ‘foo’ } end describe service(‘bar’) do it { should be_enabled } it { should be_running } end describe port(8080) do it { should be_listening } end describe command(‘apachectl –M’) do its(:stdout) { should contain(‘proxy_module’) } end Resource Matcher
  42. 42. 42 #Dynatrace test/integration/default/serverspec/default_spec.rb require ‘serverspec’ describe user(‘foo’) do it { should exist } it { should belong_to_group ‘foo’ } end Test Kitchen: Testing a Puppet Module Test Test Suite Do Serverspec!
  43. 43. 43 #Dynatrace `kitchen test`: Run Test Kitchen Test Test Kitchen: Testing a Puppet Module $ kitchen test default-ubuntu-1404 $ kitchen test ubuntu $ kitchen test regex! $ kitchen list Instance Driver Provisioner Transport Last Action default-ubuntu-1404 Docker PuppetApply Ssh <Not Created> default-centos-71 Docker PuppetApply Ssh <Not Created>
  44. 44. 44 #Dynatrace Test Kitchen: Actions Test = Converge Setup Verify Instance created and provisioned Instance ready for verification (dependencies installed)
  45. 45. 45 #Dynatrace `kitchen test`: Run Test Kitchen Test $ kitchen test ubuntu ... User "foo" should exist should belong to group "foo" Finished in 0.14825 seconds (files took 0.6271 seconds to load) 2 examples, 0 failures Finished verifying <default-ubuntu-1404> (0m37.21s). Test Kitchen: Testing a Puppet Module
  46. 46. 46 #Dynatrace `kitchen list`: List Test Kitchen Instances Test Kitchen: Testing a Puppet Module $ kitchen list Instance Driver Provisioner Transport Last Action default-ubuntu-1404 Docker PuppetApply Ssh Verified default-centos-71 Docker PuppetApply Ssh <Not Created>
  47. 47. 47 #Dynatrace Test Kitchen with Puppet Advanced Tips
  48. 48. 48 #Dynatrace Testing Puppet Modules in Amazon EC2
  49. 49. 49 #Dynatrace .kitchen.yml --- driver: name: ec2 aws_access_key_id: "<%= ENV['AWS_ACCESS_KEY_ID']%>" aws_secret_access_key: "<%= ENV['AWS_SECRET_ACCESS_KEY']%>" aws_ssh_key_id: "<%= ENV['AWS_SSH_KEY_ID']%>" region: eu-west-1 availability_zone: eu-west-1b transport: ssh_key: "<%= ENV['AWS_SSH_KEY_PATH']%>" username: admin ... Test Kitchen: Testing Puppet Modules in EC2 Environment Variables
  50. 50. 50 #Dynatrace Testing REST APIs with RSpec Not supported by Serverspec
  51. 51. 51 #Dynatrace Testing REST APIs with RSpec Infraspec not yet integrated
  52. 52. 52 #Dynatrace test/integration/default/rspec/default_spec.rb require ‘json’ require ‘net/http’ ... describe ‘Server REST API’ do it ‘/rest/foo responds correctly’ do uri = URI(‘http://localhost:8080/rest/foo’) request = Net::HTTP::Get.new(uri, { ‘Accept’ => ‘application/json’ }) request.basic_auth(‘foo’, ‘foo’) response = Net::HTTP.new(uri.host, uri.port).request(request) expect(response.code).to eq 200 expect(JSON.parse(response.body)).to eq { ‘bar’ => ‘baz’ } end end Test Kitchen: Testing REST APIs Do RSpec!
  53. 53. 53 #Dynatrace test/integration/default/rspec/default_spec.rb require ‘json’ require ‘net/http’ ... describe ‘Server REST API’ do it ‘/rest/foo responds correctly’ do uri = URI(‘http://localhost:8080/rest/foo’) request = Net::HTTP::Get.new(uri, { ‘Accept’ => ‘application/json’ }) request.basic_auth(‘foo’, ‘foo’) response = Net::HTTP.new(uri.host, uri.port).request(request) expect(response.code).to eq 200 expect(JSON.parse(response.body)).to eq { ‘bar’ => ‘baz’ } end end Test Kitchen: Testing REST APIs Could use serverspec!
  54. 54. 54 #Dynatrace Dynatrace-Puppet Module Further Examples: https://github.com/dynaTrace/Dynatrace-Puppet
  55. 55. 55 #Dynatrace
  56. 56. 56 #Dynatrace Questions?
  57. 57. 57 #Dynatrace

×