在地形中创建动态块
Create dynamic block in terraform
我想在 terraform 中创建 google_compute_health_check
,我正在考虑如何使它们成为最通用的。我的代码 atm 看起来像那样
application.hcl
inputs = {
health_checks = {
tcp-health-check = {
name = "tcp-health-check"
desc = "Health check via tcp"
port = 80
timeout_sec = 4
check_interval_sec = 30
}
}
主要terragrunt.hcl
include {
path = find_in_parent_folders()
}
terraform { source ...}
locals {
app_vars = read_terragrunt_config(find_in_parent_folders("application.hcl"))
}
inputs = {
# and my idea was that every invocation of the module, picks it's own set
# of health checks that it wants to use
health_checks = [local.app_vars.inputs.health_checks.tcp-health-check]
}
现在模块 main.tf
看起来像这样
locals {
checks = { for check in var.health_checks: check.name => check }
}
resource "google_compute_health_check" "main" {
for_each = local.checks
name = each.value.name
timeout_sec = each.value.timeout_sec
check_interval_sec = each.value.check_interval_sec
dynamic tcp_health_check {
#for_each = each.value.name == "tcp_health_check" ? each.value : []
#for_each = lookup(each.value, "tcp_health_check", [])
for_each = contains(keys(each.value), "tcp_health_check") != null ? each.value : {}
content {
port = 80
# port = each.value.port
# port_name = each.value.name
}
}
我被困在动态块中 - 如何让它工作,以便它只在我通过 tcp
health_check 时应用,当我通过时,ssh
它创建动态 ssh
块(我知道代码 atm 中没有 ssh 块,但将来我将通过我需要的任何健康检查来扩展模块)
我得到的错误如下contains
Error: List longer than MaxItems
on main.tf line 30, in resource "google_compute_health_check" "main":
30: resource "google_compute_health_check" "main" {
Attribute supports 1 item maximum, config has 7 declared
ERRO[0011] 1 error occurred:
* exit status 1
和lookup
Error: ExactlyOne
on main.tf line 30, in resource "google_compute_health_check" "main":
30: resource "google_compute_health_check" "main" {
"ssl_health_check": one of
`grpc_health_check,http2_health_check,http_health_check,https_health_check,ssl_health_check,tcp_health_check`
must be specified
ERRO[0005] 1 error occurred:
* exit status 1
与==
比较
Error: Inconsistent conditional result types
on main.tf line 44, in resource "google_compute_health_check" "main":
44: for_each = each.value.name == "tcp_health_check" ? each.value : []
|----------------
| each.value is object with 7 attributes
| each.value.name is "tcp-health-check"
The true and false result expressions must have consistent types. The given
expressions are object and tuple, respectively.
ERRO[0005] 1 error occurred:
* exit status 1
好的,用另一种方法解决了它,但感谢 Marcin 的回答
terragrunt.hcl
inputs = {
name = "nat-health-check"
used_for = "used for NATs"
check_interval_sec = 30
timeout_sec = 5
healthy_threshold = 1
unhealthy_threshold = 5
http_checks = local.app_vars.inputs.health_checks.nat-http
}
和模块main.tf
resource "google_compute_health_check" "main" {
name = var.name
timeout_sec = var.timeout_sec
check_interval_sec = var.check_interval_sec
description = "${var.name} - ${var.used_for}"
dynamic "http_health_check" {
for_each = var.http_checks != null ? [1] : []
content {
port = var.http_checks.port
request_path = var.http_checks.request_path
port_specification = var.http_checks.port_specification
}
}
}
以下
contains(keys(each.value), "tcp_health_check") != null ? each.value : {}
失败,因为当这是真的时,你的动态块 tcp_health_check
将被执行 一次 ,因为你的 each.value
只是一个值映射.你不能超过一个 tcp_health_check
块。
第二个
for_each = lookup(each.value, "tcp_health_check", [])
没有失败而且是正确的。但由于它会导致 false
,因此不会创建您的 tcp_health_check
块。这失败了,因为您没有提供任何替代块 grpc_health_check,http2_health_check,http_health_check,https_health_check,ssl_health_check,tcp_health_check
.
最后一次尝试:
for_each = each.value.name == "tcp_health_check" ? each.value : []
失败,因为它应该是 for_each = each.value.name == "tcp_health_check" ? each.value : {}
。但是,如果您修复此问题,each.value
将再次像以前一样失败。
总而言之,你总是注定要失败,因为当你像第二种情况那样消除你的障碍 tcp_health_check
时,你没有提供任何替代方案。如果您的条件是 true
,each.value
将尝试创建多个区块。
关闭的解决方案是(不考虑错误的情况,您需要提供替代方案):
dynamic tcp_health_check {
for_each = each.value.name == "tcp_health_check" ? [1] : []
content {
port = each.value.port
port_name = each.value.name
}
}
我想在 terraform 中创建 google_compute_health_check
,我正在考虑如何使它们成为最通用的。我的代码 atm 看起来像那样
application.hcl
inputs = {
health_checks = {
tcp-health-check = {
name = "tcp-health-check"
desc = "Health check via tcp"
port = 80
timeout_sec = 4
check_interval_sec = 30
}
}
主要terragrunt.hcl
include {
path = find_in_parent_folders()
}
terraform { source ...}
locals {
app_vars = read_terragrunt_config(find_in_parent_folders("application.hcl"))
}
inputs = {
# and my idea was that every invocation of the module, picks it's own set
# of health checks that it wants to use
health_checks = [local.app_vars.inputs.health_checks.tcp-health-check]
}
现在模块 main.tf
看起来像这样
locals {
checks = { for check in var.health_checks: check.name => check }
}
resource "google_compute_health_check" "main" {
for_each = local.checks
name = each.value.name
timeout_sec = each.value.timeout_sec
check_interval_sec = each.value.check_interval_sec
dynamic tcp_health_check {
#for_each = each.value.name == "tcp_health_check" ? each.value : []
#for_each = lookup(each.value, "tcp_health_check", [])
for_each = contains(keys(each.value), "tcp_health_check") != null ? each.value : {}
content {
port = 80
# port = each.value.port
# port_name = each.value.name
}
}
我被困在动态块中 - 如何让它工作,以便它只在我通过 tcp
health_check 时应用,当我通过时,ssh
它创建动态 ssh
块(我知道代码 atm 中没有 ssh 块,但将来我将通过我需要的任何健康检查来扩展模块)
我得到的错误如下contains
Error: List longer than MaxItems
on main.tf line 30, in resource "google_compute_health_check" "main":
30: resource "google_compute_health_check" "main" {
Attribute supports 1 item maximum, config has 7 declared
ERRO[0011] 1 error occurred:
* exit status 1
和lookup
Error: ExactlyOne
on main.tf line 30, in resource "google_compute_health_check" "main":
30: resource "google_compute_health_check" "main" {
"ssl_health_check": one of
`grpc_health_check,http2_health_check,http_health_check,https_health_check,ssl_health_check,tcp_health_check`
must be specified
ERRO[0005] 1 error occurred:
* exit status 1
与==
比较
Error: Inconsistent conditional result types
on main.tf line 44, in resource "google_compute_health_check" "main":
44: for_each = each.value.name == "tcp_health_check" ? each.value : []
|----------------
| each.value is object with 7 attributes
| each.value.name is "tcp-health-check"
The true and false result expressions must have consistent types. The given
expressions are object and tuple, respectively.
ERRO[0005] 1 error occurred:
* exit status 1
好的,用另一种方法解决了它,但感谢 Marcin 的回答
terragrunt.hcl
inputs = {
name = "nat-health-check"
used_for = "used for NATs"
check_interval_sec = 30
timeout_sec = 5
healthy_threshold = 1
unhealthy_threshold = 5
http_checks = local.app_vars.inputs.health_checks.nat-http
}
和模块main.tf
resource "google_compute_health_check" "main" {
name = var.name
timeout_sec = var.timeout_sec
check_interval_sec = var.check_interval_sec
description = "${var.name} - ${var.used_for}"
dynamic "http_health_check" {
for_each = var.http_checks != null ? [1] : []
content {
port = var.http_checks.port
request_path = var.http_checks.request_path
port_specification = var.http_checks.port_specification
}
}
}
以下
contains(keys(each.value), "tcp_health_check") != null ? each.value : {}
失败,因为当这是真的时,你的动态块 tcp_health_check
将被执行 一次 ,因为你的 each.value
只是一个值映射.你不能超过一个 tcp_health_check
块。
第二个
for_each = lookup(each.value, "tcp_health_check", [])
没有失败而且是正确的。但由于它会导致 false
,因此不会创建您的 tcp_health_check
块。这失败了,因为您没有提供任何替代块 grpc_health_check,http2_health_check,http_health_check,https_health_check,ssl_health_check,tcp_health_check
.
最后一次尝试:
for_each = each.value.name == "tcp_health_check" ? each.value : []
失败,因为它应该是 for_each = each.value.name == "tcp_health_check" ? each.value : {}
。但是,如果您修复此问题,each.value
将再次像以前一样失败。
总而言之,你总是注定要失败,因为当你像第二种情况那样消除你的障碍 tcp_health_check
时,你没有提供任何替代方案。如果您的条件是 true
,each.value
将尝试创建多个区块。
关闭的解决方案是(不考虑错误的情况,您需要提供替代方案):
dynamic tcp_health_check {
for_each = each.value.name == "tcp_health_check" ? [1] : []
content {
port = each.value.port
port_name = each.value.name
}
}