Ansible: Playbookの実行条件制御 `when` の使い方(3)
前々回、前回に引き続き、今回も Playbook でのタスク制御を行なう when
の使い方を勉強していきます。 今回でこのシリーズは最後です。
題材は、引き続き本家のドキュメント。
Ansible Documentation > Playbooks > Conditionals
シリーズの記事はこちら。
https://blog.tacck.net/archives/101
https://blog.tacck.net/archives/117
Conditional Imports
こちらは、「高度な内容なのでスキップしても良いよー」と書かれている内容でした。
複数の環境やOSバージョンに一つの Playbook で処理を行なう、といったような場合にどう対応するかという内容のようです。 ここは when
を使った条件評価ではないですが、変数を使った処理の切り替えのお話です。
---
- hosts: all
remote_user: root
vars_files:
- "vars/common.yml"
- [ "vars/{{ ansible_os_family }}.yml", "vars/os_defaults.yml" ]
tasks:
- name: make sure apache is running
service: name={{ apache }} state=running
このサンプルでは、変数の ansible_os_family
によって読み込み変数定義ファイルを切り替えています。 これによって、 RedHat
系の場合と Debian
系の場合で異なるパッケージ名(ここでは apache
)に変数を設定できるようにしています。
---
# for vars/CentOS.yml
apache: httpd
somethingelse: 42
こんな感じですね。
ただし、これを利用するためには、事前に facter
か ohai
というパッケージを入れておかなければいけないようです。 Ansibleを使うのに事前にパッケージを入れる、、、というのもあれな感じですが、下記のようにコマンドベースでインストールできるようです。
# for facter
ansible -m yum -a "pkg=facter state=present"
ansible -m yum -a "pkg=ruby-json state=present"
# for ohai
ansible -m yum -a "pkg=ohai state=present"
Selecting Files And Templates Based On Variables
こちらも、「高度な内容なのでスキップしても良いよー」と書かれている内容でした。 しかし、諦めずに内容をみてみます。
タイトルは、「変数を基にしたファイルとテンプレートの選択」ですね。 早速、例を見てみましょう。
- name: template a file
template: src={{ item }} dest=/etc/myapp/foo.conf
with_first_found:
- files:
- {{ ansible_distribution }}.conf
- default.conf
paths:
- search_location_one/somedir/
- /opt/other_location/somedir/
まず with_first_found
ですが、これは引数で取っている files
と paths
の中で最初にヒットしたものを利用する、、、というもののようです。 変数の ansible_distribution
は Linuxのディストリビューション名を指しています。 つまり、 CentOS
や Ubuntu
によってconfファイルの指定を切り替える、という動きになりますね。
Register Variables
最後は、「変数への登録」です。 実行結果を保存しておいて、後から別のタスクで使えるようになります。
- name: test play
hosts: all
tasks:
- shell: cat /etc/motd
register: motd_contents
- shell: echo "motd contains the word hi"
when: motd_contents.stdout.find('hi') != -1
上記の例ですと、 /etc/motd
の中身を motd_contents
という変数に格納して、次のタスクの when
で利用しています。 利用するときに motd_contents.stdout
とすることで値を取り出していますね。
値を取り出すときに、 stdout_lines
というものを使うことで行ごとに分解したリストとして扱うこともできます。 次の例を見てみましょう。
- name: registered variable usage as a with_items list
hosts: all
tasks:
- name: retrieve the list of home directories
command: ls /home
register: home_dirs
- name: add home dirs to the backup spooler
file: path=/mnt/bkspool/{{ item }} src=/home/{{ item }} state=link
with_items: "{{ home_dirs.stdout_lines }}"
# same as with_items: "{{ home_dirs.stdout.split() }}"
こちらは、 ls /home
の結果を home_dirs
に格納しています。 システムに登録されているユーザの一覧と、ほぼ同じものが格納されていることになりますね。
これを、次のタスクで home_dirs.stdout_lines
としてリストとの形で使っていますね。 (リストにする場合は、 home_dirs.stdout.split()
という書き方でも良いようです。)
最後は、実行結果が「空」だった場合の判定方法です。
- name: check registered variable for emptiness
hosts: all
tasks:
- name: list contents of directory
command: ls mydir
register: contents
- name: check contents for emptiness
debug: msg="Directory is empty"
when: contents.stdout == ""
上記のように ""
と比較することで、空であることの判定が行なえるようです。
まとめ
ここまでで、 when
の使い方を中心とした、 Conditionals
のページの内容を見てきました。
when
だけでなく、変数なども有効に利用することで、色々な条件でタスクを実行したり、または読み込むファイルを制御したり、ということもできるようです。
うまく利用すれば、 Playbook をシンプルに書いていけるようになると思いますが、やりすぎると、それはそれで込み入って見通しが悪くなる可能性もありそうです。 知識をきちんと押さえた上で、必要な時に利用できるようになっていきたいですね。