[英]Terraform Outputs: How do I create a (map?) and how do I use the map? Is a map even the right tool?
我正在努力解决一些 terraform 概念。
我成功地使用aztfmod/azurecaf
提供程序来命名我的资源组,但这意味着我需要为compan.net.resource_group
模块获取该名称作为 output,以便我可以在调用compan.net.key_vault
模块。
# terraform.tfvars
resource_groups = {
rg1 = {
name = "resourcegroup1"
location = "eastus"
}
rg2 = {
name = "resourcegroup2"
location = "eastus"
}
}
# root main.tf
provider "azurerm" {
features {}
}
module "companynet" {
source = "./modules/companynet"
tenant_id = var.tenant_id
environment = var.environment
resource_groups = var.resource_groups
key_vaults = var.key_vaults
storage_accounts = var.storage_accounts
app_service_plans = var.app_service_plans
}
# modules/companynet/main.tf
module "resource_group" {
source = "../companynet.resource_group"
environment = var.environment
resource_groups = var.resource_groups
}
module "key_vault" {
source = "../companynet.key_vault"
tenant_id = var.tenant_id
environment = var.environment
resource_groups = "${module.resource_group.resource_groups.companynet}"
key_vaults = var.key_vaults
}
模块resource_group
具有以下main.tf
:
# modules/companynet.resource_group/main.tf
resource "azurecaf_name" "resource_group" {
for_each = var.resource_groups
name = each.value.name
resource_type = "azurerm_resource_group"
suffixes = ["${var.environment}", "001"]
}
resource "azurerm_resource_group" "resource_group" {
for_each = var.resource_groups
name = azurecaf_name.resource_group[each.key].result
location = each.value.location
}
但我不知道如何获取该资源组名称的 output。
我尝试了一些不同的方法,但都不起作用
# modules/companynet.resource_group/outputs.tf
output "resource_groups" {
value = azurerm_resource_group.resource_group[*].name
}
value = azurerm_resource_group.resource_group.name
value = azurerm_resource_group.resource_group.compan.net.name
value = azurerm_resource_group.resource_group[compan.net].name
这些中的每一个都会导致一个或另一个错误,都表明modules/compan.net.resource_group/outputs.tf
有问题
理想情况下,我会得到一个 object,然后我可以在另一个模块中迭代它。 我希望能够调用类似的东西来访问其他模块中的那些资源组名称,例如:
# modules/companynet.key_vault/main.tf
resource "azurerm_key_vault" "key_vault" {
for_each = var.key_vaults
name = azurecaf_name.key_vault[each.key].result
location = var.resource_groups.location
resource_groups = "${module.resource_group.resource_groups.[companynet]}"
sku_name = "standard"
tenant_id = var.tenant_id
}
azurerm_resource_group.resource_group
是用for_each
声明的,因此该表达式引用 map 个对象,其中键与for_each
表达式的键匹配,值是相应声明的资源实例。
在References to Resource Attributes中有各种在不同情况下引用资源属性的示例,包括以下有关使用for_each
的资源:
当资源设置了
for_each
参数时,资源本身变为实例对象的 map 而不是单个 object,并且实例的属性必须由键指定,或者可以使用for
表达式访问。
aws_instance.example["a"].id
返回以“a”为键的资源的 ID。[for value in aws_instance.example: value.id]
返回每个实例的所有 ID 的列表。
第二项显示了如何使用for
表达式生成aws_instance.example
的 id列表,但它并未准确显示如何生成 map 而是希望您参考有关for
表达式的链接文档以了解那:
for
表达式周围括号的类型决定了它产生的结果类型。上面的示例使用
[
和],
它生成一个元组。 如果您改用{
和}
,则结果为 object,您必须提供两个由=>
符号分隔的结果表达式:{for s in var.list: s => upper(s)}
此表达式生成一个 object,其属性是
var.list
中的原始元素,它们的对应值是大写版本。 例如,结果值可能如下所示:{ foo = "FOO" bar = "BAR" baz = "BAZ" }
单独的
for
表达式只能生成 object 值或元组值,但 Terraform 的自动类型转换规则意味着您通常可以在需要列表、映射和集合的位置使用结果。
本节介绍如何生成 object,然后说明您可以在需要 map 的位置使用结果。 在实践中,通常可以在 Terraform 中互换使用对象类型值和映射类型值,因为它们的共同点是它们都具有由字符串键标识的元素。 区别在于 object 类型的每个属性可以有一个单独的类型,而 map 的所有属性必须有相同的类型。
鉴于所有这些信息,我们可以生成一个object值来描述每个资源组的名称,如下所示:
output "resource_groups" {
value = { for k, g in azurerm_resource_group.resource_group : k => g.name }
}
对于大多数用途来说,这是一个对象类型的结果而不是特定的 map 并不重要,但是由于我们知道.name
始终是一个字符串,我们可以推断出这个 object 的所有属性都具有字符串类型的值,因此使用tomap
function显式转换为 map 字符串也是有效的(根据上述文档,这是“预期 [...] 映射 [...] 的位置”):
output "resource_groups" {
value = tomap({
for k, g in azurerm_resource_group.resource_group : k => g.name
})
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.