Ansibleとテスト - Ansible Meetup in Tokyo LTの追加です。
このLTではAnsibleとServerspecを組み合わせて使うためのrubygemについて紹介しました。
一方で、AnsibleにはAssertなどのテストモジュールがあるので、Serverspecを使わずにテストまで行えるのでは、と考えていました。
この記事では、Assertを使ってテストを書いてみた感想と注意点について述べます。
結論から言えば、Ansible単独で構築からテストまで行うよりは、テスト系ツール(serverspec, envassert)と組み合わせて活用した方が良いです。
[前提]Ansibleの思想とテスト
Ansibleはあるべき状態(desired-state)を宣言し、サーバを構成します。
例えば、OS起動時にあるサービスが開始されるための手順を書くのではなく、OS起動時にあるサービスが開始する状態であることを宣言する(YAMLに書く)と、その通りに構成されます。
この宣言の考え方はモジュールにも現れていて、service
モジュールでは、state=start
ではなくstate=started
といった状態を記述します。
tasks:
- service: name=foo state=started enabled=yes
また、Ansibleでは、fail-fast
と呼ばれますが、playbookの実行中に失敗する(=宣言された状態に出来なかった)とすぐにfailするので、すぐに失敗に気づくことができます。
(あとで改めてテストを実行して、期待通りに出来ているか確認する手間が省ける)
Ansibleでは宣言通りに構築するので、改めてテストを行う必要はないという思想があると考えています。
Assertでテストを書く。
拙作のansible-sample-tddのNginx部分についてテストを書いてみました。
serverspec版が19行、ansible版が26行でした。
- shell: rpm -qi nginx
register: p_installed
- shell: chkconfig --list | grep nginx
register: p_enabled
- shell: ps aux | grep nginx
register: p_running
- shell: netstat -ant | grep 80
register: p_listen
- stat: path=/etc/nginx/nginx.conf
register: p_exist
- shell: cat /etc/nginx/nginx.conf
register: p_cat
- assert:
that:
- p_installed is defined
- p_enabled is defined
- p_running is defined
- p_listen is defined
- p_exist.stat.exists
- "'worker_connections 1024;' in p_cat.stdout"
感想
全6件のテストで行数はあまり変わりませんが、regsiterで変数に格納する必要があるので書くのは手間がかかりました。
公式の例文ではstatと組み合わせていましたが、statだけでは機能が全く足りないので、shellモジュールを使っています。
shellを使わなければならない時点で、微妙な感じです。。
Ansibleは宣言型の思想があるので、今後もテストは充実されるように思いません。
個人的にはrubyの慣れもあり、今後もserverspecを使っていくだろうと思います。
テストの注意点その1 statモジュール
statにはisdirがあるのでisfileがあると思いきやありません。びっくりです。
statには注意が必要です。
statモジュールのソースコードを読む限りでは、以下のことが出来ます。
'exists','mode','isdir','ischr','isblk','isreg','isfifo','islnk','issock','uid','gid','size','inode','dev','nlink','atime','mtime','ctime','wusr','rusr','xusr','wgrp','rgrp','xgrp','woth','roth','xoth','isuid','isgid'
テストの注意点その2 テストのみ行う
include
とタグを使ってテストをするファイルだけを読み込むことで、テストのみ行う事ができます。
- include: test.yml
tags: test
ansible-playbook site.yml -i hosts -t test
以上