Ansible + Serverspec + Kirbyによるサーバの自動構築

最近、Serverspecによるテストが不足している場合に指摘してくれるツールとして、Kirby(カービィ)というものを作りました。

この記事では、Kirbyをちょっと試してみたいという方の参考になるように、Ansible + Serverspec + Kirbyによるサーバの自動構築について、チュートリアルぽい感じで書いてみます。今回はVagrant上で構築します。

レポジトリの準備

最初に、GitHubから今回利用するPlaybookやSpecファイルが入ったレポジトリを取得しておきます。

git clone https://github.com/ks888/kirby_tutorial.git
cd kirby_tutorial

仮想環境の準備

VagrantVirtualBoxによる仮想環境を準備します。

それぞれ以下のサイトからOSに合ったパッケージをダウンロードして、インストールします。インストール済みであれば、不要です。

インストール後、以下のコマンドを実行し、Ansibleの設定対象となるサーバを1台作成します。

vagrant up

次に、SSH用の設定ファイルを生成します。

vagrant ssh-config node1 > ssh_config

最後に、作成したサーバにSSHできることを確認します。

ssh -F ssh_config node1

Ansibleの準備

Ansibleのインストールについては、以下のドキュメントが参考になるかと思います。インストール済みであれば、不要です。

Installation — Ansible Documentation

先ほど取得したレポジトリにあるPlaybook(site.yml)を実行してみます。先ほど立ち上げたサーバに対して、Ansibleが実行されます。

ansible-playbook -i inventory site.yml

以下のような出力が得られれば、成功です。

PLAY [web] ********************************************************************

TASK: [Apache2のインストール] ********************************************************
changed: [node1]

TASK: [/etc/apache2/conf-available/security.confの設定] **************************
changed: [node1]

TASK: [Apache2の再起動] ***********************************************************
changed: [node1]

PLAY RECAP ********************************************************************
node1                      : ok=3    changed=3    unreachable=0    failed=0

Serverspecの準備

以下のコマンドを実行し、Serverspecをインストールします。

bundle install --path vendor/bundle

次に、Serverspecが動作することを確認します。先ほど立ち上げたサーバに対して、Serverspecを実行します。

bundle exec rake spec

以下のような出力が得られれば、成功です。

Package "apache2"
  should be installed

Service "apache2"
  should be enabled
  should be running

Finished in 1.28 seconds (files took 0.28906 seconds to load)
3 examples, 0 failures

Kirbyの準備と実行

以下のコマンドを実行し、Kirbyをインストールします。

mkdir callback_plugins
wget https://raw.githubusercontent.com/ks888/kirby/master/callback_plugins/kirby.py -P callback_plugins

次に、kirby.cfgという名前で、以下の内容をもつ設定ファイルを作成します。この設定ファイルで、Serverspecを実行するディレクトリとコマンドを指定しています。

[defaults]
enable = yes

serverspec_dir = ./
serverspec_cmd = bundle exec rake spec

一度仮想環境を作り直し、Kirbyを実行します。KirbyはAnsibleのプラグインなので、通常通りAnsibleを実行すれば、Kirbyも動きます。

vagrant destroy -f && vagrant up
ansible-playbook -i inventory site.yml

以下のような出力が得られれば、成功です。

PLAY [web] ******************************************************************** 

TASK: [Apache2のインストール] ******************************************************** 
changed: [node1]
tested by: 
- rspec ./spec/node1/apache2_spec.rb:8 # Service "apache2" should be enabled
- rspec ./spec/node1/apache2_spec.rb:9 # Service "apache2" should be running
- rspec ./spec/node1/apache2_spec.rb:4 # Package "apache2" should be installed

TASK: [/etc/apache2/conf-available/security.confの設定] ************************** 
changed: [node1]
tested by: 

TASK: [Apache2の再起動] *********************************************************** 
changed: [node1]
tested by: 

PLAY RECAP ******************************************************************** 
*** Kirby Results ***
Coverage  : 33% (1 of 3 tasks are tested)
Not tested:
 - /etc/apache2/conf-available/security.confの設定
 - Apache2の再起動
*** Kirby End *******
node1                      : ok=3    changed=3    unreachable=0    failed=0

タスクごとに、tested by:という行が出力されています。これは、このタスクがどのServerspecのテストによってテストされたか、を示しています。

また、*** Kirby Results ***という行の下に、テストされていないタスクの割合と、テストされていないタスクのリストが出力されています。この例では、以下の2つがテストされていません。

  • /etc/apache2/conf-available/security.confの設定
  • Apache2の再起動

ここからは、これらのタスクへの対応例を紹介していきます。

テスト不足の改善1

1つ目のテストされていないタスクは、以下のようなタスクです。

  - name: /etc/apache2/conf-available/security.confの設定
    template: src=security.conf.j2 dest=/etc/apache2/conf-available/security.conf

本番環境向けにServerSignatureやServerTokensを設定したsecurity.confを配置しています。

このタスクに対するテストとして、以下のテストをspec/node1/apache2_spec.rbに追加してみます(実はコメントアウトされたものが既にあるので、コメントを外すだけでOKです)。

describe file('/etc/apache2/conf-available/security.conf') do
  it { should be_file }
  its(:content) { should match /^ServerTokens Prod$/ }
  its(:content) { should match /^ServerSignature Off$/ }
end

もう一度Kirbyを実行してみます。

vagrant destroy -f && vagrant up
ansible-playbook -i inventory site.yml

以下のような出力が得られれば、成功です。テストされていないタスクが1つ減ったことが確認できると思います。

PLAY [web] ******************************************************************** 

TASK: [Apache2のインストール] ******************************************************** 
changed: [node1]
tested by: 
- rspec ./spec/node1/apache2_spec.rb:13 # File "/etc/apache2/conf-available/security.conf" should be file
- rspec ./spec/node1/apache2_spec.rb:8 # Service "apache2" should be enabled
- rspec ./spec/node1/apache2_spec.rb:9 # Service "apache2" should be running
- rspec ./spec/node1/apache2_spec.rb:4 # Package "apache2" should be installed

TASK: [/etc/apache2/conf-available/security.confの設定] ************************** 
changed: [node1]
tested by: 
- rspec ./spec/node1/apache2_spec.rb:15 # File "/etc/apache2/conf-available/security.conf" content should match /^ServerSignature Off$/
- rspec ./spec/node1/apache2_spec.rb:14 # File "/etc/apache2/conf-available/security.conf" content should match /^ServerTokens Prod$/

TASK: [Apache2の再起動] *********************************************************** 
changed: [node1]
tested by: 

PLAY RECAP ******************************************************************** 
*** Kirby Results ***
Coverage  : 67% (2 of 3 tasks are tested)
Not tested:
 - Apache2の再起動
*** Kirby End *******
node1                      : ok=3    changed=3    unreachable=0    failed=0   

テスト不足の改善2

残りのテストされていないタスクは、以下のようなApache2を再起動するタスクです。

  - name: Apache2の再起動
    service: name=apache2 state=restarted

このタスクに対するテストは、どういうものが良いでしょうか?私としては、サーバの状態を特に変えないタスクや、既存のテストで十分そうなタスクについては、無理にテストを書かなくてもいいのでは、と考えています。そのため、このタスクについてはテストがなくてもいいかな、と思っています。

では、テストが不要なタスクにどう対処するとよいでしょうか?何もしないという手もありますが、Ansible実行のたびに「テストないよー」と指摘されるのは今ひとつな気がします。

実はKirbyには、「このタスクにはテストがいらないこと」を示す方法が用意されています。方法は簡単で、タスクの名前にcoverage_skipという文字列を含めると、そのタスクのテストがなくても、指摘されないようになります。

今回のケースだと、site.ymlのApache2の再起動タスクを、以下のように変更します。[]で括る必要はないですが、見栄えがいい気がするので付けてます。

  - name: Apache2の再起動 [coverage_skip]
    service: name=apache2 state=restarted

もう一度Kirbyを実行してみます。

vagrant destroy -f && vagrant up
ansible-playbook -i inventory site.yml

以下のような出力が得られれば、成功です。テストがないと指摘されているタスクが0になったことが確認できると思います。

PLAY [web] ******************************************************************** 

TASK: [Apache2のインストール] ******************************************************** 
changed: [node1]
tested by: 
- rspec ./spec/node1/apache2_spec.rb:13 # File "/etc/apache2/conf-available/security.conf" should be file
- rspec ./spec/node1/apache2_spec.rb:8 # Service "apache2" should be enabled
- rspec ./spec/node1/apache2_spec.rb:9 # Service "apache2" should be running
- rspec ./spec/node1/apache2_spec.rb:4 # Package "apache2" should be installed

TASK: [/etc/apache2/conf-available/security.confの設定] ************************** 
changed: [node1]
tested by: 
- rspec ./spec/node1/apache2_spec.rb:15 # File "/etc/apache2/conf-available/security.conf" content should match /^ServerSignature Off$/
- rspec ./spec/node1/apache2_spec.rb:14 # File "/etc/apache2/conf-available/security.conf" content should match /^ServerTokens Prod$/

TASK: [Apache2の再起動 [coverage_skip]] ******************************************* 
changed: [node1]

PLAY RECAP ******************************************************************** 
*** Kirby Results ***
Coverage  : 100% (2 of 2 tasks are tested)
*** Kirby End *******
node1                      : ok=3    changed=3    unreachable=0    failed=0   

まとめ

この記事では、Kirbyにテスト不足を指摘させる方法と、テスト不足とされたタスクへの対応例を、ご紹介しました。使用したPlaybook、Specファイル等は以下のレポジトリにあります。

ks888/kirby_tutorial · GitHub

問題やご意見などありましたら、GitHubTwitter等でご連絡ください。