diff --git a/ReadMe.md b/ReadMe.md index b3daa81..4a92019 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -1,54 +1,89 @@ -# Home-Net +
+

Home-Net

+

Home Lab IaC

+
This repository contains configurations for managing various services and infrastructure components within my home network. -## Purpose +## 🎯 Purpose -I want an easy way to automate and keep track of my local home lab. It would be nice to also have a way to easily and quickly recreate it in case of a catastrophic failure (flood, house fire, etc etc) +This repository automates the deployment and configuration of my home lab. The primary goal is to maintain a completely reproducible environment using IaC. This ensures that the entire lab can be quickly and reliably rebuilt from scratch in the event of a catastrophic failure. -## Modules +## ✨ Key Features -Reusable Terraform modules are located in the `modules/` directory. These modules are designed to be configurable and handle specific types of deployments. +* **Infrastructure as Code**: The entire infrastructure is defined using Terraform. +* **GitOps Workflow**: Changes are managed through Pull Requests, with automated plans generated by GitHub Actions and HCP Terraform. +* **Automated Deployments**: Services are deployed as Docker containers on an Unraid server via a self-hosted Terraform agent. +* **Dynamic Configuration**: Service definitions are externalized to YAML files (`stacks.yaml`, `services.yaml`), allowing for easy modification. +* **Automated Proxy & DNS**: Nginx Proxy Manager is used to automatically create proxy hosts and manage SSL certificates for services. +* **Centralized Authentication**: Services are integrated with Authentik for single sign-on (SSO) and access control. -## Services -The `services/` directory contains specific Terraform configurations that deploy various applications and services within the home network. These configurations make use of the reusable modules defined in the `modules/` directory. Each subdirectory within `services/` typically represents a distinct service or a group of related services. +## 🏗️ Architecture Overview -## Prerequisites +The workflow is designed around a GitOps model, where `git` is the single source of truth. -* **Target Environment:** This setup is primarily designed to run on an **Unraid server**. -* **Terraform Agent:** A Terraform agent [must be running on the Unraid server](https://developer.hashicorp.com/terraform/cloud-docs/agents/agents#run-an-agent-with-docker). - * This agent requires **direct access to the Docker socket** (typically `/var/run/docker.sock`) to manage Docker resources. Ensure the user running the agent has the necessary permissions. -* **Terraform CLI:** Terraform (version compatible with the configurations, e.g., v1.12.2 or later) installed. -* **Docker:** Docker must be configured and running on the Unraid server. +```mermaid +graph TD + A[Developer] -- Push to PR --> B(GitHub); + B -- Trigger Workflow --> C{GitHub Actions}; + C -- Upload Config --> D[HCP Terraform]; + D -- Create Plan --> D; + C -- Post Plan to PR --> B; + A -- Merge PR & Manually Trigger Apply --> C; + C -- Trigger Apply Run --> D; + D -- Send Job to Agent --> E(TFC Agent on Unraid); + E -- Manage Resources --> F((Docker)); + E -- Manage Resources --> G((Nginx Proxy Manager)); + E -- Manage Resources --> H((Authentik)); +``` -## Usage +## ✅ Prerequisites +Before running this configuration, the following components must be in place. -1. **Clone the repository:** - ```bash - git clone - cd home-net - ``` -2. **Configure Backend:** - Ensure your Terraform backend (e.g., HCP Terraform, S3) is configured in your root `main.tf` file. -3. **Initialize Terraform:** - ```bash - terraform init - ``` -4. **Review:** - ```bash - terraform plan - ``` +### Host Environment +- **Server**: An **Unraid server** is the primary target environment. +- **Docker**: Docker must be installed and running. +- **Network Interfaces**: The Unraid server must have two bridged network interfaces configured: + - `br0`: For the primary LAN (e.g., `192.168.1.0/24`). + - `br1`: For the container-specific network (e.g., `192.168.4.0/23`). -Any applies should be done using the [run-apply](./.github/workflows/run-apply.yml) action. +### Core Services +- **Terraform Agent**: A HCP Terraform Agent must be running on the Unraid server with access to the Docker socket (`/var/run/docker.sock`). +- **Nginx Proxy Manager**: An instance of Nginx Proxy Manager must be running and accessible to the Terraform agent. +- **Authentik**: An instance of Authentik must be running and configured. -## How is this run? +### Cloud & API Access +- **HCP Terraform**: A workspace must be created and configured. +- **Cloudflare**: An API token is required with the following permissions: + - `Zone:Read` + - `DNS:Edit` + - The token must have access to all zones being managed. -This is run on a self-hosted agent on the Unraid Server. This is invoked using HCP Terraform, the state is managed by HCP Terraform and I have the following variables set: +## 🚀 Workflow + + +This repository follows a strict Pull Request-based workflow to ensure changes are reviewed and validated before being applied. + +1. **Make Changes**: Create a new branch and make your desired infrastructure changes. +2. **Open a Pull Request**: Push your branch to GitHub and open a Pull Request against the `main` branch. +3. **Automated Plan**: The `run-plan.yml` GitHub Actions workflow automatically triggers. It uploads your configuration to HCP Terraform and runs a `terraform plan`. +4. **Review Plan**: The output of the plan is posted as a comment on your Pull Request for review. You can also view the full plan in the HCP Terraform UI. +5. **Merge**: Once the plan is approved, merge the Pull Request into `main`. +6. **Apply Changes**: The `run-apply.yml` action must be triggered manually from the GitHub Actions UI to apply the changes to production. This is a deliberate safety measure. + +## 🔐 Secrets Management + +Secrets are managed securely without ever being committed to the repository. + +### Static Secrets +Static secrets, such as API tokens and passwords, are stored as **sensitive variables** directly in the HCP Terraform workspace. The agent automatically and securely injects these at runtime. |Variable Name|Type|Sensitive?| |---|---|---| |cloudflare_api_token|terraform|Y| +|vpn_user|terraform|Y| +|vpn_pass|terraform|Y| |network_admin_email|terraform|Y| |nginx_proxy_address|terraform|N| |nginx_proxy_pass|terraform|Y| @@ -56,20 +91,32 @@ This is run on a self-hosted agent on the Unraid Server. This is invoked using |public_facing_ip|terraform|Y| |technitium_api_token|terraform|Y| |technitium_host|terraform|N| +|AUTHENTIK_URL|env|N| +|AUTHENTIK_TOKEN|env|Y| |AUTHENTIK_INSECURE|env|N| |AUTHENTIK_TOKEN|env|Y| |AUTHENTIK_URL|env|N| |vpn_pass|terraform|Y| |vpn_user|terraform|Y| +> **Note**: Some non-secret values (like `public_facing_ip`) are marked as sensitive to prevent them from being exposed in public logs or plan outputs. + +### Dynamic Secrets +For services deployed by the `proxy_service_stack` module, credentials are not stored statically. Instead: +1. A strong, random password is generated for each service during the `terraform apply` process using the `random` provider. +2. These generated credentials (`username: admin`, `password: `) are stored as attributes on the service-specific group created within Authentik. + +This ensures that each service has a unique, high-entropy password that is managed entirely by Terraform. -You may be wondering why some things such as "public facing API" and "network admin email" are set to sensitive. Well, I honestly I don't want the world knowing those details. Aside from that, there's no reason for them to be marked sensitive. +## ⚠️ Operational Notes +### Manual Step for Authentik Proxy Providers -### Cloudflare +Due to an issue with the Authentik Terraform provider (#12), a manual step is required after deploying a new service that uses proxy authentication. -The Cloudflare API token must have these permissions: -- Zone:Read -- DNS:Edit +1. After a successful `terraform apply`, navigate to your Authentik instance. +2. Go to **Applications** -> **Providers**. +3. Find the provider for your service (e.g., `prowlarr`). +4. Edit the provider and assign it to the correct **Proxy Outpost**. -In addition it must also be able to access any zones that are wished to be used. \ No newline at end of file +The credentials for the service can be found by navigating to the corresponding group in Authentik (e.g., `tf_prowlarr`) and viewing its attributes. \ No newline at end of file