Files
the_order/infra/terraform/modules/well-architected/main.tf
defiQUG 3bf47efa2b feat: implement comprehensive Well-Architected Framework and Cloud for Sovereignty compliance
- Add Well-Architected Framework implementation guide covering all 5 pillars
- Create Well-Architected Terraform module (cost, operations, performance, reliability, security)
- Add Cloud for Sovereignty compliance guide
- Implement data residency policies and enforcement
- Add operational sovereignty features (CMK, independent logging)
- Configure compliance monitoring and reporting
- Add budget management and cost optimization
- Implement comprehensive security controls
- Add backup and disaster recovery automation
- Create performance optimization resources (Redis, Front Door)
- Add operational excellence tools (Log Analytics, App Insights, Automation)
2025-11-13 11:05:28 -08:00

396 lines
12 KiB
HCL

/**
* Well-Architected Framework Module
* Implements all five pillars: Cost, Operations, Performance, Reliability, Security
* Cloud for Sovereignty compliant
*/
terraform {
required_version = ">= 1.5.0"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.0"
}
}
}
# Data sources
data "azurerm_client_config" "current" {}
data "azurerm_subscription" "current" {}
# Local values
locals {
name_prefix = var.name_prefix != "" ? var.name_prefix : "the-order"
env_short = var.environment == "production" ? "prod" : var.environment == "staging" ? "stg" : "dev"
# Standard tags for cost optimization
common_tags = merge(var.tags, {
Environment = var.environment
Project = "the-order"
CostCenter = var.cost_center
Owner = var.owner
DataClassification = var.data_classification
Sovereignty = "required"
ManagedBy = "terraform"
WellArchitected = "true"
})
# Regions for sovereignty
allowed_regions = var.allowed_regions != [] ? var.allowed_regions : [
"westeurope",
"northeurope",
"uksouth",
"switzerlandnorth",
"norwayeast",
"francecentral",
"germanywestcentral"
]
}
# ============================================================================
# COST OPTIMIZATION
# ============================================================================
# Budget and cost management
resource "azurerm_consumption_budget_subscription" "main" {
count = var.enable_cost_management ? 1 : 0
name = "${local.name_prefix}-budget-${local.env_short}"
subscription_id = data.azurerm_subscription.current.id
amount = var.monthly_budget_amount
time_grain = "Monthly"
time_period {
start_date = formatdate("YYYY-MM-01T00:00:00Z", timestamp())
end_date = timeadd(formatdate("YYYY-MM-01T00:00:00Z", timestamp()), "1y")
}
notification {
enabled = true
threshold = 50
operator = "GreaterThan"
threshold_type = "Actual"
contact_emails = var.budget_alert_emails
}
notification {
enabled = true
threshold = 75
operator = "GreaterThan"
threshold_type = "Actual"
contact_emails = var.budget_alert_emails
}
notification {
enabled = true
threshold = 90
operator = "GreaterThan"
threshold_type = "Actual"
contact_emails = var.budget_alert_emails
}
notification {
enabled = true
threshold = 100
operator = "GreaterThan"
threshold_type = "Actual"
contact_emails = var.budget_alert_emails
}
}
# Cost Management export
resource "azurerm_cost_management_export_resource_group" "main" {
count = var.enable_cost_management ? 1 : 0
name = "${local.name_prefix}-cost-export-${local.env_short}"
resource_group_id = var.resource_group_id
recurrence_type = "Monthly"
recurrence_period_start_date = formatdate("YYYY-MM-01T00:00:00Z", timestamp())
recurrence_period_end_date = timeadd(formatdate("YYYY-MM-01T00:00:00Z", timestamp()), "1y")
export_data_storage_location {
container_id = var.cost_export_storage_container_id
root_folder_path = "cost-exports"
}
export_data_options {
type = "Usage"
time_frame = "MonthToDate"
}
}
# ============================================================================
# OPERATIONAL EXCELLENCE
# ============================================================================
# Log Analytics Workspace for centralized logging
resource "azurerm_log_analytics_workspace" "main" {
name = "${local.name_prefix}-logs-${local.env_short}-${substr(var.region, 0, 6)}"
location = var.region
resource_group_name = var.resource_group_name
sku = "PerGB2018"
retention_in_days = var.environment == "production" ? 90 : 30
tags = local.common_tags
}
# Application Insights for APM
resource "azurerm_application_insights" "main" {
name = "${local.name_prefix}-appinsights-${local.env_short}-${substr(var.region, 0, 6)}"
location = var.region
resource_group_name = var.resource_group_name
application_type = "web"
workspace_id = azurerm_log_analytics_workspace.main.id
tags = local.common_tags
}
# Automation Account for runbooks
resource "azurerm_automation_account" "main" {
count = var.enable_automation ? 1 : 0
name = "${local.name_prefix}-automation-${local.env_short}-${substr(var.region, 0, 6)}"
location = var.region
resource_group_name = var.resource_group_name
sku_name = "Basic"
identity {
type = "SystemAssigned"
}
tags = local.common_tags
}
# ============================================================================
# PERFORMANCE EFFICIENCY
# ============================================================================
# Azure Front Door for global load balancing and CDN
resource "azurerm_front_door" "main" {
count = var.enable_front_door ? 1 : 0
name = "${local.name_prefix}-fd-${local.env_short}"
resource_group_name = var.resource_group_name
location = "Global"
routing_rule {
name = "default-rule"
accepted_protocols = ["Https"]
patterns_to_match = ["/*"]
frontend_endpoints = ["${local.name_prefix}-fd-${local.env_short}"]
forwarding_configuration {
forwarding_protocol = "HttpsOnly"
backend_pool_name = "default-backend"
}
}
backend_pool_load_balancing {
name = "default-load-balancer"
}
backend_pool_health_probe {
name = "default-health-probe"
}
backend_pool {
name = "default-backend"
backend {
host_header = var.backend_host_header
address = var.backend_address
http_port = 80
https_port = 443
}
load_balancing_name = "default-load-balancer"
health_probe_name = "default-health-probe"
}
frontend_endpoint {
name = "${local.name_prefix}-fd-${local.env_short}"
host_name = "${local.name_prefix}-fd-${local.env_short}.azurefd.net"
}
tags = local.common_tags
}
# Redis Cache for application caching
resource "azurerm_redis_cache" "main" {
count = var.enable_redis_cache ? 1 : 0
name = "${local.name_prefix}-redis-${local.env_short}-${substr(var.region, 0, 6)}"
location = var.region
resource_group_name = var.resource_group_name
capacity = var.redis_capacity
family = var.redis_family
sku_name = "${var.redis_family}${var.redis_capacity}"
enable_non_ssl_port = false
minimum_tls_version = "1.2"
redis_configuration {
maxmemory_reserved = 2
maxmemory_delta = 2
maxmemory_policy = "allkeys-lru"
}
tags = local.common_tags
}
# ============================================================================
# RELIABILITY
# ============================================================================
# Recovery Services Vault for backups
resource "azurerm_recovery_services_vault" "main" {
count = var.enable_backup ? 1 : 0
name = "${local.name_prefix}-rsv-${local.env_short}-${substr(var.region, 0, 6)}"
location = var.region
resource_group_name = var.resource_group_name
sku = "Standard"
soft_delete_enabled = true
identity {
type = "SystemAssigned"
}
tags = local.common_tags
}
# Backup policy
resource "azurerm_backup_policy_vm" "main" {
count = var.enable_backup ? 1 : 0
name = "${local.name_prefix}-backup-policy-${local.env_short}"
resource_group_name = var.resource_group_name
recovery_vault_name = azurerm_recovery_services_vault.main[0].name
timezone = "UTC"
backup {
frequency = "Daily"
time = "23:00"
}
retention_daily {
count = var.environment == "production" ? 30 : 7
}
retention_weekly {
count = var.environment == "production" ? 12 : 4
weekdays = ["Sunday"]
}
retention_monthly {
count = var.environment == "production" ? 12 : 3
months = ["January", "July"]
weekdays = ["Sunday"]
weeks = ["First"]
}
}
# ============================================================================
# SECURITY
# ============================================================================
# Key Vault for secrets management (if not already created)
resource "azurerm_key_vault" "main" {
count = var.create_key_vault ? 1 : 0
name = "${local.name_prefix}-kv-${local.env_short}-${substr(var.region, 0, 6)}"
location = var.region
resource_group_name = var.resource_group_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 == "production"
tags = merge(local.common_tags, {
Purpose = "SecretsManagement"
})
}
# Microsoft Defender for Cloud
resource "azurerm_security_center_subscription_pricing" "main" {
count = var.enable_defender ? 1 : 0
tier = "Standard"
subplan = "P2"
resource_type = "VirtualMachines"
}
# DDoS Protection Plan
resource "azurerm_network_ddos_protection_plan" "main" {
count = var.enable_ddos_protection ? 1 : 0
name = "${local.name_prefix}-ddos-${local.env_short}-${substr(var.region, 0, 6)}"
location = var.region
resource_group_name = var.resource_group_name
tags = local.common_tags
}
# ============================================================================
# CLOUD FOR SOVEREIGNTY
# ============================================================================
# Azure Policy for data residency enforcement
resource "azurerm_policy_definition" "data_residency" {
count = var.enable_sovereignty_policies ? 1 : 0
name = "${local.name_prefix}-data-residency-${local.env_short}"
policy_type = "Custom"
mode = "All"
display_name = "Enforce Data Residency - ${var.environment}"
policy_rule = jsonencode({
if = {
allOf = [
{
field = "location"
notIn = local.allowed_regions
}
]
}
then = {
effect = "deny"
}
})
metadata = jsonencode({
category = "Sovereignty"
})
}
# Policy assignment
resource "azurerm_policy_assignment" "data_residency" {
count = var.enable_sovereignty_policies ? 1 : 0
name = "${local.name_prefix}-data-residency-assignment-${local.env_short}"
scope = var.management_group_id != "" ? var.management_group_id : data.azurerm_subscription.current.id
policy_definition_id = azurerm_policy_definition.data_residency[0].id
display_name = "Enforce Data Residency - ${var.environment}"
identity {
type = "SystemAssigned"
}
}
# Outputs
output "log_analytics_workspace_id" {
value = azurerm_log_analytics_workspace.main.id
description = "Log Analytics Workspace ID"
}
output "application_insights_instrumentation_key" {
value = azurerm_application_insights.main.instrumentation_key
sensitive = true
description = "Application Insights Instrumentation Key"
}
output "redis_cache_hostname" {
value = var.enable_redis_cache ? azurerm_redis_cache.main[0].hostname : null
description = "Redis Cache Hostname"
}
output "key_vault_uri" {
value = var.create_key_vault ? azurerm_key_vault.main[0].vault_uri : null
description = "Key Vault URI"
}