This repository contains configurations for managing various services and infrastructure components within my home network.
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.
Comprehensive documentation can be found in docs/infra
- 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.
- Post-Provisioning Configuration: Ansible is used for configuration management tasks on running services after they have been provisioned by Terraform.
The workflow is designed around a GitOps model, where git
is the single source of truth.
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));
Before running this configuration, the following components must be in place.
- 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
).
- 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.
- Technitium: An instance of Technitium must be running and configured.
- 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 repository follows a strict Pull Request-based workflow to ensure changes are reviewed and validated before being applied.
- Make Changes: Create a new branch and make your desired infrastructure changes.
- Open a Pull Request: Push your branch to GitHub and open a Pull Request against the
main
branch. - Automated Plan: The
run-plan.yml
GitHub Actions workflow automatically triggers. It uploads your configuration to HCP Terraform and runs aterraform plan
. - 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.
- Merge: Once the plan is approved, merge the Pull Request into
main
. - 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.
This project is configured primarily through YAML files located in the config/
directory. For detailed instructions on how to structure these files, please refer to the documentation in the docs/
directory:
- Stack Configuration Guide: stack-config.md
- Service Configuration Guide: service-config.md
Secrets are managed securely without ever being committed to the repository.
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 |
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.
For services deployed by the proxy_service_stack
module, credentials are not stored statically. Instead:
- Infisical Integration: For services requiring arbitrary secrets (like API keys or JWT signing keys), you can define a list of secret names in the stack's YAML file under
generated_secrets
. Terraform will fetch these secrets from Infisical Cloud and inject them into the container's environment variables. - OAuth Credentials: For services using OAuth, the
docker-stack
module automatically creates an OAuth2 provider in Authentik. The resultingclient_id
andclient_secret
are then injected as environment variables into the container.
This ensures that secrets are managed dynamically and securely, with minimal manual intervention.'''
This project uses Ansible to perform configuration tasks after Terraform has provisioned the infrastructure. It uses a static inventory file located at ansible/inventory/inventory.yml
to connect to the Unraid server.
To run a playbook, first set the required environment variable for the password, then execute the playbook:
export ANSIBLE_SSH_PASS="your_unraid_password"
cd ansible/
ansible-playbook playbooks/your_playbook.yml
Due to an issue with the Authentik Terraform provider (#12), a manual step is required after deploying a new service that uses proxy authentication.
- After a successful
terraform apply
, navigate to your Authentik instance. - Go to Applications -> Providers.
- Find the provider for your service (e.g.,
prowlarr
). - Edit the provider and assign it to the correct Proxy Outpost.
The credentials for the service can be found by navigating to the corresponding group in Authentik (e.g., tf_prowlarr
) and viewing its attributes.
The following are good sources for icons: