在terraform中使用嵌套变量的正确方法

在terraform中使用嵌套变量的正确方法,terraform,terraform-provider-azure,Terraform,Terraform Provider Azure,在我的地形脚本中,我有 resource "azuread_application" "main" { count = "${length(var.sp_names)}" name = "${sp_prefix}-${var.sp_names[count.index]}" available_to_other_tenants = false } resource "azuread_service_principal" "main" {

在我的地形脚本中,我有

resource "azuread_application" "main" {
  count           = "${length(var.sp_names)}"
  name            = "${sp_prefix}-${var.sp_names[count.index]}"

  available_to_other_tenants = false
}

resource "azuread_service_principal" "main" {
  count           = "${length(var.sp_names)}"
  application_id  = "${azuread_application.main.["${sp_prefix}"-"${var.sp_names[count.index]}"].application_id}"
}
当我运行
terraforminit
时,我得到以下错误:

点后面需要一个属性名


使用嵌套变量和列表对象的正确方法是什么?

为了将资源表示为实例映射而不是实例列表,您需要使用而不是:

上述每个表达式的
都是一个将列表或名称集转换为从给定名称到前缀名称的映射的表达式。因此,在该块中的其他表达式中,
each.key
将生成原始给定名称,
each.value
将生成前缀名称

然后,您可以类似地使用
for_each
声明意图“为每个应用程序创建一个服务主体”,方法是将应用程序资源的映射本身用作服务主体资源的
for each
表达式:

resource "azuread_service_principal" "main" {
  for_each = azuread_application.main

  application_id  = each.value.application_id
}
在本例中,
azuread_application.main
值是从非固定名称到表示每个已声明应用程序的对象的映射。因此,此块中的
each.key
再次是未固定的名称,但
each.value
是相应的应用程序对象,我们可以从中访问
application\u id


如果您的
var.sp_name
中有一个字符串
“example”
,则Terraform会将上述内容解释为创建两个名为
azuread_application.main[“example”]
azuread_service_principal.main[“example”]
的对象的请求,通过
var.sp_name
值标识这些实例。这与
count
不同,在
azuread\u application.main[0]
azuread\u service\u principal.main[0]
中的实例都有地址。通过使用
for_each
,我们确保从
var.sp_names
添加和删除项目将从这些资源中添加和删除相应的实例,与其更新碰巧共享相同数字索引的现有资源,不如使用以下方法将资源表示为实例映射而不是实例列表:

上述每个
表达式的
都是一个将列表或名称集转换为从给定名称到前缀名称的映射的表达式。因此,在该块中的其他表达式中,
each.key
将生成原始给定名称,
each.value
将生成前缀名称

然后,您可以类似地使用
for_each
声明意图“为每个应用程序创建一个服务主体”,方法是将应用程序资源的映射本身用作服务主体资源的
for each
表达式:

resource "azuread_service_principal" "main" {
  for_each = azuread_application.main

  application_id  = each.value.application_id
}
在本例中,
azuread_application.main
值是从非固定名称到表示每个已声明应用程序的对象的映射。因此,此块中的
each.key
再次是未固定的名称,但
each.value
是相应的应用程序对象,我们可以从中访问
application\u id


如果您的
var.sp_name
中有一个字符串
“example”
,则Terraform会将上述内容解释为创建两个名为
azuread_application.main[“example”]
azuread_service_principal.main[“example”]
的对象的请求,通过
var.sp_name
值标识这些实例。这与
count
不同,在
azuread\u application.main[0]
azuread\u service\u principal.main[0]
中的实例都有地址。通过使用
for_each
,我们可以确保从
var.sp_names
中添加和删除项目将从这些资源中添加和删除相应的实例,而不是更新碰巧共享相同数字索引的现有实例。

我假设您使用的是0.12.x的旧版本。如果不是,马丁的回答是最好的

你需要充分利用铺张浪费

resource "azuread_service_principal" "main" {
  count           = "${length(var.sp_names)}"
  application_id  = "${azuread_application.main.*.application_id}"
}

我假设您使用的版本比0.12.x旧。如果不是,马丁的回答是最好的

你需要充分利用铺张浪费

resource "azuread_service_principal" "main" {
  count           = "${length(var.sp_names)}"
  application_id  = "${azuread_application.main.*.application_id}"
}

您使用的是哪一版本的Terraform?下面的答案与0.12.x有关。我假设你正在使用。你正在使用哪一版本的地形?下面的答案与0.12.x有关。我假设你正在使用。