From 28eedea37208970ee2c6c1459869b94e52f84795 Mon Sep 17 00:00:00 2001 From: Moritz Graf Date: Tue, 20 Oct 2026 09:39:26 +0200 Subject: [PATCH] refactor(terraform): move shelly to projects/shelly_taupunktluefter and flatten core infra --- AGENTS.md | 26 ++++++++------- README.md | 8 +++-- ...as-code-and-reproducible-infrastructure.md | 2 +- k8s/README.md | 2 +- k8s/auth/README.md | 4 +-- k8s/auth/USER_MANAGEMENT.md | 10 +++--- .../shelly_taupunktluefter}/.gitignore | 0 .../.terraform.lock.hcl | 0 .../shelly_taupunktluefter}/AGENTS.md | 10 +++--- projects/shelly_taupunktluefter/README.md | 26 +++++++++++++++ .../shelly_taupunktluefter}/main.tf | 0 .../shelly_taupunktluefter}/providers.tf | 0 .../scripts/Taupi-4.0.js | 0 .../scripts/get_status.py | 0 .../shelly_taupunktluefter}/scripts/upload.py | 0 .../shelly_taupunktluefter}/terraform.tfvars | 0 .../shelly_taupunktluefter}/variables.tf | 0 terraform/.gitignore | 5 +-- .../{infrastructure => }/.terraform.lock.hcl | 0 terraform/AGENTS.md | 31 ++++++++++++++++++ terraform/README.md | 25 ++++++++++++++ .../authentik.secret.auto.tfvars | Bin terraform/{infrastructure => }/authentik.tf | 0 terraform/{infrastructure => }/gcp_apis.tf | 0 terraform/{infrastructure => }/gcp_backups.tf | 0 .../{infrastructure => }/gcp_calendar.tf | 0 .../{infrastructure => }/google_workspace.tf | 0 .../haumdaucher-theme.css | 0 terraform/infrastructure/.gitignore | 2 -- .../misc/get_consumer_key.py | 0 .../{infrastructure => }/misc/get_domain.py | 0 terraform/{infrastructure => }/misc/ovh.conf | 0 terraform/{infrastructure => }/ovh.tf | 0 .../{infrastructure => }/terraform.tfstate | 0 .../terraform.tfstate.1748511344.backup | 0 .../terraform.tfstate.1748511364.backup | 0 .../terraform.tfstate.backup | 0 terraform/{infrastructure => }/versions.tf | 0 38 files changed, 118 insertions(+), 33 deletions(-) rename {terraform/shelly => projects/shelly_taupunktluefter}/.gitignore (100%) rename {terraform/shelly => projects/shelly_taupunktluefter}/.terraform.lock.hcl (100%) rename {terraform/shelly => projects/shelly_taupunktluefter}/AGENTS.md (79%) create mode 100644 projects/shelly_taupunktluefter/README.md rename {terraform/shelly => projects/shelly_taupunktluefter}/main.tf (100%) rename {terraform/shelly => projects/shelly_taupunktluefter}/providers.tf (100%) rename {terraform/shelly => projects/shelly_taupunktluefter}/scripts/Taupi-4.0.js (100%) rename {terraform/shelly => projects/shelly_taupunktluefter}/scripts/get_status.py (100%) rename {terraform/shelly => projects/shelly_taupunktluefter}/scripts/upload.py (100%) rename {terraform/shelly => projects/shelly_taupunktluefter}/terraform.tfvars (100%) rename {terraform/shelly => projects/shelly_taupunktluefter}/variables.tf (100%) rename terraform/{infrastructure => }/.terraform.lock.hcl (100%) create mode 100644 terraform/AGENTS.md create mode 100644 terraform/README.md rename terraform/{infrastructure => }/authentik.secret.auto.tfvars (100%) rename terraform/{infrastructure => }/authentik.tf (100%) rename terraform/{infrastructure => }/gcp_apis.tf (100%) rename terraform/{infrastructure => }/gcp_backups.tf (100%) rename terraform/{infrastructure => }/gcp_calendar.tf (100%) rename terraform/{infrastructure => }/google_workspace.tf (100%) rename terraform/{infrastructure => }/haumdaucher-theme.css (100%) delete mode 100644 terraform/infrastructure/.gitignore rename terraform/{infrastructure => }/misc/get_consumer_key.py (100%) rename terraform/{infrastructure => }/misc/get_domain.py (100%) rename terraform/{infrastructure => }/misc/ovh.conf (100%) rename terraform/{infrastructure => }/ovh.tf (100%) rename terraform/{infrastructure => }/terraform.tfstate (100%) rename terraform/{infrastructure => }/terraform.tfstate.1748511344.backup (100%) rename terraform/{infrastructure => }/terraform.tfstate.1748511364.backup (100%) rename terraform/{infrastructure => }/terraform.tfstate.backup (100%) rename terraform/{infrastructure => }/versions.tf (100%) diff --git a/AGENTS.md b/AGENTS.md index c2a74f5..19f8850 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -19,16 +19,12 @@ This repository is divided into distinct domains, each with its own `AGENTS.md` * **OpenClaw**: For OpenClaw AI agent deployment and troubleshooting, see [k8s/openclaw/AGENTS.md](./k8s/openclaw/AGENTS.md) and [k8s/openclaw/TROUBLESHOOTING.md](./k8s/openclaw/TROUBLESHOOTING.md). * **Read**: [k8s/AGENTS.md](./k8s/AGENTS.md) -### 3. Terraform (`terraform/`) -* **Purpose**: Infrastructure as Code divided into two symmetrical modules: - * **Cloud & DNS (`terraform/infrastructure/`)**: - * **DNS Zones**: `haumdaucher.de`, `moritzgraf.de`, `ameliegraf.de`, and others via OVH (`ovh/ovh`). - * **Cloud Services**: Authentik SSO (`authentik.tf`), GCP APIs, backups, and Google Workspace MX/SPF/DKIM. - * **Usage**: `cd terraform/infrastructure && terraform apply` - * **Smart Home Shelly Automation (`terraform/shelly/`)**: - * **Taupi Cellar Mold Ventilation**: Automates Shelly Plug S with psychrometric dew point calculations (`Taupi-4.0.js`) and BTHome Bluetooth sensor telemetry. - * **Usage**: `cd terraform/shelly && terraform apply` -* **Read**: [terraform/shelly/AGENTS.md](./terraform/shelly/AGENTS.md) +### 3. [Terraform](./terraform/AGENTS.md) (`terraform/`) +* **Purpose**: Declarative core cloud infrastructure as code. + * **DNS Zones**: `haumdaucher.de`, `moritzgraf.de`, `ameliegraf.de`, and others via OVH (`ovh/ovh`). + * **Cloud Services**: Authentik SSO (`authentik.tf`), GCP APIs, Velero backup SA (`gcp_backups.tf`), OpenClaw calendar SA (`gcp_calendar.tf`), and Google Workspace MX/SPF/DKIM (`google_workspace.tf`). + * **Usage**: `cd terraform && terraform apply` +* **Read**: [terraform/AGENTS.md](./terraform/AGENTS.md) ### 4. Monitoring (`monitoring/`) * **Purpose**: Physical ambient BLE sensor fleet monitoring across living areas. @@ -112,12 +108,18 @@ This repository is divided into distinct domains, each with its own `AGENTS.md` * **Key Rules**: Vue 3, Vite, TypeScript, and Tailwind CSS; net calorie balance hero, Garmin health breakdown, and quick meal logger. * **Read**: [projects/moritz/AGENTS.md](./projects/moritz/AGENTS.md) -### 15. Utility Scripts (`scripts/`) +### 15. [Shelly Taupunktlüfter](./projects/shelly_taupunktluefter/AGENTS.md) (`projects/shelly_taupunktluefter/`) +* **Purpose**: Automated cellar ventilation controller ("Taupi") on Shelly Plug S Gen 3 to prevent mold growth using psychrometric calculations and BTHome BLE sensors. +* **Usage**: `cd projects/shelly_taupunktluefter && terraform apply` +* **Key Rules**: Sedlbauer LIM I decoupled mold danger evaluation, summer overheating and winter cold guards, optimal night drying window (03:00–07:00), and Prometheus metrics export. +* **Read**: [projects/shelly_taupunktluefter/AGENTS.md](./projects/shelly_taupunktluefter/AGENTS.md) + +### 16. Utility Scripts (`scripts/`) * **Purpose**: Cross-cutting operational and administration CLI scripts that do not belong inside Kubernetes namespace directories. * **Key Tools**: * `scripts/htpasswd.py`: Generates bcrypt-hashed htpasswd credentials for ingress basic auth secrets. -### 16. Network & Router Integration (`fritzbox/`) +### 17. Network & Router Integration (`fritzbox/`) * **Purpose**: Site-to-Site WireGuard LAN coupling and DynDNS OVH synchronization for the home FritzBox router. * **Cluster Endpoint**: `k8s/wireguard/` (`vpn.haumdaucher.de`). * **Read**: [fritzbox/README.md](./fritzbox/README.md) diff --git a/README.md b/README.md index 1f7a2b6..1106e5d 100644 --- a/README.md +++ b/README.md @@ -6,15 +6,17 @@ Infrapuzzle is the monorepo for personal infrastructure, Kubernetes cluster oper - **[`bootstrap/`](bootstrap/)**: Provisioning the single-node Kubernetes cluster (`haumdaucher`) using Kubespray. - **[`k8s/`](k8s/)**: Kubernetes workloads. **Every subdirectory represents a Kubernetes namespace.** -- **[`terraform/`](terraform/)**: Declarative Infrastructure as Code: - - `terraform/infrastructure/`: Cloud infrastructure, OVH DNS zones, Authentik SSO, and Google Workspace. - - `terraform/shelly/`: Smart home Shelly Plug S ventilation controller ("Taupi") for cellar mold prevention. +- **[`terraform/`](terraform/)**: Declarative Infrastructure as Code for core cloud infrastructure (OVH DNS zones, Authentik SSO, Google Workspace, and GCP APIs). - **[`projects/`](projects/)**: Self-contained hosted applications and projects: + - `projects/shelly_taupunktluefter/`: Smart home Shelly Plug S ventilation controller ("Taupi") for cellar mold prevention. - `projects/sasch40/`: Retro birthday adventure game (`sasch40.haumdaucher.de`). - `projects/moritzgrafde/`: Personal homepage and executive portfolio (`moritzgraf.de`). - `projects/haumdaucherde/`: Official community website & portal (`haumdaucher.de`). - `projects/grabengasse/`: Climate & weather dashboard (`grabengasse7.de`). - `projects/esphome_display_kitchen/`: ESP32 e-Paper kitchen status display & flashing wizard. + - `projects/duckdb-backend/`: In-memory analytics and tracking query API. + - `projects/mila/`: Baby tracking PWA (`family.haumdaucher.de/tracking/mila`). + - `projects/moritz/`: Health and nutrition dashboard (`family.haumdaucher.de/tracking/moritz`). - **[`monitoring/`](monitoring/)**: ESPHome fleet for BLE ambient room temperature & humidity sensors. - **[`fritzbox/`](fritzbox/)**: Home router Site-to-Site WireGuard VPN coupling and DynDNS synchronization. - **[`scripts/`](scripts/)**: Operational utility scripts (e.g. `htpasswd.py`). diff --git a/docs/adr/0003-everything-as-code-and-reproducible-infrastructure.md b/docs/adr/0003-everything-as-code-and-reproducible-infrastructure.md index ce5c6c6..bc684c6 100644 --- a/docs/adr/0003-everything-as-code-and-reproducible-infrastructure.md +++ b/docs/adr/0003-everything-as-code-and-reproducible-infrastructure.md @@ -99,7 +99,7 @@ Chosen Option: **Option 3: Comprehensive Everything-as-Code with Pragmatic State - Cluster IP mapping to the bare-metal ingress endpoint. * **Execution**: Fully automated via `terraform plan` / `terraform apply` directly from version-controlled state. -#### Tier 4: Smart Home & IoT Edge Hardware (`terraform_shelly/`, `esphome/`, `monitoring/`) +#### Tier 4: Smart Home & IoT Edge Hardware (`projects/shelly_taupunktluefter/`, `esphome/`, `monitoring/`) * **Tooling**: ESPHome, Shelly Terraform Provider, YAML configs. * **Scope**: - Shelly relays and smart switches provisioned declaratively via Terraform. diff --git a/k8s/README.md b/k8s/README.md index 052c0c0..802091b 100644 --- a/k8s/README.md +++ b/k8s/README.md @@ -678,7 +678,7 @@ kubectl create ns migrate # backup on moritzgraf.de ssh moritzgraf.de "sudo su - docker -c 'cd /home/docker/mailu && docker-compose stop' && sudo su - root -c 'cd /home/docker && tar czvf mailu.tar.gz ./mailu && mv mailu.tar.gz /home/moritz/ && chown moritz. /home/moritz/mailu.tar.gz' && scp mailu.tar.gz haumdaucher.de:/home/moritz/" # terraform change -cd ../terraform/infrastructure && terraform apply +cd ../terraform && terraform apply # helm apply cd ../k8s helm upgrade --create-namespace --install mailu mailu/mailu -n mailu -f mailu/mailu.secret.yml diff --git a/k8s/auth/README.md b/k8s/auth/README.md index cfac163..fc9526a 100644 --- a/k8s/auth/README.md +++ b/k8s/auth/README.md @@ -170,10 +170,10 @@ The Authentik login screen is customized with a **Haumdaucher** glassmorphism th * **Branded Footer**: "HAUMDAUCHER Wurst und Spezialitäten n.e.V." subtle watermark. ### Managing Theme via Terraform -Branding is provisioned via the `authentik_brand` resource in `terraform/infrastructure/authentik.tf` using the stylesheet `terraform/infrastructure/haumdaucher-theme.css`: +Branding is provisioned via the `authentik_brand` resource in `terraform/authentik.tf` using the stylesheet `terraform/haumdaucher-theme.css`: ```bash -cd terraform/infrastructure +cd terraform terraform apply -target=authentik_brand.haumdaucher ``` diff --git a/k8s/auth/USER_MANAGEMENT.md b/k8s/auth/USER_MANAGEMENT.md index 596936d..4576fca 100644 --- a/k8s/auth/USER_MANAGEMENT.md +++ b/k8s/auth/USER_MANAGEMENT.md @@ -22,7 +22,7 @@ This guide covers everything you need to know about managing users in Authentik | Question | Answer & Key Mechanism | | :--- | :--- | | **How to add new users?** | **4 Ways**: (1) Admin Web UI (`Directory > Users`), (2) **Invitations flow** (`Directory > Invitations` - recommended for self-service), (3) **Terraform** (`authentik_user` resource), or (4) **REST API / Python script** for bulk imports. | -| **Can this be done in Terraform?** | **Yes.** Use `resource "authentik_user"` in `terraform/infrastructure/authentik.tf`. Supports custom attributes via `jsonencode()`, group assignments, and active status. | +| **Can this be done in Terraform?** | **Yes.** Use `resource "authentik_user"` in `terraform/authentik.tf`. Supports custom attributes via `jsonencode()`, group assignments, and active status. | | **Can I change the email sent to the user?** | **Yes.** Configured in **Flows & Stages > Stages > Email Stage**. You can customize the subject line, token expiration, and HTML template (written in Django template syntax with access to user fields and custom attributes). | | **Can I limit what a user has access to?** | **Yes.** Through **Policy Bindings** attached to Applications: Group Membership Policies (e.g., `infra-admins` vs `users`), IP/Geo Policies, or Python Expression Policies checking custom attributes (e.g., only active club members). | | **How to handle Excel tables with custom attributes?** | Authentik stores arbitrary key-value pairs in `user.attributes` (JSON). You can import an Excel/CSV file with a Python script or Terraform `csvdecode()`, map fields like `haumdaucher_mitgliedsnummer` or `second_email`, and expose them to downstream apps (Nextcloud, Grafana, Gitea) via OIDC Scope Mappings. | @@ -75,7 +75,7 @@ If you encounter this screen when opening an invite link: ### Solution: The Haumdaucher Custom Invitation Flow (`haumdaucher-invitation-flow`) -We provision a dedicated, streamlined flow in `terraform/infrastructure/authentik.tf`: +We provision a dedicated, streamlined flow in `terraform/authentik.tf`: ```mermaid graph LR @@ -122,7 +122,7 @@ graph LR ## 🏗️ Method 2: User Provisioning via Terraform -You can manage users, groups, and permissions directly in `terraform/infrastructure/authentik.tf`. +You can manage users, groups, and permissions directly in `terraform/authentik.tf`. ### 1. Single User Definition ```hcl @@ -161,7 +161,7 @@ max.mustermann,Max Mustermann,max@example.com,max.privat@gmail.com,HM-2024-042,f anna.schmidt,Anna Schmidt,anna@example.com,anna.work@company.de,HM-2024-043,true ``` -In `terraform/infrastructure/authentik.tf`: +In `terraform/authentik.tf`: ```hcl locals { csv_users = csvdecode(file("${path.module}/users.csv")) @@ -479,7 +479,7 @@ graph TD | **haumdaucher.de** | `haumdaucher.de` | ForwardAuth / OIDC | **`Admin`** ✅ | **`Member Access`** ✅ | ❌ *Denied* | ### Policy Bindings in Terraform -All policy bindings are enforced directly in `terraform/infrastructure/authentik.tf`: +All policy bindings are enforced directly in `terraform/authentik.tf`: ```hcl # 1. Admin-Only Tools (Restricted strictly to infra-admins) diff --git a/terraform/shelly/.gitignore b/projects/shelly_taupunktluefter/.gitignore similarity index 100% rename from terraform/shelly/.gitignore rename to projects/shelly_taupunktluefter/.gitignore diff --git a/terraform/shelly/.terraform.lock.hcl b/projects/shelly_taupunktluefter/.terraform.lock.hcl similarity index 100% rename from terraform/shelly/.terraform.lock.hcl rename to projects/shelly_taupunktluefter/.terraform.lock.hcl diff --git a/terraform/shelly/AGENTS.md b/projects/shelly_taupunktluefter/AGENTS.md similarity index 79% rename from terraform/shelly/AGENTS.md rename to projects/shelly_taupunktluefter/AGENTS.md index 2e56d66..c5ce3e9 100644 --- a/terraform/shelly/AGENTS.md +++ b/projects/shelly_taupunktluefter/AGENTS.md @@ -4,11 +4,11 @@ This directory manages the configuration, code templating, and deployment for th ## Domain Structure & Key Files -* **[main.tf](file:///Users/moritz/src/infrapuzzle/terraform/shelly/main.tf)**: Coordinates rendering the JavaScript template and executing the Python upload script. -* **[variables.tf](file:///Users/moritz/src/infrapuzzle/terraform/shelly/variables.tf)**: Defines MAC addresses for the Bluetooth sensors, safety parameters, and the mold calculation coefficients. -* **[scripts/Taupi-4.0.js](file:///Users/moritz/src/infrapuzzle/terraform/shelly/scripts/Taupi-4.0.js)**: The source Shelly control script containing the logic for parsing Bluetooth BTHome events, calculating dew points, evaluating mold danger, and switching the relay. -* **[scripts/Taupi-4.0.templated.js](file:///Users/moritz/src/infrapuzzle/terraform/shelly/scripts/Taupi-4.0.templated.js)**: The locally generated script rendering the variables passed from Terraform. Do not edit directly. -* **[scripts/upload.py](file:///Users/moritz/src/infrapuzzle/terraform/shelly/scripts/upload.py)**: Helper script executing during `terraform apply` to upload the templated script to the Shelly device over local HTTP RPC commands. +* **[main.tf](file:///Users/moritz/src/infrapuzzle/projects/shelly_taupunktluefter/main.tf)**: Coordinates rendering the JavaScript template and executing the Python upload script. +* **[variables.tf](file:///Users/moritz/src/infrapuzzle/projects/shelly_taupunktluefter/variables.tf)**: Defines MAC addresses for the Bluetooth sensors, safety parameters, and the mold calculation coefficients. +* **[scripts/Taupi-4.0.js](file:///Users/moritz/src/infrapuzzle/projects/shelly_taupunktluefter/scripts/Taupi-4.0.js)**: The source Shelly control script containing the logic for parsing Bluetooth BTHome events, calculating dew points, evaluating mold danger, and switching the relay. +* **[scripts/Taupi-4.0.templated.js](file:///Users/moritz/src/infrapuzzle/projects/shelly_taupunktluefter/scripts/Taupi-4.0.templated.js)**: The locally generated script rendering the variables passed from Terraform. Do not edit directly. +* **[scripts/upload.py](file:///Users/moritz/src/infrapuzzle/projects/shelly_taupunktluefter/scripts/upload.py)**: Helper script executing during `terraform apply` to upload the templated script to the Shelly device over local HTTP RPC commands. ## Architecture Decisions & Logic Gates diff --git a/projects/shelly_taupunktluefter/README.md b/projects/shelly_taupunktluefter/README.md new file mode 100644 index 0000000..7505a06 --- /dev/null +++ b/projects/shelly_taupunktluefter/README.md @@ -0,0 +1,26 @@ +# Shelly Taupunktlüfter ("Taupi") 💨 + +Automated psychrometric cellar ventilation controller for mold prevention, running on a Shelly Plug S (Gen 3) paired with outdoor and indoor Shelly BLU H&T Bluetooth low-energy sensors. + +## Features + +- **Dew Point Ventilation**: Dynamically switches the ventilation fan based on indoor and outdoor psychrometric dew point calculations. +- **Sedlbauer LIM I Mold Alert**: Decoupled mold danger warning curve evaluated against Fraunhofer IBP Lowest Isopleth for Mould specifications. +- **Thermal Governors**: Summer cellar overheating protection (blocks warm moist air ingestion) and winter frost/overcooling protection. +- **Prometheus Metrics Pipeline**: Generates standard Prometheus exposition text scraped by cluster monitoring. +- **Automated Deployment**: Templated JavaScript upload via local Shelly RPC API orchestrated by Terraform. + +## Usage + +```bash +# Initialize Terraform providers +terraform init + +# Plan and preview changes +terraform plan + +# Deploy templated Taupi script to the Shelly device +terraform apply +``` + +For in-depth architectural decisions, state-machine logic gates, and sensor parameters, see [AGENTS.md](AGENTS.md). diff --git a/terraform/shelly/main.tf b/projects/shelly_taupunktluefter/main.tf similarity index 100% rename from terraform/shelly/main.tf rename to projects/shelly_taupunktluefter/main.tf diff --git a/terraform/shelly/providers.tf b/projects/shelly_taupunktluefter/providers.tf similarity index 100% rename from terraform/shelly/providers.tf rename to projects/shelly_taupunktluefter/providers.tf diff --git a/terraform/shelly/scripts/Taupi-4.0.js b/projects/shelly_taupunktluefter/scripts/Taupi-4.0.js similarity index 100% rename from terraform/shelly/scripts/Taupi-4.0.js rename to projects/shelly_taupunktluefter/scripts/Taupi-4.0.js diff --git a/terraform/shelly/scripts/get_status.py b/projects/shelly_taupunktluefter/scripts/get_status.py similarity index 100% rename from terraform/shelly/scripts/get_status.py rename to projects/shelly_taupunktluefter/scripts/get_status.py diff --git a/terraform/shelly/scripts/upload.py b/projects/shelly_taupunktluefter/scripts/upload.py similarity index 100% rename from terraform/shelly/scripts/upload.py rename to projects/shelly_taupunktluefter/scripts/upload.py diff --git a/terraform/shelly/terraform.tfvars b/projects/shelly_taupunktluefter/terraform.tfvars similarity index 100% rename from terraform/shelly/terraform.tfvars rename to projects/shelly_taupunktluefter/terraform.tfvars diff --git a/terraform/shelly/variables.tf b/projects/shelly_taupunktluefter/variables.tf similarity index 100% rename from terraform/shelly/variables.tf rename to projects/shelly_taupunktluefter/variables.tf diff --git a/terraform/.gitignore b/terraform/.gitignore index 22128ee..984d595 100644 --- a/terraform/.gitignore +++ b/terraform/.gitignore @@ -1,2 +1,3 @@ -.terraform - +.terraform/ +crash.log +crash.*.log diff --git a/terraform/infrastructure/.terraform.lock.hcl b/terraform/.terraform.lock.hcl similarity index 100% rename from terraform/infrastructure/.terraform.lock.hcl rename to terraform/.terraform.lock.hcl diff --git a/terraform/AGENTS.md b/terraform/AGENTS.md new file mode 100644 index 0000000..88913e9 --- /dev/null +++ b/terraform/AGENTS.md @@ -0,0 +1,31 @@ +# Core Terraform Infrastructure Agent Documentation + +This directory manages the core external cloud infrastructure, DNS zones, Authentik SSO, Google Cloud platform integrations, and Google Workspace configurations for Infrapuzzle. + +## Key Files & Resources + +* **[authentik.tf](file:///Users/moritz/src/infrapuzzle/terraform/authentik.tf)**: Provisions Authentik SSO flows, applications, groups, proxy outposts, OIDC providers, and custom styling with `haumdaucher-theme.css`. +* **[authentik.secret.auto.tfvars](file:///Users/moritz/src/infrapuzzle/terraform/authentik.secret.auto.tfvars)**: Git-crypt encrypted token variables for authenticating with the cluster Authentik API. +* **[haumdaucher-theme.css](file:///Users/moritz/src/infrapuzzle/terraform/haumdaucher-theme.css)**: Custom branded stylesheet injected into Authentik login and flow pages. +* **[ovh.tf](file:///Users/moritz/src/infrapuzzle/terraform/ovh.tf)**: DNS zone and record definitions for `haumdaucher.de`, `moritzgraf.de`, and other domains. +* **[gcp_apis.tf](file:///Users/moritz/src/infrapuzzle/terraform/gcp_apis.tf)**: Enables foundational Google Cloud APIs. +* **[gcp_backups.tf](file:///Users/moritz/src/infrapuzzle/terraform/gcp_backups.tf)**: Provisions GCP service account and credentials for Velero Google Drive cluster backups (`k8s/velero/gdrive_sa.json.secret`). +* **[gcp_calendar.tf](file:///Users/moritz/src/infrapuzzle/terraform/gcp_calendar.tf)**: Provisions GCP service account and credentials for OpenClaw Google Calendar integration (`k8s/openclaw/calendar_sa.json.secret`). +* **[google_workspace.tf](file:///Users/moritz/src/infrapuzzle/terraform/google_workspace.tf)**: DNS records for Google Workspace (MX, SPF, DKIM, TXT verification). +* **[versions.tf](file:///Users/moritz/src/infrapuzzle/terraform/versions.tf)**: Terraform provider versions and requirements. + +## Usage & Execution + +```bash +# Initialize providers (OVH, Authentik, Google, Local, Random) +terraform init + +# Review execution plan +terraform plan + +# Apply infrastructure changes +terraform apply +``` + +> [!IMPORTANT] +> Secrets in this directory (such as `authentik.secret.auto.tfvars`) and generated service account keys are encrypted using `git-crypt`. Ensure the repository is unlocked before planning or applying. diff --git a/terraform/README.md b/terraform/README.md new file mode 100644 index 0000000..30e3a68 --- /dev/null +++ b/terraform/README.md @@ -0,0 +1,25 @@ +# Core Infrastructure (Terraform) ☁️ + +Declarative Infrastructure as Code managing external cloud services, DNS zones, and cluster identity. + +## Managed Resources + +- **OVH DNS**: Authoritative DNS zones and records (`haumdaucher.de`, `moritzgraf.de`, etc.). +- **Authentik SSO**: Central IdP configuration, applications, proxy outposts, OIDC clients, and custom theme CSS. +- **Google Cloud Platform**: Service accounts for Velero backups and OpenClaw calendar integration. +- **Google Workspace**: Domain verification, MX, SPF, and DKIM DNS records. + +## Usage + +```bash +# Initialize Terraform +terraform init + +# Plan changes +terraform plan + +# Apply changes +terraform apply +``` + +For agent documentation and architecture guidelines, see [AGENTS.md](AGENTS.md). diff --git a/terraform/infrastructure/authentik.secret.auto.tfvars b/terraform/authentik.secret.auto.tfvars similarity index 100% rename from terraform/infrastructure/authentik.secret.auto.tfvars rename to terraform/authentik.secret.auto.tfvars diff --git a/terraform/infrastructure/authentik.tf b/terraform/authentik.tf similarity index 100% rename from terraform/infrastructure/authentik.tf rename to terraform/authentik.tf diff --git a/terraform/infrastructure/gcp_apis.tf b/terraform/gcp_apis.tf similarity index 100% rename from terraform/infrastructure/gcp_apis.tf rename to terraform/gcp_apis.tf diff --git a/terraform/infrastructure/gcp_backups.tf b/terraform/gcp_backups.tf similarity index 100% rename from terraform/infrastructure/gcp_backups.tf rename to terraform/gcp_backups.tf diff --git a/terraform/infrastructure/gcp_calendar.tf b/terraform/gcp_calendar.tf similarity index 100% rename from terraform/infrastructure/gcp_calendar.tf rename to terraform/gcp_calendar.tf diff --git a/terraform/infrastructure/google_workspace.tf b/terraform/google_workspace.tf similarity index 100% rename from terraform/infrastructure/google_workspace.tf rename to terraform/google_workspace.tf diff --git a/terraform/infrastructure/haumdaucher-theme.css b/terraform/haumdaucher-theme.css similarity index 100% rename from terraform/infrastructure/haumdaucher-theme.css rename to terraform/haumdaucher-theme.css diff --git a/terraform/infrastructure/.gitignore b/terraform/infrastructure/.gitignore deleted file mode 100644 index 22128ee..0000000 --- a/terraform/infrastructure/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -.terraform - diff --git a/terraform/infrastructure/misc/get_consumer_key.py b/terraform/misc/get_consumer_key.py similarity index 100% rename from terraform/infrastructure/misc/get_consumer_key.py rename to terraform/misc/get_consumer_key.py diff --git a/terraform/infrastructure/misc/get_domain.py b/terraform/misc/get_domain.py similarity index 100% rename from terraform/infrastructure/misc/get_domain.py rename to terraform/misc/get_domain.py diff --git a/terraform/infrastructure/misc/ovh.conf b/terraform/misc/ovh.conf similarity index 100% rename from terraform/infrastructure/misc/ovh.conf rename to terraform/misc/ovh.conf diff --git a/terraform/infrastructure/ovh.tf b/terraform/ovh.tf similarity index 100% rename from terraform/infrastructure/ovh.tf rename to terraform/ovh.tf diff --git a/terraform/infrastructure/terraform.tfstate b/terraform/terraform.tfstate similarity index 100% rename from terraform/infrastructure/terraform.tfstate rename to terraform/terraform.tfstate diff --git a/terraform/infrastructure/terraform.tfstate.1748511344.backup b/terraform/terraform.tfstate.1748511344.backup similarity index 100% rename from terraform/infrastructure/terraform.tfstate.1748511344.backup rename to terraform/terraform.tfstate.1748511344.backup diff --git a/terraform/infrastructure/terraform.tfstate.1748511364.backup b/terraform/terraform.tfstate.1748511364.backup similarity index 100% rename from terraform/infrastructure/terraform.tfstate.1748511364.backup rename to terraform/terraform.tfstate.1748511364.backup diff --git a/terraform/infrastructure/terraform.tfstate.backup b/terraform/terraform.tfstate.backup similarity index 100% rename from terraform/infrastructure/terraform.tfstate.backup rename to terraform/terraform.tfstate.backup diff --git a/terraform/infrastructure/versions.tf b/terraform/versions.tf similarity index 100% rename from terraform/infrastructure/versions.tf rename to terraform/versions.tf