Ansibleでwith_itemとregisterをあわせて使う


やりたいこと

  • with_itemsでループしているコマンドリストでリターンコードが0の要素のみ、特定のタスクを実行したい
  • 次の例では、aaaコマンドの結果のみリターンコードが0とならないため、Loop checkタスクが実行されない

- hosts: all
  gather_facts: false
  vars:
    commands: ["pwd", "ls", "aaa"]
  tasks:
    - name: Loop cmd
      shell: |-
        eval '{{ item }}'
      register: r
      changed_when: false
      failed_when: false
      with_items: '{{ commands }}'

    - name: Loop check
      shell: |-
        echo {{ index }}
      loop_control:
        index_var: index
      when: r.results[index].rc == 0
      with_items: '{{ commands }}'

実行

ansible-playbook -i localhost, -c local main.yaml -v

出力結果

  • pwdとlsのみchangedとなっている
Using /etc/ansible/ansible.cfg as config file

PLAY [all] ***********************************************************************************************************************************************************************************

TASK [Loop cmd] ******************************************************************************************************************************************************************************
ok: [localhost] => (item=pwd) => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"}, "ansible_loop_var": "item", "changed": false, "cmd": "eval 'pwd'", "delta": "0:00:00.002043", "end": "2022-03-20 04:00:57.860651", "failed_when_result": false, "item": "pwd", "msg": "", "rc": 0, "start": "2022-03-20 04:00:57.858608", "stderr": "", "stderr_lines": [], "stdout": "/home/yuta/ansible-register", "stdout_lines": ["/home/yuta/ansible-register"]}
ok: [localhost] => (item=ls) => {"ansible_loop_var": "item", "changed": false, "cmd": "eval 'ls'", "delta": "0:00:00.003060", "end": "2022-03-20 04:00:57.975312", "failed_when_result": false, "item": "ls", "msg": "", "rc": 0, "start": "2022-03-20 04:00:57.972252", "stderr": "", "stderr_lines": [], "stdout": "main.yaml", "stdout_lines": ["main.yaml"]}
ok: [localhost] => (item=aaa) => {"ansible_loop_var": "item", "changed": false, "cmd": "eval 'aaa'", "delta": "0:00:00.034866", "end": "2022-03-20 04:00:58.121764", "failed_when_result": false, "item": "aaa", "msg": "non-zero return code", "rc": 127, "start": "2022-03-20 04:00:58.086898", "stderr": "/bin/sh: 1: eval: aaa: not found", "stderr_lines": ["/bin/sh: 1: eval: aaa: not found"], "stdout": "", "stdout_lines": []}

TASK [Loop check] ****************************************************************************************************************************************************************************
changed: [localhost] => (item=pwd) => {"ansible_index_var": "index", "ansible_loop_var": "item", "changed": true, "cmd": "echo 0", "delta": "0:00:00.002383", "end": "2022-03-20 04:00:58.253491", "index": 0, "item": "pwd", "msg": "", "rc": 0, "start": "2022-03-20 04:00:58.251108", "stderr": "", "stderr_lines": [], "stdout": "0", "stdout_lines": ["0"]}
changed: [localhost] => (item=ls) => {"ansible_index_var": "index", "ansible_loop_var": "item", "changed": true, "cmd": "echo 1", "delta": "0:00:00.002435", "end": "2022-03-20 04:00:58.369974", "index": 1, "item": "ls", "msg": "", "rc": 0, "start": "2022-03-20 04:00:58.367539", "stderr": "", "stderr_lines": [], "stdout": "1", "stdout_lines": ["1"]}
skipping: [localhost] => (item=aaa)  => {"ansible_index_var": "index", "ansible_loop_var": "item", "changed": false, "index": 2, "item": "aaa", "skip_reason": "Conditional result was False"}

PLAY RECAP ***********************************************************************************************************************************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0