Skip to content

Commit 56096bf

Browse files
authored
Add multi-server support (#5)
* Added provider config and variable * Formatting * Added host config and formatting * Added host to stack * Added host to each service from the stack. * Removed copy/paste error * Update modules to use relative paths * Add workflow * Added ignore directories * Forgot to tell it to actually ignore them... * Test * Test * Test * Test * Test * Test * Test * Test * Test * Maybe AI can help? * AI was useless, just going to make it stupid simple.... * oops * Update uri path in auth module * Moved provider configuration out of modules. This will require caller to use new host-connection module to get connection string and then passthat into the module under host_connection variable. * Forgot to include host_connection in docker-stack module * Remove all provider configuration for docker provider from module. * . * .
1 parent d27c4e8 commit 56096bf

File tree

14 files changed

+131
-58
lines changed

14 files changed

+131
-58
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
name: Terraform Module Validation
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- main
10+
workflow_dispatch:
11+
12+
jobs:
13+
validate_each_module:
14+
runs-on: ubuntu-latest
15+
strategy:
16+
fail-fast: false
17+
matrix:
18+
module_dir:
19+
- "./authentik"
20+
- "./dns"
21+
- "./docker"
22+
- "./docker-network"
23+
- "./docker-service"
24+
- "./docker-stack"
25+
- "./nginx_config"
26+
- "./oauth_auth"
27+
- "./proxy_auth"
28+
29+
steps:
30+
- name: Checkout Repository
31+
uses: actions/checkout@v4
32+
33+
- name: Setup Terraform
34+
uses: hashicorp/setup-terraform@v3
35+
with:
36+
terraform_version: "latest"
37+
38+
- name: Validate Module ${{ matrix.module_dir }}
39+
shell: bash
40+
run: |
41+
module_dir="${{ matrix.module_dir }}"
42+
echo "--- Validating module: $module_dir ---"
43+
44+
pushd "$module_dir" > /dev/null || { echo "Failed to change directory to $module_dir"; exit 1; }
45+
46+
echo "Running terraform init in $module_dir..."
47+
if ! terraform init -backend=false -input=false -upgrade; then
48+
echo "::error file=$module_dir::Terraform init failed for module: $module_dir"
49+
exit 1
50+
else
51+
echo "Running terraform validate in $module_dir..."
52+
if ! terraform validate; then
53+
echo "::error file=$module_dir::Terraform validate failed for module: $module_dir"
54+
exit 1
55+
fi
56+
fi
57+
58+
popd > /dev/null || { echo "Failed to return from directory"; exit 1; }
59+
echo "Module $module_dir validated successfully!"

ReadMe.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,10 @@
1-
Just working on breaking these modules out for now. Will update the documentation later.
1+
Just working on breaking these modules out for now. Will update the documentation later.
2+
3+
Just a quick note. When using any of the following modules:
4+
5+
- docker
6+
- docker-service
7+
- docker-network
8+
- docker-stack
9+
10+
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)

docker-service/auth.tf

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module "proxy_authentication" {
2-
source = "[email protected]:DCCoder90/home-tf-modules.git//proxy_auth?ref=1.0.0"
2+
source = "../proxy_auth"
33

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

@@ -24,16 +24,16 @@ module "proxy_authentication" {
2424
}
2525

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

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

3131
group = var.service.auth.group
3232
description = var.service.description
3333
name = var.service.service_name
3434
create_access_group = true
35-
access_group_name = "tf_${var.service.service_name}"
36-
user_to_add_to_access_group = var.system.network_admin_username
35+
access_group_name = "tf_${var.service.service_name}"
36+
user_to_add_to_access_group = var.system.network_admin_username
3737
allowed_redirect_uris = concat(
3838
[
3939
{
@@ -43,7 +43,7 @@ module "oauth_authentication" {
4343
[
4444
for uri_path in coalesce(var.service.auth.oauth.redirect_uris, []) : {
4545
matching_mode = "strict",
46-
url = "https://${var.service.dns.domain_name}/${uri_path}"
46+
url = "${uri_path}"
4747
}
4848
]
4949
)

docker-service/dns.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
data "nginxproxymanager_access_lists" "access_lists" {}
22

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

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

docker-service/locals.tf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ locals {
2929
# Create a map of Nginx Proxy Manager access lists by name for easy lookup.
3030
npm_access_lists_by_name = { for al in data.nginxproxymanager_access_lists.access_lists.access_lists : al.name => al.id }
3131

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

3636
}

docker-service/main.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module "service_container" {
2-
source = "[email protected]:DCCoder90/home-tf-modules.git//docker?ref=1.0.0"
2+
source = "../docker"
33

44
icon = var.service.icon
55
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

docker-service/secrets.tf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@ data "infisical_projects" "home-net" {
77
data "infisical_secrets" "secrets" {
88
# Only fetch secrets if the stack configuration requests them.
99
count = (var.service.secrets != null && length(var.service.secrets) > 0) || (try(var.service.auth.proxy.enabled, false)) ? 1 : 0
10-
10+
1111
env_slug = var.system.infisical.environment
1212
workspace_id = data.infisical_projects.home-net.id
1313
# This path corresponds to where the root `secrets` module stores secrets.
1414
folder_path = var.system.infisical.folder
1515
}
1616

17-
locals{
17+
locals {
1818
# Create a list of environment variables from the secrets map.
1919
secret_envs = (var.service.secrets != null && length(var.service.secrets) > 0) ? [
2020
for key, value in var.service.secrets :

docker-service/variables.tf

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,12 @@ variable "service" {
2020
volumes = optional(list(string))
2121

2222
# --- Environment & Secrets ---
23-
env = optional(list(string))
24-
secrets = optional(map(string))
23+
env = optional(list(string))
24+
secrets = optional(map(string))
25+
host = optional(string, "tower")
2526

2627
# --- Networking & DNS ---
27-
network = optional(object({
28+
network = optional(object({
2829
internal = optional(bool, false)
2930
service_port = optional(number)
3031
networks = optional(list(object({

docker-stack/main.tf

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,37 +5,20 @@ data "infisical_projects" "home-net" {
55
}
66

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

1111
networks = local.creatable_networks
1212
}
1313

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

1818
service = each.value
19-
system = var.system
19+
system = var.system
2020

21-
/*
21+
/*
2222
Still need to combine environment, mounts, and networks!
23-
24-
25-
icon = each.value.icon
26-
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
27-
container_name = each.value.service_name
28-
container_image = each.value.image_name
29-
container_network_mode = each.value.network_mode
30-
enable_gpu = each.value.enable_gpu
31-
environment_vars = toset(concat(coalesce(var.stack.env, []), local.processed_envs[each.key], coalesce(var.stack.env, []), coalesce(local.oauth_envs[each.key], [])))
32-
mounts = concat(coalesce(var.stack.mounts, []), coalesce(each.value.mounts, []))
33-
container_capabilities = each.value.capabilities
34-
commands = each.value.commands
35-
36-
# Attach the container to custom networks defined in the stack, but only if the service
37-
# explicitly lists that network in its own configuration.
38-
# The docker module expects a list of objects with `name` and `ipv4_address`.
39-
networks = coalesce(each.value.network.networks, [])
4023
*/
4124
}

docker-stack/variables.tf

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
variable "stack" {
22
type = object({
3-
env = optional(list(string))
4-
mounts = optional(list(string))
5-
volumes = optional(list(string))
6-
networks = optional(map(object({
3+
host = optional(string, "tower")
4+
env = optional(list(string))
5+
mounts = optional(list(string))
6+
volumes = optional(list(string))
7+
networks = optional(map(object({
78
internal = optional(bool, false)
89
driver = optional(string, "bridge")
910
options = optional(map(string), {})
@@ -19,7 +20,7 @@ variable "stack" {
1920
enable_gpu = optional(bool, false)
2021
env = optional(list(string))
2122
volumes = optional(list(string)),
22-
secrets = optional(map(string)),
23+
secrets = optional(map(string)),
2324
capabilities = optional(object({
2425
add = optional(list(string))
2526
drop = optional(list(string))
@@ -29,21 +30,21 @@ variable "stack" {
2930
internal = optional(bool, true),
3031
domain_name = optional(string)
3132
})
32-
auth = optional(object({
33-
enabled = optional(bool, false)
34-
group = optional(string, "Uncategorized")
35-
proxy = optional(object({
36-
enabled = optional(bool, false)
37-
user_secret = optional(string)
38-
pass_secret = optional(string)
33+
auth = optional(object({
34+
enabled = optional(bool, false)
35+
group = optional(string, "Uncategorized")
36+
proxy = optional(object({
37+
enabled = optional(bool, false)
38+
user_secret = optional(string)
39+
pass_secret = optional(string)
40+
}), {})
41+
oauth = optional(object({
42+
enabled = optional(bool, false),
43+
keys = optional(map(string), {}),
44+
scopes = optional(list(string)),
45+
redirect_uris = optional(list(string))
46+
}), {})
3947
}), {})
40-
oauth = optional(object({
41-
enabled = optional(bool, false),
42-
keys = optional(map(string), {}),
43-
scopes = optional(list(string)),
44-
redirect_uris = optional(list(string))
45-
}), {})
46-
}), {})
4748
network = optional(object({
4849
internal = optional(bool, false)
4950
service_port = optional(number)

0 commit comments

Comments
 (0)