前章ではタスクの繰り返し実行を見てみましたが、ここではタスクを実行するかどうかの判定を行う方法を紹介します。
被管理ホストのOSが複数あり、一部のタスクは特定のOSでだけ実行したいというような制御を考えます。
このような場合、タスクに対し「when」要素を追加します。whenの値として条件式を記述し、その条件が満たされた場合のみタスクが実行されるようになります。
被管理ホストがCentOSの場合はyumを、Ubuntuの場合はaptを使ってhttpdをインストールさせるプレイブックは以下のようになります。
tasks: - name: CentOS用httpdインストール yum: name=httpd state=latest when: ansible_distribution == 'CentOS' - name: Ubuntu用httpdインストール apt: name=apache2 state=latest when: ansible_distribution == 'Ubuntu'
ここで条件の中で指定している「ansible_distribution」はAnsibleが自動で実行しているsetupモジュールにより設定された変数名です。whenの中では、変数は{{}}で囲まずにそのまま参照できます。
whenで指定する条件式は「Jinja2」というPythonのテンプレートエンジンの文法が使われています。whenで利用できる演算子は以下のようなものがあります。
機能 | 演算子 | 利用例 |
---|---|---|
比較 | ==, !=, >,<, >=,<= | when: size > 100 |
論理 | and, or | when: size > 100 and size < 200 |
真偽値 | true, false | when: false |
含まれる | in, not in | when: name in ['hoge','piyo'] |
whenに記載した条件が満たされなかった場合、実行時は以下のように「skipped」と表示されタスクが実行されなかったことが分かります。
TASK [CentOS用httpdインストール] ***************************** skipping: [ubuntu] changed: [localhost] TASK [Ubuntu用httpdインストール] ***************************** skipping: [localhost] changed: [ubuntu]
複数のタスクに対し同じ実行条件を設定する場合、whenのみでは以下のように同じ条件判定を書かなければいけません。これでは条件を変更したい場合に修正に手間が掛かり、修正漏れも起こり得ます。
tasks: - name: CentOS用httpdインストール yum: name=httpd state=latest when: ansible_distribution == 'CentOS' - name: 設定ファイルの転送 copy: src=httpd.conf dest=/etc/httpd/conf/ when: ansible_distribution == 'CentOS'
このような場合、「block」という要素を使い複数のタスクをまとめ、blockに対しwhen要素を指定することで条件判定を1カ所のみにできます。
tasks: - block: - name: CentOS用httpdインストール yum: name=httpd state=latest - name: 設定ファイルの転送 copy: src=httpd.conf dest=/etc/httpd/conf/ when: ansible_distribution == 'CentOS'
shellモジュールは実行したコマンドの戻り値が0でない場合に実行失敗と見なされ、以後のタスクが実行されなくなってしまいます。しかし、例えば既存のシェルを利用する際、戻り値が0以外でも正常終了と見なしたい場合もあるかと思います。
このような場合は、「ignore_errors」「failed_when」要素が利用できます。
ignore_errorsを指定したタスクは実行失敗と見なされた場合でも無視して次のタスクに進みます。
tasks: - name: 0以外を返すシェルの実行 shell: /home/piyo/multi_rc.sh ignore_errors: true
failed_whenは任意の条件を使ってタスクの失敗判定を行いたい場合に利用します。例えば、「実行したシェルの戻り値が2以上ならば失敗とする」という条件は以下のように書けます。
tasks: - name: 2以上ならエラーとするタスク shell: /home/piyo/multi_rc.sh register: result failed_when: result.rc >= 2
ここで「register」という要素を利用していますが、これはモジュールの実行結果を変数に保存する機能です。registerで指定した値が変数名となり、実行結果が保存されます。モジュールの実行結果はマッピングで値が保持されており、shellモジュールの実行結果の戻り値はrcというキーで保持されているため、条件式ではその値を参照しています。
モジュールの実行結果はモジュールごとに異なっており、例えばshellモジュールであれば、標準出力、エラー出力をそれぞれ「stdout」「stderr」というキーで取得可能です。
モジュールの実行結果について確認したい場合、「debug」モジュールを使うと便利です。debugモジュールは引数「msg」に指定された文字列をそのまま画面表示してくれます。shellモジュールの実行結果を確認する例は以下の通りです。
tasks: - shell: /home/piyo/multi_rc.sh register: result - debug: msg={{result}}
Ansibleの実行時、以下のように「-vvv」を引数に追加することでより詳細な情報が表示されるようになります。プレイブックの実行が失敗する場合はこの引数を追加して実行し、原因特定のヒントを探しましょう。
ansible-playbook -i hosts hoge.yml -vvv
今回は、プレイブックの作成における変数の利用、タスクの繰り返し実行と実行要否の条件判定、実行結果の制御を紹介しました。これらを用いることで、ほとんどのサーバ作業は自動化できるようになるかと思います。
次回はプレイブックをメンテナンスしやすくするためのプレイブックの分割方法と推奨ディレクトリ構成、Ansibleの実行をGUIで行えるツールを紹介します。
2011年より、株式会社ビーブレイクシステムズに在籍。「あるべきものを、あるべき姿に」をモットーに、保守しやすいプログラムを書くため日々まい進中。
Copyright © ITmedia, Inc. All Rights Reserved.