2

I have multiple files with the same variable names, but with different values in vars/all directory. I used to run with the following command to achieve running all of them.

$ for var in `ls vars/all/`; do ansible-playbook foo.yaml -e@vars/all/$var; done

PLAY [localhost] **************************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************************
ok: [localhost]

TASK [shell] ******************************************************************************************************************
changed: [localhost]

TASK [debug] ******************************************************************************************************************
ok: [localhost] => {
    "msg": "john"
}

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

PLAY [localhost] **************************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************************
ok: [localhost]

TASK [shell] ******************************************************************************************************************
changed: [localhost]

TASK [debug] ******************************************************************************************************************
ok: [localhost] => {
    "msg": "smc"
}

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

The playbook is as follows

---
- hosts: localhost
  tasks:
    - shell: echo "{{ name }}"
      register: print
    - debug:
        msg: "{{ print.stdout }}"

variable file

$ cat vars/all/one.yaml
name: john

$ cat vars/all/two.yaml 
name: smc

I wanted to automate it, so I don't have to use for loop every time. I have used include_vars to solve the problem, as below, however, it is taking only the last file in the loop.

---
- hosts: localhost
  tasks:
    - name: Include vars
      include_vars:
        dir: vars/all
    - shell: echo "{{ name }}"
      register: print
    - debug:
        msg: "{{ print.stdout }}"

Output

ansible-playbook foo.yaml

PLAY [localhost] **************************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************************
ok: [localhost]

TASK [Include vars] ***********************************************************************************************************
ok: [localhost]

TASK [shell] ******************************************************************************************************************
changed: [localhost]

TASK [debug] ******************************************************************************************************************
ok: [localhost] => {
    "msg": "smc"
}

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

I think I am using the loop, may I know is there a way to use same variable name, but with different values, in a loop to execute same set of tasks?

NOTE: There can be more variable files under vars/all/ can be created, so it is not possible to hard-code using vars_files.

smc
  • 2,175
  • 3
  • 17
  • 30

1 Answers1

2

Include the files in the loop and store the variables in the dictionaries with unique names. For example, create such names of the dictionaries from the names of the files

    - name: Include vars
      include_vars:
        file: "{{ item }}"
        name: "my_vars_name_{{ item|basename|splitext|first }}"
      with_fileglob:
        - "vars/all/*.yaml"

Then, use the lookup varnames to find the dictionaries and iterate the list. Use the lookup vars to get the value of the particular dictionary and select the attribute name

    - command:
        cmd: "echo {{ lookup('vars', item).name }}"
      register: print
      with_varnames:
        - "my_vars_name_.*"

Use attribute results because the variable print was registered in a loop

    - debug:
        msg: "{{ print.results|map(attribute='stdout')|list }}"

gives

  msg:
  - john
  - smc

Example of a complete playbook for testing

- hosts: localhost
  tasks:
    - name: Include vars
      include_vars:
        file: "{{ item }}"
        name: "my_vars_name_{{ item|basename|splitext|first }}"
      with_fileglob:
        - "vars/all/*.yaml"
    - command:
        cmd: "echo {{ lookup('vars', item).name }}"
      register: print
      with_varnames:
        - "my_vars_name_.*"
    - debug:
        msg: "{{ print.results|map(attribute='stdout')|list }}"

gives

PLAY [localhost] *****************************************************************************

TASK [Include vars] **************************************************************************
ok: [localhost] => (item=/export/scratch/tmp8/test-979/vars/all/one.yaml)
ok: [localhost] => (item=/export/scratch/tmp8/test-979/vars/all/two.yaml)

TASK [command] *******************************************************************************
changed: [localhost] => (item=my_vars_name_one)
changed: [localhost] => (item=my_vars_name_two)

TASK [debug] *********************************************************************************
ok: [localhost] => 
  msg:
  - john
  - smc

PLAY RECAP ***********************************************************************************
localhost: ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
Vladimir Botka
  • 58,131
  • 4
  • 32
  • 63