Ansible: Playbookの実行条件制御 `when` の使い方(1)
Ansible の Playbook を書いていると、条件によって実行したいタスク、スキップしたタスク、というものが出てくることがあります。
そんな場合に when
というステートメントで制御するのですが、なかなかきちんと使う機会が少なく、行き当たりばったりな感じで使うことも多くありました。
なので、一度しっかりと when
の使い方を学んでみようと思います。
題材は、もちろん本家のドキュメント。
数回に分けて、記事にしながら理解を深めていきます。
まずは、 when
の基礎的なところから。
目次
The When Statement
when
では、条件評価を行なって「真」となったらそのタスクを実行する、という挙動になります。
条件評価については、 Jinja2
の評価式が利用可能だそうです。
ちなみに、 Jinja2
の簡単な説明と使い方は以前の記事をご参照ください。
when
の条件評価例
というわけで、ドキュメント内の例をベースに見ていきたいと思います。
その1
これは、Ansibleの操作対象マシンのOSが “Debian” 系だった場合に、 command
の内容である /bin/shutdown
を実行します。
つまり、 OSが “RedHat” 系だったり、 “FreeBSD” だったりした場合は、このタスクはスキップとなりますね。
tasks: - name: "shut down Debian flavored systems" command: /sbin/shutdown -t now when: ansible_os_family == "Debian" # note that Ansible facts and vars like ansible_os_family can be used # directly in conditionals without double curly braces
その2
今度は、Linuxのディストリビューションが”CentOS”の6系、または、 “Debian” の7系、の場合にコマンドが実行されます。
つまり、Debian系でも “Ubuntu” であったり、 “CentOS” でもバージョンが7の場合は、やはりタスクはスキップとなります。
tasks: - name: "shut down CentOS 6 and Debian 7 systems" command: /sbin/shutdown -t now when: (ansible_distribution == "CentOS" and ansible_distribution_major_version == "6") or (ansible_distribution == "Debian" and ansible_distribution_major_version == "7")
また、条件についてはリストで書くこともできるようです。この場合は、すべての条件を満たしたときにタスクが実行されるため、 and
と同じ効果になるようです。
tasks: - name: "shut down CentOS 6 systems" command: /sbin/shutdown -t now when: - ansible_distribution == "CentOS" - ansible_distribution_major_version == "6"
その3
こちらはちょっと長いですが、あるタスクの結果に応じて(成功:succeeded、失敗:failed、スキップ:skipped)実行するタスクを選択する、という時の書き方になります。
例えば、Apache Httpdの設定の書き換えが成功した場合(succeeded)のみhttpdの再起動を行なう、、、というような使い方ができます。
tasks: - command: /bin/false register: result ignore_errors: True - command: /bin/something when: result|failed # In older versions of ansible use |success, now both are valid but succeeded uses the correct tense. - command: /bin/something_else when: result|succeeded - command: /bin/still/something_else when: result|skipped
ちなみに、3行目の register
は、タスクの実行結果を result
という変数に格納する、という意味になります。
when
の後にある |
については、Jinja2
の filters
という機能です。
すごくざっくり言えば、 result
の中に色々と含まれている情報の中に、 failed
や skipped
があれば、、、のような動作となります。
また、 filters
を使って文字列を整数として評価させることもできるようです。
ここでは、変数 ansible_lsb.major_release
を int
で整数にして >=
で評価を行なっていますね。
tasks: - shell: echo "only on Red Hat 6, derivatives, and later" when: ansible_os_family == "RedHat" and ansible_lsb.major_release|int >= 6
その4
ここは変数を取り扱うパターンです。
ドキュメントにいくつかのパターンが分割して書かれてありますが、ここはまとめて。
vars: epic: true tasks: - shell: echo "This certainly is epic!" when: epic - shell: echo "This certainly isn't epic!" when: not epic - shell: echo "I've got '{{ foo }}' and am not afraid to use it!" when: foo is defined - fail: msg="Bailing out. this play requires 'bar'" when: bar is undefined
最初の vars
で、このPlaybook内で使う変数を定義できます。
直後の when: epic
は、変数の内容が true
なのでこのタスクが実行されることになります。
epic
が false
の場合は、その次の when: not epic
のタスクの方が実行されます。
3つ目、4つ目は foo
という変数がそもそも定義されているか、という条件になります。(これもJinja2の機能のようです。)
定義されていれば3つ目、定義されていなければ4つ目、のタスクが実行されます。
まとめ
駆け足で when
の基本的な使い方を見てみました。
非常にシンプルですが、特に Jinja2
の条件評価を使えることがよくわかりました。
また、この when
で変数を使う場合は、他の部分で使うような {{}} で囲む必要が無いともドキュメントに書かれています。
こういったところに気をつけつつ、 より良いPlaybookを書いていきたいと思います。
続きは次回!