Compare commits
2 Commits
b11172504d
...
299fa26c4e
| Author | SHA1 | Date | |
|---|---|---|---|
|
299fa26c4e
|
|||
|
0928b59bda
|
10
main.tf
10
main.tf
@@ -1,3 +1,13 @@
|
|||||||
|
/**
|
||||||
|
* # Root Configuration
|
||||||
|
*
|
||||||
|
* Orchestrates the homelab infrastructure:
|
||||||
|
* - **pip** – Discovers the current public IP for firewall allowlisting.
|
||||||
|
* - **pangolin** – Deploys an Azure Linux VM as a reverse-proxy / WireGuard gateway.
|
||||||
|
* - **foundry** – Creates a Proxmox LXC container running Foundry VTT.
|
||||||
|
* - **dns** – Manages Cloudflare DNS records pointing at the Pangolin proxy.
|
||||||
|
*/
|
||||||
|
|
||||||
module "pip" {
|
module "pip" {
|
||||||
source = "./modules/pip"
|
source = "./modules/pip"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,11 @@
|
|||||||
|
/**
|
||||||
|
* # DNS Module
|
||||||
|
*
|
||||||
|
* Manages Cloudflare DNS records for the root domain:
|
||||||
|
* - A / AAAA records for the apex and wildcard pointing at the Pangolin proxy.
|
||||||
|
* - CDN-proxied A / AAAA records for selected subdomains.
|
||||||
|
*/
|
||||||
|
|
||||||
terraform {
|
terraform {
|
||||||
required_providers {
|
required_providers {
|
||||||
cloudflare = {
|
cloudflare = {
|
||||||
|
|||||||
@@ -1,16 +1,20 @@
|
|||||||
variable "domain_zone_id" {
|
variable "domain_zone_id" {
|
||||||
|
description = "Cloudflare Zone ID for the target domain."
|
||||||
type = string
|
type = string
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "domain_name" {
|
variable "domain_name" {
|
||||||
|
description = "Root domain name (e.g. 'example.com')."
|
||||||
type = string
|
type = string
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "pangolin-proxy-v4" {
|
variable "pangolin-proxy-v4" {
|
||||||
|
description = "IPv4 address of the Pangolin reverse-proxy."
|
||||||
type = string
|
type = string
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "pangolin-proxy-v6" {
|
variable "pangolin-proxy-v6" {
|
||||||
|
description = "IPv6 address of the Pangolin reverse-proxy."
|
||||||
type = string
|
type = string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,10 @@
|
|||||||
|
/**
|
||||||
|
* # Foundry Module
|
||||||
|
*
|
||||||
|
* Creates a Proxmox LXC container running Foundry Virtual Tabletop.
|
||||||
|
* Supports configurable resources, networking, and static or DHCP addressing.
|
||||||
|
*/
|
||||||
|
|
||||||
terraform {
|
terraform {
|
||||||
required_providers {
|
required_providers {
|
||||||
proxmox = {
|
proxmox = {
|
||||||
|
|||||||
@@ -1,3 +1,10 @@
|
|||||||
|
/**
|
||||||
|
* # Pangolin Module
|
||||||
|
*
|
||||||
|
* Deploys an Azure Linux VM with dual-stack (IPv4 + IPv6) networking,
|
||||||
|
* intended as a reverse-proxy and WireGuard gateway for the homelab.
|
||||||
|
*/
|
||||||
|
|
||||||
terraform {
|
terraform {
|
||||||
required_providers {
|
required_providers {
|
||||||
azurerm = {
|
azurerm = {
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
output "public_ipv4" {
|
output "public_ipv4" {
|
||||||
|
description = "The static public IPv4 address of the Pangolin proxy."
|
||||||
value = azurerm_public_ip.pip_v4.ip_address
|
value = azurerm_public_ip.pip_v4.ip_address
|
||||||
}
|
}
|
||||||
|
|
||||||
output "public_ipv6" {
|
output "public_ipv6" {
|
||||||
|
description = "The static public IPv6 address of the Pangolin proxy."
|
||||||
value = azurerm_public_ip.pip_v6.ip_address
|
value = azurerm_public_ip.pip_v6.ip_address
|
||||||
}
|
}
|
||||||
|
|
||||||
output "ssh_ipv4" {
|
output "ssh_ipv4" {
|
||||||
|
description = "Ready-to-use SSH command for connecting to the VM over IPv4."
|
||||||
value = "ssh ${var.admin_username}@${azurerm_public_ip.pip_v4.ip_address}"
|
value = "ssh ${var.admin_username}@${azurerm_public_ip.pip_v4.ip_address}"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,23 @@
|
|||||||
variable "location" {
|
variable "location" {
|
||||||
|
description = "Azure region for all resources in this module."
|
||||||
type = string
|
type = string
|
||||||
default = "westeurope"
|
default = "westeurope"
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "environment" {
|
variable "environment" {
|
||||||
|
description = "Deployment environment label (e.g. 'prod', 'staging')."
|
||||||
type = string
|
type = string
|
||||||
default = "prod"
|
default = "prod"
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "instance" {
|
variable "instance" {
|
||||||
|
description = "Instance identifier appended to resource names."
|
||||||
type = string
|
type = string
|
||||||
default = "homelab"
|
default = "homelab"
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "tags" {
|
variable "tags" {
|
||||||
|
description = "Tags applied to all Azure resources in this module."
|
||||||
type = map(string)
|
type = map(string)
|
||||||
default = {
|
default = {
|
||||||
project = "pangolin"
|
project = "pangolin"
|
||||||
@@ -22,47 +26,54 @@ variable "tags" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
variable "vm_name" {
|
variable "vm_name" {
|
||||||
|
description = "Name of the Azure Linux VM."
|
||||||
type = string
|
type = string
|
||||||
default = "pangolin-proxy"
|
default = "pangolin-proxy"
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "vm_size" {
|
variable "vm_size" {
|
||||||
|
description = "Azure VM size/SKU."
|
||||||
type = string
|
type = string
|
||||||
default = "Standard_A2_v2"
|
default = "Standard_A2_v2"
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "admin_username" {
|
variable "admin_username" {
|
||||||
|
description = "Admin SSH username for the VM."
|
||||||
type = string
|
type = string
|
||||||
default = "azureuser"
|
default = "azureuser"
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "ssh_pubkey" {
|
variable "ssh_pubkey" {
|
||||||
|
description = "SSH public key content for the admin user."
|
||||||
type = string
|
type = string
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "vnet_cidr_ipv4" {
|
variable "vnet_cidr_ipv4" {
|
||||||
|
description = "IPv4 address space for the virtual network."
|
||||||
type = string
|
type = string
|
||||||
default = "10.50.0.0/16"
|
default = "10.50.0.0/16"
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "vnet_cidr_ipv6" {
|
variable "vnet_cidr_ipv6" {
|
||||||
|
description = "IPv6 address space for the virtual network."
|
||||||
type = string
|
type = string
|
||||||
default = "fd7d:bb99:1da4::/48"
|
default = "fd7d:bb99:1da4::/48"
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "subnet_cidr_ipv4" {
|
variable "subnet_cidr_ipv4" {
|
||||||
|
description = "IPv4 CIDR for the VM subnet."
|
||||||
type = string
|
type = string
|
||||||
default = "10.50.1.0/24"
|
default = "10.50.1.0/24"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
variable "subnet_cidr_ipv6" {
|
variable "subnet_cidr_ipv6" {
|
||||||
|
description = "IPv6 CIDR for the VM subnet."
|
||||||
type = string
|
type = string
|
||||||
default = "fd7d:bb99:1da4:195::/64"
|
default = "fd7d:bb99:1da4:195::/64"
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "allowed_ssh_cidrs_ipv4" {
|
variable "allowed_ssh_cidrs_ipv4" {
|
||||||
type = list(string)
|
|
||||||
description = "IPv4 CIDRs allowed to SSH (22/tcp). Empty list means allow from anywhere."
|
description = "IPv4 CIDRs allowed to SSH (22/tcp). Empty list means allow from anywhere."
|
||||||
|
type = list(string)
|
||||||
default = []
|
default = []
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,10 @@
|
|||||||
|
/**
|
||||||
|
* # Public IP Module
|
||||||
|
*
|
||||||
|
* Discovers the caller's public IPv4 address using an external echo-IP service.
|
||||||
|
* Used to dynamically allowlist the deployer's IP in firewall rules.
|
||||||
|
*/
|
||||||
|
|
||||||
terraform {
|
terraform {
|
||||||
required_providers {
|
required_providers {
|
||||||
http = { }
|
http = { }
|
||||||
|
|||||||
56
variables.tf
56
variables.tf
@@ -1,46 +1,84 @@
|
|||||||
variable "domain" {
|
variable "domain" {
|
||||||
|
description = "Root domain name managed in Cloudflare."
|
||||||
type = string
|
type = string
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "domain_zone_id" {
|
variable "domain_zone_id" {
|
||||||
|
description = "Cloudflare Zone ID for the domain."
|
||||||
type = string
|
type = string
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "cloudflare_api_token" {
|
variable "cloudflare_api_token" {
|
||||||
|
description = "Cloudflare API token with DNS edit permissions."
|
||||||
type = string
|
type = string
|
||||||
sensitive = true
|
sensitive = true
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "pve_api_url" { type = string }
|
variable "pve_api_url" {
|
||||||
|
description = "Proxmox VE API endpoint URL."
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
variable "pve_token" {
|
variable "pve_token" {
|
||||||
|
description = "Proxmox VE API token in 'user@realm!tokenid=secret' format."
|
||||||
type = string
|
type = string
|
||||||
sensitive = true
|
sensitive = true
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "node_name" { type = string } # e.g. "pve"
|
variable "node_name" {
|
||||||
variable "datastore_id" { type = string } # e.g. "local-lvm"
|
description = "Proxmox node to deploy resources on (e.g. 'pve')."
|
||||||
variable "bridge" { type = string } # e.g. "vmbr0"
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
variable "template_vmid" { type = number } # VMID of your template
|
variable "datastore_id" {
|
||||||
variable "vm_id" { type = number } # VMID to assign
|
description = "Proxmox datastore for VM/container disks (e.g. 'local-lvm')."
|
||||||
variable "name" { type = string }
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
variable "ssh_pubkey_path" { type = string } # e.g. "~/.ssh/id_ed25519.pub"
|
variable "bridge" {
|
||||||
|
description = "Proxmox network bridge for VM/container NICs (e.g. 'vmbr0')."
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "template_vmid" {
|
||||||
|
description = "VMID of the Proxmox VM template to clone."
|
||||||
|
type = number
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vm_id" {
|
||||||
|
description = "VMID to assign to the new VM."
|
||||||
|
type = number
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "name" {
|
||||||
|
description = "Name for the VM."
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "ssh_pubkey_path" {
|
||||||
|
description = "Path to the SSH public key file (e.g. '~/.ssh/id_ed25519.pub')."
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
variable "admin_username" {
|
variable "admin_username" {
|
||||||
|
description = "Admin username for provisioned VMs."
|
||||||
type = string
|
type = string
|
||||||
default = "azureuser"
|
default = "azureuser"
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "azure_location" {
|
variable "azure_location" {
|
||||||
|
description = "Azure region for resource deployment."
|
||||||
type = string
|
type = string
|
||||||
default = "westeurope"
|
default = "westeurope"
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "azure_subscription_id" {
|
variable "azure_subscription_id" {
|
||||||
|
description = "Azure subscription ID to deploy resources into."
|
||||||
type = string
|
type = string
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "allowed_ssh_cidrs_ipv4" {
|
variable "allowed_ssh_cidrs_ipv4" {
|
||||||
type = list(string)
|
|
||||||
description = "IPv4 CIDRs allowed to SSH (22/tcp). Empty list means allow from anywhere."
|
description = "IPv4 CIDRs allowed to SSH (22/tcp). Empty list means allow from anywhere."
|
||||||
|
type = list(string)
|
||||||
default = []
|
default = []
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user