Terraform模块化部署Azure KeyVault:子网名转ID配置网络ACL
模块化部署带网络ACL的Azure KeyVault(子网名称转ID实现)
根模块调用代码
首先在根模块中定义变量,传入KeyVault名称、子网所在VNet的信息,以及包含子网名称的网络规则列表:
variable "keyvault_name" { type = string description = "Azure Key Vault名称" } variable "keyvault_network_rules" { type = list(object({ subnet_name = string action = string # 仅允许"Allow"或"Deny" priority = number # 取值范围100-4096 })) description = "Key Vault网络访问规则,使用子网名称而非硬编码ID" } variable "vnet_resource_group_name" { type = string description = "子网所属虚拟网络的资源组名称" } variable "vnet_name" { type = string description = "子网所属的虚拟网络名称" } module "keyvault" { source = "./modules/keyvault" keyvault_name = var.keyvault_name vnet_resource_group_name = var.vnet_resource_group_name vnet_name = var.vnet_name keyvault_network_rules = var.keyvault_network_rules }
KeyVault模块内部实现
模块中通过数据块获取VNet信息,建立子网名称到ID的映射,再用dynamic块批量生成网络规则:
# 模块变量定义 variable "keyvault_name" { type = string description = "Azure Key Vault名称" } variable "vnet_resource_group_name" { type = string description = "子网所属虚拟网络的资源组名称" } variable "vnet_name" { type = string description = "子网所属的虚拟网络名称" } variable "keyvault_network_rules" { type = list(object({ subnet_name = string action = string priority = number })) description = "Key Vault网络访问规则列表" # 校验参数合法性 validation { condition = alltrue([for r in var.keyvault_network_rules : r.action == "Allow" || r.action == "Deny"]) error_message = "规则action只能是Allow或Deny。" } validation { condition = alltrue([for r in var.keyvault_network_rules : r.priority >= 100 && r.priority <= 4096]) error_message = "规则priority必须在100-4096之间。" } } # 获取目标VNet的详细数据,用于提取子网ID data "azurerm_virtual_network" "target_vnet" { name = var.vnet_name resource_group_name = var.vnet_resource_group_name } # 生成子网名称到ID的映射表 locals { subnet_map = { for s in data.azurerm_virtual_network.target_vnet.subnets : s.name => s.id } } # 获取当前租户ID,用于KeyVault配置 data "azurerm_client_config" "current" {} # 部署KeyVault resource "azurerm_key_vault" "main" { name = var.keyvault_name location = data.azurerm_virtual_network.target_vnet.location resource_group_name = var.vnet_resource_group_name tenant_id = data.azurerm_client_config.current.tenant_id soft_delete_retention_days = 7 sku_name = "standard" # 配置网络ACL network_acls { default_action = "Deny" # 默认拒绝所有流量,仅允许指定规则 bypass = "AzureServices" # 动态生成子网访问规则 dynamic "virtual_network_rule" { for_each = var.keyvault_network_rules content { id = local.subnet_map[virtual_network_rule.value.subnet_name] action = virtual_network_rule.value.action priority = virtual_network_rule.value.priority } } } # 可按需添加访问策略等其他配置 }
核心要点说明
- 子网ID动态映射:通过
data.azurerm_virtual_network拉取VNet下所有子网数据,用本地变量subnet_map建立名称到ID的关联,彻底避免硬编码ID。 - Dynamic块批量生成规则:使用
dynamic "virtual_network_rule"遍历传入的规则列表,每个规则对应一个子网的访问控制条目,支持自定义动作和优先级。 - 参数合法性校验:在模块变量中添加校验逻辑,提前拦截非法参数,减少部署失败概率。
- 网络ACL生效前提:必须将
default_action设为Deny,否则所有流量会被默认允许,配置的规则不会生效。
常见问题排查
- 子网名称匹配失败:检查VNet名称、资源组是否正确,确认子网确实存在于该VNet中;若子网在其他资源组,需调整数据块的
resource_group_name。 - Dynamic块语法错误:确保
for_each遍历的是合法列表,content块内的参数与Azure Provider要求一致(id为子网ID,action和priority为必填项)。 - 规则不生效:验证KeyVault的防火墙是否已启用,
default_action是否设置为Deny,同时检查子网ID是否正确关联。
内容的提问来源于stack exchange,提问作者pieter-jan goeman
相关产品推荐
相关产品推荐

