如何在同一列表上迭代多个资源?

时间:2019-05-14 19:13:35

标签: terraform terraform-provider-gcp

此处是Terraform的新功能。我正在尝试使用Terraform创建多个项目(在Google Cloud中)。问题是我必须执行多个资源才能完全建立一个项目。我尝试过count,但是如何使用count顺序绑定多个资源?这是每个项目我需要执行的以下资源:

  1. 使用resource "google_project"创建项目
  2. 使用resource "google_project_service"启用API服务
  3. 使用resource "google_compute_shared_vpc_service_project"将服务项目附加到宿主项目(我正在使用共享VPC)

如果我要创建一个项目,则此方法有效。但是,如果我将一个项目列表作为输入传递,那么如何为该列表中的每个项目依次执行所有上述资源?

例如。

输入

project_list=["proj-1","proj-2"]

依次执行以下操作:

resource "google-project" for "proj-1"
resource "google_project_service" for "proj-1"
resource "google_compute_shared_vpc_service_project" for "proj-1"

resource "google-project" for "proj-2"
resource "google_project_service" for "proj-2"
resource "google_compute_shared_vpc_service_project" for "proj-2"

我使用的Terraform版本0.11不支持for循环

2 个答案:

答案 0 :(得分:0)

在Terraform中,您可以使用count和两个插值函数element()length()来完成此操作。

首先,为模块提供一个输入变量:

variable "project_list" {
  type = "list"
}

然后,您将得到类似的内容:

resource "google_project" {
  count = "${length(var.project_list)}"
  name  = "${element(var.project_list, count.index)}"
}

resource "google_project_service" {
  count = "${length(var.project_list)}"
  name  = "${element(var.project_list, count.index)}"
}

resource "google_compute_shared_vpc_service_project" {
  count = "${length(var.project_list)}"
  name  = "${element(var.project_list, count.index)}"
}

当然,您还将在这些资源声明中拥有其他配置。

请注意,第5章Terraform Up and Running中描述了这种模式,文档here中还有使用count.index的其他示例。

答案 1 :(得分:0)

此问题/答案的小更新(terraform 0.13 及更高版本)。由于 terraforms 的工作方式,不建议再使用计数或长度,让我们想象下一个场景:

假设您有一个包含 3 个元素的数组:project_list=["proj-1","proj-2","proj-3"],一旦您应用它,如果您想在运行计划后从数组中删除 "proj-2" 项,terraform 会将您的第二个元素修改为"proj-3" 而不是从列表 (more info in this good post) 中删除它。获得正确行为的解决方案是使用 for_each 函数,如下所示:

variable "project_list" {
  type = list(string)
}

resource "google_project" {
  for_each = toset(var.project_list)
  name  = each.value
}

resource "google_project_service" {
  for_each = toset(var.project_list)
  name  = each.value
}

resource "google_compute_shared_vpc_service_project" {
  for_each = toset(var.project_list)
  name  = each.value
}

希望这有帮助! ?