Add PostgreSQL and Miniflux services to tailnet #16
7 changed files with 177 additions and 3 deletions
Add ansible-managed borgmatic config with PostgreSQL backup
- Move borgmatic config.yaml from manual to ansible-managed template - Add postgresql_databases backup for miniflux database - Consolidate 1Password credential fetching to playbook pre_tasks to reduce auth prompts during full playbook runs - Roles now check if credentials are already defined before fetching, so they still work when running with --tags Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
commit
cdb8432691
|
|
@ -1,6 +1,66 @@
|
|||
---
|
||||
- name: Configure indri
|
||||
hosts: indri
|
||||
|
||||
# Fetch all 1Password credentials upfront to minimize prompts
|
||||
# Each role also fetches its own credentials (with 'when: <var> is not defined')
|
||||
# so they still work when running with --tags
|
||||
pre_tasks:
|
||||
- name: Fetch PostgreSQL superuser password
|
||||
ansible.builtin.command:
|
||||
cmd: op --vault vg6xf6vvfmoh5hqjjhlhbeoaie item get guxu3j7ajhjyey6xxl2ovsl2ui --fields password --reveal
|
||||
delegate_to: localhost
|
||||
register: _pg_superuser_pw
|
||||
changed_when: false
|
||||
no_log: true
|
||||
|
||||
- name: Set PostgreSQL superuser password fact
|
||||
ansible.builtin.set_fact:
|
||||
pg_superuser_password: "{{ _pg_superuser_pw.stdout }}"
|
||||
no_log: true
|
||||
|
||||
- name: Fetch PostgreSQL alloy user password
|
||||
ansible.builtin.command:
|
||||
cmd: op --vault vg6xf6vvfmoh5hqjjhlhbeoaie item get guxu3j7ajhjyey6xxl2ovsl2ui --fields alloy-user-pw --reveal
|
||||
delegate_to: localhost
|
||||
register: _pg_alloy_pw
|
||||
changed_when: false
|
||||
no_log: true
|
||||
|
||||
- name: Set PostgreSQL alloy password fact
|
||||
ansible.builtin.set_fact:
|
||||
alloy_postgres_password: "{{ _pg_alloy_pw.stdout }}"
|
||||
no_log: true
|
||||
|
||||
- name: Fetch miniflux database password
|
||||
ansible.builtin.command:
|
||||
cmd: op --vault vg6xf6vvfmoh5hqjjhlhbeoaie item get ns6wylqiuqgczpo7gq2akaxbti --fields password --reveal
|
||||
delegate_to: localhost
|
||||
register: _miniflux_db_pw
|
||||
changed_when: false
|
||||
no_log: true
|
||||
|
||||
- name: Set miniflux passwords fact
|
||||
ansible.builtin.set_fact:
|
||||
miniflux_db_password: "{{ _miniflux_db_pw.stdout }}"
|
||||
no_log: true
|
||||
|
||||
- name: Fetch borgmatic database password
|
||||
ansible.builtin.command:
|
||||
cmd: op --vault vg6xf6vvfmoh5hqjjhlhbeoaie item get mw2bv5we7woicjza7hc6s44yvy --fields db-password --reveal
|
||||
delegate_to: localhost
|
||||
register: _borgmatic_db_pw
|
||||
changed_when: false
|
||||
no_log: true
|
||||
|
||||
- name: Build PostgreSQL user password lookup
|
||||
ansible.builtin.set_fact:
|
||||
pg_user_passwords:
|
||||
miniflux: "{{ _miniflux_db_pw.stdout }}"
|
||||
borgmatic: "{{ _borgmatic_db_pw.stdout }}"
|
||||
alloy: "{{ _pg_alloy_pw.stdout }}"
|
||||
no_log: true
|
||||
|
||||
roles:
|
||||
- role: loki
|
||||
tags: loki
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@
|
|||
mode: '0755'
|
||||
|
||||
# === Fetch PostgreSQL password from 1Password ===
|
||||
# Skipped when running full playbook (pre_tasks sets it)
|
||||
# but runs when using --tags alloy
|
||||
|
||||
- name: Fetch PostgreSQL metrics password from 1Password
|
||||
ansible.builtin.command:
|
||||
|
|
@ -34,13 +36,17 @@
|
|||
register: alloy_postgres_password_result
|
||||
changed_when: false
|
||||
no_log: true
|
||||
when: alloy_collect_postgres | default(false)
|
||||
when:
|
||||
- alloy_collect_postgres | default(false)
|
||||
- alloy_postgres_password is not defined
|
||||
|
||||
- name: Set PostgreSQL password fact
|
||||
ansible.builtin.set_fact:
|
||||
alloy_postgres_password: "{{ alloy_postgres_password_result.stdout }}"
|
||||
no_log: true
|
||||
when: alloy_collect_postgres | default(false)
|
||||
when:
|
||||
- alloy_collect_postgres | default(false)
|
||||
- alloy_postgres_password is not defined
|
||||
|
||||
# === Deploy configuration ===
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,48 @@
|
|||
---
|
||||
borgmatic_config: /Users/erichblume/.config/borgmatic/config.yaml
|
||||
borgmatic_config_dir: /Users/erichblume/.config/borgmatic
|
||||
borgmatic_log_dir: /Users/erichblume/Library/Logs
|
||||
|
||||
# Schedule: runs daily at 2:00 AM
|
||||
borgmatic_schedule_hour: 2
|
||||
borgmatic_schedule_minute: 0
|
||||
|
||||
# Source directories to back up
|
||||
borgmatic_source_directories:
|
||||
- /Users/erichblume/code/personal/zk
|
||||
- /opt/homebrew/var/forgejo
|
||||
- /Users/erichblume/code/3rd/kiwix-tools
|
||||
- /Users/erichblume/.config/borgmatic
|
||||
- /Users/erichblume/Documents
|
||||
- /Users/erichblume/Pictures
|
||||
- /Users/erichblume/devpi
|
||||
- /opt/homebrew/var/loki
|
||||
|
||||
# Backup repository
|
||||
borgmatic_repositories:
|
||||
- path: /Volumes/backups/borg/
|
||||
label: sifaka-borg-backups
|
||||
encryption: repokey
|
||||
append_only: true
|
||||
|
||||
# Exclude patterns
|
||||
borgmatic_exclude_patterns:
|
||||
# Exclude mirrored PyPI cache (only backup private packages)
|
||||
- /Users/erichblume/devpi/+files/root/pypi
|
||||
- /opt/homebrew/var/loki
|
||||
|
||||
# Encryption passcommand (reads borg passphrase)
|
||||
borgmatic_encryption_passcommand: cat /Users/erichblume/.borg/config.yaml
|
||||
|
||||
# Retention policy
|
||||
borgmatic_keep_daily: 7
|
||||
borgmatic_keep_monthly: 12
|
||||
borgmatic_keep_yearly: 1000
|
||||
|
||||
# PostgreSQL databases to backup (streamed via pg_dump)
|
||||
# Password is read from ~/.pgpass (managed by postgresql role)
|
||||
borgmatic_postgresql_databases:
|
||||
- name: miniflux
|
||||
hostname: localhost
|
||||
port: 5432
|
||||
username: borgmatic
|
||||
|
|
|
|||
|
|
@ -1,6 +1,18 @@
|
|||
---
|
||||
# Note: borgmatic is installed via mise (pipx), not managed here.
|
||||
# This role manages only the scheduled LaunchAgent.
|
||||
# This role manages the config file and scheduled LaunchAgent.
|
||||
|
||||
- name: Ensure borgmatic config directory exists
|
||||
ansible.builtin.file:
|
||||
path: "{{ borgmatic_config_dir }}"
|
||||
state: directory
|
||||
mode: '0700'
|
||||
|
||||
- name: Deploy borgmatic configuration
|
||||
ansible.builtin.template:
|
||||
src: config.yaml.j2
|
||||
dest: "{{ borgmatic_config }}"
|
||||
mode: '0600'
|
||||
|
||||
- name: Deploy borgmatic LaunchAgent plist
|
||||
ansible.builtin.template:
|
||||
|
|
|
|||
45
ansible/roles/borgmatic/templates/config.yaml.j2
Normal file
45
ansible/roles/borgmatic/templates/config.yaml.j2
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
# {{ ansible_managed }}
|
||||
|
||||
source_directories:
|
||||
{% for dir in borgmatic_source_directories %}
|
||||
- {{ dir }}
|
||||
{% endfor %}
|
||||
|
||||
source_directories_must_exist: true
|
||||
|
||||
repositories:
|
||||
{% for repo in borgmatic_repositories %}
|
||||
- path: {{ repo.path }}
|
||||
label: {{ repo.label }}
|
||||
{% if repo.encryption is defined %}
|
||||
encryption: {{ repo.encryption }}
|
||||
{% endif %}
|
||||
{% if repo.append_only is defined %}
|
||||
append_only: {{ repo.append_only | lower }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% if borgmatic_exclude_patterns %}
|
||||
exclude_patterns:
|
||||
{% for pattern in borgmatic_exclude_patterns %}
|
||||
- {{ pattern }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
encryption_passcommand: {{ borgmatic_encryption_passcommand }}
|
||||
|
||||
# Retention policy
|
||||
keep_daily: {{ borgmatic_keep_daily }}
|
||||
keep_monthly: {{ borgmatic_keep_monthly }}
|
||||
keep_yearly: {{ borgmatic_keep_yearly }}
|
||||
|
||||
{% if borgmatic_postgresql_databases %}
|
||||
# PostgreSQL database backups (streamed via pg_dump)
|
||||
postgresql_databases:
|
||||
{% for db in borgmatic_postgresql_databases %}
|
||||
- name: {{ db.name }}
|
||||
hostname: {{ db.hostname | default('localhost') }}
|
||||
port: {{ db.port | default(5432) }}
|
||||
username: {{ db.username }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
|
@ -14,6 +14,8 @@
|
|||
state: present
|
||||
|
||||
# === Fetch passwords from 1Password ===
|
||||
# These are skipped when running full playbook (pre_tasks sets them)
|
||||
# but run when using --tags miniflux
|
||||
|
||||
- name: Fetch miniflux database password from 1Password
|
||||
ansible.builtin.command:
|
||||
|
|
@ -22,11 +24,13 @@
|
|||
register: miniflux_db_password_result
|
||||
changed_when: false
|
||||
no_log: true
|
||||
when: miniflux_db_password is not defined
|
||||
|
||||
- name: Set database password fact
|
||||
ansible.builtin.set_fact:
|
||||
miniflux_db_password: "{{ miniflux_db_password_result.stdout }}"
|
||||
no_log: true
|
||||
when: miniflux_db_password is not defined
|
||||
|
||||
- name: Fetch miniflux admin password from 1Password (for first run)
|
||||
ansible.builtin.command:
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@
|
|||
state: present
|
||||
|
||||
# === Fetch passwords from 1Password (on control machine) ===
|
||||
# These are skipped when running full playbook (pre_tasks sets them)
|
||||
# but run when using --tags postgresql
|
||||
|
||||
- name: Fetch superuser password from 1Password
|
||||
ansible.builtin.command:
|
||||
|
|
@ -18,11 +20,13 @@
|
|||
register: pg_superuser_password_result
|
||||
changed_when: false
|
||||
no_log: true
|
||||
when: pg_superuser_password is not defined
|
||||
|
||||
- name: Set superuser password fact
|
||||
ansible.builtin.set_fact:
|
||||
pg_superuser_password: "{{ pg_superuser_password_result.stdout }}"
|
||||
no_log: true
|
||||
when: pg_superuser_password is not defined
|
||||
|
||||
- name: Fetch user passwords from 1Password
|
||||
ansible.builtin.command:
|
||||
|
|
@ -32,12 +36,14 @@
|
|||
register: pg_user_passwords_result
|
||||
changed_when: false
|
||||
no_log: true
|
||||
when: pg_user_passwords is not defined
|
||||
|
||||
- name: Build user password lookup
|
||||
ansible.builtin.set_fact:
|
||||
pg_user_passwords: "{{ pg_user_passwords | default({}) | combine({item.item.name: item.stdout}) }}"
|
||||
loop: "{{ pg_user_passwords_result.results }}"
|
||||
no_log: true
|
||||
when: pg_user_passwords is not defined
|
||||
|
||||
# === Initialize PostgreSQL cluster ===
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue