Help us understand the problem. What is going on with this article?

test-kitchen test (test-kitchenハンズオン資料)vagrantもec2もazureもdockerもchefもpuppetもansibleも継続的インテグレーション!

More than 5 years have passed since last update.

chefでImmutable Infrastructureって本当に出来るの?人のcookbooks使うと動かないしさ、gitで管理してても使えるかわからないんだけど…
…それ、test-kitchenでやってみたら?
みたいな話。
(本当はjenkinsで回したいけどまだやってない)

社内LT用資料です。

前提

  • anyenv やら rbenvやらを使ってrubyをインストールしておく
  • このリポジトリをgit clone する人、かつ、chef-dkを使っていない人(この資料はchef-dkを使用していない場合のコマンドで書いています)
$ cd test-kitchen-test/
$ bundle install
-> vendor/bundle/ 配下にtest-kitchenがインストールされる
  • chef-dkを使うとchef、test-kitchen、berkshelf等がインストールされているので、以下の手順の中に出てくる bundle exec はいらないです。
    • 例: bundle exec kitchen list -> kitchen list

test-kitchenとは?

  • chef cookbookをテストするためのツール
  • 好きな仮想サーバでテストができる
    • vagrant、docker、ec2、azure、gce等
  • Busser(ビュッセル)ライブラリによって好きなサーバ設定自動化ツールでテストができる
    • chef、puppet、ansible等
  • 好きなテストコードでテストができる
    • serverspec、Bats、minitest等

URL

特に Chef実践入門 は超おすすめです!わかりやすかったー

test-kitchenコマンドの流れを ざっくり 理解する

test-kitchen-zakkuri.png

押さえておくところ

  • いろんなOSをいっぺんにテストできる(図の.kitchen.ymlから矢印が2本出ているところ)
  • いろんなテストコードでテストできる(図の吹き出し部分)
  • この図のサイクルを運用で回すことによって品質を担保する(図全体)=> CI(継続的インテグレーション)

サクッとコマンドだけ試したい人

https://github.com/imura81gt/test-kitchen-test

をcloneして、この資料の test-kitchen ハンズオン! までお進みください。

準備

オマエの作ったgitリポジトリなんか使わないぜ!って人向け。
全部自分でやりたい人向け。です。

chef リポジトリ

$ knife solo init test-kitchen-test

この時点でのディレクトリ構成

$ tree -a test-kitchen-test/
test-kitchen-test/
├── .chef
│   └── knife.rb
├── .gitignore
├── Berksfile
├── cookbooks
│   └── .gitkeep
├── data_bags
│   └── .gitkeep
├── environments
│   └── .gitkeep
├── nodes
│   └── .gitkeep
├── roles
│   └── .gitkeep
└── site-cookbooks
    └── .gitkeep

7 directories, 9 files
$

git

$ cd test-kitchen-test/
$ git init

bundle

初期化

$ bundle init
Writing new Gemfile to /path/test-kitchen-test/Gemfile
$

-> Gemfileが作成される

test-kitchen等インストール

Gemfile

# A sample Gemfile
source "https://rubygems.org"

# gem "rails"

gem 'test-kitchen'
gem 'kitchen-vagrant'
gem 'berkshelf'
gem 'serverspec'
gem 'rake'
gem 'knife-solo'

インストール

$ bundle install --path vendor/bundle

-> 時間がかかるので待つ

test-kitchen

初期化

$ bundle exec kitchen init
      create  .kitchen.yml
      create  test/integration/default
      append  .gitignore
      append  .gitignore
$

Berkself

Berksfile

site :opscode

cookbook 'apt'
cookbook 'apache2'

-> 何かしら入れておかないと kitchen test が途中でこける

[2014-07-01T14:09:28+00:00] ERROR: None of the cookbook paths set in Chef::Config[:cookbook_path], ["/tmp/kitchen/cookbooks", "/tmp/kitchen/site-cookbooks"], contain any cookbooks
[2014-07-01T14:09:28+00:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)
>>>>>> Converge failed on instance <default-ubuntu-1204>.
>>>>>> Please see .kitchen/logs/default-ubuntu-1204.log for more details
>>>>>> ------Exception-------
>>>>>> Class: Kitchen::ActionFailed
>>>>>> Message: SSH exited (1) for command: [sudo -E chef-solo --config /tmp/kitchen/solo.rb --json-attributes /tmp/kitchen/dna.json  --log_level info]
>>>>>> ----------------------
$

github

リポジトリ作成

(割愛)

git commit

$ touch README.md
$ git add .
$ git commit -m "first commit"
$ git remote add origin https://github.com/imura81gt/test-kitchen-test
$ git push -u origin master

試しに動かしてみる

この設定で試しに動かしてみる

kitchen.yml
---
driver:
  name: vagrant

provisioner:
  name: chef_solo

platforms:
  - name: ubuntu-12.04
  - name: centos-6.4

suites:
  - name: default
    run_list:
    attributes:

ヘルプ

$ bundle exec kitchen
Commands:
  kitchen console                         # Kitchen Console!
  kitchen converge [INSTANCE|REGEXP|all]  # Converge one or more instances
  kitchen create [INSTANCE|REGEXP|all]    # Create one or more instances
  kitchen destroy [INSTANCE|REGEXP|all]   # Destroy one or more instances
  kitchen diagnose [INSTANCE|REGEXP|all]  # Show computed diagnostic configuration
  kitchen driver                          # Driver subcommands
  kitchen driver create [NAME]            # Create a new Kitchen Driver gem project
  kitchen driver discover                 # Discover Test Kitchen drivers published on RubyGems
  kitchen driver help [COMMAND]           # Describe subcommands or one specific subcommand
  kitchen help [COMMAND]                  # Describe available commands or one specific command
  kitchen init                            # Adds some configuration to your cookbook so Kitchen can rock
  kitchen list [INSTANCE|REGEXP|all]      # Lists one or more instances
  kitchen login INSTANCE|REGEXP           # Log in to one instance
  kitchen setup [INSTANCE|REGEXP|all]     # Setup one or more instances
  kitchen test [INSTANCE|REGEXP|all]      # Test one or more instances
  kitchen verify [INSTANCE|REGEXP|all]    # Verify one or more instances
  kitchen version                         # Print Kitchen's version information

$

list

test-kitchenで作成される環境のリスト

$ bundle exec kitchen list
Instance             Driver   Provisioner  Last Action
default-ubuntu-1204  Vagrant  ChefSolo     <Not Created>
default-centos-64    Vagrant  ChefSolo     <Not Created>
$

.kitchen.ymlの設定

platforms:
  - name: ubuntu-12.04
  - name: centos-6.4

suites:
  - name: default

-> platforms:suites: の値の組み合わせ分テストを行える

一通りテストしてみる

$ bundle exec kitchen test
-----> Starting Kitchen (v1.2.1)
-----> Cleaning up any prior instances of <default-ubuntu-1204>★ubuntuのインスタンスを起動してテストをし始める

(省略)
       Vagrant instance <default-ubuntu-1204> destroyed.
       Finished destroying <default-ubuntu-1204> (0m4.30s).
       Finished testing <default-ubuntu-1204> (1m33.21s).
-----> Cleaning up any prior instances of <default-centos-64>★centosのインスタンスを起動してテストをし始める

(省略)

       Vagrant instance <default-centos-64> destroyed.
       Finished destroying <default-centos-64> (0m4.76s).
       Finished testing <default-centos-64> (2m0.60s).
-----> Kitchen is finished. (3m34.67s)
$

-> テストコードをおいていないから何もしてない状態なので参考まで。

(以下、まとめ中)

test-kitchenコマンドの流れを コマンド で理解する

test-kitchen-flow.png

apache2をインスタンスに適用する

web roleを作成する

roles/web.json
{
    "name": "web",
    "json_class": "Chef::Role",
    "description": "web role",
    "default_attributes": {
      "apache": {
      }
    },
    "run_list": [
        "recipe[apache2]"
    ],
    "chef_type": "role"
}

ubuntu roleを作成する

apt-get updateを実行しないといろいろ動かない

roles/ubuntu.json
{
    "name": "ubuntu",
    "json_class": "Chef::Role",
    "description": "ubuntu role",
    "default_attributes": {
    },
    "run_list": [
        "recipe[apt]"
    ],
    "chef_type": "role"
}

web role、ubuntu roleが適用されるように .kitchen.ymlを修正する

.kitchen.yml
---
driver:
  name: vagrant

provisioner:
  name: chef_solo

platforms:
  - name: ubuntu-12.04
    run_list:
      - role[ubuntu]
  - name: centos-6.4

suites:
  - name: default
    run_list:
      - role[web]
    attributes:

試しに起動/cookbook適用してみる(converge)

$ bundle exec kitchen converge
$ bundle exec kitchen list
Instance             Driver   Provisioner  Last Action
default-ubuntu-1204  Vagrant  ChefSolo     Converged
default-centos-64    Vagrant  ChefSolo     Converged
$

テストコードを書く

serverspec

$ cd test/integration/default/
$
$ bundle exec serverspec-init
Select OS type:

  1) UN*X
  2) Windows

Select number: 1

Select a backend type:

  1) SSH
  2) Exec (local)

Select number: 2

 + spec/
 + spec/localhost/
 + spec/localhost/httpd_spec.rb
 + spec/spec_helper.rb
 + Rakefile
$

test-kitchenでは
serverspec//_spec.rb をテストコードとして実行するため
フォルダ名を変更する

$ mv spec/ serverspec/

テストコードを実行してみる(verify)

.kitchen.yml があるディレクトリに戻って実行

$ bundle exec kitchen verify

-> ubuntuでapacheをインストールするとpackage名がhttpdじゃなかったして、
  ubuntuのテストがほとんど失敗するので
  CentOSのテストだけを流してみる

$ bundle exec kitchen verify default-centos-64

(省略)

       Finished in 0.18527 seconds
       6 examples, 1 failure

       Failed examples:

       rspec /tmp/busser/suites/serverspec/localhost/httpd_spec.rb:18 # File "/etc/httpd/conf/httpd.conf" content should match /ServerName localhost/
       /opt/chef/embedded/bin/ruby -I/tmp/busser/suites/serverspec -S /opt/chef/embedded/bin/rspec /tmp/busser/suites/serverspec/localhost/httpd_spec.rb --color --format documentation failed
       Ruby Script [/tmp/busser/gems/gems/busser-serverspec-0.2.6/lib/busser/runner_plugin/../serverspec/runner.rb /tmp/busser/suites/serverspec] exit code was 1
>>>>>> Verify failed on instance <default-centos-64>.
>>>>>> Please see .kitchen/logs/default-centos-64.log for more details
>>>>>> ------Exception-------
>>>>>> Class: Kitchen::ActionFailed
>>>>>> Message: SSH exited (1) for command: [sh -c 'BUSSER_ROOT="/tmp/busser" GEM_HOME="/tmp/busser/gems" GEM_PATH="/tmp/busser/gems" GEM_CACHE="/tmp/busser/gems/cache" ; export BUSSER_ROOT GEM_HOME GEM_PATH GEM_CACHE; sudo -E /tmp/busser/bin/busser test']
>>>>>> ----------------------
$

テストが混ざっているのでコメントアウトする

test/integration/default/serverspec/localhost/httpd_spec.rb
require 'spec_helper'

describe package('httpd') do
  it { should be_installed }
end

describe service('httpd') do
  it { should be_enabled   }
  it { should be_running   }
end

describe port(80) do
  it { should be_listening }
end

#describe file('/etc/httpd/conf/httpd.conf') do
#  it { should be_file }
#  its(:content) { should match /ServerName localhost/ }
#end

もう一度テストを流してみる

$ bundle exec kitchen verify default-centos-64
-----> Starting Kitchen (v1.2.1)
-----> Verifying <default-centos-64>...
       Removing /tmp/busser/suites/serverspec
       Uploading /tmp/busser/suites/serverspec/localhost/httpd_spec.rb (mode=0644)
       Uploading /tmp/busser/suites/serverspec/spec_helper.rb (mode=0644)
-----> Running serverspec test suite
       /opt/chef/embedded/bin/ruby -I/tmp/busser/suites/serverspec -S /opt/chef/embedded/bin/rspec /tmp/busser/suites/serverspec/localhost/httpd_spec.rb --color --format documentation

       Package "httpd"
         should be installed

       Service "httpd"
         should be enabled
         should be running

       Port "80"
         should be listening

       Finished in 0.16363 seconds
       4 examples, 0 failures
       Finished verifying <default-centos-64> (0m2.11s).
-----> Kitchen is finished. (0m2.73s)
$

destroy

$ bundle exec kitchen destroy default-centos-64
$ bundle exec kitchen list
Instance             Driver   Provisioner  Last Action
default-ubuntu-1204  Vagrant  ChefSolo     Set Up
default-centos-64    Vagrant  ChefSolo     <Not Created>
$

convergeやらverifyやらdestoyやらを全部一気に流してみる(test)

$ bundle exec kitchen test default-centos-64

(省略)

       Package "httpd"
         should be installed

       Service "httpd"
         should be enabled
         should be running

       Port "80"
         should be listening

       Finished in 0.16632 seconds
       4 examples, 0 failures
       Finished verifying <default-centos-64> (0m2.11s).
-----> Destroying <default-centos-64>...
       ==> default: Forcing shutdown of VM...
       ==> default: Destroying VM and associated drives...
       Vagrant instance <default-centos-64> destroyed.
       Finished destroying <default-centos-64> (0m5.01s).
       Finished testing <default-centos-64> (5m51.67s).
-----> Kitchen is finished. (5m52.26s)
$

test-kitchen ハンズオン!

$ cd /path/to/work/
$ git clone https://github.com/imura81gt/test-kitchen-test
$ cd test-kitchen-test/
$ bundle install
$ bundle exec kitchen
-> ヘルプを参照する

$ bundle exec kitchen list
-> test-kitchenで起動するインスタンスを確認する

$ cat .kitchen.yml
-> test-kitchenで起動するインスタンス情報を確認する

$ bundle exec kitchen create
-> インスタンスを起動する

$ bundle exec kitchen list
-> 2つインスタンスが起動していることを確認する
-> `Last Action` が `Created`

$ ls .kitchen/kitchen-vagrant/*/Vagrantfile
$ cat .kitchen/kitchen-vagrant/default-centos-64/Vagrantfile 
$ cat .kitchen/kitchen-vagrant/default-ubuntu-1204/Vagrantfile
-> .kitchen.yamlの情報を元にVagrantfileが作成されていることを確認する


$ bundle exec kitchen converge
-> インスタンスを起動し、cookbooksを適用する

$ bundle exec kitchen list
-> 2つインスタンスが起動していることを確認する
-> `Last Action` が `Converged`

$ bundle exec kitchen login default-ubuntu-1204
-> ubuntuのインスタンスにログインできることを確認する(終わったらexitする)
-> `bundle exec kitchen lo default-u` といった省略も可能


$ bundle exec kitchen login default-centos-64
-> centosのインスタンスにログインできることを確認する(終わったらexitする)

$ bundle exec kitchen verify
-> テストを実行する(default-ubuntu-1204のテストでコケる)

$ bundle exec kitchen vefiry default-centos-64
-> テストを実行する(成功する)

$ bundle exec kitchen destroy
-> インスタンスを削除する

$ bundle exec kitchen test default-centos-64
-> インスタンスの起動、cookbook適用、テスト実行、インスタンス削除まで一気にテストできることを確認する

$ bundle exec kitchen test default-ubuntu-1204
-> インスタンスの起動、cookbook適用までは上手くいくが、テストが失敗し、インスタンスが起動状態で残っていることを確認する。

メモ

ec2やGCEでもできるのがとてもいい。
テストさえ通ってしまえば、最低課金時間で済みますね
&最小インスタンスでもいいかもですね。

$ kitchen driver discover
    Gem Name                          Latest Stable Release
    kitchen-all                       0.2.0
    kitchen-ansible                   0.0.1
    kitchen-azure                     0.1.0
    kitchen-bluebox                   0.6.2
    kitchen-cabinet                   3.0.0
    kitchen-cloudstack                0.9.2
    kitchen-digitalocean              0.7.1
    kitchen-docker                    1.5.0
    kitchen-docker-api                0.4.0
    kitchen-driver-vagrant_provision  1.0.0
    kitchen-ec2                       0.8.0
    kitchen-fifo                      0.1.0
    kitchen-fog                       0.7.3
    kitchen-gce                       0.1.2
    kitchen-goiardi                   0.1.1
    kitchen-inspector                 1.3.0
    kitchen-joyent                    0.1.1
    kitchen-libvirtlxc                0.4.0
    kitchen-local                     0.0.1
    kitchen-lxc                       0.0.1
    kitchen-openstack                 1.5.2
    kitchen-puppet                    0.0.12
    kitchen-rackspace                 0.7.0
    kitchen-rightscale                0.1.0
    kitchen-salt                      0.0.18
    kitchen-scribe                    0.3.1
    kitchen-sharedtests               0.2.0
    kitchen-ssh                       0.0.4
    kitchen-sshgzip                   0.0.3
    kitchen-sync                      1.0.1
    kitchen-vagrant                   0.15.0
    kitchen-vagrant_sandbox           0.1.1
    kitchen-zcloudjp                  0.4.0
    test-kitchen-provisioners         0.1
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした