smc
smc

Reputation: 2355

Identical variable names when using include_vars

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.

Upvotes: 2

Views: 411

Answers (1)

Vladimir Botka
Vladimir Botka

Reputation: 68124

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

Upvotes: 2

Related Questions