1

I am trying to run multiple roles using with_items command, however I am getting error:

"ERROR! 'item' is undefined"

role.yml:

---
- hosts: '{{ host }}'
  become: yes

  roles:
    - role: "{{item}}"
      with_items: "{{ roles }}"

Here is my command:

ansible-playbook -i ./inventory/Dev ./playbooks/role.yml --extra-vars='{"host": "db", "roles": ["mysql", "apache"]}'
techraf
  • 64,883
  • 27
  • 193
  • 198
MMA
  • 408
  • 3
  • 7
  • 19

2 Answers2

2

You cannot do it this way. with_ loops are not valid for roles.

If anything, you need to provide a list of roles to the roles: directive, so the syntax would be just like for the list of host groups hosts: '{{ host }}'. The problem is: Ansible does not resolve the variable for roles, so roles: '{{ roles }}' does not work.


What you can do, however, is to use include_role module in which you can access the variables.

No, include_role module doesn't take {{ item }} from the with_items as a value for name either.

So the only workaround I can think of (assuming you don't want to process the JSON beforehand) is to the include the roles statically:

tasks:
  - include_role:
      name: "mysql"
    when: "'mysql' in roles"
  - include_role:
      name: "apache"
    when: "'apache' in roles"

The roles need to exist on the control machine anyway, so all their names are predefined.

techraf
  • 64,883
  • 27
  • 193
  • 198
  • Thanks for reply, actually i want the roles count to be dynamically passed. Sometimes i may need just one role and sometimes multiple roles, also more roles will be added in future, so i want to make it flexible. Any other alternate ways we have? – MMA Mar 22 '17 at 10:37
1

You cannot use with_ loop with roles directive. A simple solution would be to use normal yaml list like below:

---
- hosts: '{{ host }}'
  become: yes

  roles:
    - myrole1
    - myrole2

Another example where you could declare the roles as well as pass corresponding variables to the role would be like below:

---
- hosts: '{{ host }}'
  become: yes

  roles:
    - role: 
      name: myrole1
      vars:
        host: "db1"
        myroles: 
         - mysql1
         - apache1

    - role: 
      name: myrole2
      vars:
        host: "db2"
        myroles: 
         - mysql2
         - apache2

Also avoid using ansible keywords as your variable names Finally your command to run your playbook will be as below:

ansible-playbook -i ./inventory/Dev ./playbooks/role.yml 
Paul92
  • 137
  • 2
  • 7