Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Docker + serverspecで作る configspec CI

Docker + serverspecで作る configspec CI

2014/04/11(金)に開催されたDocker Meetup #2のLTで使った資料です

smokeymonkey

April 11, 2014
Tweet

More Decks by smokeymonkey

Other Decks in Programming

Transcript

  1. classmethod.jp 15 ΍ͬͨ͜ͱ  Amazon  Linux     Container (1)git

     push (2)webhook (3)rake  -‐‑‒>  docker-‐‑‒api (4)Launch          Container (5)rake  -‐‑‒>            configspec (6)rake  -‐‑‒>            serverspecspec
  2. classmethod.jp 17 "NB[PO-JOVY%PDLFS*NBHFXJUI44) w%PDLFSGJMF ! ! ! ! ! !

    ! ! ! ! ! w EPDLFSCVJMEUMPDBMBN[OTTI FROM  local/amzn   ! #  PAM設定を変えておかないとsshがいきなり切切れる   RUN  sed  -‐‑‒ri  's/UsePAM  yes/#UsePAM  yes/g'  /etc/ssh/sshd_̲config   RUN  sed  -‐‑‒ri  's/#UsePAM  no/UsePAM  no/g'  /etc/ssh/sshd_̲config   RUN  passwd  -‐‑‒f  -‐‑‒u  ec2-‐‑‒user   ! #  start-‐‑‒stopしてhost_̲keyを作る   RUN  service  sshd  start   RUN  service  sshd  stop   ! ADD  ./authorized_̲keys  /home/ec2-‐‑‒user/.ssh/authorized_̲keys   ! EXPOSE  22
  3. classmethod.jp 18 TNPLFZNPOLFZTQFDDJ wUSFF . ├── README.md ├── Rakefile └──

    spec ├── configspec_helper.rb ├── serverspec_helper.rb ├── web_config │ └── nginx_spec.rb └── web_test └── nginx_spec.rb Roleのconfig Roleのtest
  4. classmethod.jp 19 3BLFGJMF  require 'rake' require 'rspec/core/rake_task' require 'docker'

    ! hosts = [ { :name => 'docker', :roles => %w( web ), :image => 'local/amznssh' } ] ! hosts = hosts.map do |host| { :name => host[:name], :short_name => host[:name].split('.')[0], :roles => host[:roles], :image => host[:image], } docker-‐‑‒api 対象Hostの指定の中で Docker  Imageを指定
  5. classmethod.jp 20 3BLFGJMF  namespace :spec do task :all =>

    hosts.map {|h| 'spec:' + h[:short_name] } hosts.each do |host| container = Docker::Container.create( 'Cmd' => ['/usr/sbin/sshd', '- D'], 'Image' => host[:image], 'PortSpecs' => '22' ) container.start('PortBindings' => {'22/tcp' => [{'HostIp' => '0.0.0.0'},{'HostPort' => '54322'}]}) host毎にsshdを実⾏行行して   ContainerをCreate
  6. classmethod.jp 21 3BLFGJMF  # configspec RSpec::Core::RakeTask.new(host[:short_name].to_sym) do |t| t.pattern

    = 'spec/{' + host[:roles].join(',') + '} _config/*_spec.rb' end ! # serverspec RSpec::Core::RakeTask.new(host[:short_name].to_sym) do |t| t.pattern = 'spec/{' + host[:roles].join(',') + '} _test/*_spec.rb' end container.stop configspec実⾏行行 serverspec実⾏行行 Containerをstop
  7. classmethod.jp 22 DPOGJHTQFD@IFMQFSSC require 'configspec' require 'net/ssh' require 'net/scp' !

    include SpecInfra::Helper::Ssh include SpecInfra::Helper::RedHat ! RSpec.configure do |c| c.sudo_password = '' c.host = ENV['TARGET_HOST'] options = Net::SSH::Config.for(c.host) user = options[:user] || Etc.getlogin c.ssh = Net::SSH.start(c.host, user, options) c.scp = Net::SCP.start(c.host, user, options) end
  8. classmethod.jp 23 TFSWFSTQFD@IFMQFSSC require 'serverspec' require 'pathname' require 'net/ssh' !

    include SpecInfra::Helper::Ssh include SpecInfra::Helper::RedHat ! RSpec.configure do |c| c.sudo_password = '' c.host = ENV['TARGET_HOST'] options = Net::SSH::Config.for(c.host) user = options[:user] || Etc.getlogin c.ssh = Net::SSH.start(c.host, user, options) end
  9. classmethod.jp 24 TVEPSBLF /usr/bin/ruby2.0 -S rspec spec/web_config/ nginx_spec.rb . !

    Finished in 0.52104 seconds 1 example, 0 failures /usr/bin/ruby2.0 -S rspec spec/web_test/ nginx_spec.rb . ! Finished in 0.09493 seconds 1 example, 0 failures
  10. classmethod.jp 30 ·ͱΊ w ௒ٱ͠ͿΓʹ3VCZॻ͍ͨ w "NB[PO-JOVY".*Ͱ %PDLFS(Pʹͳͬͨ w "84

    $POUBJOFS%FQMPZ͕zී௨z ʹͳΔͷ΋͍ۙʁ w ΋ͪΖΜ(PPHMF$MPVE1MBUGPSN Ͱ΋Ͷʂ w ࠓޙͷۀ຿ʹ׆͔ͤΔͱ͍͍ͳ͊