Reading variable values set in a role which is called multiple times using with-items

Hello everyone,
First time poster here so apologies if something is not in correct format.

I am trying to read a two values in a script which are set inside a role using set_fact. The role is called twice using with-items from the script.

But do not know how to get values in calling script.

In below example, I am expecting two values in variable value_in_role_register

Could someone please help how to achieve this ?

Here is the role which is emitting value_in_role with time stamp.

# dummy_role.yml
- name: set x
  set_fact:
    value_in_role: "{{ ansible_date_time.iso8601 }}"

# test.yaml
- hosts: local
  connection: local
  tasks:
    - name: Task 1
      include_role:
        name: dummy_role
      register: "value_in_role_register"
      with_items:
        - call-1st-Time
        - call-2nd-Time

    - debug:
        msg="value_in_role_register => {{ value_in_role_register.results }}"

    - debug:
        msg="value_in_role => {{ value_in_role }}"

Output (expecting two values in *value_in_role_register* but that is not
the case

ok: [local] => {
    "msg": "*value_in_role_register* => [{'item': u'call-1st-Time',
'ansible_loop_var': u'item', 'include_args': {u'name': u'dummy_role'}},
{'item': u'call-2nd-Time', 'ansible_loop_var': u'item', 'include_args':
{u'name': u'dummy_role'}}]"
}

"include_role" does not return the tasks' results. Instead, you might
want to iterate the task inside the role and create the list of the
results there. For example

  > cat roles/dummy_role/tasks/main.yml
  - shell: "sleep 1 && date +%T"
    register: value_in_role
    loop: "{{ calls }}"

  > cat playbook.yml
  - hosts: localhost
    tasks:
      - include_role:
          name: dummy_role
        vars:
          calls: [call-1st-Time,call-2nd-Time,call-3nd-Time]
      - debug:
          msg: "{{ dict(value_in_role.results|
                        json_query('.[item,stdout]')) }}"

give

  ok: [localhost] =>
    msg:
      call-1st-Time: '10:04:22'
      call-2nd-Time: '10:04:23'
      call-3nd-Time: '10:04:24'

TASK [debug]
*******************************************************************
ok: [local] => {
    "msg": "*value_in_role* => 2020-12-09T04:56:22Z"
}

JFYI, the value of "ansible_date_time" is set by the module "setup".
It's not updated automatically. You have to execute "setup" to update
"ansible_date_time".

Thanks Vladimir for complete working example. Yes it resolved the use case I have.

Wondering if it is the issue with ‘set_fact’ vs ‘register’ used in role when role is called multiple times. Seems like set_fact (sets only last value) instead of maintaining multiple values as register does when called in a loop.

Yours >> register: value_in_role

Mine >> set_fact:
value_in_role:

Anyways, thanks again !

... Seems like set_fact (sets only last value) instead of
maintaining multiple values as register does when called in a loop.

Correct. The next option would be the addition of an item to
the list, e.g. *my_dates*, in each invocation of the role

  > cat roles/dummy_role_02/tasks/main.yml
  - setup:
      gather_subset: date_time
  - set_fact:
      my_dates: "{{ my_dates|default() +
                    [ansible_date_time.iso8601_micro] }}"

Then the playbook

  - hosts: localhost
    vars:
      calls: [call-1st-Time,call-2nd-Time,call-3nd-Time]
    tasks:
      - include_role:
          name: dummy_role_02
        loop: "{{ calls }}"
      - debug:
          msg: "{{ dict(calls|zip(my_dates)) }}"

gives

  msg:
    call-1st-Time: '2020-12-09T20:33:06.776459Z'
    call-2nd-Time: '2020-12-09T20:33:07.267783Z'
    call-3nd-Time: '2020-12-09T20:33:07.862950Z'

If you're interested in profiling see
https://ansible-runner.readthedocs.io/en/latest/intro.html#runner-profiling-data-directory

Thanks for sharing… always good to know multiple approaches to solve a problem :slight_smile: .