端くれプログラマの備忘録 Ansible [Ansible] 変数による条件付き実行

[Ansible] 変数による条件付き実行

登録された変数に基づく条件

プレイブックでは、以前のタスクの結果に基づいてタスクを実行したり、スキップしたりしたいことがある。例えば、以前のタスクによってアップグレードされた後にサービスを設定したい場合など。登録された変数に基づいた条件を適用したい場合には以下のようにする。

  1. 先のタスクの結果を変数として登録する
  2. 登録した変数に基づいて条件テストを行う

変数の登録はregisterキーワードを使って行う。登録された変数には、それを作成したタスクのステータスと、そのタスクが生成した出力が含まれる。登録された変数は、テンプレートとアクションライン、および条件付きwhenステートメントで使うことができる。variable.stdoutを使うと、登録された変数の中身の文字列にアクセスすることができる。以下に例を示す。

- name: Test play
  hosts: all

  tasks:

      - name: Register a variable
        ansible.builtin.shell: cat /etc/motd
        register: motd_contents

      - name: Use the variable in conditional statement
        ansible.builtin.shell: echo "motd contains the word hi"
        when: motd_contents.stdout.find('hi') != -1

変数がリストの場合、タスクのループ内で登録された結果を使うことができる。リストでない場合は、stdout_linesまたはvariable.stdout.split()を使ってリストに変更することができる。また、他のフィールドによりラインを分割することもできる。

- name: Registered variable usage as a loop list
  hosts: all
  tasks:

    - name: Retrieve the list of home directories
      ansible.builtin.command: ls /home
      register: home_dirs

    - name: Add home dirs to the backup spooler
      ansible.builtin.file:
        path: /mnt/bkspool/{{ item }}
        src: /home/{{ item }}
        state: link
      loop: "{{ home_dirs.stdout_lines }}"
      # same as loop: "{{ home_dirs.stdout.split() }}"

登録された変数の中身の文字列が空の場合もある。登録された変数のstdoutが空であるホストでのみ他のタスクを実行したい場合は、登録された変数の中身の文字列が空かどうかを確認する。

- name: check registered variable for emptiness
  hosts: all

  tasks:

      - name: List contents of directory
        ansible.builtin.command: ls mydir
        register: contents

      - name: Check contents for emptiness
        ansible.builtin.debug:
          msg: "Directory is empty"
        when: contents.stdout == ""

タスクが失敗したホストや、条件を満足せずにタスクがスキップされたホストであっても、Ansibleは常に全てのホストの登録変数に何かを登録する。これらのホストでフォローアップタスクを実行するには、スキップされたホストに関して登録された変数を照会する(“undefined”や”default”に対しては行わない)。

以下に、タスクの成功/失敗に基づく条件例を示す。失敗した場合でもAnsibleをホストで実行させ続けたい場合にはエラーを無視する必要がある。

tasks:
  - name: Register a variable, ignore errors and continue
    ansible.builtin.command: /bin/false
    register: result
    ignore_errors: true

  - name: Run only if the task that registered the "result" variable fails
    ansible.builtin.command: /bin/something
    when: result is failed

  - name: Run only if the task that registered the "result" variable succeeds
    ansible.builtin.command: /bin/something_else
    when: result is succeeded

  - name: Run only if the task that registered the "result" variable is skipped
    ansible.builtin.command: /bin/still/something_else
    when: result is skipped

参考サイト

Conditionals — Ansible Documentation
https://docs.ansible.com/ansible/latest/user_guide/playbooks_conditionals.html#the-when-statement