Terraform配置google_compute_health_check动态块实现多类型兼容
Terraform通用GCP健康检查配置实现方案
需求
创建可复用的google_compute_health_check资源模块,支持动态适配TCP、HTTP、SSH等不同类型的健康检查配置,无需每次新增类型就修改核心调用逻辑。
原始配置报错原因
最初采用多健康检查批量传入模块的设计,在动态块配置环节出现三类报错,对应原因如下:
- 使用
contains函数报错:将健康检查对象直接传给动态块for_each,Terraform会遍历对象所有属性生成多个类型块,违反GCP健康检查最多只能配置1个类型块的限制 - 使用
lookup函数报错:没有匹配到对应类型参数时返回空列表,导致没有任何类型块被渲染,违反GCP健康检查必须指定至少一个类型块的要求 - 使用名称匹配条件判断报错:条件分支返回类型不统一,真分支返回对象、假分支返回空元组,不符合Terraform语法要求
最终实现方案
调整为按健康检查类型独立传参的模式,逻辑更简单,扩展性更强。
上层Terragrunt配置
application.hcl示例:
inputs = { health_checks = { nat-http = { port = 80 request_path = "/health" port_specification = "USE_FIXED_PORT" } } }
主terragrunt.hcl示例:
include { path = find_in_parent_folders() } terraform { source = "你的模块地址"} locals { app_vars = read_terragrunt_config(find_in_parent_folders("application.hcl")) } inputs = { name = "nat-health-check" used_for = "NAT实例健康检查" check_interval_sec = 30 timeout_sec = 5 healthy_threshold = 1 unhealthy_threshold = 5 // 对应类型的健康检查参数传入对应变量,不需要的类型传null即可 http_checks = local.app_vars.inputs.health_checks.nat-http tcp_checks = null ssh_checks = null }
模块配置
模块variables.tf补充变量声明:
variable "name" { type = string } variable "used_for" { type = string } variable "check_interval_sec" { type = number } variable "timeout_sec" { type = number } variable "healthy_threshold" { type = number } variable "unhealthy_threshold" { type = number } variable "http_checks" { type = object({ port = number request_path = string port_specification = string }) default = null } // 后续扩展其他类型只需新增对应变量即可 variable "tcp_checks" { type = any, default = null } variable "ssh_checks" { type = any, default = null }
模块main.tf配置:
resource "google_compute_health_check" "main" { name = var.name timeout_sec = var.timeout_sec check_interval_sec = var.check_interval_sec healthy_threshold = var.healthy_threshold unhealthy_threshold = var.unhealthy_threshold 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 } } // 后续扩展其他类型只需新增对应动态块即可 dynamic "tcp_health_check" { for_each = var.tcp_checks != null ? [1] : [] content { port = var.tcp_checks.port } } dynamic "ssl_health_check" { for_each = var.ssh_checks != null ? [1] : [] content { port = var.ssh_checks.port } } }
方案优势
- 完全符合GCP健康检查的资源约束,不会出现多类型块或者无类型块的报错
- 扩展新类型健康检查成本极低,只需新增对应变量和动态块,不影响现有调用逻辑
- 传参逻辑清晰,上层调用时只需按需传入对应类型的配置即可,无需额外处理
内容的提问来源于stack exchange,提问作者CptDolphin
相关产品推荐
相关产品推荐

