--- - name: Create n8n directories ansible.builtin.file: path: "{{ item.path }}" state: directory owner: "{{ item.owner }}" group: "{{ item.owner }}" mode: "{{ item.mode }}" loop: - { path: "{{ n8n_data_dir }}", owner: root, mode: "0755" } # n8n runs as uid 1000 (node) inside the container - { path: "{{ n8n_data_dir }}/data", owner: "1000", mode: "0700" } - { path: "{{ n8n_data_dir }}/import", owner: "1000", mode: "0700" } - { path: "{{ n8n_data_dir }}/import/workflows", owner: "1000", mode: "0700" } - { path: "{{ n8n_data_dir }}/import/credentials", owner: "1000", mode: "0700" } tags: n8n - name: Deploy Docker Compose file ansible.builtin.template: src: docker-compose.yml.j2 dest: "{{ n8n_data_dir }}/docker-compose.yml" owner: root group: root mode: "0644" notify: Restart n8n tags: n8n # __TELEGRAM_USER_ID__ and __OLLAMA_MODEL__ in the workflow files are replaced by telegram_user_id and ollama_model - name: Deploy workflows ansible.builtin.copy: content: "{{ lookup('ansible.builtin.file', item) | replace('__TELEGRAM_USER_ID__', telegram_user_id | string) | replace('__OLLAMA_MODEL__', ollama_model) }}" dest: "{{ n8n_data_dir }}/import/workflows/{{ item | basename }}" owner: "1000" group: "1000" mode: "0600" with_fileglob: - "workflows/*.json" notify: Import n8n content tags: n8n - name: Deploy Ollama credential ansible.builtin.copy: src: credentials/ollama.json dest: "{{ n8n_data_dir }}/import/credentials/ollama.json" owner: "1000" group: "1000" mode: "0600" notify: Import n8n content tags: n8n - name: Deploy SMTP credential ansible.builtin.template: src: smtp-credential.json.j2 dest: "{{ n8n_data_dir }}/import/credentials/smtp.json" owner: "1000" group: "1000" mode: "0600" no_log: true notify: Import n8n content tags: n8n # Workflows with "active": true in their JSON are published after import - name: Collect workflow ids to publish ansible.builtin.set_fact: n8n_publish_ids: >- {%- set ns = namespace(ids=[]) -%} {%- for f in query('fileglob', role_path ~ '/files/workflows/*.json') -%} {%- set wf = lookup('file', f) | from_json -%} {%- if wf.active | default(false) -%}{%- set ns.ids = ns.ids + [wf.id] -%}{%- endif -%} {%- endfor -%} {{ ns.ids | to_json }} tags: n8n - name: Deploy Telegram credential ansible.builtin.template: src: telegram-credential.json.j2 dest: "{{ n8n_data_dir }}/import/credentials/telegram.json" owner: "1000" group: "1000" mode: "0600" no_log: true notify: Import n8n content tags: n8n - name: Deploy Gemini credential ansible.builtin.template: src: gemini-credential.json.j2 dest: "{{ n8n_data_dir }}/import/credentials/gemini.json" owner: "1000" group: "1000" mode: "0600" no_log: true notify: Import n8n content tags: n8n - name: Start n8n community.docker.docker_compose_v2: project_src: "{{ n8n_data_dir }}" state: present pull: missing tags: n8n # Handlers run at the end of the play; flush so the import happens before the role finishes - name: Apply pending handlers ansible.builtin.meta: flush_handlers tags: n8n