Search code examples
ansiblejinja2

How to iterate over several list/names in Ansible?


I'm simply trying to make those three tasks into one, but can't find a proper way to do it.

- name: "Create directories for virtual users"
  ansible.builtin.file:
    dest: "/var/ftp_clients/{{ item.name }}"
    state: directory
    mode: 0755
    owner: ftp
    group: ftp
  with_items: "{{ ftp_users }}"

- name: "Create import dir for virtual users"
  ansible.builtin.file:
    dest: "/var/ftp_clients/{{ item.name }}/import"
    state: directory
    mode: 0755
    owner: ftp
    group: ftp
  with_items: "{{ ftp_users }}"

- name: "Create export for virtual users"
  ansible.builtin.file:
    dest: "/var/ftp_clients/{{ item.name }}/export"
    state: directory
    mode: 0755
    owner: ftp
    group: ftp
  with_items: "{{ ftp_users }}"

with the folowing variable:

ftp_users:
  - name: client1
    password: toto
  - name: client2
    password: toto
  - name: client3
    password: toto

The goal is only to create the directory for each client, and every client has to have an import and export subfolder.


Solution

  • You can achieve it using a product of the two lists (of directories and users) and the format filter.

    - name: Create directories for virtual users
      ansible.builtin.file:
        dest: "{{ item.0 | format(item.1.name) }}"
        state: directory
        mode: 0755
        owner: ftp
        group: ftp
      loop: "{{ _directories | product(ftp_users) }}"
      vars:
        _directories:
          - /var/ftp_clients/%s
          - /var/ftp_clients/%s/import
          - /var/ftp_clients/%s/export
    

    After running it, you should get the expected directories structure:

    /var/ftp_clients/
    ├── client1
    │   ├── export
    │   └── import
    ├── client2
    │   ├── export
    │   └── import
    └── client3
        ├── export
        └── import