Files
the_order/infra/terraform/modules/regional-landing-zone/main.tf
defiQUG 6a8582e54d feat: comprehensive project structure improvements and Cloud for Sovereignty landing zone
- Add Cloud for Sovereignty landing zone architecture and deployment
- Implement complete legal document management system
- Reorganize documentation with improved navigation
- Add infrastructure improvements (Dockerfiles, K8s, monitoring)
- Add operational improvements (graceful shutdown, rate limiting, caching)
- Create comprehensive project structure documentation
- Add Azure deployment automation scripts
- Improve repository navigation and organization
2025-11-13 09:32:55 -08:00

343 lines
10 KiB
HCL

# Regional Landing Zone Module
# Deploys a complete landing zone for a single Azure region
# Follows Cloud for Sovereignty and Well-Architected Framework principles
variable "region" {
description = "Azure region (e.g., westeurope, northeurope)"
type = string
validation {
condition = contains([
"westeurope",
"northeurope",
"uksouth",
"switzerlandnorth",
"norwayeast",
"francecentral",
"germanywestcentral"
], var.region)
error_message = "Region must be a non-US commercial Azure region."
}
}
variable "environment" {
description = "Environment name (dev, stage, prod)"
type = string
validation {
condition = contains(["dev", "stage", "prod"], var.environment)
error_message = "Environment must be dev, stage, or prod."
}
}
variable "management_group_id" {
description = "Management group ID for this landing zone"
type = string
}
variable "hub_vnet_address_space" {
description = "Address space for hub VNet"
type = string
default = "10.0.0.0/16"
}
variable "spoke_vnet_address_space" {
description = "Address space for spoke VNet"
type = string
default = "10.1.0.0/16"
}
variable "tags" {
description = "Tags to apply to all resources"
type = map(string)
default = {}
}
# Local values for naming
locals {
region_abbrev = {
westeurope = "we"
northeurope = "ne"
uksouth = "uk"
switzerlandnorth = "ch"
norwayeast = "no"
francecentral = "fr"
germanywestcentral = "de"
}
env_abbrev = {
dev = "dev"
stage = "stg"
prod = "prd"
}
region_short = lookup(local.region_abbrev, var.region, "we")
env_short = lookup(local.env_abbrev, var.environment, "dev")
name_prefix = "az-${local.region_short}"
common_tags = merge(var.tags, {
Region = var.region
Environment = var.environment
DataResidency = var.region
ManagedBy = "terraform"
LandingZone = "regional"
SovereigntyLevel = "high"
})
}
# Resource Group
resource "azurerm_resource_group" "landing_zone" {
name = "${local.name_prefix}-rg-${local.env_short}-lz"
location = var.region
tags = local.common_tags
}
# Hub Virtual Network
resource "azurerm_virtual_network" "hub" {
name = "${local.name_prefix}-vnet-${local.env_short}-hub"
address_space = [var.hub_vnet_address_space]
location = var.region
resource_group_name = azurerm_resource_group.landing_zone.name
tags = merge(local.common_tags, {
Purpose = "HubNetwork"
})
}
# Hub Subnets
resource "azurerm_subnet" "hub_gateway" {
name = "GatewaySubnet"
resource_group_name = azurerm_resource_group.landing_zone.name
virtual_network_name = azurerm_virtual_network.hub.name
address_prefixes = [cidrsubnet(var.hub_vnet_address_space, 8, 0)]
}
resource "azurerm_subnet" "hub_firewall" {
name = "AzureFirewallSubnet"
resource_group_name = azurerm_resource_group.landing_zone.name
virtual_network_name = azurerm_virtual_network.hub.name
address_prefixes = [cidrsubnet(var.hub_vnet_address_space, 8, 1)]
}
resource "azurerm_subnet" "hub_management" {
name = "ManagementSubnet"
resource_group_name = azurerm_resource_group.landing_zone.name
virtual_network_name = azurerm_virtual_network.hub.name
address_prefixes = [cidrsubnet(var.hub_vnet_address_space, 8, 2)]
}
# Azure Firewall
resource "azurerm_public_ip" "firewall" {
name = "${local.name_prefix}-pip-${local.env_short}-fw"
location = var.region
resource_group_name = azurerm_resource_group.landing_zone.name
allocation_method = "Static"
sku = "Standard"
tags = local.common_tags
}
resource "azurerm_firewall" "hub" {
name = "${local.name_prefix}-fw-${local.env_short}-hub"
location = var.region
resource_group_name = azurerm_resource_group.landing_zone.name
sku_name = "AZFW_VNet"
sku_tier = "Standard"
ip_configuration {
name = "configuration"
subnet_id = azurerm_subnet.hub_firewall.id
public_ip_address_id = azurerm_public_ip.firewall.id
}
tags = local.common_tags
}
# Spoke Virtual Network
resource "azurerm_virtual_network" "spoke" {
name = "${local.name_prefix}-vnet-${local.env_short}-spoke"
address_space = [var.spoke_vnet_address_space]
location = var.region
resource_group_name = azurerm_resource_group.landing_zone.name
tags = merge(local.common_tags, {
Purpose = "SpokeNetwork"
})
}
# Spoke Subnets
resource "azurerm_subnet" "spoke_app" {
name = "ApplicationSubnet"
resource_group_name = azurerm_resource_group.landing_zone.name
virtual_network_name = azurerm_virtual_network.spoke.name
address_prefixes = [cidrsubnet(var.spoke_vnet_address_space, 8, 0)]
}
resource "azurerm_subnet" "spoke_db" {
name = "DatabaseSubnet"
resource_group_name = azurerm_resource_group.landing_zone.name
virtual_network_name = azurerm_virtual_network.spoke.name
address_prefixes = [cidrsubnet(var.spoke_vnet_address_space, 8, 1)]
delegation {
name = "postgresql-delegation"
service_delegation {
name = "Microsoft.DBforPostgreSQL/flexibleServers"
actions = [
"Microsoft.Network/virtualNetworks/subnets/join/action",
]
}
}
}
resource "azurerm_subnet" "spoke_storage" {
name = "StorageSubnet"
resource_group_name = azurerm_resource_group.landing_zone.name
virtual_network_name = azurerm_virtual_network.spoke.name
address_prefixes = [cidrsubnet(var.spoke_vnet_address_space, 8, 2)]
}
# VNet Peering: Hub to Spoke
resource "azurerm_virtual_network_peering" "hub_to_spoke" {
name = "hub-to-spoke"
resource_group_name = azurerm_resource_group.landing_zone.name
virtual_network_name = azurerm_virtual_network.hub.name
remote_virtual_network_id = azurerm_virtual_network.spoke.id
allow_forwarded_traffic = true
allow_gateway_transit = true
}
resource "azurerm_virtual_network_peering" "spoke_to_hub" {
name = "spoke-to-hub"
resource_group_name = azurerm_resource_group.landing_zone.name
virtual_network_name = azurerm_virtual_network.spoke.name
remote_virtual_network_id = azurerm_virtual_network.hub.id
allow_forwarded_traffic = true
use_remote_gateways = false
}
# Data source for current client config
data "azurerm_client_config" "current" {}
# Key Vault (Regional)
resource "azurerm_key_vault" "regional" {
name = "${local.name_prefix}-kv-${local.env_short}-${local.region_short}"
location = var.region
resource_group_name = azurerm_resource_group.landing_zone.name
tenant_id = data.azurerm_client_config.current.tenant_id
sku_name = "premium"
# Network ACLs - Private endpoint only
network_acls {
default_action = "Deny"
bypass = "AzureServices"
}
# Enable soft delete and purge protection
soft_delete_retention_days = 90
purge_protection_enabled = var.environment == "prod"
tags = merge(local.common_tags, {
Purpose = "RegionalSecrets"
})
}
# Private Endpoint for Key Vault
resource "azurerm_private_endpoint" "key_vault" {
name = "${local.name_prefix}-pe-${local.env_short}-kv"
location = var.region
resource_group_name = azurerm_resource_group.landing_zone.name
subnet_id = azurerm_subnet.hub_management.id
private_service_connection {
name = "kv-connection"
private_connection_resource_id = azurerm_key_vault.regional.id
subresource_names = ["vault"]
is_manual_connection = false
}
tags = local.common_tags
}
# Log Analytics Workspace (Regional)
resource "azurerm_log_analytics_workspace" "regional" {
name = "${local.name_prefix}-law-${local.env_short}-${local.region_short}"
location = var.region
resource_group_name = azurerm_resource_group.landing_zone.name
sku = "PerGB2018"
retention_in_days = var.environment == "prod" ? 90 : 30
tags = merge(local.common_tags, {
Purpose = "RegionalLogging"
})
}
# Storage Account (Regional)
resource "azurerm_storage_account" "regional" {
name = "${local.name_prefix}sa${local.env_short}${local.region_short}"
resource_group_name = azurerm_resource_group.landing_zone.name
location = var.region
account_tier = "Standard"
account_replication_type = var.environment == "prod" ? "GRS" : "LRS"
min_tls_version = "TLS1_2"
allow_blob_public_access = false
# Customer-managed encryption
identity {
type = "SystemAssigned"
}
blob_properties {
versioning_enabled = true
delete_retention_policy {
days = var.environment == "prod" ? 90 : 30
}
}
tags = merge(local.common_tags, {
Purpose = "RegionalStorage"
})
}
# Private Endpoint for Storage Account
resource "azurerm_private_endpoint" "storage" {
name = "${local.name_prefix}-pe-${local.env_short}-st"
location = var.region
resource_group_name = azurerm_resource_group.landing_zone.name
subnet_id = azurerm_subnet.spoke_storage.id
private_service_connection {
name = "storage-connection"
private_connection_resource_id = azurerm_storage_account.regional.id
subresource_names = ["blob"]
is_manual_connection = false
}
tags = local.common_tags
}
# Outputs
output "resource_group_name" {
value = azurerm_resource_group.landing_zone.name
}
output "hub_vnet_id" {
value = azurerm_virtual_network.hub.id
}
output "spoke_vnet_id" {
value = azurerm_virtual_network.spoke.id
}
output "key_vault_id" {
value = azurerm_key_vault.regional.id
}
output "log_analytics_workspace_id" {
value = azurerm_log_analytics_workspace.regional.workspace_id
}
output "storage_account_name" {
value = azurerm_storage_account.regional.name
}