wulf-ansible/playbooks/n8n.yml
lorentz 9358eb3302 Skip n8n Deploy stack task in check mode
The command module validates args.chdir before honoring check mode, so
dry runs fail with ENOENT on the stack dir (file task only pretends to
create it). Gate Deploy stack on ansible_check_mode — dry runs should
not run docker compose up anyway.
2026-04-21 01:37:07 +00:00

103 lines
No EOL
3.2 KiB
YAML

- name: Deploy n8n
hosts: all
become: true
vars:
stack_dir: "/opt/stacks/{{ stack_name }}"
pre_tasks:
- name: Fail if stack_name is not set
fail:
msg: "stack_name is required"
when: stack_name is not defined or stack_name | length == 0
- name: Fail if n8n_url is not set
fail:
msg: "n8n_url is required"
when: n8n_url is not defined or n8n_url | length == 0
tasks:
# 🔎 Check if 1Password item exists
- name: Check if 1Password item exists
shell: |
op item get "{{ stack_name }}" --vault="Automation"
register: op_check
failed_when: false
changed_when: false
check_mode: no
environment:
OP_SERVICE_ACCOUNT_TOKEN: "{{ lookup('env','OP_SERVICE_ACCOUNT_TOKEN') }}"
# 🔐 Load existing secrets
- name: Load secrets from 1Password
when: op_check.rc == 0
shell: |
op item get "{{ stack_name }}" --vault="Automation" --format json
register: op_item
check_mode: no
environment:
OP_SERVICE_ACCOUNT_TOKEN: "{{ lookup('env','OP_SERVICE_ACCOUNT_TOKEN') }}"
- name: Set secrets from 1Password
when: op_check.rc == 0
set_fact:
n8n_postgres_password: "{{ (op_item.stdout | from_json).fields | selectattr('label','equalto','postgres_password') | map(attribute='value') | first }}"
n8n_encryption_key: "{{ (op_item.stdout | from_json).fields | selectattr('label','equalto','encryption_key') | map(attribute='value') | first }}"
# 🔑 Generate if new
- name: Generate postgres password
when: op_check.rc != 0
set_fact:
n8n_postgres_password: "{{ lookup('password','/dev/null length=32 chars=ascii_letters') }}"
- name: Generate encryption key
when: op_check.rc != 0
set_fact:
n8n_encryption_key: "{{ lookup('password','/dev/null length=64 chars=hexdigits') }}"
# 📦 Store in 1Password
- name: Create 1Password item
when: op_check.rc != 0
shell: |
op item create \
--category="Server" \
--title="{{ stack_name }}" \
--vault="Automation" \
"url=https://{{ n8n_url }}" \
"username={{ n8n_editor_email }}" \
"password={{ n8n_editor_password }}" \
"postgres_password={{ n8n_postgres_password }}" \
"encryption_key={{ n8n_encryption_key }}"
environment:
OP_SERVICE_ACCOUNT_TOKEN: "{{ lookup('env','OP_SERVICE_ACCOUNT_TOKEN') }}"
# 🧱 Infrastructure
- name: Ensure stack directory exists
file:
path: "{{ stack_dir }}"
state: directory
mode: "0755"
- name: Ensure pangolin network exists
community.docker.docker_network:
name: pangolin
state: present
# 📄 Templates
- name: Render .env
template:
src: templates/n8n.env.j2
dest: "{{ stack_dir }}/.env"
mode: "0600"
- name: Render compose file
template:
src: templates/n8n-compose.yml.j2
dest: "{{ stack_dir }}/compose.yml"
# 🚀 Deploy
- name: Deploy stack
command: docker compose up -d
args:
chdir: "{{ stack_dir }}"
when: not ansible_check_mode