Search code examples
ansibleansible-2.xansible-facts

Variable with_items and hostvars


I need to pass a dynamic group name info with_items so that i can access a specific fact that is ran from another host. I cannot hard code the group name

I tried to set a generic variable that is passed as 'GroupName' a few different ways. Including

with_items: "{{ groups['{{GROUPNAME}}'] }}"

   - name: Name of task
     debug:
       msg: "{{ hostvars[item]['ansible_check_mode'] }}"
     with_items: "{{ groups['GROUPNAME'] }}"

fatal: [localhost]: FAILED! => {"msg": "'dict object' has no attribute '{{ GROUPNAME }}'"}


Solution

  • update

    Do not close the variable GROUPNAME in any quotes or curls

      groups[GROUPNAME]
    

    For example, given the below inventory

    shell> cat hosts
    [group_A]
    host_1
    host_2
    host_3
    
    [group_B]
    host_4
    host_5
    
    [group_C]
    host_6
    host_7
    host_8
    

    the play

    shell> cat pb.yml
    - hosts: all
    
      tasks:
    
        - debug:
            msg: "{{ item }}"
          loop: "{{ groups[GROUPNAME] }}"
          run_once: true
    
        - debug:
            msg: "{{ hostvars[item]['ansible_check_mode'] }}"
          loop: "{{ groups[GROUPNAME] }}"
          run_once: true
    

    gives (abridged)

    shell> ansible-playbook pb.yml -e GROUPNAME=group_B
      ...
    TASK [debug] *********************************************************************************
    ok: [host_1] => (item=host_4) => 
      msg: host_4
    ok: [host_1] => (item=host_5) => 
      msg: host_5
    
    TASK [debug] *********************************************************************************
    ok: [host_1] => (item=host_4) => 
      msg: false
    ok: [host_1] => (item=host_5) => 
      msg: false
    

    When you run the play in the check mode you should get

    shell> ansible-playbook pb.yml -e GROUPNAME=group_B --check
      ...
    TASK [debug] *********************************************************************************
    ok: [host_1] => (item=host_4) => 
      msg: true
    ok: [host_1] => (item=host_5) => 
      msg: true
    

    origin

    Get the list of the hosts in the group and loop them

          vars:
            my_group: GROUPNAME
          tasks:
            - set_fact:
                my_hosts: "{{ groups|
                              dict2items|
                              selectattr('key', 'match', my_group)|
                              map(attribute='value')|
                              list|
                              flatten }}"
            - debug:
                msg: "{{ hostvars[item]['ansible_check_mode'] }}"
              loop: "{{ my_hosts }}"
    

    (not tested)