- 追加された行はこの色です。
- 削除された行はこの色です。
#contents
** Serverspecとは何か? [#yf8d7104]
- 概要
-- サーバー構成のテスト
-- 特定のツールに依存しない
- 公式サイト: serverspec.org
- 知識
-- Vagrant
-- Ruby
-- RSpec
-- Itamae
- 全体像
-- host: Ruby, Itamae, Serverspec
-- web: Apache, PHP
** サーバーの設定をしていこう [#o455a9fd]
- 利用可能なBoxファイルを検索
-- Atlas >> Discover Vagrant Boxes
- 'bento/centos-6.7'のVagrant boxを利用
- Vagrantfileを生成
$ cd ~/Documents/MyVagrant
$ mkdir serverspec_lessons
$ cd serverspec_lessons
$ vagrant init bento/centos-6.7
- Vagrantfileを開き下記をコメントアウト
$ vi Vagrantfile
config.vm.box = "bento/centos-6.7"
- 下記を貼り付け
config.vm.define "host" do |node|
node.vm.box = "bento/centos-6.7"
node.vm.hostname = "host"
node.vm.network :private_network, ip: "192.168.33.10"
end
config.vm.define "web" do |node|
node.vm.box = "bento/centos-6.7"
node.vm.hostname = "web"
node.vm.network :private_network, ip: "192.168.33.11"
end
$ vagrant up
- Vagrant確認
$ vagrant status
Current machine states:
host running (virtualbox)
web running (virtualbox)
This environment represents multiple VMs. The VMs are all listed
above with their current state. For more information about a specific
VM, run `vagrant status NAME`.
- webに対してssh configを設定
$ vagrant ssh host
$ vi .ssh/config
Host web
HostName 192.168.33.11
$ chmod 600 .ssh/config
- 秘密鍵/公開鍵作成
$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/vagrant/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
- webに公開鍵を転送 &color(red){*};Vagrantユーザーのデフォルトパスワードは 'vagrant'
[vagrant@host ~]$ ssh-copy-id web
The authenticity of host '192.168.33.11 (192.168.33.11)' can't be established.
RSA key fingerprint is 90:d8:41:6f:c5:39:1d:54:0d:43:4e:34:dc:f1:d2:6b.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.33.11' (RSA) to the list of known hosts.
vagrant@192.168.33.11's password:
- SSH接続確認
$ ssh web
$ exit
** Serverspecをインストールしよう [#acee2252]
- hostにgitをインストール
$ sudo yum -y install git
- 環境初期構築用のスクリプト&color(red){*};を dotinstallres/centos65 リポジトリからダウンロード&hostに対して実行
-- &color(red){*}; run.sh: Ansibleインストール, main.yml実行
-- main.yml: CentOS初期設定, Apache, PHP 5.6, MySQL, Ruby 2.2.2 (rbenv/ruby-build), Node.jsインストール
-- php.ini.custom: main.ymlより参照。php.iniの設定内容を記述
-- my.cnf.custom: main.ymlより参照。my.cnfの設定内容を記述
-- bash_profile.custom: main.ymlより参照。bash_profileの設定内容を記述
$ git clone https://github.com/dotinstallres/centos65.git
$ cd centos65
$ ./run.sh
....
....
PLAY RECAP *********************************************************************
localhost : ok=32 changed=31 unreachable=0 failed=0
- シェルの再起動
$ exec $SHELL -l
- ruby確認
$ ruby -v
ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]
- インストール済みGem一覧の表示(rakeがインストールされていることを確認)
$ gem list
*** LOCAL GEMS ***
bigdecimal (1.2.6)
io-console (0.4.3)
json (1.8.1)
minitest (5.4.3)
power_assert (0.2.2)
psych (2.0.8)
rake (10.4.2)
rdoc (4.2.0)
test-unit (3.0.8)
- itamaeとserverspecをインストール
$ gem install itamae serverspec
- gem list確認
$ gem list
*** LOCAL GEMS ***
ansi (1.5.0)
....
diff-lcs (1.3)
hashie (3.5.5)
....
itamae (1.9.11)
....
multi_json (1.12.1)
net-scp (1.2.1)
net-ssh (4.1.0)
net-telnet (0.1.1)
....
rspec (3.5.0)
rspec-core (3.5.4)
rspec-expectations (3.5.0)
rspec-its (1.2.0)
rspec-mocks (3.5.0)
rspec-support (3.5.0)
schash (0.1.2)
serverspec (2.38.0)
sfl (2.3)
specinfra (2.67.2)
....
thor (0.19.4)
$ cd
** serverspec-initを使ってみよう [#fdc2e94f]
- Itamaeの設定ファイル(recipe.rb)作成
$ mkdir myproject
$ cd myproject/
$ mkdir cookbooks
$ cd cookbooks/
$ vi recipe.rb
$ cd ..
- serverspec-initコマンドを使ってserverspecの設定ファイルを自動作成
$ pwd
/home/vagrant/myproject
$ serverspec-init
Select OS type:
1) UN*X
2) Windows
Select number: 1
Select a backend type:
1) SSH
2) Exec (local)
Select number: 1
Vagrant instance y/n: n
Input target host name: web
+ spec/
+ spec/web/
+ spec/web/sample_spec.rb
+ spec/spec_helper.rb
+ Rakefile
+ .rspec
- /home/vagrant/myproject配下のファイル構造
/home/vagrant/myproject
|--.rspec
|--Rakefile
|--cookbooks
| |--recipe.rb
|--spec
| |--spec_helper.rb
| |--web
| | |--sample_spec.rb
- Apacheに関するspecファイルを作成(デフォルトのsample_spec.rbは削除)
$ rm spec/web/sample_spec.rb
$ vi spec/web/httpd_spec.rb
** はじめてのテストをしてみよう [#v932faab]
- テスト駆動開発の手順に沿ってテストを記述
+ fail: 失敗するテストを書く
+ pass: テストを通るようにする
+ refactor: リファクタリングをする
- httpdのテストコード(myproject/spec/web/httpd_spec.rb)
# 1. fail
# 2. pass
# 3. refactor
require 'spec_helper'
describe package('httpd') do
it { should be_installed }
end
- テスト実行
$ rake spec
/home/vagrant/.rbenv/versions/2.2.2/bin/ruby -I/home/vagrant/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rspec-support-3.5.0/lib:/home/vagrant/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rspec-core-3.5.4/lib /home/vagrant/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rspec-core-3.5.4/exe/rspec --pattern spec/web/\*_spec.rb
Package "httpd"
should be installed (FAILED - 1)
Failures:
1) Package "httpd" should be installed
On host `web'
Failure/Error: it { should be_installed }
expected Package "httpd" to be installed
sudo -p 'Password: ' /bin/sh -c rpm\ -q\ httpd
package httpd is not installed
# ./spec/web/httpd_spec.rb:8:in `block (2 levels) in <top (required)>'
Finished in 1.08 seconds (files took 0.5465 seconds to load)
1 example, 1 failure
Failed examples:
rspec ./spec/web/httpd_spec.rb:8 # Package "httpd" should be installed
/home/vagrant/.rbenv/versions/2.2.2/bin/ruby -I/home/vagrant/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rspec-support-3.5.0/lib:/home/vagrant/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rspec-core-3.5.4/lib /home/vagrant/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rspec-core-3.5.4/exe/rspec --pattern spec/web/\*_spec.rb failed
- Itamaeの設定ファイル編集(myproject/cookbooks/recipe.rb)
package 'httpd'
- Itamae実行(dry run)
$ itamae ssh -h web cookbooks/recipe.rb -n
- Itamae実行
$ itamae ssh -h web cookbooks/recipe.rb
INFO : Starting Itamae...
INFO : Recipe: /home/vagrant/myproject/cookbooks/recipe.rb
INFO : package[httpd] installed will change from 'false' to 'true'
- テスト再実行
$ rake spec
/home/vagrant/.rbenv/versions/2.2.2/bin/ruby -I/home/vagrant/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rspec-support-3.5.0/lib:/home/vagrant/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rspec-core-3.5.4/lib /home/vagrant/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rspec-core-3.5.4/exe/rspec --pattern spec/web/\*_spec.rb
Package "httpd"
should be installed
Finished in 0.64223 seconds (files took 0.43663 seconds to load)
1 example, 0 failures
** ResourceとMatcherを調べてみよう [#u8cd6585]
- 上記テストの例では Resourceは package('httpd') で Matcherは should be_installed
- ResourceとMatcherの一覧は公式サイト >> Resource Types で確認可能
** httpdのテストをしてみよう [#o39b3d36]
- httpdが起動しているか/80番ポートでListenしているかのテスト(httpd_spec.rb)
# 1. fail
# 2. pass
# 3. refactor
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
- テスト実行
$ rake spec
/home/vagrant/.rbenv/versions/2.2.2/bin/ruby -I/home/vagrant/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rspec-support-3.5.0/lib:/home/vagrant/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rspec-core-3.5.4/lib /home/vagrant/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rspec-core-3.5.4/exe/rspec --pattern spec/web/\*_spec.rb
Package "httpd"
should be installed
Service "httpd"
should be enabled (FAILED - 1)
should be running (FAILED - 2)
Port "80"
should be listening (FAILED - 3)
Failures:
1) Service "httpd" should be enabled
On host `web'
Failure/Error: it { should be_enabled }
expected Service "httpd" to be enabled
sudo -p 'Password: ' /bin/sh -c chkconfig\ --list\ httpd\ \|\ grep\ 3:on
# ./spec/web/httpd_spec.rb:12:in `block (2 levels) in <top (required)>'
2) Service "httpd" should be running
On host `web'
Failure/Error: it { should be_running }
expected Service "httpd" to be running
sudo -p 'Password: ' /bin/sh -c service\ httpd\ status
httpd is stopped
# ./spec/web/httpd_spec.rb:13:in `block (2 levels) in <top (required)>'
3) Port "80" should be listening
On host `web'
Failure/Error: it { should be_listening }
expected Port "80" to be listening
sudo -p 'Password: ' /bin/sh -c netstat\ -tunl\ \|\ grep\ --\ :80\\\
# ./spec/web/httpd_spec.rb:17:in `block (2 levels) in <top (required)>'
Finished in 0.86085 seconds (files took 0.43814 seconds to load)
4 examples, 3 failures
Failed examples:
rspec ./spec/web/httpd_spec.rb:12 # Service "httpd" should be enabled
rspec ./spec/web/httpd_spec.rb:13 # Service "httpd" should be running
rspec ./spec/web/httpd_spec.rb:17 # Port "80" should be listening
/home/vagrant/.rbenv/versions/2.2.2/bin/ruby -I/home/vagrant/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rspec-support-3.5.0/lib:/home/vagrant/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rspec-core-3.5.4/lib /home/vagrant/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rspec-core-3.5.4/exe/rspec --pattern spec/web/\*_spec.rb failed
- Itamaeの設定ファイル修正(recipe.rb)
package 'httpd'
service 'httpd' do
action [:enable, :start]
end
- Itamae実行
$ itamae ssh -h web cookbooks/recipe.rb
INFO : Starting Itamae...
INFO : Recipe: /home/vagrant/myproject/cookbooks/recipe.rb
INFO : service[httpd] enabled will change from 'false' to 'true'
INFO : service[httpd] running will change from 'false' to 'true'
- テスト再実行
$ rake spec
/home/vagrant/.rbenv/versions/2.2.2/bin/ruby -I/home/vagrant/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rspec-support-3.5.0/lib:/home/vagrant/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rspec-core-3.5.4/lib /home/vagrant/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rspec-core-3.5.4/exe/rspec --pattern spec/web/\*_spec.rb
Package "httpd"
should be installed
Service "httpd"
should be enabled
should be running
Port "80"
should be listening
Finished in 0.8126 seconds (files took 0.4321 seconds to load)
4 examples, 0 failures
** fileリソースを使ってみよう [#s04cf7bd]
- index.htmlが存在しHello Worldという文字列が記述されているかのテスト(httpd_spec.rb)
# 1. fail
# 2. pass
# 3. refactor
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('/var/www/html/index.html') do
it { should be_file }
it { should be_owned_by 'apache' }
it { should be_grouped_into 'apache' }
its(:content) { should match /Hello World/ }
end
- テスト実行
$ rake spec
/home/vagrant/.rbenv/versions/2.2.2/bin/ruby -I/home/vagrant/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rspec-support-3.5.0/lib:/home/vagrant/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rspec-core-3.5.4/lib /home/vagrant/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rspec-core-3.5.4/exe/rspec --pattern spec/web/\*_spec.rb
Package "httpd"
should be installed
Service "httpd"
should be enabled
should be running
Port "80"
should be listening
File "/var/www/html/index.html"
should be file (FAILED - 1)
should be owned by "apache" (FAILED - 2)
should be grouped into "apache" (FAILED - 3)
content
should match /Hello World/ (FAILED - 4)
Failures:
1) File "/var/www/html/index.html" should be file
On host `web'
Failure/Error: it { should be_file }
expected `File "/var/www/html/index.html".file?` to return true, got false
sudo -p 'Password: ' /bin/sh -c test\ -f\ /var/www/html/index.html
# ./spec/web/httpd_spec.rb:21:in `block (2 levels) in <top (required)>'
2) File "/var/www/html/index.html" should be owned by "apache"
On host `web'
Failure/Error: it { should be_owned_by 'apache' }
expected `File "/var/www/html/index.html".owned_by?("apache")` to return true, got false
sudo -p 'Password: ' /bin/sh -c stat\ -c\ \%U\ /var/www/html/index.html\ \|\ grep\ --\ \\\^apache\\\$
# ./spec/web/httpd_spec.rb:22:in `block (2 levels) in <top (required)>'
3) File "/var/www/html/index.html" should be grouped into "apache"
On host `web'
Failure/Error: it { should be_grouped_into 'apache' }
expected `File "/var/www/html/index.html".grouped_into?("apache")` to return true, got false
sudo -p 'Password: ' /bin/sh -c stat\ -c\ \%G\ /var/www/html/index.html\ \|\ grep\ --\ \\\^apache\\\$
# ./spec/web/httpd_spec.rb:23:in `block (2 levels) in <top (required)>'
4) File "/var/www/html/index.html" content should match /Hello World/
On host `web'
Failure/Error: its(:content) { should match /Hello World/ }
expected "" to match /Hello World/
Diff:
@@ -1,2 +1,2 @@
-/Hello World/
+""
sudo -p 'Password: ' /bin/sh -c cat\ /var/www/html/index.html\ 2\>\ /dev/null\ \|\|\ echo\ -n
# ./spec/web/httpd_spec.rb:24:in `block (2 levels) in <top (required)>'
Finished in 0.90728 seconds (files took 0.4069 seconds to load)
8 examples, 4 failures
Failed examples:
rspec ./spec/web/httpd_spec.rb:21 # File "/var/www/html/index.html" should be file
rspec ./spec/web/httpd_spec.rb:22 # File "/var/www/html/index.html" should be owned by "apache"
rspec ./spec/web/httpd_spec.rb:23 # File "/var/www/html/index.html" should be grouped into "apache"
rspec ./spec/web/httpd_spec.rb:24 # File "/var/www/html/index.html" content should match /Hello World/
/home/vagrant/.rbenv/versions/2.2.2/bin/ruby -I/home/vagrant/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rspec-support-3.5.0/lib:/home/vagrant/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rspec-core-3.5.4/lib /home/vagrant/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rspec-core-3.5.4/exe/rspec --pattern spec/web/\*_spec.rb failed
- index.html作成
$ cd cookbooks/
$ mkdir files
$ cd files/
$ vi index.html
<html>
Hello World
</html>
$ cd ../..
- Itamae設定ファイル修正(recipe.rb)
package 'httpd'
service 'httpd' do
action [:enable, :start]
end
remote_file '/var/www/html/index.html' do
owner 'apache'
group 'apache'
end
- Itamae実行
$ itamae ssh -h web cookbooks/recipe.rb
INFO : Starting Itamae...
INFO : Recipe: /home/vagrant/myproject/cookbooks/recipe.rb
INFO : remote_file[/var/www/html/index.html] exist will change from 'false' to 'true'
INFO : remote_file[/var/www/html/index.html] modified will change from 'false' to 'true'
INFO : remote_file[/var/www/html/index.html] owner will be 'apache'
INFO : remote_file[/var/www/html/index.html] group will be 'apache'
INFO : diff:
INFO : --- /dev/null 2017-03-12 12:01:09.240000001 +0000
INFO : +++ /tmp/itamae_tmp/1489326611.9137843 2017-03-12 13:50:11.959835316 +0000
INFO : @@ -0,0 +1,3 @@
INFO : +<html>
INFO : +Hello World
INFO : +</html>
- テスト再実行
$ rake spec
/home/vagrant/.rbenv/versions/2.2.2/bin/ruby -I/home/vagrant/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rspec-support-3.5.0/lib:/home/vagrant/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rspec-core-3.5.4/lib /home/vagrant/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rspec-core-3.5.4/exe/rspec --pattern spec/web/\*_spec.rb
Package "httpd"
should be installed
Service "httpd"
should be enabled
should be running
Port "80"
should be listening
File "/var/www/html/index.html"
should be file
should be owned by "apache"
should be grouped into "apache"
content
should match /Hello World/
Finished in 0.8986 seconds (files took 0.43226 seconds to load)
8 examples, 0 failures