--- - name: Initialization stage hosts: all become: true gather_facts: true vars: stage_name: initialization inventory_init: "/path/to/Infrastrucutre as Code/ansible/inventory_initialization.yml" inventory_active: "/path/to/Infrastrucutre as Code/ansible/inventory.yml" vars_files: - /path/to/Infrastrucutre as Code/ansible/roles_metadata.yml - /path/to/Infrastrucutre as Code/ansible/group_vars/all/vault_token.yml pre_tasks: - name: Ensure active inventory exists ansible.builtin.file: path: "{{ inventory_active }}" state: touch delegate_to: localhost run_once: true - name: Load existing active inventory ansible.builtin.slurp: src: "{{ inventory_active }}" register: active_inv_raw delegate_to: localhost run_once: true - name: Parse active inventory YAML (or initialize empty) ansible.builtin.set_fact: active_inventory: >- {{ (active_inv_raw.content | b64decode | from_yaml) if (active_inv_raw.content | b64decode | from_yaml is mapping) else {'all': {'hosts': {}}} }} run_once: true tasks: - name: Run initialization roles for uninitialized hosts ansible.builtin.include_role: name: "{{ item }}" loop: >- {{ vm_tags | select('in', roles_metadata | dict2items | selectattr('value.' ~ stage_name, 'defined') | selectattr('value.' ~ stage_name) | map(attribute='key') | list ) | list }} post_tasks: - name: Append or update host in active inventory ansible.builtin.set_fact: active_inventory: >- {{ active_inventory | combine({ 'all': { 'hosts': ( active_inventory.all.hosts | combine({ inventory_hostname: { 'ansible_host': hostvars[inventory_hostname]['ansible_host'], 'ansible_port': hostvars[inventory_hostname]['ssh_port'] | default(22), 'initialized': true } }) ) } }, recursive=True) }} delegate_to: localhost - name: Write updated active inventory back to file ansible.builtin.copy: dest: "{{ inventory_active }}" content: "{{ active_inventory | to_nice_yaml }}" delegate_to: localhost run_once: true