Terraform部署Azure多区域最佳实践:如何避免代码重复?
Terraform Azure 跨多区域部署最佳实践
核心思路:for_each迭代区域+模块化封装
不用为每个区域重复编写模块调用代码,通过集中定义区域列表+for_each批量实例化模块实现多区域部署,同时保留区域配置的灵活性。
1. 定义全局区域变量
在根模块中统一管理要部署的目标区域,后续新增/移除区域只需修改这个变量:
variable "target_regions" { type = list(string) description = "Azure regions to deploy infrastructure" default = ["eastus", "westeurope", "southeastasia"] }
2. 封装区域通用资源模块
把每个区域需要部署的资源(资源组、VNet、VM、存储账户等)封装到独立模块,模块核心参数为目标区域:
# ./modules/regional_infra/main.tf variable "region" { type = string description = "Target Azure region for this module instance" } variable "resource_prefix" { type = string description = "Prefix for all resource names in this region" } # 区域资源组 resource "azurerm_resource_group" "regional_rg" { name = "${var.resource_prefix}-rg-${var.region}" location = var.region } # 区域虚拟网络(用区域索引生成唯一网段) resource "azurerm_virtual_network" "regional_vnet" { name = "${var.resource_prefix}-vnet-${var.region}" address_space = ["10.${index(var.target_regions, var.region)}.0.0/16"] location = var.region resource_group_name = azurerm_resource_group.regional_rg.name } # 其他区域级资源(VM、存储账户等)可按需添加...
3. 用for_each批量调用模块
在根模块中通过for_each迭代区域列表,自动为每个区域创建模块实例,无需重复编写代码:
module "regional_deployments" { source = "./modules/regional_infra" # 将列表转为集合,实现逐个区域迭代 for_each = toset(var.target_regions) region = each.value resource_prefix = "my-production-app" }
4. 处理区域特定配置
如果不同区域需要差异化参数(比如VM SKU、存储冗余策略、标签),用map类型变量定义区域专属配置:
# 根模块中定义区域特定配置 variable "region_specific_settings" { type = map(object({ vm_sku = string storage_account_tier = string tags = map(string) })) default = { eastus = { vm_sku = "Standard_D4s_v3" storage_account_tier = "Premium_LRS" tags = { environment = "prod", role = "primary" } } westeurope = { vm_sku = "Standard_D2s_v3" storage_account_tier = "Standard_GRS" tags = { environment = "prod", role = "secondary" } } } } # 模块调用时传入对应配置 module "regional_deployments" { source = "./modules/regional_infra" for_each = toset(var.target_regions) region = each.value resource_prefix = "my-production-app" vm_sku = var.region_specific_settings[each.value].vm_sku storage_tier = var.region_specific_settings[each.value].storage_account_tier resource_tags = var.region_specific_settings[each.value].tags }
5. 全局资源单独处理
对于Azure全局资源(比如Traffic Manager、Front Door),不需要按区域迭代,直接在根模块中部署,并通过模块输出关联区域资源:
# 部署Traffic Manager关联多区域端点 resource "azurerm_traffic_manager_profile" "global_profile" { name = "my-app-traffic-manager" resource_group_name = azurerm_resource_group.global_rg.name traffic_routing_method = "Priority" endpoint { name = "eastus-endpoint" target_resource_id = module.regional_deployments["eastus"].public_ip_id priority = 1 } endpoint { name = "westeurope-endpoint" target_resource_id = module.regional_deployments["westeurope"].public_ip_id priority = 2 } }
6. 状态与输出
- 状态管理:推荐用Azure Blob存储作为远程后端,集中管理多区域部署状态;若需隔离区域状态,可按区域创建Terraform工作区,但集中状态更便于统一维护。
- 批量输出:用
for表达式批量导出所有区域的资源信息:
output "regional_resource_groups" { type = map(string) value = { for region in var.target_regions : region => module.regional_deployments[region].rg_id } }
内容的提问来源于stack exchange,提问作者Chris Taverner
相关产品推荐
相关产品推荐

