Nオガワです。前回の記事で、test-kitchenでAWS上にインスタンスを立てるとこまでを
ご紹介しました。
今回は、実際にテストコード、構築コードを作成してAWS上でtest-kitchenを利用してテストする方法をご紹介します。
以下は前回の記事からの続きです。
前提
Linux環境で利用頻度の高いApache、PHP、MySQLを例にご紹介します。
細かいミドルウェアの設定は記載していません。
1. specを作成
$ mkdir -p blog_demo/test/integration/default/serverspec/
[補足]テストコードの保存先は「test/integration/SUITES_NAME/TESTING_FRAMEWORK/*_spec.rb」になります。
「SUITES_NAME」は.kitchen.yamlで定義したスイート名(今回はdefault)、「TESTINGFRAMEWORK」はserverspecを
利用します。
$ cd blog_demo
$ vim test/integration/default/serverspec/default_spec.rb
----------[以下の通り設定]----------
require 'serverspec'
set :backend, :exec
# apacheテスト
describe 'apache' do
# インストールされていること
describe package('httpd') do
it { should be_installed }
end
# 自動起動と起動ステータスの確認
describe service('httpd') do
it { should be_enabled }
it { should be_running }
end
# listenポートの確認
%w[
80
443
].each do |port_num|
describe port(port_num) do
it { should be_listening }
end
end
# バージョンの確認
describe command('httpd -v') do
its(:stdout) { should contain(' Apache/2.4.6').before('Server built') }
end
end
# mysqlテスト
describe 'mysqld' do
# インストールされていること
describe package('mysql-community-server') do
it { should be_installed }
end
# 自動起動と起動ステータスの確認
describe service('mysqld') do
it { should be_enabled }
it { should be_running }
end
# listenポートの確認
describe port(3306) do
it { should be_listening }
end
# バージョンの確認
describe command('rpm -qa | grep mysql') do
its(:stdout) { should contain('^mysql-community-server-5.7.22-') }
end
end
# phpテスト
describe 'php' do
# インストールされていること
describe package('php') do
it { should be_installed }
end
# バージョンの確認
describe command('php -v') do
its(:stdout) { should contain('^PHP 5.4.16 (cli) (built: Apr 12 2018 19:02:01)') }
end
# module確認
%w[
bz2
calendar
Core
ctype
curl
].each do |php_module|
describe command('php -m') do
its(:stdout) { should contain(php_module) }
end
end
end
-------------[ここまで]-------------
2. テストコードの実行
$ bundle exec kitchen verify
----------[以下出力結果]----------
-----> Starting Kitchen (v1.20.0)
-----> Verifying ...
Preparing files for transfer
-----> Busser installation detected (busser)
-----> Busser plugin detected: busser-serverspec
Removing /tmp/verifier/suites/serverspec
Transferring files to
-----> Running serverspec test suite
/opt/chef/embedded/bin/ruby -I/tmp/verifier/suites/serverspec -I/tmp/verifier/gems/gems/rspec-support-3.7.1/lib:/tmp/verifier/gems/gems/rspec-core-3.7.1/lib /opt/chef/embedded/bin/rspec --pattern /tmp/verifier/suites/serverspec/**/*_spec.rb --color --format documentation --default-path /tmp/verifier/suites/serverspec
apache
Package "httpd"
should be installed (FAILED - 1)
Service "httpd"
should be enabled (FAILED - 2)
should be running (FAILED - 3)
Port "80"
should be listening (FAILED - 4)
Port "443"
should be listening (FAILED - 5)
Command "httpd -v"
stdout
should contain " Apache/2.4.6" (FAILED - 6)
mysqld
Package "mysql-community-server"
should be installed (FAILED - 7)
Service "mysqld"
should be enabled (FAILED - 8)
should be running (FAILED - 9)
Port "3306"
should be listening (FAILED - 10)
Command "rpm -qa | grep mysql"
stdout
should contain "^mysql-community-server-5.7.22-" (FAILED - 11)
php
Package "php"
should be installed (FAILED - 12)
Command "php -v"
stdout
should contain "^PHP 5.4.16 \(cli\) \(built: Apr 12 2018 19:02:01\)" (FAILED - 13)
Command "php -m"
stdout
should contain "bz2" (FAILED - 14)
Command "php -m"
stdout
should contain "calendar" (FAILED - 15)
Command "php -m"
stdout
should contain "Core" (FAILED - 16)
Command "php -m"
stdout
should contain "ctype" (FAILED - 17)
Command "php -m"
stdout
should contain "curl" (FAILED - 18)
Failures:
1) apache Package "httpd" should be installed
Failure/Error: it { should be_installed }
expected Package "httpd" to be installed
/bin/sh -c rpm -q httpd
package httpd is not installed
# /tmp/verifier/suites/serverspec/default_spec.rb:9:in `block (3 levels) in '
2) apache Service "httpd" should be enabled
Failure/Error: it { should be_enabled }
expected Service "httpd" to be enabled
/bin/sh -c systemctl --quiet is-enabled httpd
# /tmp/verifier/suites/serverspec/default_spec.rb:13:in `block (3 levels) in '
3) apache Service "httpd" should be running
Failure/Error: it { should be_running }
expected Service "httpd" to be running
/bin/sh -c systemctl is-active httpd
unknown
# /tmp/verifier/suites/serverspec/default_spec.rb:14:in `block (3 levels) in '
4) apache Port "80" should be listening
Failure/Error: it { should be_listening }
expected Port "80" to be listening
/bin/sh -c ss -tunl | grep -- :80\
# /tmp/verifier/suites/serverspec/default_spec.rb:22:in `block (4 levels) in '
5) apache Port "443" should be listening
Failure/Error: it { should be_listening }
expected Port "443" to be listening
/bin/sh -c ss -tunl | grep -- :443\
# /tmp/verifier/suites/serverspec/default_spec.rb:22:in `block (4 levels) in '
6) apache Command "httpd -v" stdout should contain " Apache/2.4.6"
Failure/Error: its(:stdout) { should contain(' Apache/2.4.6').before('Server built') }
expected "" to contain " Apache/2.4.6"
/bin/sh -c httpd -v
# /tmp/verifier/suites/serverspec/default_spec.rb:27:in `block (3 levels) in '
7) mysqld Package "mysql-community-server" should be installed
Failure/Error: it { should be_installed }
expected Package "mysql-community-server" to be installed
/bin/sh -c rpm -q mysql-community-server
package mysql-community-server is not installed
# /tmp/verifier/suites/serverspec/default_spec.rb:35:in `block (3 levels) in '
8) mysqld Service "mysqld" should be enabled
Failure/Error: it { should be_enabled }
expected Service "mysqld" to be enabled
/bin/sh -c systemctl --quiet is-enabled mysqld
# /tmp/verifier/suites/serverspec/default_spec.rb:39:in `block (3 levels) in '
9) mysqld Service "mysqld" should be running
Failure/Error: it { should be_running }
expected Service "mysqld" to be running
/bin/sh -c systemctl is-active mysqld
unknown
# /tmp/verifier/suites/serverspec/default_spec.rb:40:in `block (3 levels) in '
10) mysqld Port "3306" should be listening
Failure/Error: it { should be_listening }
expected Port "3306" to be listening
/bin/sh -c ss -tunl | grep -- :3306\
# /tmp/verifier/suites/serverspec/default_spec.rb:44:in `block (3 levels) in '
11) mysqld Command "rpm -qa | grep mysql" stdout should contain "^mysql-community-server-5.7.22-"
Failure/Error: its(:stdout) { should contain('^mysql-community-server-5.7.22-') }
expected "" to contain "^mysql-community-server-5.7.22-"
/bin/sh -c rpm -qa | grep mysql
# /tmp/verifier/suites/serverspec/default_spec.rb:48:in `block (3 levels) in '
12) php Package "php" should be installed
Failure/Error: it { should be_installed }
expected Package "php" to be installed
/bin/sh -c rpm -q php
package php is not installed
# /tmp/verifier/suites/serverspec/default_spec.rb:56:in `block (3 levels) in '
13) php Command "php -v" stdout should contain "^PHP 5.4.16 \(cli\) \(built: Apr 12 2018 19:02:01\)"
Failure/Error: its(:stdout) { should contain('^PHP 5.4.16 (cli) (built: Apr 12 2018 19:02:01)') }
expected "" to contain "^PHP 5.4.16 \(cli\) \(built: Apr 12 2018 19:02:01\)"
/bin/sh -c php -v
# /tmp/verifier/suites/serverspec/default_spec.rb:60:in `block (3 levels) in '
14) php Command "php -m" stdout should contain "bz2"
Failure/Error: its(:stdout) { should contain(php_module) }
expected "" to contain "bz2"
/bin/sh -c php -m
# /tmp/verifier/suites/serverspec/default_spec.rb:71:in `block (4 levels) in '
15) php Command "php -m" stdout should contain "calendar"
Failure/Error: its(:stdout) { should contain(php_module) }
expected "" to contain "calendar"
/bin/sh -c php -m
# /tmp/verifier/suites/serverspec/default_spec.rb:71:in `block (4 levels) in '
16) php Command "php -m" stdout should contain "Core"
Failure/Error: its(:stdout) { should contain(php_module) }
expected "" to contain "Core"
/bin/sh -c php -m
# /tmp/verifier/suites/serverspec/default_spec.rb:71:in `block (4 levels) in '
17) php Command "php -m" stdout should contain "ctype"
Failure/Error: its(:stdout) { should contain(php_module) }
expected "" to contain "ctype"
/bin/sh -c php -m
# /tmp/verifier/suites/serverspec/default_spec.rb:71:in `block (4 levels) in '
18) php Command "php -m" stdout should contain "curl"
Failure/Error: its(:stdout) { should contain(php_module) }
expected "" to contain "curl"
/bin/sh -c php -m
# /tmp/verifier/suites/serverspec/default_spec.rb:71:in `block (4 levels) in '
Finished in 0.61133 seconds (files took 0.34191 seconds to load)
18 examples, 18 failures
Failed examples:
rspec /tmp/verifier/suites/serverspec/default_spec.rb:9 # apache Package "httpd" should be installed
rspec /tmp/verifier/suites/serverspec/default_spec.rb:13 # apache Service "httpd" should be enabled
rspec /tmp/verifier/suites/serverspec/default_spec.rb:14 # apache Service "httpd" should be running
rspec /tmp/verifier/suites/serverspec/default_spec.rb[1:3:1] # apache Port "80" should be listening
rspec /tmp/verifier/suites/serverspec/default_spec.rb[1:4:1] # apache Port "443" should be listening
rspec /tmp/verifier/suites/serverspec/default_spec.rb:27 # apache Command "httpd -v" stdout should contain " Apache/2.4.6"
rspec /tmp/verifier/suites/serverspec/default_spec.rb:35 # mysqld Package "mysql-community-server" should be installed
rspec /tmp/verifier/suites/serverspec/default_spec.rb:39 # mysqld Service "mysqld" should be enabled
rspec /tmp/verifier/suites/serverspec/default_spec.rb:40 # mysqld Service "mysqld" should be running
rspec /tmp/verifier/suites/serverspec/default_spec.rb:44 # mysqld Port "3306" should be listening
rspec /tmp/verifier/suites/serverspec/default_spec.rb:48 # mysqld Command "rpm -qa | grep mysql" stdout should contain "^mysql-community-server-5.7.22-"
rspec /tmp/verifier/suites/serverspec/default_spec.rb:56 # php Package "php" should be installed
rspec /tmp/verifier/suites/serverspec/default_spec.rb:60 # php Command "php -v" stdout should contain "^PHP 5.4.16 \(cli\) \(built: Apr 12 2018 19:02:01\)"
rspec /tmp/verifier/suites/serverspec/default_spec.rb[3:3:1:1] # php Command "php -m" stdout should contain "bz2"
rspec /tmp/verifier/suites/serverspec/default_spec.rb[3:4:1:1] # php Command "php -m" stdout should contain "calendar"
rspec /tmp/verifier/suites/serverspec/default_spec.rb[3:5:1:1] # php Command "php -m" stdout should contain "Core"
rspec /tmp/verifier/suites/serverspec/default_spec.rb[3:6:1:1] # php Command "php -m" stdout should contain "ctype"
rspec /tmp/verifier/suites/serverspec/default_spec.rb[3:7:1:1] # php Command "php -m" stdout should contain "curl"
/opt/chef/embedded/bin/ruby -I/tmp/verifier/suites/serverspec -I/tmp/verifier/gems/gems/rspec-support-3.7.1/lib:/tmp/verifier/gems/gems/rspec-core-3.7.1/lib /opt/chef/embedded/bin/rspec --pattern /tmp/verifier/suites/serverspec/**/*_spec.rb --color --format documentation --default-path /tmp/verifier/suites/serverspec failed
!!!!!! Ruby Script [/tmp/verifier/gems/gems/busser-serverspec-0.5.10/lib/busser/runner_plugin/../serverspec/runner.rb /tmp/verifier/suites/serverspec] exit code was 1
>>>>>> ------Exception-------
>>>>>> Class: Kitchen::ActionFailed
>>>>>> Message: 1 actions failed.
>>>>>> Verify failed on instance . Please see .kitchen/logs/default-blog-demo.log for more details
>>>>>> ----------------------
>>>>>> Please see .kitchen/logs/kitchen.log for more details
>>>>>> Also try running kitchen diagnose --all
for configuration
-------------[ここまで]-------------
[補足] まだ、kitchenのEC2インスタンスにApache、PHP、MySQLはインストールされていないた
め、各テストでエラーが出力されます。基本的に、構築コード作成よりも前にテストコードを先に
作成して設定項目に漏れがないか確認したほうが良いと思います。(構築コードでの抜け漏れを防ぐ)
3. 構築コードの作成
$ vim recipes/default.rb
----------[以下の通り設定]----------
#
# Cookbook:: blog_demo
# Recipe:: default
#
# Copyright:: 2018, The Authors, All Rights Reserved.
# apacheインストール
package 'httpd' do
version '2.4.6'
action :install
end
service "httpd" do
action [ :enable, :start ]
end
package 'mod_ssl' do
action :install
notifies :restart, 'service[httpd]'
end
# mysqlインストール
bash 'mysql install' do
code <<-EOH
yum -y remove mariadb-libs
rm -rf /var/lib/mysql/
yum -y localinstall http://dev.mysql.com/get/mysql57-community-release-el7-7.noarch.rpm
yum -y install mysql-community-server-5.7.22
EOH
not_if "rpm -qa | grep mysql-community-server"
end
service "mysqld" do
action [ :enable, :start ]
end
# phpインストール
package 'php' do
version '5.4.16'
action :install
end
------------[ここまで]------------
4. 構築コードの実行
$ bundle exec kitchen converge
----------[以下出力結果]----------
-----> Starting Kitchen (v1.20.0)
-----> Converging ...
Preparing files for transfer
Preparing dna.json
Resolving cookbook dependencies with Berkshelf 6.3.2...
Removing non-cookbook files before transfer
Preparing solo.rb
-----> Chef Omnibus installation detected (install only if missing)
Transferring files to
Starting Chef Client, version 14.1.12
resolving cookbooks for run list: ["blog_demo::default"]
Synchronizing Cookbooks:
- blog_demo (0.1.0)
Installing Cookbook Gems:
Compiling Cookbooks...
Converging 6 resources
Recipe: blog_demo::default
* yum_package[httpd] action install
- install version 2.4.6 of package httpd
* service[httpd] action enable
- enable service service[httpd]
* service[httpd] action start
- start service service[httpd]
* yum_package[mod_ssl] action install
- install version 1:2.4.6-80.el7.centos.x86_64 of package mod_ssl
* bash[mysql install] action run
- execute "bash" "/tmp/chef-script20180521-23285-a6purr"
* service[mysqld] action enable (up to date)
* service[mysqld] action start
- start service service[mysqld]
* yum_package[php] action install
- install version 5.4.16 of package php
* service[httpd] action restart
- restart service service[httpd]
Running handlers:
Running handlers complete
Chef Client finished, 8/9 resources updated in 01 minutes 11 seconds
Downloading files from
Finished converging (1m17.08s).
-----> Kitchen is finished. (1m20.53s)
------------[ここまで]------------
5. 構築コード反映後のテスト
$ bundle exec kitchen verify
----------[以下出力結果]----------
-----> Starting Kitchen (v1.20.0)
-----> Setting up ...
Finished setting up (0m0.00s).
-----> Verifying ...
Preparing files for transfer
-----> Busser installation detected (busser)
-----> Busser plugin detected: busser-serverspec
Removing /tmp/verifier/suites/serverspec
Transferring files to
-----> Running serverspec test suite
/opt/chef/embedded/bin/ruby -I/tmp/verifier/suites/serverspec -I/tmp/verifier/gems/gems/rspec-support-3.7.1/lib:/tmp/verifier/gems/gems/rspec-core-3.7.1/lib /opt/chef/embedded/bin/rspec --pattern /tmp/verifier/suites/serverspec/**/*_spec.rb --color --format documentation --default-path /tmp/verifier/suites/serverspec
apache
Package "httpd"
should be installed
Service "httpd"
should be enabled
should be running
Port "80"
should be listening
Port "443"
should be listening
Command "httpd -v"
stdout
should contain " Apache/2.4.6"
mysqld
Package "mysql-community-server"
should be installed
Service "mysqld"
should be enabled
should be running
Port "3306"
should be listening
Command "rpm -qa | grep mysql"
stdout
should contain "^mysql-community-server-5.7.22-"
php
Package "php"
should be installed
Command "php -v"
stdout
should contain "^PHP 5.4.16 \(cli\) \(built: Apr 12 2018 19:02:01\)"
Command "php -m"
stdout
should contain "bz2"
Command "php -m"
stdout
should contain "calendar"
Command "php -m"
stdout
should contain "Core"
Command "php -m"
stdout
should contain "ctype"
Command "php -m"
stdout
should contain "curl"
Finished in 0.7623 seconds (files took 2.36 seconds to load)
18 examples, 0 failures
Finished verifying (0m6.00s).
-----> Kitchen is finished. (0m9.37s)
------------[ここまで]------------
[補足] テストが全てOKになりました。これで構築コードのテストができます。
最後に
chefやserverspecは視覚的にもわかりやすいので良いですね。
他の構成管理ツールは触ったことがないので、比較しようがありませんが。。。
以上、読んでいただいてありがとうございました。