ようへいの日々精進XP

よかろうもん

Ansible と serverspec のパラレルテストを試してみる

概要

  • こちら の中で Ansible という python で書かれた構成管理ツールを知った
  • そう言えば、前回の Chef Casual Talks Vol.3 で @urasoko さんも言っていたような...
  • ということで試してみる
  • Ansible についてはこちら

インストール

環境

Ansible をインストールする cookbook

  • あえて chef の cookbook で導入
  • cookbook はこちら

knife ec2 server create

knife ec2 server create -S xxxxxx -i ~/pathto/xxxxxx -r "recipe[ansible_install_cookbook::ansible]" -I ami-39b23d38 --flavor t1.micro --region ap-northeast-1 --availability-zone ap-northeast-1a -G quick-start-8 -x ec2-user -N Ansible -VV

この辺はお約束。

Debian Wheezy には...

python のパッケージ管理ツールはどんなものがあるか知らなかったが pip というツールが良いらしいのでそれをまずインストールする。

sudo apt-get install pip

続いて python のバージョンを確認しつつ、pythonx.x-dev をインストールする。

sudo apt-get install python2.7-dev

そして pip install を実行する。

sudo pip install ansible

はじめの一歩

Ansible について

  • Chef とか puppet と比較してシンプルな構成(を目指して作られている)
  • Chef だと cookbook にあたるものが Ansible だと Playbooks と呼ばれる YAML で記述されたファイルとなる
  • Chef だと resource にあたるものが Ansible だと module と呼ばれるようだ(package とか cookbook_file とかにあたる)

対象ホストを ANSIBLE_HOSTS に追加する

まずは ansible で設定を適用するホストを環境変数ANSIBLE_HOSTS で指定するファイルに設定する。

vim /tmp/ansible_host

以下のように記述する。

[test]
ec2-xx-xxx-xx-xxx.ap-northeast-1.compute.amazonaws.com

環境変数ANSIBLE_HOSTS を適用する。

export ANSIBLE_HOSTS=/tmp/ansible_host

対象ホストでコマンドを実行してみる

-m でモジュールを指定、-uリモートホスト(対象ホスト)のユーザー名を指定、--private-key で鍵ファイルを指定して...以下のように実行する。

ansible all -m ping -u ec2-user --private-key=~/pathto/xxxxx.pem

以下のような結果が出力される。

ec2-xx-xxx-xx-xxx.ap-northeast-1.compute.amazonaws.com | success >> {
    "changed": false, 
    "ping": "pong"
}

Playbooks を試してみる

Playbooks を以下のように記載する。

vim /tmp/mysql.yml

以下のように ansible-playbook を実行する。

ansible-playbook /tmp/mysql.yml --private-key=~/pathto/xxxxxxx.pem

以下のように出力された。

PLAY [test] ******************************************************************* 

GATHERING FACTS *************************************************************** 
ok: [ec2-xx-xxx-xx-xxx.ap-northeast-1.compute.amazonaws.com]

TASK: [install mysql-server] ************************************************** 
changed: [ec2-xx-xxx-xx-xxx.ap-northeast-1.compute.amazonaws.com]

PLAY RECAP ******************************************************************** 
ec2-xx-xxx-xx-xxx.ap-northeast-1.compute.amazonaws.com : ok=2    changed=1    unreachable=0    failed=0

二回目実行すると...

以下のように出力された。

PLAY [test] ******************************************************************* 

GATHERING FACTS *************************************************************** 
ok: [ec2-xx-xxx-xx-xxx.ap-northeast-1.compute.amazonaws.com]

TASK: [install mysql-server] ************************************************** 
ok: [ec2-xx-xxx-xx-xxx.ap-northeast-1.compute.amazonaws.com] => {"changed": false, "msg": "", "rc": 0, "results": ["mysql-server-5.5-1.3.amzn1.noarch providing mysql-server is already installed"]}

TASK: [mysql is running] ****************************************************** 
changed: [ec2-xx-xxx-xx-xxx.ap-northeast-1.compute.amazonaws.com] => {"changed": true, "name": "mysqld", "state": "started"}

PLAY RECAP ******************************************************************** 
ec2-xx-xxx-xx-xxx.ap-northeast-1.compute.amazonaws.com : ok=3    changed=1    unreachable=0    failed=0 

並列処理

二台のホストに対して同じ Playbooks を適用する。

PLAY [test] ******************************************************************* 

GATHERING FACTS *************************************************************** 
ok: [ec2-xx-xxx-xx-xx1.ap-northeast-1.compute.amazonaws.com]
ok: [ec2-xx-xxx-xx-xx2.ap-northeast-1.compute.amazonaws.com]

TASK: [install mysql-server] ************************************************** 
ok: [ec2-xx-xxx-xx-xx1.ap-northeast-1.compute.amazonaws.com] => {"changed": false, "msg": "", "rc": 0, "results": ["mysql-server-5.5-1.3.amzn1.noarch providing mysql-server is already installed"]}
changed: [ec2-xx-xxx-xx-xx2.ap-northeast-1.compute.amazonaws.com] => {"changed": true, "msg": "", "rc": 0, "results": (略)\n\n"]}

TASK: [mysql is running] ****************************************************** 
ok: [ec2-xx-xxx-xx-xx1.ap-northeast-1.compute.amazonaws.com] => {"changed": false, "name": "mysqld", "state": "started"}
changed: [ec2-xx-xxx-xx-xx2.ap-northeast-1.compute.amazonaws.com] => {"changed": true, "name": "mysqld", "state": "started"}

PLAY RECAP ******************************************************************** 
ec2-xx-xxx-xx-xx1.ap-northeast-1.compute.amazonaws.com : ok=3    changed=2    unreachable=0    failed=0   
ec2-xx-xxx-xx-xx2.ap-northeast-1.compute.amazonaws.com : ok=3    changed=0    unreachable=0    failed=0

Chef には出来ない並列処理が標準で備わっている。

ホストへの適用を serverspec でテストする

serverspec-init

serverspec-init

を実行して二台分の spec ファイルを準備する。

spec ファイル

以下のように作成した。

並列実行

serverspec の @gosukenator さんが以下のように serverspec の並列処理についてツイートされていたので、早速、並列処理で serverspec を実行させてみた。

sudo gem install parallel_tests --no-ri --no-rdoc -V

まずは上記のように parallel_test を導入してからの...以下のようにテストを実行する。

parallel_rspec spec
4 processes for 2 specs, ~ 0 specs per process
....

Finished in 0.55082 seconds
3 examples, 0 failures
..

Finished in 0.69609 seconds
3 examples, 0 failures

6 examples, 0 failures

Took 2.2947824 seconds

全てのテストがクリア。Ansible での適用が正常に動作していることが確認出来た。

ちなみに、従来通りにも実行してみる。

rspec spec

結果は以下の通り。

......

Finished in 1.21 seconds
6 examples, 0 failures

対象のホストが少ないので、従来の方法でのテストとパラレルテストではそれほど処理時間に差は見られないが、@gosukenator さんのブログでは 300 程度のテストを実施した場合には処理時間はパラレルテストの方が二倍ほど速くなるようだ。

まとめ

Ansible と Chef を比較して...

  • 並列処理が出来るのは嬉しい
  • Ansible の方がシンプルかな
  • 色々とディレクトリを作る必要がなくて、設定ファイルの設置場所なども選ばないので自由度が高い
  • べき等性もよろしくやってくれる
  • モジュール(リソース)は Chef の方が充実しているものの Ansible は環境に合わせて自作することが出来るようなので汎用性は高い?
  • Ansible はクライアントレス
  • でも Playbooks の書き方がよくわからない...
  • Chef の方が情報が豊富

とは言え...

  • 個人的にはシンプルな Ansible と機能充実の Chef という棲み分けでどっちも追っていきたい
  • 今まで手作業で頑張ってきたことを自動で出来るなら何でもいいやと思っている