Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 85 additions & 38 deletions ReadMe.md
Original file line number Diff line number Diff line change
@@ -1,75 +1,122 @@
# Home-Net
<div align="center">
<h1>Home-Net</h1>
<p><strong>Home Lab IaC</strong></p>
</div>

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 <repository-url>
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|
|nginx_proxy_user|terraform|Y|
|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: <random>`) 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.
The credentials for the service can be found by navigating to the corresponding group in Authentik (e.g., `tf_prowlarr`) and viewing its attributes.