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

将创建Azure基础设施的Ansible脚本替换为Terraform的相关问题咨询

解决方案

你描述的CIDR自动计算、跨订阅拉取现有VNET、过滤冲突网段的需求,完全可以通过Terraform原生能力实现,无需调用外部脚本或Ansible,各逻辑段的对应实现方式如下:


核心实现逻辑

  • 生成候选CIDR列表:使用Terraform内置的cidrsubnet函数,可完全替代Ansible的ipsubnet过滤器,批量生成指定基准网段下、指定前缀长度的所有可用网段。
  • 拉取所有可访问订阅:直接使用AzureRM provider的azurerm_subscriptions数据源即可获取所有订阅ID,无需调用az命令行工具。
  • 拉取各订阅现有VNET:循环遍历订阅ID,使用azurerm_virtual_networks数据源按标签筛选目标VNET,提取已占用的地址前缀。
  • 过滤冲突网段:使用Terraform内置的setsubtract函数对候选网段和已占用网段做差集,取首个可用网段即可。

参考Terraform代码

# 配置AzureRM provider,允许跨订阅访问
terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = ">=3.0.0"
    }
  }
}

provider "azurerm" {
  features {}
}

# 输入变量,对应你Ansible中的vnet_base、subnet_size
variable "vnet_base" {
  type        = string
  description = "基准CIDR网段"
  default     = "10.0.0.0/8"
}

variable "subnet_size" {
  type        = number
  description = "生成VNET的前缀长度"
  default     = 16
}

# 1. 生成所有候选VNET网段列表,对应Ansible的gen_vnet_list
locals {
  # 计算基准网段下可生成的指定前缀长度的网段总数
  vnet_count = pow(2, var.subnet_size - cidrnetmask(var.vnet_base))
  # 生成所有候选网段
  gen_vnet_list = [for i in range(local.vnet_count) : cidrsubnet(var.vnet_base, var.subnet_size - cidrnetmask(var.vnet_base), i)]
}

# 2. 拉取当前账号可访问的所有订阅,对应Ansible的subscription_list
data "azurerm_subscriptions" "all" {}

# 3. 拉取每个订阅下带deploy:ccsvnet标签的VNET,对应Ansible的existing_vnets
data "azurerm_virtual_networks" "existing" {
  for_each             = toset(data.azurerm_subscriptions.all.subscriptions[*].subscription_id)
  subscription_id      = each.value
  # 按标签筛选
  tag_filter {
    name = "deploy"
    values = ["ccsvnet"]
  }
}

# 4. 提取所有已占用的CIDR列表,对应Ansible的existing_vnet_list
locals {
  existing_vnet_list = flatten([
    for vnet_group in data.azurerm_virtual_networks.existing : [
      for vnet in vnet_group.virtual_networks : vnet.address_space[0]
    ]
  ])
  # 5. 取差集首个可用网段,对应Ansible的selected_cidr
  selected_cidr = element(setsubtract(local.gen_vnet_list, local.existing_vnet_list), 0)
}

# 后续可以直接用local.selected_cidr创建VNET
resource "azurerm_virtual_network" "example" {
  name                = "example-vnet"
  address_space       = [local.selected_cidr]
  location            = "chinanorth3"
  resource_group_name = "example-rg"
  tags = {
    deploy = "ccsvnet"
  }
}

注意事项

  • 如果所有候选网段都被占用,setsubtract会返回空列表,可提前加判断逻辑抛出明确报错,避免执行失败。
  • 如果Azure认证账号没有所有订阅的访问权限,需要提前配置对应权限或者在azurerm_subscriptions数据源中过滤指定订阅范围。

内容的提问来源于stack exchange,提问作者DeirdreRodgers

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 21:24:01