Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
11c1e04
Update arr services
DCCoder90 Jun 18, 2025
2d1f488
Update arr services
DCCoder90 Jun 18, 2025
7cbea39
Services setup, still need bindmount volumes
DCCoder90 Jun 18, 2025
6c653cd
Added github workflows
DCCoder90 Jun 18, 2025
5b2b732
Update workflows
DCCoder90 Jun 18, 2025
2bdd241
Removed comment from arrr services
DCCoder90 Jun 18, 2025
d41a5ab
Update plan
DCCoder90 Jun 18, 2025
6f23186
Update plan
DCCoder90 Jun 18, 2025
219ff40
Updated ReadMe.md
DCCoder90 Jun 18, 2025
1150abf
Ignore non-tf paths
DCCoder90 Jun 18, 2025
b278c5d
Update to use config.yaml
DCCoder90 Jun 18, 2025
4b5c621
Update TF config
DCCoder90 Jun 18, 2025
799be8c
Update TF config
DCCoder90 Jun 18, 2025
7246793
Update configuration for apply
DCCoder90 Jun 18, 2025
f7618b5
Removed service_config.tf and added service level ReadMe.md
DCCoder90 Jun 18, 2025
f2a67a9
Move service to reusable module
DCCoder90 Jun 20, 2025
c96f095
Update config and converted arrrs to proxy service stack
DCCoder90 Jun 20, 2025
4329b32
Moved all TF into terraform directory
DCCoder90 Jun 20, 2025
e23d038
Add TF version file for use with tfenv
DCCoder90 Jun 20, 2025
5f36732
Update stacks and fix issues
DCCoder90 Jun 21, 2025
5543237
Huge update to stack module and docker module, includes icons for unraid
DCCoder90 Jun 21, 2025
8cfa5de
Add capabilities to deluge vpn service
DCCoder90 Jun 21, 2025
e52af8a
Update and correct deluge config
DCCoder90 Jun 21, 2025
a8340b8
Update icons for some services in arr stack
DCCoder90 Jun 21, 2025
aa54977
Added VPN creds to readme
DCCoder90 Jun 21, 2025
4dc4f0e
Updated proxy stack to accept internal
DCCoder90 Jun 21, 2025
f074345
Oops, forgot to add it here
DCCoder90 Jun 21, 2025
51a7306
Update plan workflow
DCCoder90 Jun 21, 2025
85ac0d2
Update plan workflow
DCCoder90 Jun 21, 2025
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
73 changes: 73 additions & 0 deletions .github/workflows/run-apply.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
name: Terraform Apply

on:
push:
branches:
- main
paths-ignore:
- .github/workflows/run-apply.yml
- .github/workflows/run-plan.yml
- ReadMe.md
- .gitignore
workflow_dispatch: #
inputs:
tfc_run_id:
description: 'Optional: Terraform Cloud Run ID to apply. If left empty, a new run will be created.'
required: false
type: string

jobs:
terraform_apply:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
env:
TF_WORKSPACE: ${{ secrets.TF_WORKSPACE }}
CONFIG_DIRECTORY: "./"

steps:
- name: Checkout Code
uses: actions/checkout@v4

- name: Upload Configuration
uses: hashicorp/tfc-workflows-github/actions/upload-configuration@v1.3.2
id: upload-configuration
with:
workspace: ${{ env.TF_WORKSPACE }}
directory: ${{ env.CONFIG_DIRECTORY }}
token: ${{ secrets.TF_API_TOKEN }}
organization: ${{ secrets.TF_ORGANIZATION }}

- name: Trigger Terraform Cloud Apply Plan
uses: hashicorp/tfc-workflows-github/actions/create-run@v1.3.2
id: create-run
if: ${{ github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && (github.event.inputs.tfc_run_id == '' || github.event.inputs.tfc_run_id == null)) }}
with:
token: ${{ secrets.TF_API_TOKEN }}
hostname: app.terraform.io
organization: ${{ secrets.TF_ORGANIZATION }}
workspace: ${{ secrets.TF_WORKSPACE }}
message: "Triggered by push to main: ${{ github.sha }}"
is_destroy: false

- name: Check Terraform Cloud Run Status
if: ${{ github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && (github.event.inputs.tfc_run_id == '' || github.event.inputs.tfc_run_id == null)) }}
run: |
echo "Terraform Cloud Plan ID: ${{ steps.create-run.outputs.run_id }}"
echo "Terraform Cloud Plan URL: ${{ steps.create-run.outputs.run_url }}"

- name: Run Plan
uses: hashicorp/tfc-workflows-github/actions/apply-run@v1.3.2
id: apply
continue-on-error: true
with:
hostname: app.terraform.io
token: ${{ secrets.TF_API_TOKEN }}
run: ${{ github.event.inputs.tfc_run_id || steps.create-run.outputs.run_id }}
comment: "Confirmed from GitHub Actions CI"

- name: Check Terraform Cloud Run Status
run: |
echo "Terraform Cloud Apply ID: ${{ steps.apply.outputs.run_id }}"
echo "Terraform Cloud Apply URL: ${{ steps.apply.outputs.run_link }}"
96 changes: 96 additions & 0 deletions .github/workflows/run-plan.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
name: Terraform Plan

on:
pull_request:
branches:
- main
paths-ignore:
- .github/workflows/run-apply.yml
- .github/workflows/run-plan.yml
- ReadMe.md
- .gitignore
jobs:
terraform_plan:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
env:
TF_WORKSPACE: ${{ secrets.TF_WORKSPACE }}
CONFIG_DIRECTORY: "./"

steps:
- name: Checkout Code
uses: actions/checkout@v4

- name: Upload Configuration
uses: hashicorp/tfc-workflows-github/actions/upload-configuration@v1.3.2
id: upload-configuration
with:
workspace: ${{ env.TF_WORKSPACE }}
directory: ${{ env.CONFIG_DIRECTORY }}
token: ${{ secrets.TF_API_TOKEN }}
organization: ${{ secrets.TF_ORGANIZATION }}

- name: Trigger Terraform Cloud Plan
uses: hashicorp/tfc-workflows-github/actions/create-run@v1.3.2
id: create-run
with:
token: ${{ secrets.TF_API_TOKEN }}
hostname: app.terraform.io
organization: ${{ secrets.TF_ORGANIZATION }}
workspace: ${{ secrets.TF_WORKSPACE }}
message: "Triggered by PR push: ${{ github.event.pull_request.head.ref }}"
plan_only: true

- uses: hashicorp/tfc-workflows-github/actions/plan-output@v1.3.2
id: plan-output
with:
plan: ${{ steps.create-run.outputs.plan_id }}
token: ${{ secrets.TF_API_TOKEN }}
organization: ${{ secrets.TF_ORGANIZATION }}

- uses: actions/github-script@v6
if: github.event_name == 'pull_request'
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
// 1. Retrieve existing bot comments for the PR
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
})
const botComment = comments.find(comment => {
return comment.user.type === 'Bot' && comment.body.includes('HCP Terraform Plan Output')
})
const output = `#### HCP Terraform Plan Output
\`\`\`\n
Plan: ${{ steps.plan-output.outputs.add }} to add, ${{ steps.plan-output.outputs.change }} to change, ${{ steps.plan-output.outputs.destroy }} to destroy.
\`\`\`
[HCP Terraform Plan](${{ steps.create-run.outputs.run_link }})
`
// 3. If we have a comment, update it, otherwise create a new one
if (botComment) {
github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: output
})
} else {
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: output
})
}

- id: terraform-cloud-check-run-status
if: ${{ steps.create-run.outputs.run_status != 'planned_and_finished'}}
run: |
echo "HCP Terraform Run Failed or Requires Further Attention"
echo "Run Status: '${{ steps.create-run.outputs.run_status }}'"
echo "${{ steps.create-run.outputs.run_link }}"
exit 1
29 changes: 16 additions & 13 deletions ReadMe.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# Home-Net

This repository contains Terraform configurations for managing various services and infrastructure components within my home network.
This repository contains configurations for managing various services and infrastructure components within my home network.

Should I move this from Terraform to OpenTofu? Hmmm....
## 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)

## Modules

Expand All @@ -15,10 +17,10 @@ The `services/` directory contains specific Terraform configurations that deploy
## Prerequisites

* **Target Environment:** This setup is primarily designed to run on an **Unraid server**.
* **Terraform Agent:** A Terraform agent (e.g., HCP Terraform self-hosted agent, GitLab Runner, GitHub Actions self-hosted runner, etc.) must be running on the 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 on the machine where `terraform plan/apply` commands are initiated or on the agent itself.
* **Docker:** Docker must be installed and running on the Unraid server.
* **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.

## Usage

Expand All @@ -33,12 +35,12 @@ The `services/` directory contains specific Terraform configurations that deploy
```bash
terraform init
```
4. **Review and Apply:**
4. **Review:**
```bash
terraform plan
terraform apply
```

Any applies should be done using the [run-apply](./.github/workflows/run-apply.yml) action.

## How is this run?

Expand All @@ -57,16 +59,17 @@ This is run on a self-hosted agent on the Unraid Server. This is invoked using
|AUTHENTIK_INSECURE|env|N|
|AUTHENTIK_TOKEN|env|Y|
|AUTHENTIK_URL|env|N|
|vpn_pass|terraform|Y|
|vpn_user|terraform|Y|


You may be wondering why some things such as "public facing API" and "network admin email" are set to sensitive. Well, I want to update this soon to be invoked here by github actions, and honestly I don't want the world knowing those details. Aside from that, there's no reason for them to be marked sensitive.
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.


Quick note:
### Cloudflare

Cloudflare API token must have these permissions:
The Cloudflare API token must have these permissions:
- Zone:Read
- DNS:Edit

## 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)
In addition it must also be able to access any zones that are wished to be used.
4 changes: 0 additions & 4 deletions config.yaml

This file was deleted.

42 changes: 42 additions & 0 deletions config/services.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
authentik:
admin-user: ""
flaresolverr:
service_name: "flaresolverr"
ip_address: "192.168.5.27"
image_name: "flaresolverr/flaresolverr:v3.3.25"
env:
- "TZ=America/Chicago"
deluge-vpn:
icon: "https://vectorified.com/images/deluge-icon-3.jpg"
service_name: "deluge-vpn"
ip_address: "192.168.5.28"
image_name: "binhex/arch-delugevpn:2.2"
service_port: 8112
env:
- "TZ=America/Chicago"
- "ENABLE_SOCKS=no"
- "STRICT_PORT_FORWARD=yes"
- "DEBUG=false"
- "ENABLE_PRIVOXY=no"
- "PGID=100"
- "PUID=1000"
- "VPN_ENABLED=yes"
- "VPN_PROV=custom"
- "VPN_CLIENT=openvpn"
- "LAN_NETWORK=192.168.1.0/24"
capabilities:
add:
- "NET_ADMIN"
mounts:
- "/etc/localtime:/etc/localtime:ro"
- "/mnt/user/Arr/deluge-data:/config"
- "/mnt/user/Downloads:/data/downloads"
- "/mnt/user/appdata/binhex-delugevpn/openvpn:/config/openvpn"
requestrr:
service_name: "requestrr"
service_port: 4545
image_name: "linuxserver/requestrr:2.1.2"
ip_address: "192.168.5.27"
mounts:
- "/mnt/user/Arr/requestrr-data:/config"
- "/etc/localtime:/etc/localtime:ro"
68 changes: 68 additions & 0 deletions config/stacks.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
arr_services:
env:
- "PUID=1000"
- "PGID=100"
- "TZ=America/Chicago"
mounts:
- "/etc/localtime:/etc/localtime:ro"
- "/mnt/user/Media:/media"
- "/mnt/user/Downloads:/downloads"
services:
prowlarr:
internal: true
icon: "https://static-00.iconduck.com/assets.00/prowlarr-icon-512x512-v9ekdjxx.png"
service_name: "prowlarr"
service_port: 9696
image_name: "linuxserver/prowlarr:1.37.0"
username: "default_username"
password: "ProwlarrPassword1!"
domain_name: "prowlarr.dcapi.app"
ip_address: "192.168.5.22"
mounts:
- "/mnt/user/Arr/prowlarr-data:/config"
sonarr:
internal: true
icon: "https://static-00.iconduck.com/assets.00/sonarr-icon-1024x1024-wkay604k.png"
service_name: "sonarr"
service_port: 8989
image_name: "linuxserver/sonarr:4.0.14.2939-ls281"
username: "default_username"
password: "SonarrPassword1!"
domain_name: "sonarr.dcapi.app"
ip_address: "192.168.5.23"
mounts:
- "/mnt/user/Arr/sonarr-data:/config"
radarr:
internal: true
icon: "https://static-00.iconduck.com/assets.00/radarr-icon-462x512-bydv4e4f.png"
service_name: "radarr"
service_port: 7878
image_name: "linuxserver/radarr:5.26.2"
username: "default_username"
password: "RadarrPassword1!"
domain_name: "radarr.dcapi.app"
ip_address: "192.168.5.24"
mounts:
- "/mnt/user/Arr/radarr-data:/config"
lidarr:
internal: true
service_name: "lidarr"
service_port: 8686
image_name: "linuxserver/lidarr:1.0.2.1495-ls108"
username: "default_username"
password: "LidarrPassword1!"
domain_name: "lidarr.dcapi.app"
ip_address: "192.168.5.25"
mounts:
- "/mnt/user/Arr/lidarr-data:/config"
readarr:
internal: true
service_name: "readarr"
service_port: 8787
image_name: "linuxserver/readarr:1.0.2.1495-ls108"
username: "default_username"
password: "ReadarrPassword1!"
domain_name: "readarr.dcapi.app"
ip_address: "192.168.5.26"
mounts:
- "/mnt/user/Arr/readarr-data:/config"
7 changes: 7 additions & 0 deletions config/system.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
authentik:
ip_address: "192.168.4.55"
port: 9000
proxy_ip: "192.168.4.2"
zones:
dcapi: "dcapi.app"
mallett: "mallett.family"
22 changes: 0 additions & 22 deletions services.tf

This file was deleted.

Loading