--- - name: "📁 Pre-create NFS subdirs for '{{ application_id }}'" ansible.builtin.file: path: "{{ STORAGE_NFS_STATE_PATH }}/{{ item.value.name | default(item.key) }}" state: directory owner: "{{ (item.value['x-infinito-nfs'] | default({})).uid | default(omit) }}" group: "{{ (item.value['x-infinito-nfs'] | default({})).gid | default(omit) }}" mode: "{{ (item.value['x-infinito-nfs'] | default({})).mode | default(omit) }}" delegate_to: "{{ (groups['svc-storage-nfs-server'] | default([]))[0] | default(inventory_hostname) }}" run_once: true # nocheck: include-uniform-apply-keyword (per-task delegation targets differ) loop: "{{ (lookup('compose_volumes') | from_yaml).volumes | default({}) | dict2items }}" loop_control: label: "{{ item.key }}" when: - DEPLOYMENT_MODE == 'swarm' - (storage.backend | default('local')) == 'nfs' - (groups['svc-storage-nfs-server'] | default([])) | length > 0 - item.value is mapping - item.value.driver_opts is defined - application_id not in lookup('roles_with_placement', 'manager') - name: "🔁 Materialize NFS subdirs for '{{ application_id }}' on every swarm node" ansible.builtin.file: path: "{{ DIR_VAR_LIB }}/{{ item.0.value.name | default(item.0.key) }}" state: directory owner: "{{ (item.0.value['x-infinito-nfs'] | default({})).uid | default(omit) }}" group: "{{ (item.0.value['x-infinito-nfs'] | default({})).gid | default(omit) }}" mode: "{{ (item.0.value['x-infinito-nfs'] | default({})).mode | default(omit) }}" delegate_to: "{{ item.1 }}" run_once: true loop: "{{ (lookup('compose_volumes') | from_yaml).volumes | default({}) | dict2items | product(groups['svc-swarm-node'] | default([])) | list }}" loop_control: label: "{{ item.0.key }} @ {{ item.1 }}" when: - DEPLOYMENT_MODE == 'swarm' - (storage.backend | default('local')) == 'nfs' - (groups['svc-storage-nfs-server'] | default([])) | length > 0 - item.0.value is mapping - item.0.value.driver_opts is defined - application_id not in lookup('roles_with_placement', 'manager')