Ansibleで地味に詰まったこと
現在勉強を兼ねてAnsibleでZABBIXサーバ(LAMPただしMはMariaDB)を自動でインストールするPlaybookを作成している。その中で多少詰まったところをメモしておく。
Ansibleの変数名に使える形式
Ansibleの変数名では使えるパターン、使えないパターンがある(参考)
- ○:ansible
- ○:ansible_playbook
- ○:ansible24
- ×:ansible-playbook
- ×:ansible playbook ←半角空白入り
- ×:ansible.playbook
- ×:24
ハイフンを入れてしまったときに演算できませんみたいなエラーが出たことから、恐らく数式として評価されてしまう記号は間に入れられないのではないかと思われる。試してないけど/とか*も駄目なんじゃなかろうか。
ApacheのConfigをテンプレートにしたらパースエラーが出てパースできなかった
ApacheのLog形式をLTSV書式にしようとして書いていたのだが、下記のコンフィグの部分でAnsibleからパースエラーが出て結局テンプレートにできなかった。
LogFormat "domain:%V\thost:%h\tserver:%A\tident:%l\tuser:%u\ttime:%{%d/%b/%Y:%H:%M:%S %z}t\tmethod:%m\tpath:%U%q\tprotocol:%H\tstatus:%>s\tsize:%b\treferer:%{Referer}i\tagent:%{User-Agent}i\tresponse_time:%D\tcookie:%{cookie}i\tset_cookie:%{Set-Cookie}o" combined
結局copyを使って凌いでいるが、ServerNameなどは当然デフォルトから書き換えたいのでlineinfileモジュールで編集しており、すると必ず編集されたことになってしまう。実行するたびにhttpdをリロードする羽目になる。本当は変更時のみchangedになるようにすべきだが…。
handlerの実行順序
notifyによって起動されるhandlerは全部のロールの処理が終わったあと、起動される。 ロールの処理ひとつ終わってから、という順ではない。 なお、起動される順序は恐らくnotifyされた順と思われるが調べられてない。
例えば、A,B,Cというroleとタスクがあり、そのhandlerをa,b,cとする。 実行される順序は、A->B->C->a->b->cとなる。当然Cで止まればaは実行されない。
実際これで困る例というのは、例えば下記のような書き方をした場合となる。
- ZABBIXサーバをインストールするためにroleを実行する
- roleのzabbixServerは依存関係として、base,apache,php,mariadb,snmptrap がある
- 各roleではインストールされたり、コンフィグの変更がある場合、notifyとhandlerを用いてサービス起動・および設定を行う
- ZABBIXの設定ではmariaDB上のデータベース作成、ユーザ作成、初期zabbixテーブル作成を含む
さて、最初にこれを実行すると、説明に記載した通り各種インストールやコンフィグの展開は完了するものの、「サービス起動と設定」が本当に全てのインストールの最後尾に回されてしまう。特に困るのはmysqlやmariaDBだ。これがZABBIXの設定のときに実行されていないとインストールスクリプトは失敗する。個別にroleを実行する分には問題ないのでデバッグ時には発覚しづらい。
そんなわけで単独で実行するタスクならともかく、role化したPlaybookにおいてnotify-handlerを使うのはお勧めしない。 特にエラー時に冪等性が怪しくなることは以下にも指摘がある。