first commit

This commit is contained in:
Yuris Cakranegara
2025-06-06 12:01:54 +10:00
commit cac26957a8
42 changed files with 2235 additions and 0 deletions

12
environments/README.md Normal file
View File

@@ -0,0 +1,12 @@
# Homelab Environments
This directory contains environment-specific configurations that help organize your infrastructure modules into logical groupings.
Each subdirectory represents a category or environment that can be applied independently or together with others.
```
/environments/
├── core/ # Essential infrastructure (tunnel, monitoring)
├── services/ # Application services (ActualBudget, EmulatorJS)
└── network/ # (Future) Network configs
```

17
environments/core/main.tf Normal file
View File

@@ -0,0 +1,17 @@
// Core infrastructure components
// These are the foundational services that other services depend on
locals {
module_dir = "../../modules"
}
// Core monitoring and maintenance service
module "watchtower" {
source = "${local.module_dir}/20-services-apps/watchtower"
timezone = var.timezone
poll_interval = 86400
cleanup = true
enable_notifications = var.watchtower_enable_notifications
notification_url = var.watchtower_notification_url
}

View File

@@ -0,0 +1,19 @@
// Generic
variable "timezone" {
description = "Timezone for the system"
type = string
}
// Watchtower
variable "watchtower_enable_notifications" {
description = "Enable Watchtower update notifications"
type = bool
default = false
}
variable "watchtower_notification_url" {
description = "Webhook URL for Watchtower notifications (Discord, Slack, etc.)"
type = string
sensitive = true
default = ""
}

View File

@@ -0,0 +1,45 @@
// Network environment
// Contains configurations for network infrastructure
locals {
module_dir = "../../modules"
}
module "cloudflare_globals" {
source = "${local.module_dir}/00-globals/cloudflare"
cloudflare_api_token = var.cloudflare_api_token
cloudflare_account_id = var.cloudflare_account_id
cloudflare_zone_id = var.cloudflare_zone_id
domain = var.domain
}
module "homelab_docker_network" {
source = "${local.module_dir}/01-networking/docker-network"
name = "homelab-network"
driver = "bridge"
attachable = true
subnet = "10.100.0.0/16"
}
module "homelab_cloudflared_tunnel" {
source = "${local.module_dir}/01-networking/cloudflared-tunnel"
cloudflare_account_id = module.cloudflare_globals.cloudflare_account_id
cloudflare_zone_id = module.cloudflare_globals.cloudflare_zone_id
tunnel_name = "homelab"
container_name = "cloudflared-homelab"
ingress_rules = [
{
hostname = "budget.${var.domain}"
service = "http://actualbudget:5006"
},
]
networks = [module.homelab_docker_network.name]
monitoring = true
}

View File

@@ -0,0 +1,36 @@
output "cloudflare_account_id" {
description = "Cloudflare account ID"
value = module.cloudflare_globals.cloudflare_account_id
}
output "cloudflare_zone_id" {
description = "Cloudflare zone ID"
value = module.cloudflare_globals.cloudflare_zone_id
}
output "domain" {
description = "Base domain name"
value = module.cloudflare_globals.domain
}
// Docker network outputs
output "homelab_docker_network_name" {
description = "Name of the Docker network"
value = module.homelab_docker_network.name
}
// Tunnel outputs
output "homelab_cloudflared_tunnel_id" {
description = "ID of the Cloudflare tunnel"
value = module.homelab_cloudflared_tunnel.tunnel_id
}
output "homelab_cloudflared_tunnel_name" {
description = "Name of the Cloudflare tunnel"
value = module.homelab_cloudflared_tunnel.tunnel_name
}
output "homelab_cloudflared_tunnel_cname_target" {
description = "CNAME target for the tunnel"
value = module.homelab_cloudflared_tunnel.cname_target
}

View File

@@ -0,0 +1,21 @@
variable "cloudflare_api_token" {
description = "API token for Cloudflare with the necessary permissions"
type = string
sensitive = true
}
variable "cloudflare_account_id" {
description = "Cloudflare account ID"
type = string
}
variable "cloudflare_zone_id" {
description = "Cloudflare zone ID for the domain"
type = string
}
variable "domain" {
description = "Base domain name (e.g., example.com)"
type = string
}

View File

@@ -0,0 +1,36 @@
// Application services environment
// Contains configurations for all application services
// Import global Terraform settings
terraform {
# Include backend configuration if needed
# backend "local" { ... }
}
locals {
module_dir = "../../modules"
}
module "actualbudget" {
source = "${local.module_dir}/20-services-apps/actualbudget"
container_name = "actualbudget"
timezone = var.timezone
data_volume_path = "${var.data_dir}/actual/data"
port = var.actualbudget_port
networks = var.default_networks
}
module "emulatorjs" {
source = "${local.module_dir}/20-services-apps/emulatorjs"
container_name = "emulatorjs"
timezone = var.timezone
puid = var.puid
pgid = var.pgid
config_volume_path = "${var.data_dir}/emulatorjs/config"
data_volume_path = "${var.data_dir}/emulatorjs/data"
frontend_port = var.emulatorjs_frontend_port
config_port = var.emulatorjs_config_port
backend_port = var.emulatorjs_backend_port
}

View File

@@ -0,0 +1,38 @@
// Services environment outputs
// ActualBudget
output "actualbudget_container_name" {
description = "The name of the ActualBudget container"
value = module.actualbudget.container_name
}
output "actualbudget_container_id" {
description = "The ID of the ActualBudget container"
value = module.actualbudget.container_id
}
output "actualbudget_local_url" {
description = "The local URL to access ActualBudget"
value = module.actualbudget.local_url
}
// EmulatorJS
output "emulatorjs_container_name" {
description = "The name of the EmulatorJS container"
value = module.emulatorjs.container_name
}
output "emulatorjs_container_id" {
description = "The ID of the EmulatorJS container"
value = module.emulatorjs.container_id
}
output "emulatorjs_frontend_url" {
description = "The frontend URL for EmulatorJS"
value = module.emulatorjs.frontend_url
}
output "emulatorjs_config_url" {
description = "The configuration URL for EmulatorJS"
value = module.emulatorjs.config_url
}

View File

@@ -0,0 +1,50 @@
// Variables for the services environment
// Generic
variable "timezone" {
description = "Timezone for the system"
type = string
}
variable "puid" {
description = "User ID for the container"
type = number
}
variable "pgid" {
description = "Group ID for the container"
type = number
}
variable "data_dir" {
description = "Base directory for data volumes"
type = string
}
variable "default_networks" {
description = "List of networks to which the container should be attached"
type = list(string)
default = []
}
// ActualBudget
variable "actualbudget_port" {
description = "External port for the ActualBudget server"
type = number
}
// EmulatorJS
variable "emulatorjs_frontend_port" {
description = "External port for the EmulatorJS frontend"
type = number
}
variable "emulatorjs_config_port" {
description = "External port for the EmulatorJS configuration interface"
type = number
}
variable "emulatorjs_backend_port" {
description = "External port for the EmulatorJS backend"
type = number
}