You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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
      }
    }
  }

  # 可按需添加访问策略等其他配置
}

核心要点说明

  1. 子网ID动态映射:通过data.azurerm_virtual_network拉取VNet下所有子网数据,用本地变量subnet_map建立名称到ID的关联,彻底避免硬编码ID。
  2. Dynamic块批量生成规则:使用dynamic "virtual_network_rule"遍历传入的规则列表,每个规则对应一个子网的访问控制条目,支持自定义动作和优先级。
  3. 参数合法性校验:在模块变量中添加校验逻辑,提前拦截非法参数,减少部署失败概率。
  4. 网络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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 08:53:22