iteration using with_items and register

2019-04-05 15:39发布

问题:

Looking for help with a problem I've been struggling with for a few hours. I want to iterate over a list, run a command, register the output for each command and then iterate with debug over each unique registers {{ someregister }}.stdout

For example, the following code will spit out "msg": "1" and "msg": "2"

---

- hosts: localhost
  gather_facts: false

  vars:
    numbers:
      - name: "first"
        int: "1"
      - name: "second"
        int: "2"

  tasks:

    - name: Register output
      command: "/bin/echo {{ item.int }}"
      register: result
      with_items: "{{ numbers }}"

    - debug: msg={{ item.stdout }}
      with_items: "{{ result.results }}"

If however, I try and capture the output of a command in a register variable that is named using with_list, I am having trouble accessing the list or the elements within it. For example, altering the code slightly to:

---

- hosts: localhost
  gather_facts: false

  vars:
    numbers:
      - name: "first"
        int: "1"
      - name: "second"
        int: "2"

  tasks:

    - name: Register output
      command: "/bin/echo {{ item.int }}"
      register: "{{ item.name }}"
      with_items: "{{ numbers }}"

    - debug: var={{ item.name.stdout }}
      with_items: "{{ numbers }}"

Gives me:

TASK [debug] 

> ******************************************************************* fatal: [localhost]: FAILED! => {"failed": true, "msg": "'unicode
> object' has no attribute 'stdout'"}

Is it not possible to dynamically name the register the output of a command which can then be called later on in the play? I would like each iteration of the command and its subsequent register name to be accessed uniquely, e.g, given the last example I would expect there to be variables registered called "first" and "second" but there aren't.

Taking away the with_items from the debug stanza, and just explicitly defining the var or message using first.stdout returns "undefined".

Ansible version is 2.0.2.0 on Centos 7_2.

Thanks in advance.

回答1:

OK so I found a post on stackoverflow that helped me better understand what is going on here and how to access the elements in result.results.

The resultant code I ended up with was:

---

- hosts: localhost
  gather_facts: false

  vars:
    numbers:
      - name: "first"
        int: "1"
      - name: "second"
        int: "2"

  tasks:

    - name: Register output
      command: "/bin/echo {{ item.int }}"
      register: echo_out
      with_items: "{{ numbers }}"

    - debug: msg="item.item={{item.item.name}}, item.stdout={{item.stdout}}"
      with_items: "{{ echo_out.results }}"

Which gave me the desired result:

"msg": "item.item=first, item.stdout=1"
"msg": "item.item=second, item.stdout=2"


回答2:

I am not sure if I understand the question correctly, but maybe this can help:

    - debug: msg="{{ item.stdout }}"
      with_items: echo_out.results

Please note that Ansible will print each item and the msg both - so you need to look carefully for a line that looks like "msg": "2".