Brandon Shutter
Brandon Shutter

Reputation: 143

Running with_items inside with_items

I'm currently running a command as follows:

name: Generate a timed-based code for user
  command: "{{ item.command }} creates={{ item.file}}"
  with_items:
    - { command: '/usr/bin/google-authenticator -t -f -d --label=user1 --qr-mode=ANSI -r 3 -R 30 -w 1 --secret=/home/user1/.google_authenticator', file: '/home/user1/.google_authenticator' }
    - { command: '/usr/bin/google-authenticator -t -f -d --label=user2 --qr-mode=ANSI -r 3 -R 30 -w 1 --secret=/home/user2/.google_authenticator', file: '/home/user2/.google_authenticator' }

This works fine but isn't DRY at all.

I'm attempting to do a second with_items like this role:

- include_vars: main.yml

- name: Generate a timed-based code for user
  command: "{{ item.command }} creates={{ item.file }}"
  with_items:
    - { command: '/usr/bin/google-authenticator -t -f -d --label="{{ item.username }}" --qr-mode=ANSI -r 3 -R 30 -w 1 --secret=/home/"{{ item.username }}"/.google_authenticator', file: '/home/"{{{ item.username }}"/.google_authenticator' }
  with_items: "{{ users }}"
  become: true

Inside vars/main.yml I have:

---

users:
  username: user1 
  username: user2 
  username: user3

Upon running the playbook I'm presented with:

[WARNING]: While constructing a mapping from /Users/bshutter/Dev/server/roles/googlemfa/tasks/main.yml, line 55, column 3, found a duplicate dict key (with_items). Using last
defined value only.

[WARNING]: While constructing a mapping from /Users/bshutter/Dev/server/roles/googlemfa/vars/main.yml, line 4, column 3, found a duplicate dict key (username). Using last defined
value only.

When it runs through the role and gets to the task Generate a timed-based code for user

TASK [googlemfa : Generate a timed-based code for user] **************************************
fatal: [10.1.10.36]: FAILED! => {"failed": true, "msg": "the field 'args' has an invalid value, which appears to include a variable that is undefined. The error was: 'ansible.vars.unsafe_proxy.AnsibleUnsafeText object' has no attribute 'file'\n\nThe error appears to have been in '/Users/bshutter/Dev/server/roles/googlemfa/tasks/main.yml': line 55, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- name: Generate a timed-based code for user\n  ^ here\n"}

Upvotes: 2

Views: 2000

Answers (2)

Jack
Jack

Reputation: 6158

You are probably looking for with_nested.

However, it will be difficult to implement with the creates option, since only one of the commands will create that file. Also note that the loops must be distinct -- you cannot reference one list from the other.

Upvotes: 0

maximede
maximede

Reputation: 1823

I'm not sure I fully understand your issue as it looks like you only have one type of command to run. So, if you really only have the google authenticator command to run, I'd do something like this :

- name: Generate a timed-based code for user
  command: '/usr/bin/google-authenticator -t -f -d --label="{{item}}" --qr-mode=ANSI -r 3 -R 30 -w 1 --secret=/home/{{item}}' creates='/home/{{{ item }}/.google_authenticator'
  with_items: "{{ users }}"
  become: true

Upvotes: 2

Related Questions