11

I want to run a task where the parameters are filled using with_items, rather than having to manually write parameter:{{item.key}}. For example, I have this host var:

HtpasswdsToSet:
 - path: /etc/nginx/passwdfile
   name: janedoe
   password: 'abc123'
 - path: /etc/nginx/passwdfile
   name: bob
   password: '123abc'

Note that the dictionary list keys are actual htpasswd task parameters.

In the playbook, instead of doing this:

- name: add htpasswd users
  htpasswd:
    path: {{item.path}}
    name: {{item.name}}
    password: '{{item.password}}'
  with_items: "{{HtpasswdsToSet}}"

Is there some way to simply do this?

- name: add htpasswd users
  htpasswd: "{{HtpasswdsToSet}}"

This would really help me reduce playbook verbosity. Thank you.

tom_nb_ny
  • 51
  • 1
  • 9
  • 1
    The [`htpasswd`](http://docs.ansible.com/ansible/htpasswd_module.html) module indicates `name` and `path` are both _required_ parameters. There is no short hand syntax which bypasses that. – jscott Jan 06 '17 at 01:24
  • Both `name` and `path` are defined in the `HtpasswdsToSet` dictionary list. Can it be somehow included directly, rather than having to type out each `parameter:{{item.key}}` in the htpasswd task? – tom_nb_ny Jan 06 '17 at 01:56
  • 1
    I understood your definition of `HtpasswdsToSet`. You're asking for two things, neither of which seem ideal. 1. Interpolation of module parameter names from variables. 2. Some form of automagic-looping without a `with_x` clause. I don't know of supported way to do this, but [this](http://stackoverflow.com/questions/27805976/resolve-dictionary-key-or-parameter-variable-in-ansible) seems particularly fragile if you're interested. – jscott Jan 06 '17 at 02:09

2 Answers2

9

With Ansible 2.2 you can still use args parameter to achieve that.
But it is deprecated for a while already and will display a warning for you.
Some details about deprecation.

Example:

- hosts: localhost
  gather_facts: no
  vars:
    args_list:
      - content: hello world
        dest: /tmp/test1.txt
        mode: 0666
      - content: test test test
        dest: /tmp/test2.txt
        mode: 0444
  tasks:
    - copy:
      args: "{{ item }}"
      with_items: "{{ args_list }}"
Konstantin Suvorov
  • 3,996
  • 1
  • 12
  • 13
3

For those who came here from a search engine, i have successfully tested the following on Ansible 2.9.14:

vars:
 my_module_defaults:
   state: present
 data_to_fetch:
    - arg1: 42
      arg2: foo
    - arg1: 43
[...]

tasks:
  - name: Very slim task
    my_module: "{{ my_module_defaults | combine(item) }}"
    with_items: "{{ data_to_fetch }}"
phowner
  • 31
  • 1