Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
defcd6e
Added provider config and variable
DCCoder90 Jul 10, 2025
6c20698
Formatting
DCCoder90 Jul 10, 2025
ef9506b
Added host config and formatting
DCCoder90 Jul 10, 2025
eb4ef54
Added host to stack
DCCoder90 Jul 10, 2025
34b0b46
Added host to each service from the stack.
DCCoder90 Jul 10, 2025
1cd2cf9
Removed copy/paste error
DCCoder90 Jul 10, 2025
3b4d967
Update modules to use relative paths
DCCoder90 Jul 10, 2025
7ca79ac
Add workflow
DCCoder90 Jul 10, 2025
7c4e884
Added ignore directories
DCCoder90 Jul 10, 2025
e10b293
Forgot to tell it to actually ignore them...
DCCoder90 Jul 10, 2025
f9db425
Test
DCCoder90 Jul 10, 2025
a7dddfa
Test
DCCoder90 Jul 10, 2025
af27652
Test
DCCoder90 Jul 10, 2025
4aec8e4
Test
DCCoder90 Jul 10, 2025
1a3f772
Test
DCCoder90 Jul 10, 2025
8ee5165
Test
DCCoder90 Jul 10, 2025
f29da5f
Test
DCCoder90 Jul 10, 2025
be201a4
Test
DCCoder90 Jul 10, 2025
20c474f
Test
DCCoder90 Jul 10, 2025
16b81ad
Maybe AI can help?
DCCoder90 Jul 10, 2025
87102a7
AI was useless, just going to make it stupid simple....
DCCoder90 Jul 10, 2025
00342e3
oops
DCCoder90 Jul 10, 2025
9e4ef28
Update uri path in auth module
DCCoder90 Jul 14, 2025
cd5476b
Moved provider configuration out of modules. This will require calle…
DCCoder90 Jul 14, 2025
c35849f
Forgot to include host_connection in docker-stack module
DCCoder90 Jul 14, 2025
1063abf
Remove all provider configuration for docker provider from module.
DCCoder90 Jul 14, 2025
055753a
.
DCCoder90 Jul 14, 2025
ba85c7d
.
DCCoder90 Jul 14, 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
59 changes: 59 additions & 0 deletions .github/workflows/terraform-validate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: Terraform Module Validation

on:
push:
branches:
- main
pull_request:
branches:
- main
workflow_dispatch:

jobs:
validate_each_module:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
module_dir:
- "./authentik"
- "./dns"
- "./docker"
- "./docker-network"
- "./docker-service"
- "./docker-stack"
- "./nginx_config"
- "./oauth_auth"
- "./proxy_auth"

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

- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: "latest"

- name: Validate Module ${{ matrix.module_dir }}
shell: bash
run: |
module_dir="${{ matrix.module_dir }}"
echo "--- Validating module: $module_dir ---"

pushd "$module_dir" > /dev/null || { echo "Failed to change directory to $module_dir"; exit 1; }

echo "Running terraform init in $module_dir..."
if ! terraform init -backend=false -input=false -upgrade; then
echo "::error file=$module_dir::Terraform init failed for module: $module_dir"
exit 1
else
echo "Running terraform validate in $module_dir..."
if ! terraform validate; then
echo "::error file=$module_dir::Terraform validate failed for module: $module_dir"
exit 1
fi
fi

popd > /dev/null || { echo "Failed to return from directory"; exit 1; }
echo "Module $module_dir validated successfully!"
11 changes: 10 additions & 1 deletion ReadMe.md
Original file line number Diff line number Diff line change
@@ -1 +1,10 @@
Just working on breaking these modules out for now. Will update the documentation later.
Just working on breaking these modules out for now. Will update the documentation later.

Just a quick note. When using any of the following modules:

- docker
- docker-service
- docker-network
- docker-stack

The provider configuration has to be set by the caller. As outlined in the [legacy module documentation](https://developer.hashicorp.com/terraform/language/modules/develop/providers#legacy-shared-modules-with-provider-configurations)
10 changes: 5 additions & 5 deletions docker-service/auth.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module "proxy_authentication" {
source = "[email protected]:DCCoder90/home-tf-modules.git//proxy_auth?ref=1.0.0"
source = "../proxy_auth"

count = var.service.auth.enabled && var.service.auth.proxy.enabled ? 1 : 0

Expand All @@ -24,16 +24,16 @@ module "proxy_authentication" {
}

module "oauth_authentication" {
source = "[email protected]:DCCoder90/home-tf-modules.git//oauth_auth?ref=1.0.0"
source = "../oauth_auth"

count = var.service.auth.enabled && var.service.auth.oauth.enabled ? 1 : 0

group = var.service.auth.group
description = var.service.description
name = var.service.service_name
create_access_group = true
access_group_name = "tf_${var.service.service_name}"
user_to_add_to_access_group = var.system.network_admin_username
access_group_name = "tf_${var.service.service_name}"
user_to_add_to_access_group = var.system.network_admin_username
allowed_redirect_uris = concat(
[
{
Expand All @@ -43,7 +43,7 @@ module "oauth_authentication" {
[
for uri_path in coalesce(var.service.auth.oauth.redirect_uris, []) : {
matching_mode = "strict",
url = "https://${var.service.dns.domain_name}/${uri_path}"
url = "${uri_path}"
}
]
)
Expand Down
2 changes: 1 addition & 1 deletion docker-service/dns.tf
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
data "nginxproxymanager_access_lists" "access_lists" {}

module "service_dns" {
source = "[email protected]:DCCoder90/home-tf-modules.git//dns?ref=1.0.0"
source = "../dns"

count = var.service.dns.enabled ? 1 : 0

Expand Down
4 changes: 2 additions & 2 deletions docker-service/locals.tf
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ locals {
# Create a map of Nginx Proxy Manager access lists by name for easy lookup.
npm_access_lists_by_name = { for al in data.nginxproxymanager_access_lists.access_lists.access_lists : al.name => al.id }

domain = var.service.dns.domain_name == null ? "test.example" : var.service.dns.domain_name
domain = var.service.dns.domain_name == null ? "test.example" : var.service.dns.domain_name
domain_name_parts = split(".", local.domain)
zone_name = join(".", slice(local.domain_name_parts, length(local.domain_name_parts) - 2, length(local.domain_name_parts)))
zone_name = join(".", slice(local.domain_name_parts, length(local.domain_name_parts) - 2, length(local.domain_name_parts)))

}
2 changes: 1 addition & 1 deletion docker-service/main.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module "service_container" {
source = "[email protected]:DCCoder90/home-tf-modules.git//docker?ref=1.0.0"
source = "../docker"

icon = var.service.icon
web_ui = try(var.service.network.service_port, null) != null && local.service_ip_address != null ? "http://${local.service_ip_address}:${var.service.network.service_port}" : null
Expand Down
4 changes: 2 additions & 2 deletions docker-service/secrets.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ data "infisical_projects" "home-net" {
data "infisical_secrets" "secrets" {
# Only fetch secrets if the stack configuration requests them.
count = (var.service.secrets != null && length(var.service.secrets) > 0) || (try(var.service.auth.proxy.enabled, false)) ? 1 : 0

env_slug = var.system.infisical.environment
workspace_id = data.infisical_projects.home-net.id
# This path corresponds to where the root `secrets` module stores secrets.
folder_path = var.system.infisical.folder
}

locals{
locals {
# Create a list of environment variables from the secrets map.
secret_envs = (var.service.secrets != null && length(var.service.secrets) > 0) ? [
for key, value in var.service.secrets :
Expand Down
7 changes: 4 additions & 3 deletions docker-service/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ variable "service" {
volumes = optional(list(string))

# --- Environment & Secrets ---
env = optional(list(string))
secrets = optional(map(string))
env = optional(list(string))
secrets = optional(map(string))
host = optional(string, "tower")

# --- Networking & DNS ---
network = optional(object({
network = optional(object({
internal = optional(bool, false)
service_port = optional(number)
networks = optional(list(object({
Expand Down
27 changes: 5 additions & 22 deletions docker-stack/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,20 @@ data "infisical_projects" "home-net" {
}

module "custom_network" {
count = length(local.creatable_networks) > 0 ? 1 : 0
source = "[email protected]:DCCoder90/home-tf-modules.git//docker-network?ref=1.0.0"
count = length(local.creatable_networks) > 0 ? 1 : 0
source = "../docker-network"

networks = local.creatable_networks
}

module "service_container" {
for_each = var.stack.services
source = "[email protected]:DCCoder90/home-tf-modules.git//docker-service?ref=1.0.0"
source = "../docker-service"

service = each.value
system = var.system
system = var.system

/*
/*
Still need to combine environment, mounts, and networks!


icon = each.value.icon
web_ui = try(each.value.network.service_port, null) != null && local.service_ip_addresses[each.key] != null ? "http://${local.service_ip_addresses[each.key]}:${each.value.network.service_port}" : null
container_name = each.value.service_name
container_image = each.value.image_name
container_network_mode = each.value.network_mode
enable_gpu = each.value.enable_gpu
environment_vars = toset(concat(coalesce(var.stack.env, []), local.processed_envs[each.key], coalesce(var.stack.env, []), coalesce(local.oauth_envs[each.key], [])))
mounts = concat(coalesce(var.stack.mounts, []), coalesce(each.value.mounts, []))
container_capabilities = each.value.capabilities
commands = each.value.commands

# Attach the container to custom networks defined in the stack, but only if the service
# explicitly lists that network in its own configuration.
# The docker module expects a list of objects with `name` and `ipv4_address`.
networks = coalesce(each.value.network.networks, [])
*/
}
39 changes: 20 additions & 19 deletions docker-stack/variables.tf
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
variable "stack" {
type = object({
env = optional(list(string))
mounts = optional(list(string))
volumes = optional(list(string))
networks = optional(map(object({
host = optional(string, "tower")
env = optional(list(string))
mounts = optional(list(string))
volumes = optional(list(string))
networks = optional(map(object({
internal = optional(bool, false)
driver = optional(string, "bridge")
options = optional(map(string), {})
Expand All @@ -19,7 +20,7 @@ variable "stack" {
enable_gpu = optional(bool, false)
env = optional(list(string))
volumes = optional(list(string)),
secrets = optional(map(string)),
secrets = optional(map(string)),
capabilities = optional(object({
add = optional(list(string))
drop = optional(list(string))
Expand All @@ -29,21 +30,21 @@ variable "stack" {
internal = optional(bool, true),
domain_name = optional(string)
})
auth = optional(object({
enabled = optional(bool, false)
group = optional(string, "Uncategorized")
proxy = optional(object({
enabled = optional(bool, false)
user_secret = optional(string)
pass_secret = optional(string)
auth = optional(object({
enabled = optional(bool, false)
group = optional(string, "Uncategorized")
proxy = optional(object({
enabled = optional(bool, false)
user_secret = optional(string)
pass_secret = optional(string)
}), {})
oauth = optional(object({
enabled = optional(bool, false),
keys = optional(map(string), {}),
scopes = optional(list(string)),
redirect_uris = optional(list(string))
}), {})
}), {})
oauth = optional(object({
enabled = optional(bool, false),
keys = optional(map(string), {}),
scopes = optional(list(string)),
redirect_uris = optional(list(string))
}), {})
}), {})
network = optional(object({
internal = optional(bool, false)
service_port = optional(number)
Expand Down
4 changes: 2 additions & 2 deletions docker/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ variable "networks" {
}

variable "enable_gpu" {
type = bool
default = false
type = bool
default = false
description = "If true, use nvidia runtime to add GPU support to the container."
}

Expand Down
10 changes: 10 additions & 0 deletions host-connection/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
data "infisical_projects" "home-net" {
slug = var.system.infisical.project
}

data "infisical_secrets" "host_connections" {
env_slug = var.system.infisical.environment
workspace_id = data.infisical_projects.home-net.id

folder_path = var.system.infisical.host_connections
}
5 changes: 5 additions & 0 deletions host-connection/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
output "host_connection" {
description = "Connection details for host"
value = data.infisical_secrets.host_connections.secrets[var.service.host].value
sensitive = true
}
5 changes: 5 additions & 0 deletions host-connection/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
variable "host" {
type = string
default = "tower"
description = "Name of host connection string as stored in infisical"
}