Terraform 模块:使用模块创建多个资源并相互引用
Terraform modules: creating multiple resources with modules and reference each other
我定义了一个变量tenants
,它是一个映射:
variable tenants {
type = map
default = {
tenant1 = {
name = "Tenant1"
},
tenant2 = {
name = "Tenant2"
}
}
}
在根文件中,我调用了一个模块tenant
如下:
module "tenant" {
source = "./modules/tenant"
for_each = var.tenants
tenant = each.value.name
}
子模块tenant
如下所示:
resource "mso_tenant" "tenant" {
name = var.tenant
}
并且我在子模块中定义了一个输出:
output "mso_tenant" {
value = mso_tenant.tenant
在 root 下的输出文件中,我执行以下操作以打印所有租户:
output "tenant_names" {
value = { for p in sort(keys(var.tenants)) : p => module.tenant[p].mso_tenant.name }
}
到目前为止一切顺利,以上都有效。
现在我有另一个名为 schemas
的变量,也是一张地图。一个租户可以有多个模式。所以我定义了以下
variable schemas {
type = map
default = {
schema1 = {
name = "Schema1",
template_name = "Template1",
tenant = <refer to tenant1> <==== refer to tenant module
},
schema2 = {
name = "Schema2"
template_name = "Template2",
tenant = <refer to tenant2> <==== refer to tenant module
},
schema3 = {
name = "Schema3"
template_name = "Template3",
tenant = <refer to tenant1> <==== refer to tenant module
},
}
}
在 root 下的 main.tf 文件中,我想执行以下操作:
module "schema" {
source = "./modules/schema"
for_each = var.schemas
name = each.value.name
template_name = each.value.template_name
tenant_id = each.value.tenant
}
我如何在架构变量中或直接在架构模块中引用各个租户?
更新:
已尝试解决方案 1:
在变量文件中,我按如下方式传递了租户:
schema1 = {
name = "Schema1",
template_name = "Template1",
tenant = module.tenant["tenant1"].mso_tenant
}
Error: Variables not allowed
已尝试解决方案 2:
module "tenant" {
source = "./modules/tenant"
for_each = var.tenants
tenant = each.value.name
}
module "schema" {
source = "./modules/schema"
for_each = var.schemas
name = each.value.name
template_name = each.value.template_name
tenant_id = module.tenant[each.value.tenant].mso_tenant
}
导致以下错误:
on main.tf line 30, in module "schema":
30: tenant_id = module.tenant[each.value.tenant].mso_tenant
|----------------
| each.value is object with 2 attributes
This object does not have an attribute named "tenant".
如果你想引用 tenant1
的租户资源,你可以使用 module.tenant["tenant1"].mso_tenant
并将其直接分配给模式或在第二个模块的输入变量中。
当您使用模块 for_each
时,module.tenant
是由 tenant_id 键控的对象映射。每个对象都包含租户子模块的所有输出。
重构:
根变量定义:
variable tenants {
type = map
default = {
tenant1 = {
name = "Tenant1"
},
tenant2 = {
name = "Tenant2"
}
}
}
variable schemas {
type = map
default = {
schema1 = {
name = "Schema1",
template_name = "Template1",
tenant_id = "tenant1"
},
schema2 = {
name = "Schema2"
template_name = "Template2",
tenant_id = "tenant2"
},
schema3 = {
name = "Schema3"
template_name = "Template3",
tenant_id = "tenant1"
},
}
}
在根目录中像这样调用模块:
module "tenant" {
source = "./modules/tenant"
for_each = var.tenants
tenant = each.value.name
}
module "schema" {
source = "./modules/schema"
for_each = var.schemas
name = each.value.name
template_name = each.value.template_name
tenant = module.tenant[each.value.tenant_id].mso_tenant
}
root 输出定义可能如下所示:
output "tenant_names" {
value = { for p in sort(keys(var.tenants)) : p => module.tenant[p].mso_tenant.name }
}
output "schemas" {
value = module.schema
}
这会导致以下输出:
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
schemas = {
"schema1" = {
"schema" = {
"name" = "Schema1"
"template_name" = "Template1"
"tenant" = {
"name" = "Tenant1"
}
}
}
"schema2" = {
"schema" = {
"name" = "Schema2"
"template_name" = "Template2"
"tenant" = {
"name" = "Tenant2"
}
}
}
"schema3" = {
"schema" = {
"name" = "Schema3"
"template_name" = "Template3"
"tenant" = {
"name" = "Tenant1"
}
}
}
}
tenant_names = {
"tenant1" = "Tenant1"
"tenant2" = "Tenant2"
}
用于模拟的架构模块:
variable "name" {
type = string
}
variable "template_name" {
type = string
}
variable "tenant" {
type = any
}
output "schema" {
value = {
name = var.name
template_name = var.template_name
tenant = var.tenant
}
}
用于模拟的租户模块:
variable "tenant" {
type = string
}
locals {
mso_tenant = {
tenant = {
name = var.tenant
}
}
}
output "mso_tenant" {
value = local.mso_tenant.tenant
}
希望在完整的上下文中这更容易、更清楚;)
我定义了一个变量tenants
,它是一个映射:
variable tenants {
type = map
default = {
tenant1 = {
name = "Tenant1"
},
tenant2 = {
name = "Tenant2"
}
}
}
在根文件中,我调用了一个模块tenant
如下:
module "tenant" {
source = "./modules/tenant"
for_each = var.tenants
tenant = each.value.name
}
子模块tenant
如下所示:
resource "mso_tenant" "tenant" {
name = var.tenant
}
并且我在子模块中定义了一个输出:
output "mso_tenant" {
value = mso_tenant.tenant
在 root 下的输出文件中,我执行以下操作以打印所有租户:
output "tenant_names" {
value = { for p in sort(keys(var.tenants)) : p => module.tenant[p].mso_tenant.name }
}
到目前为止一切顺利,以上都有效。
现在我有另一个名为 schemas
的变量,也是一张地图。一个租户可以有多个模式。所以我定义了以下
variable schemas {
type = map
default = {
schema1 = {
name = "Schema1",
template_name = "Template1",
tenant = <refer to tenant1> <==== refer to tenant module
},
schema2 = {
name = "Schema2"
template_name = "Template2",
tenant = <refer to tenant2> <==== refer to tenant module
},
schema3 = {
name = "Schema3"
template_name = "Template3",
tenant = <refer to tenant1> <==== refer to tenant module
},
}
}
在 root 下的 main.tf 文件中,我想执行以下操作:
module "schema" {
source = "./modules/schema"
for_each = var.schemas
name = each.value.name
template_name = each.value.template_name
tenant_id = each.value.tenant
}
我如何在架构变量中或直接在架构模块中引用各个租户?
更新:
已尝试解决方案 1:
在变量文件中,我按如下方式传递了租户:
schema1 = {
name = "Schema1",
template_name = "Template1",
tenant = module.tenant["tenant1"].mso_tenant
}
Error: Variables not allowed
已尝试解决方案 2:
module "tenant" {
source = "./modules/tenant"
for_each = var.tenants
tenant = each.value.name
}
module "schema" {
source = "./modules/schema"
for_each = var.schemas
name = each.value.name
template_name = each.value.template_name
tenant_id = module.tenant[each.value.tenant].mso_tenant
}
导致以下错误:
on main.tf line 30, in module "schema":
30: tenant_id = module.tenant[each.value.tenant].mso_tenant
|----------------
| each.value is object with 2 attributes
This object does not have an attribute named "tenant".
如果你想引用 tenant1
的租户资源,你可以使用 module.tenant["tenant1"].mso_tenant
并将其直接分配给模式或在第二个模块的输入变量中。
当您使用模块 for_each
时,module.tenant
是由 tenant_id 键控的对象映射。每个对象都包含租户子模块的所有输出。
重构:
根变量定义:
variable tenants {
type = map
default = {
tenant1 = {
name = "Tenant1"
},
tenant2 = {
name = "Tenant2"
}
}
}
variable schemas {
type = map
default = {
schema1 = {
name = "Schema1",
template_name = "Template1",
tenant_id = "tenant1"
},
schema2 = {
name = "Schema2"
template_name = "Template2",
tenant_id = "tenant2"
},
schema3 = {
name = "Schema3"
template_name = "Template3",
tenant_id = "tenant1"
},
}
}
在根目录中像这样调用模块:
module "tenant" {
source = "./modules/tenant"
for_each = var.tenants
tenant = each.value.name
}
module "schema" {
source = "./modules/schema"
for_each = var.schemas
name = each.value.name
template_name = each.value.template_name
tenant = module.tenant[each.value.tenant_id].mso_tenant
}
root 输出定义可能如下所示:
output "tenant_names" {
value = { for p in sort(keys(var.tenants)) : p => module.tenant[p].mso_tenant.name }
}
output "schemas" {
value = module.schema
}
这会导致以下输出:
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
schemas = {
"schema1" = {
"schema" = {
"name" = "Schema1"
"template_name" = "Template1"
"tenant" = {
"name" = "Tenant1"
}
}
}
"schema2" = {
"schema" = {
"name" = "Schema2"
"template_name" = "Template2"
"tenant" = {
"name" = "Tenant2"
}
}
}
"schema3" = {
"schema" = {
"name" = "Schema3"
"template_name" = "Template3"
"tenant" = {
"name" = "Tenant1"
}
}
}
}
tenant_names = {
"tenant1" = "Tenant1"
"tenant2" = "Tenant2"
}
用于模拟的架构模块:
variable "name" {
type = string
}
variable "template_name" {
type = string
}
variable "tenant" {
type = any
}
output "schema" {
value = {
name = var.name
template_name = var.template_name
tenant = var.tenant
}
}
用于模拟的租户模块:
variable "tenant" {
type = string
}
locals {
mso_tenant = {
tenant = {
name = var.tenant
}
}
}
output "mso_tenant" {
value = local.mso_tenant.tenant
}
希望在完整的上下文中这更容易、更清楚;)