在我的Terraform脚本中,我有
let billable = { aanwezig: "Aanwezig", hours: 12 }
if (!this.urenRegistratie.some(x => x.aanwezig == billable.aanwezig && x.hours == billable.hours)) {
this.urenRegistratie.push(billable);
}
我运行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}"
}
时遇到以下错误:
点名后需要属性名称。
使用嵌套变量和列表对象的正确方法是什么?
答案 0 :(得分:0)
为了将资源表示为实例映射而不是实例列表,您需要使用for_each
而不是count
:
resource "azuread_application" "main" {
for_each = { for n in var.sp_names : n => "${var.sp_prefix}-${n}" }
name = each.value
available_to_other_tenants = false
}
上面的for_each
表达式是for
expression,它将您的列表或名称集转换为从给定名称到前缀名称的映射。因此,在该块的其他表达式中,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
值是从无前缀名称到代表每个已声明应用程序的对象的映射。因此, this 块中的each.key
仍然是未前缀的名称,而each.value
是我们可以从中访问application_id
值的相应应用程序对象。
如果您的var.sp_names
中包含字符串"example"
,则Terraform会将以上内容解释为创建两个名为azuread_application.main["example"]
和azuread_service_principal.main["example"]
的对象的请求,以标识这些实例通过var.sp_names
值。这与count
不同,在azuread_application.main[0]
中,实例的地址将类似于azuread_service_principal.main[0]
和for_each
。通过使用var.sp_names
,我们确保从return ''.join(y)
添加和删除项目将在这些资源中添加和删除相应的实例,而不是更新碰巧共享相同数字索引的现有实例。
答案 1 :(得分:0)
我假设您使用的版本早于0.12.x。如果不是,马丁的答案是最好的。
您需要利用喷溅。
resource "azuread_service_principal" "main" {
count = "${length(var.sp_names)}"
application_id = "${azuread_application.main.*.application_id}"
}