Terraform模块:使用模块创建多个资源并相互引用

Terraform模块:使用模块创建多个资源并相互引用,terraform,terraform0.12+,Terraform,Terraform0.12+,我定义了一个变量tenants,它是一个映射: variable tenants { type = map default = { tenant1 = { name = "Tenant1" }, tenant2 = { name = "Tenant2" } } } 在根文件中,我调用模块tenant,如下所示: module "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
}
resource "mso_tenant" "tenant" {
  name            = var.tenant
}
    schema1 = {
      name          = "Schema1",
      template_name = "Template1",
      tenant        = module.tenant["tenant1"].mso_tenant
    }
子模块
tenant
如下所示:

module "tenant" {
  source = "./modules/tenant"

  for_each     =    var.tenants
  tenant = each.value.name
}
resource "mso_tenant" "tenant" {
  name            = var.tenant
}
    schema1 = {
      name          = "Schema1",
      template_name = "Template1",
      tenant        = module.tenant["tenant1"].mso_tenant
    }
我在子模块中定义了一个输出:

output "mso_tenant" {
  value = mso_tenant.tenant
在根目录下的输出文件中,我执行以下操作以打印所有租户:

output "tenant_names" {
    value       = { for p in sort(keys(var.tenants)) : p => module.tenant[p].mso_tenant.name }
}
到目前为止,一切都很好

现在我有了另一个名为
schemas
的变量,也是一个map。租户可以有多个架构。因此,我定义了以下内容

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
    },
  }
}
如何在模式变量中引用相应的租户,或者直接在模式模块中引用

更新:

解决方案1:

在变量文件中,我传递了租户,如下所示:

module "tenant" {
  source = "./modules/tenant"

  for_each     =    var.tenants
  tenant = each.value.name
}
resource "mso_tenant" "tenant" {
  name            = var.tenant
}
    schema1 = {
      name          = "Schema1",
      template_name = "Template1",
      tenant        = module.tenant["tenant1"].mso_tenant
    }
错误:不允许使用变量

解决方案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
并将其直接分配给架构或第二个模块的输入变量

当您为每个
模块使用模块时。租户
是由租户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
}
根输出定义可能如下所示:

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
}

租户模块用于模拟:

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
}


希望在完整的背景下,这更容易、更清楚;)

如果要引用
tenant1
的租户资源,可以使用
module.tenant[“tenant1”].mso_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
}
根输出定义可能如下所示:

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
}

租户模块用于模拟:

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
}


希望在完整的背景下,这更容易、更清楚;)

非常感谢。选项1(通过变量文件):我返回
这里可能不使用变量。
似乎无法在变量文件中使用module.tenant。在选项2上:我总是
此对象没有名为“tenant”的属性。
原始问题已更新以反映这一点。我的坏。。尝试使用
值(var.schemas)
以获得原始映射的值列表。编辑我的答案以反映这一点它抱怨
值(var.schemas)
,并显示以下消息:
给定的“for\u each”参数值不合适:“for\u each”参数必须是一个映射或字符串集,并且您提供了一个对象列表类型的值。
。然而,我的模式变量是一个映射。因为这太复杂了,无法将所有的东西放在一起,所以我将添加一个完整的工作示例,用局部变量模拟实际的资源;)很抱歉给你添麻烦。。我还添加了子模块si,用于在不实际创建资源的情况下模拟行为,并附加应用程序运行的输出(为此使用terraform 0.13.5),非常感谢。选项1(通过变量文件):我返回
这里可能不使用变量。
似乎无法在变量文件中使用module.tenant。在选项2上:我总是
此对象没有名为“tenant”的属性。
原始问题已更新以反映这一点。我的坏。。尝试使用
值(var.schemas)
以获得原始映射的值列表。编辑我的答案以反映这一点它抱怨
值(var.schemas)
,并显示以下消息:
给定的“for\u each”参数值不合适:“for\u each”参数必须是一个映射或字符串集,并且您提供了一个对象列表类型的值。
。然而,我的模式变量是一个映射。因为这太复杂了,无法将所有的东西放在一起,所以我将添加一个完整的工作示例,用局部变量模拟实际的资源;)很抱歉给你添麻烦。。我还添加了子模块si,用于在不实际创建资源的情况下模拟行为,并附加应用程序运行的输出(为此使用terraform 0.13.5)