1

My question is somehow similar to the one posted here, but that doesn't quite answer it. In my case I have an array containing multiple vars: entries, which I loop over when calling a certain role. The following examples shows the idea:

some_vars_file.yml:

redis_config:
  - vars:
      redis_version: 6.0.6
      redis_port: 6379
      redis_bind: 127.0.0.1
      redis_databases: 1
  - vars:
      redis_version: 6.0.6
      redis_port: 6380
      redis_bind: 127.0.0.1
      redis_databases: 1

playbook.yml:

...

- name: Install and setup redis
  include_role:
    name: davidwittman.redis
  with_dict: "{{ dictionary }}"
  loop: "{{ redis_config }}"
  loop_control:
    loop_var: dictionary

...

As far as I understand, this should just set the dictionary beginning with the vars node on every iteration, but it somehow doesn't. Is there any chance to get something like this to work, or do I really have to redefine all properties at the role call, populating them using with_items?

Migsi
  • 107
  • 2
  • 10

1 Answers1

0

Given the role

shell> cat roles/davidwittman_redis/tasks/main.yml
- debug:
    var: dictionary

Remove with_dict. The playbook

shell> cat playbook.yml
- hosts: localhost
  vars_files:
    - some_vars_file.yml
  tasks:
    - name: Install and setup redis
      include_role:
        name: davidwittman_redis
      loop: "{{ redis_config }}"
      loop_control:
        loop_var: dictionary

gives

shell> ansible-playbook playbook.yml

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

TASK [Install and setup redis] ********************************

TASK [davidwittman_redis : debug] *****************************
ok: [localhost] => 
  dictionary:
    vars:
      redis_bind: 127.0.0.1
      redis_databases: 1
      redis_port: 6379
      redis_version: 6.0.6

TASK [davidwittman_redis : debug] ******************************
ok: [localhost] => 
  dictionary:
    vars:
      redis_bind: 127.0.0.1
      redis_databases: 1
      redis_port: 6380
      redis_version: 6.0.6

Q: "Might there be an issue related to the variable population on role call?"

A: Yes. It can. See Variable precedence. vars_files is precedence 14. Any higher precedence will override it. Decide how to structure the data and optionally use include_vars (precedence 18). For example

shell> cat playbook.yml
- hosts: localhost
  tasks:
    - include_vars: some_vars_file.yml
    - name: Install and setup redis
      include_role:
        name: davidwittman_redis
      loop: "{{ redis_config }}"
      loop_control:
        loop_var: dictionary

Ultimately, command line --extra-vars would override all previous settings

shell> ansible-playbook playbook.yml --extra-vars "@some_vars_file.yml"

Q: "Maybe it is not possible to set the vars section directly via an external dictionary?"

A: It is possible, of course. The example in this answer clearly proves it.

Vladimir Botka
  • 58,131
  • 4
  • 32
  • 63
  • While I can confirm, the variables are added, it still seems to ignore them. Might there be an issue related to variable population on role calling? – Migsi Aug 07 '20 at 07:59
  • Thank you for the explanation. Just to clarify, I was not referring to variable precendence but to (possible) mismatches when setting the vars section via a loop. Maybe it is not possible to set the vars section directly via an external dictionary? Any variation of notations I tried to run resulted either in the role using its defaults or ansible complaining about misuse of syntax. – Migsi Aug 07 '20 at 08:43
  • It's not possible to proceed here this way. Open a new question and make it [mcve](https://stackoverflow.com/help/minimal-reproducible-example) please! – Vladimir Botka Aug 07 '20 at 08:52
  • I might have explained myself a little bad. The overall question I'd like to have answered is still what you already answered to. But even though it looked promising, it did not result in the role using the two different sets of variables. Thats why I brought in those thoughts about what else could cause this issues. I'd still be happy if we are able to come up with a working example for the code I gave in my question. – Migsi Aug 07 '20 at 09:01
  • 1
    Sure. This is also my intention. Open a new question and make it `mcve`. I'll not proceed to guess. Read `mcve` properly, 1) make it minimal (e.g. complex Redis structure is not necessary, simple `key: val1` will serve the purpose; create new empty role for testing and make minimal changes; post it) 2) make it complete (if there is an error message, post it) 3) make it verifiable (post all details (minimal! but all) to reproduce your problem). – Vladimir Botka Aug 07 '20 at 09:11
  • I will do so as soon as I can and place a cross reference between the questions. – Migsi Aug 07 '20 at 09:22