feat: add Hetzner-hosted todo application stack

Implement the server-rendered Go todo application with PostgreSQL persistence, Tailwind styling, health checks, and test coverage.

Provision production and staging infrastructure with OpenTofu, including private networking, static IPs, Object Storage backups, and load balancing.

Configure Rocky Linux hosts with Ansible, rootless Podman, PostgreSQL, WAL-G backup automation, staging restores, and generated inventory.
This commit is contained in:
cole-maxwell1
2026-08-06 21:34:56 -05:00
commit 1382c42803
68 changed files with 2380 additions and 0 deletions
+75
View File
@@ -0,0 +1,75 @@
---
- name: Initialize PostgreSQL data directory
ansible.builtin.command:
argv: [postgresql-setup, --initdb]
args:
creates: "{{ postgres_data_dir }}/PG_VERSION"
- name: Create canonical PostgreSQL configuration directory
ansible.builtin.file:
path: /etc/todo-postgresql
state: directory
owner: root
group: postgres
mode: "0750"
- name: Render canonical PostgreSQL server configuration
ansible.builtin.template:
src: postgresql.conf.j2
dest: /etc/todo-postgresql/postgresql.conf
owner: root
group: postgres
mode: "0640"
notify: Restart PostgreSQL
- name: Render canonical PostgreSQL client authentication
ansible.builtin.template:
src: pg_hba.conf.j2
dest: /etc/todo-postgresql/pg_hba.conf
owner: root
group: postgres
mode: "0640"
notify: Restart PostgreSQL
- name: Install PostgreSQL configuration in data directory
ansible.builtin.copy:
src: "/etc/todo-postgresql/{{ item }}"
dest: "{{ postgres_data_dir }}/{{ item }}"
remote_src: true
owner: postgres
group: postgres
mode: "0600"
loop:
- postgresql.conf
- pg_hba.conf
notify: Restart PostgreSQL
- name: Start PostgreSQL
ansible.builtin.systemd_service:
name: "{{ postgres_service }}"
enabled: true
state: started
- name: Apply PostgreSQL configuration before provisioning
ansible.builtin.meta: flush_handlers
- name: Provision application database role
ansible.builtin.command:
argv: [psql, --set, "role={{ app_db_user }}", --set, "password={{ app_db_password }}", --dbname, postgres]
stdin: |
SELECT format('CREATE ROLE %I LOGIN PASSWORD %L', :'role', :'password')
WHERE NOT EXISTS (SELECT FROM pg_roles WHERE rolname = :'role') \gexec
SELECT format('ALTER ROLE %I LOGIN PASSWORD %L', :'role', :'password') \gexec
become_user: postgres
changed_when: false
no_log: true
- name: Provision application database
ansible.builtin.command:
argv: [psql, --set, "database={{ app_db_name }}", --set, "role={{ app_db_user }}", --dbname, postgres]
stdin: |
SELECT format('CREATE DATABASE %I OWNER %I', :'database', :'role')
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = :'database') \gexec
SELECT format('ALTER DATABASE %I OWNER TO %I', :'database', :'role') \gexec
become_user: postgres
changed_when: false