wulf-ansible/playbooks/planka.yml
Lorentz cedebad116 Fix planka.yml secrets tasks skipped in check mode
Add `when: not ansible_check_mode` to the slurp and set_fact tasks
so that dry runs don't fail when .secrets hasn't been created yet.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 14:08:16 -04:00

133 lines
4.5 KiB
YAML

---
- name: Deploy Planka kanban board
hosts: all
become: true
vars:
planka_stack_dir: /opt/stacks/planka
planka_version: "2.0.0-rc.3"
planka_port: 3000
planka_base_url: "http://{{ ansible_default_ipv4.address }}:{{ planka_port }}"
planka_trust_proxy: false
planka_token_expires_in: 365
planka_log_level: warn
planka_db_name: planka
planka_admin_email: "admin@example.com"
planka_admin_password: "ChangeMe123!"
planka_admin_name: "Planka Admin"
planka_admin_username: "admin"
# Set true to force regeneration of SECRET_KEY and INTERNAL_ACCESS_TOKEN
planka_rotate_secrets: false
pre_tasks:
- name: Fail if planka_admin_password is default
ansible.builtin.fail:
msg: "planka_admin_password is still the default value. Pass a real password via -e or Semaphore extra vars."
when: planka_admin_password == "ChangeMe123!"
- name: Fail if planka_base_url is not set
ansible.builtin.fail:
msg: "planka_base_url is required. Pass it via -e planka_base_url=https://planka.example.wulf.cloud"
when: planka_base_url is not defined or planka_base_url | length == 0
- name: Verify Docker is running
ansible.builtin.service_facts:
- name: Fail if Docker is not running
ansible.builtin.fail:
msg: "Docker is not running on this host."
when: "'docker.service' not in ansible_facts.services or ansible_facts.services['docker.service'].state != 'running'"
- name: Ensure pangolin Docker network exists
community.docker.docker_network:
name: pangolin
driver: bridge
state: present
tasks:
- name: Create stack directory
ansible.builtin.file:
path: "{{ planka_stack_dir }}"
state: directory
owner: root
group: root
mode: "0750"
- name: Check if .secrets file exists (persisted secrets)
ansible.builtin.stat:
path: "{{ planka_stack_dir }}/.secrets"
register: _secrets_stat
- name: Generate new secrets
ansible.builtin.shell:
cmd: "echo SECRET_KEY=$(openssl rand -hex 64) && echo INTERNAL_ACCESS_TOKEN=$(openssl rand -hex 32)"
register: _new_secrets
changed_when: false
when: not _secrets_stat.stat.exists or planka_rotate_secrets
- name: Persist generated secrets
ansible.builtin.copy:
dest: "{{ planka_stack_dir }}/.secrets"
content: "{{ _new_secrets.stdout }}"
owner: root
group: root
mode: "0600"
when: not _secrets_stat.stat.exists or planka_rotate_secrets
- name: Read persisted secrets
ansible.builtin.slurp:
src: "{{ planka_stack_dir }}/.secrets"
register: _secrets_file
when: not ansible_check_mode
- name: Parse secret values
ansible.builtin.set_fact:
planka_secret_key: "{{ (_secrets_file.content | b64decode).split('\n') | select('match', '^SECRET_KEY=') | first | regex_replace('^SECRET_KEY=', '') }}"
planka_access_token: "{{ (_secrets_file.content | b64decode).split('\n') | select('match', '^INTERNAL_ACCESS_TOKEN=') | first | regex_replace('^INTERNAL_ACCESS_TOKEN=', '') }}"
when: not ansible_check_mode
- name: Deploy compose.yaml
ansible.builtin.template:
src: templates/planka-compose.yml.j2
dest: "{{ planka_stack_dir }}/compose.yaml"
owner: root
group: root
mode: "0640"
notify: Restart planka
- name: Deploy Planka stack
community.docker.docker_compose_v2:
project_src: "{{ planka_stack_dir }}"
pull: always
build: never
state: present
register: _compose_result
- name: Wait for Planka to respond
ansible.builtin.uri:
url: "http://{{ ansible_default_ipv4.address }}:{{ planka_port }}"
status_code: 200
follow_redirects: safe
register: _health
until: _health.status == 200
retries: 12
delay: 5
ignore_errors: true
- name: Deployment summary
ansible.builtin.debug:
msg:
- "Planka deployed"
- "URL: {{ planka_base_url }}"
- "Admin: {{ planka_admin_email }}"
- "API token: {{ planka_access_token }}"
- "Stack dir: {{ planka_stack_dir }}"
- "Secrets rotated: {{ planka_rotate_secrets }}"
handlers:
- name: Restart planka
community.docker.docker_compose_v2:
project_src: "{{ planka_stack_dir }}"
state: present
recreate: always
listen: Restart planka