如何在同一个列表上迭代多个资源?
How to iterate multiple resources over the same list?
这里是 Terraform 的新手。我正在尝试使用 Terraform 创建多个项目(在 Google Cloud 中)。问题是我必须执行多个资源才能完全设置一个项目。我尝试了 count
,但如何使用 count
顺序绑定多个资源?以下是我需要为每个项目执行的以下资源:
- 使用
resource "google_project"
创建项目
- 使用
resource "google_project_service"
启用 API 服务
- 使用
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"
我使用的是不支持 for
循环的 Terraform 版本 0.11
在 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)}"
}
当然,您在这些资源声明中也会有其他配置。
请注意,此模式在 Terraform Up and Running, Chapter 5, and there are other examples of using count.index
in the docs here 中有描述。
对此 question/answer 的小更新(terraform 0.13 及更高版本)。由于 terraforms 的工作方式,不建议再使用计数或长度,让我们想象下一个场景:
假设你有一个包含 3 个元素的数组:project_list=["proj-1","proj-2","proj-3"]
,一旦你应用它,如果你想从你的数组中删除 "proj-2"
项目,一旦你 运行 计划,terraform会将您的第二个元素修改为 "proj-3"
而不是将其从列表 (more info in this good post). The solution to get the proper behavior is to use the 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
}
希望对您有所帮助!
这里是 Terraform 的新手。我正在尝试使用 Terraform 创建多个项目(在 Google Cloud 中)。问题是我必须执行多个资源才能完全设置一个项目。我尝试了 count
,但如何使用 count
顺序绑定多个资源?以下是我需要为每个项目执行的以下资源:
- 使用
resource "google_project"
创建项目
- 使用
resource "google_project_service"
启用 API 服务
- 使用
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"
我使用的是不支持 for
循环的 Terraform 版本 0.11
在 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)}"
}
当然,您在这些资源声明中也会有其他配置。
请注意,此模式在 Terraform Up and Running, Chapter 5, and there are other examples of using count.index
in the docs here 中有描述。
对此 question/answer 的小更新(terraform 0.13 及更高版本)。由于 terraforms 的工作方式,不建议再使用计数或长度,让我们想象下一个场景:
假设你有一个包含 3 个元素的数组:project_list=["proj-1","proj-2","proj-3"]
,一旦你应用它,如果你想从你的数组中删除 "proj-2"
项目,一旦你 运行 计划,terraform会将您的第二个元素修改为 "proj-3"
而不是将其从列表 (more info in this good post). The solution to get the proper behavior is to use the 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
}
希望对您有所帮助!