Files
claudeandClaude Opus 5.5 a74d580b0a Style newsletters and system e-mails like www.eom.dev
Catppuccin Mocha campaign template (default) and archive variant, kept
in sync in the database; system e-mail header/footer overridden via
--static-dir from a ConfigMap. PNG logo for mail clients. Tested in
Mailpit (desktop, phone width; 87% CSS support, rest inlined).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 21:36:39 -05:00

139 lines
5.0 KiB
YAML

# SPDX-License-Identifier: MIT-0
---
- name: Validate required secrets
ansible.builtin.assert:
that:
- listmonk_db_password | length >= 16
- listmonk_admin_password | length >= 8
- listmonk_smtp_password | length > 0
- not listmonk_oidc_enabled | bool or listmonk_oidc_client_secret | length > 0
fail_msg: >-
Set listmonk_db_password (16+ chars), listmonk_admin_password (8+),
listmonk_smtp_password and listmonk_oidc_client_secret in Vault.
quiet: true
- name: Create namespace
kubernetes.core.k8s:
kubeconfig: "{{ listmonk_kubeconfig | default(omit, true) }}"
context: "{{ listmonk_kube_context | default(omit, true) }}"
state: present
definition:
apiVersion: v1
kind: Namespace
metadata:
name: "{{ listmonk_namespace }}"
when: listmonk_create_namespace | bool
- name: Store credentials
kubernetes.core.k8s:
kubeconfig: "{{ listmonk_kubeconfig | default(omit, true) }}"
context: "{{ listmonk_kube_context | default(omit, true) }}"
state: present
apply: true
definition: "{{ lookup('ansible.builtin.template', 'secret.yml.j2') | from_yaml }}"
no_log: true
- name: Deploy PostgreSQL
kubernetes.core.k8s:
kubeconfig: "{{ listmonk_kubeconfig | default(omit, true) }}"
context: "{{ listmonk_kube_context | default(omit, true) }}"
state: present
apply: true
definition: "{{ lookup('ansible.builtin.template', 'postgres.yml.j2') | from_yaml_all | list }}"
wait: true
wait_timeout: "{{ listmonk_wait_timeout }}"
- name: Store the system e-mail templates
kubernetes.core.k8s:
kubeconfig: "{{ listmonk_kubeconfig | default(omit, true) }}"
context: "{{ listmonk_kube_context | default(omit, true) }}"
state: present
apply: true
definition: "{{ lookup('ansible.builtin.template', 'email-configmap.yml.j2') | from_yaml }}"
- name: Deploy listmonk
kubernetes.core.k8s:
kubeconfig: "{{ listmonk_kubeconfig | default(omit, true) }}"
context: "{{ listmonk_kube_context | default(omit, true) }}"
state: present
apply: true
definition: "{{ lookup('ansible.builtin.template', 'listmonk.yml.j2') | from_yaml_all | list }}"
wait: true
wait_timeout: "{{ listmonk_wait_timeout }}"
- name: Read the newsletter automation credentials
kubernetes.core.k8s_info:
kubeconfig: "{{ listmonk_kubeconfig | default(omit, true) }}"
context: "{{ listmonk_kube_context | default(omit, true) }}"
kind: Secret
namespace: "{{ listmonk_namespace }}"
name: "{{ listmonk_name }}-newsletter-api"
register: _listmonk_newsletter_secret
no_log: true
when: listmonk_newsletter_api_enabled | bool
# Generated once, then reused; delete the Secret to rotate the token.
- name: Use or generate the newsletter automation token
ansible.builtin.set_fact:
listmonk_newsletter_api_token: >-
{{ (_listmonk_newsletter_secret.resources[0].data.token | b64decode)
if _listmonk_newsletter_secret.resources | length > 0
else lookup('ansible.builtin.password', '/dev/null', chars=['ascii_letters', 'digits'], length=48) }}
no_log: true
when: listmonk_newsletter_api_enabled | bool
- name: Store the newsletter automation credentials
kubernetes.core.k8s:
kubeconfig: "{{ listmonk_kubeconfig | default(omit, true) }}"
context: "{{ listmonk_kube_context | default(omit, true) }}"
state: present
definition:
apiVersion: v1
kind: Secret
metadata:
name: "{{ listmonk_name }}-newsletter-api"
namespace: "{{ listmonk_namespace }}"
type: Opaque
stringData:
url: "{{ listmonk_root_url }}"
username: "{{ listmonk_newsletter_api_user }}"
token: "{{ listmonk_newsletter_api_token }}"
no_log: true
when: listmonk_newsletter_api_enabled | bool
# Settings, Dex admins and lists live in listmonk's database, not its config.
- name: Converge database-held configuration
kubernetes.core.k8s_exec:
kubeconfig: "{{ listmonk_kubeconfig | default(omit, true) }}"
context: "{{ listmonk_kube_context | default(omit, true) }}"
namespace: "{{ listmonk_namespace }}"
pod: "{{ listmonk_name }}-db-0"
container: postgres
command: >-
sh -c 'echo {{ lookup('ansible.builtin.template', 'configure.sql.j2') | b64encode }}
| base64 -d | psql -U listmonk -d listmonk -qtA'
register: listmonk_configure
changed_when: listmonk_configure.stdout_lines | map('int') | sum > 0
no_log: true
- name: Restart listmonk to load the new settings
kubernetes.core.k8s:
kubeconfig: "{{ listmonk_kubeconfig | default(omit, true) }}"
context: "{{ listmonk_kube_context | default(omit, true) }}"
state: patched
kind: Deployment
namespace: "{{ listmonk_namespace }}"
name: "{{ listmonk_name }}"
definition:
spec:
template:
metadata:
annotations:
kubectl.kubernetes.io/restartedAt: "{{ now(utc=true).isoformat() }}"
wait: true
wait_condition:
type: Available
status: "True"
wait_timeout: "{{ listmonk_wait_timeout }}"
when: listmonk_configure is changed