Terraform 对象中存在每个值时的地形
我想从.tfvars文件动态创建一些子网和路由表,然后将每个子网链接到关联的路由表(如果指定) 这是我的.tfvars文件:Terraform 对象中存在每个值时的地形,terraform,terraform0.12+,Terraform,Terraform0.12+,我想从.tfvars文件动态创建一些子网和路由表,然后将每个子网链接到关联的路由表(如果指定) 这是我的.tfvars文件: vnet_spoke_object = { specialsubnets = { Subnet_1 = { name = "test1"
vnet_spoke_object = {
specialsubnets = {
Subnet_1 = {
name = "test1"
cidr = ["10.0.0.0/28"]
route = "route1"
}
Subnet_2 = {
name = "test2"
cidr = ["10.0.0.16/28"]
route = "route2"
}
Subnet_3 = {
name = "test3"
cidr = ["10.0.0.32/28"]
}
}
}
route_table = {
route1 = {
name = "route1"
disable_bgp_route_propagation = true
route_entries = {
re1 = {
name = "rt-rfc-10-28"
prefix = "10.0.0.0/28"
next_hop_type = "VirtualAppliance"
next_hop_in_ip_address = "10.0.0.10"
}
}
}
route2 = {
name = "route2"
disable_bgp_route_propagation = true
route_entries = {
re1 = {
name = "rt-rfc-10-28"
prefix = "10.0.0.16/28"
next_hop_type = "VirtualAppliance"
next_hop_in_ip_address = "10.0.0.10"
}
}
}
}
…下面是我的构建脚本:
provider "azurerm" {
version = "2.18.0"
features{}
}
variable "ARM_LOCATION" {
default = "uksouth"
}
variable "ARM_SUBSCRIPTION_ID" {
default = "asdf-b31e023c78b8"
}
variable "vnet_spoke_object" {}
variable "route_table" {}
module "names" {
source = "./nbs-azure-naming-standard"
env = "dev"
location = var.ARM_LOCATION
subId = var.ARM_SUBSCRIPTION_ID
}
resource "azurerm_resource_group" "test" {
name = "${module.names.standard["resource-group"]}-vnet"
location = var.ARM_LOCATION
}
resource "azurerm_virtual_network" "test" {
name = "${module.names.standard["virtual-network"]}-test"
location = var.ARM_LOCATION
resource_group_name = azurerm_resource_group.test.name
address_space = ["10.0.0.0/16"]
}
resource "azurerm_subnet" "test" {
for_each = var.vnet_spoke_object.specialsubnets
name = "${module.names.standard["subnet"]}-${each.value.name}"
resource_group_name = azurerm_resource_group.test.name
virtual_network_name = azurerm_virtual_network.test.name
address_prefixes = each.value.cidr
}
resource "azurerm_route_table" "test" {
for_each = var.route_table
name = "${module.names.standard["route-table"]}-${each.value.name}"
location = var.ARM_LOCATION
resource_group_name = azurerm_resource_group.test.name
disable_bgp_route_propagation = each.value.disable_bgp_route_propagation
dynamic "route" {
for_each = each.value.route_entries
content {
name = route.value.name
address_prefix = route.value.prefix
next_hop_type = route.value.next_hop_type
next_hop_in_ip_address = contains(keys(route.value), "next_hop_in_ip_address") ? route.value.next_hop_in_ip_address: null
}
}
}
这一部分在创建vnet/subnet/route资源时工作得很好,但我面临的问题是将每个子网动态链接到.tfvars中列出的路由表。并非所有子网都有与之关联的路由表,因此仅当列出键/值路由时才需要运行
resource "azurerm_subnet_route_table_association" "test" {
for_each = {
for key, value in var.vnet_spoke_object.specialsubnets:
key => value
if value.route != null
}
lifecycle {
ignore_changes = [
subnet_id
]
}
subnet_id = azurerm_subnet.test[each.key].id
route_table_id = azurerm_route_table.test[each.key].id
}
我在上述代码中遇到的错误是:
Error: Unsupported attribute
on main.tf line 65, in resource "azurerm_subnet_route_table_association" "test":
65: if value.route != null
This object does not have an attribute named "route".
我尝试了各种方法,但都没有成功,我在这里不知所措,希望能提供任何指导。根据您的场景,我猜输入中的vnet_speak_对象如下所示:
vnet_spoke_object = {
specialsubnets = {
subnetA = {
cidr = "..."
}
subnetB = {
cidr = "..."
route = "..."
}
}
}
for_each = {
for key, value in var.vnet_spoke_object.specialsubnets:
key => value
if lookup(value, "route", null) != null
}
问题是丢失的路由条目不能解析为null,它会导致恐慌或崩溃。您需要像这样使用显式空值编写输入:
或按名称路由,并在for map generator表达式中提供空默认值,如下所示:
vnet_spoke_object = {
specialsubnets = {
subnetA = {
cidr = "..."
}
subnetB = {
cidr = "..."
route = "..."
}
}
}
for_each = {
for key, value in var.vnet_spoke_object.specialsubnets:
key => value
if lookup(value, "route", null) != null
}
根据您的场景,我猜输入中的vnet_speak_对象如下所示:
vnet_spoke_object = {
specialsubnets = {
subnetA = {
cidr = "..."
}
subnetB = {
cidr = "..."
route = "..."
}
}
}
for_each = {
for key, value in var.vnet_spoke_object.specialsubnets:
key => value
if lookup(value, "route", null) != null
}
问题是丢失的路由条目不能解析为null,它会导致恐慌或崩溃。您需要像这样使用显式空值编写输入:
或按名称路由,并在for map generator表达式中提供空默认值,如下所示:
vnet_spoke_object = {
specialsubnets = {
subnetA = {
cidr = "..."
}
subnetB = {
cidr = "..."
route = "..."
}
}
}
for_each = {
for key, value in var.vnet_spoke_object.specialsubnets:
key => value
if lookup(value, "route", null) != null
}
非常感谢。my.tfvars中的null部分是修复方法:DYou可以通过在变量上设置一个更明确的值,如type=mapobject{cidr=string,route=string},然后Terraform将在.tfvars文件中报告该值,如果它没有同时设置这两个属性,而不是在模块的实现中失败。谢谢。my.tfvars中的null部分是修复方法:DYou可以通过在变量上设置一个更明确的值,如type=mapobject{cidr=string,route=string},然后Terraform将在.tfvars文件中报告该值,如果它没有同时设置这两个属性,则该值无效,而不是在模块的实现中失败。