/** * # 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 { required_providers { azurerm = { source = "hashicorp/azurerm" } } } resource "azurerm_resource_group" "rg" { location = var.location name = "rg-pangolin-${var.environment}-${var.location}-${var.instance}" } resource "azurerm_linux_virtual_machine" "vm" { name = var.vm_name location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name size = var.vm_size admin_username = var.admin_username disable_password_authentication = true admin_ssh_key { username = var.admin_username public_key = var.ssh_pubkey } os_disk { name = "${var.vm_name}-osdisk" caching = "ReadWrite" storage_account_type = "Standard_LRS" } source_image_reference { publisher = "Canonical" offer = "ubuntu-24_04-lts" sku = "server-gen1" version = "latest" } network_interface_ids = [azurerm_network_interface.nic.id] tags = var.tags } resource "azurerm_virtual_network" "vnet" { name = "${var.vm_name}-vnet" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name address_space = [var.vnet_cidr_ipv4, var.vnet_cidr_ipv6] tags = var.tags } resource "azurerm_subnet" "subnet" { name = "${var.vm_name}-subnet" resource_group_name = azurerm_resource_group.rg.name virtual_network_name = azurerm_virtual_network.vnet.name address_prefixes = [var.subnet_cidr_ipv4, var.subnet_cidr_ipv6] } resource "azurerm_network_interface" "nic" { name = "${var.vm_name}-nic" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name tags = var.tags ip_forwarding_enabled = true ip_configuration { name = "ipconfig-v4" subnet_id = azurerm_subnet.subnet.id private_ip_address_allocation = "Dynamic" private_ip_address_version = "IPv4" public_ip_address_id = azurerm_public_ip.pip_v4.id primary = true } ip_configuration { name = "ipconfig-v6" subnet_id = azurerm_subnet.subnet.id private_ip_address_allocation = "Dynamic" private_ip_address_version = "IPv6" public_ip_address_id = azurerm_public_ip.pip_v6.id } } resource "azurerm_public_ip" "pip_v4" { name = "pip-pangolin-${var.environment}-${var.location}-${var.instance}-v4" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name allocation_method = "Static" sku = "Standard" ip_version = "IPv4" tags = var.tags } resource "azurerm_public_ip" "pip_v6" { name = "pip-pangolin-${var.environment}-${var.location}-${var.instance}-v6" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name allocation_method = "Static" sku = "Standard" ip_version = "IPv6" tags = var.tags }