--- - name: Create temporary directory on localhost delegate_to: localhost become: false ansible.builtin.tempfile: state: directory register: tempdir - name: Define list of binary extensions set_fact: binary_extensions: - png - jpg - jpeg - gif - pdf - bin - exe - zip - tar - gz - bz2 - xz - mp3 - mp4 - wav - avi - name: Initialize file lists set_fact: text_files: [] binary_files: [] - name: Classify files into text and binary set_fact: text_files: "{{ text_files + [item] if (file_ext not in binary_extensions) else text_files }}" binary_files: "{{ binary_files + [item] if (file_ext in binary_extensions) else binary_files }}" vars: file_ext: "{{ (item.path | splitext | last | regex_replace('^\\.', '')) | lower }}" loop: "{{ lookup('filetree', render_dir) }}" when: item.state == "file" loop_control: label: "{{ item.path }}" - name: Ensure parent directories exist for all files delegate_to: localhost become: false ansible.builtin.file: path: "{{ tempdir.path }}/{{ item.path | dirname }}" state: directory mode: "{{ mode | default('0755') }}" with_filetree: "{{ render_dir }}" when: item.state == "file" - name: Render templates (text files only) delegate_to: localhost become: false ansible.builtin.template: src: "{{ render_dir }}/{{ item.path }}" dest: "{{ tempdir.path }}/{{ item.path }}" mode: "{{ mode | default('0755') }}" loop: "{{ text_files }}" - name: Copy binary files directly delegate_to: localhost become: false ansible.builtin.copy: src: "{{ render_dir }}/{{ item.path }}" dest: "{{ tempdir.path }}/{{ item.path }}" mode: "{{ mode | default('0644') }}" loop: "{{ binary_files }}" - name: Create tarball of rendered files delegate_to: localhost become: false ansible.builtin.command: cmd: tar -czf /tmp/rendered-files-{{ tempdir.path | basename }}.tar.gz -C {{ tempdir.path }} . register: tar_result changed_when: tar_result.rc == 0 - name: Transfer tarball to remote host ansible.builtin.copy: src: "/tmp/rendered-files-{{ tempdir.path | basename }}.tar.gz" dest: "/tmp/rendered-files.tar.gz" mode: '0644' - name: Ensure destination directory exists become: true ansible.builtin.file: path: "{{ destination_dir }}" state: directory owner: "{{ owner }}" group: "{{ group | default(owner) }}" - name: Extract tarball to destination become: true ansible.builtin.unarchive: src: "/tmp/rendered-files.tar.gz" dest: "{{ destination_dir }}" remote_src: yes owner: "{{ owner }}" group: "{{ group | default(owner) }}" - name: Remove remote tarball ansible.builtin.file: path: "/tmp/rendered-files.tar.gz" state: absent - name: Remove local tarball delegate_to: localhost become: false ansible.builtin.file: path: "/tmp/rendered-files-{{ tempdir.path | basename }}.tar.gz" state: absent - name: Remove local temporary directory delegate_to: localhost become: false ansible.builtin.file: path: "{{ tempdir.path }}" state: absent