我在
module-1
中有一个本地块,并且想在 dev/variables.tf 上覆盖它
我尝试了一切,但没有任何效果。由于我在此 locals 块中使用多个变量,因此我需要保持这种方式而不是转换为变量。我怎样才能做到这一点?
├── _modules
│ ├── module-1
│ │ ├── main.tf
│ │ └── variables.tf
└── env
├── dev
│ ├── main.tf
│ └── variables.tf
├── staging
│ ├── main.tf
│ └── variables.tf
根据此文档,我还尝试使用 override.tf 文件,但它没有覆盖该块。
ChatGPT 表示如果这是真的,则本地变量不能在模块外部被覆盖。在这种情况下,替换 terraform 中的块的最佳实践是什么?正如我所提到的,我在这个块中使用了多个变量,并且不能为其使用变量,但与此同时,我想覆盖这个块而不是重复自己。 :思考:
编辑:
_modules/module-1/variables.tf
...
...
variable "host_address" {
type = string
}
locals {
health_checks = {
checks-1 = {
api_name = "Name X"
api_method = "GET"
host = var.host_address
custom_headers = {
Content-Type = "application/json"
}
}
checks-2 = {
api_name = "Name Y"
api_method = "POST"
host = var.host_address
custom_headers = {
Content-Type = "application/json"
}
}
# Add more checks as needed
}
}
_modules/module-1/main.tf
...
...
resource "checkly_check" "health-checks" {
for_each = local.health_checks
name = "${var.environment} - ${each.value.api_name}"
host = "${each.value.host_address}"
# ...
}
基本上,这个本地变量应该在 env/dev、env/staging 等中被覆盖。
编辑2:
env/dev/variables.tf
...
...
variable "host_address" {
type = string
}
locals {
health_checks = {
checks-1 = {
api_name = "Name Dev Test"
api_method = "GET"
host = var.host_address
custom_headers = {
Content-Type = "application/json"
}
}
}
env/staging/variables.tf
...
...
variable "host_address" {
type = string
}
variable "main_domain" {
type = string
}
locals {
health_checks = {
checks-1 = {
api_name = "Name Staging Test"
api_method = "GET"
host = var.host_address
custom_headers = {
Content-Type = "application/json"
}
checks-2 = {
api_name = "Name Staging Test 2"
api_method = "GET"
host = var.main_domain
custom_headers = {
Content-Type = "application/json"
}
}
}
checks-3 = {
api_name = "Name Staging Test 3"
api_method = "GET"
host = "www.anything.com"
custom_headers = {
Content-Type = "application/json"
}
}
}
当我将本地文件添加到 env 文件夹时,terraform 不尊重这一点,它只引用模块中的本地文件,我理解这一点,因为本地文件不会超出模块的范围。而且我不能使用变量,因为我需要引用此块中的其他变量。这就是我使用本地的原因。那么最好的方法是什么?
所以我个人在评论中也同意马修斯的观点。这应该是模块的变量。它应该只提供健康检查的抽象。然后环境应该通过他们想要的健康检查。您甚至可以定义所有环境中可能需要的常见健康检查。
foo 模块
variable "health_checks" {
type = map(object({
api_name = string
api_method = string
host = string
custom_headers = map(string)
}))
}
output "checks" {
value = var.health_checks
}
然后在你的根模块中你可以有类似的东西
variable "host_address" {
type = string
}
locals {
common_health_checks = {
checks-1 = {
api_name = "Name X"
api_method = "GET"
host = var.host_address
custom_headers = {
Content-Type = "application/json"
}
}
}
}
module "prod" {
source = "./modules/foo"
health_checks = merge(local.common_health_checks, {
checks-B = {
api_name = "Name Y"
api_method = "POST"
host = "example.com"
custom_headers = {
Content-Type = "application/json"
}
}
})
}
module "dev" {
source = "./modules/foo"
health_checks = merge(local.common_health_checks,{
checks-A = {
api_name = "Name Z"
api_method = "GET"
host = var.host_address
custom_headers = {
Content-Type = "application/json"
}
}
})
}
output "prod" {
value = module.prod.checks
}
output "dev" {
value = module.dev.checks
}
因此,每个环境都会通过自己的健康检查,但也可以使用常见的健康检查等。这会给出如下所示的输出,您可以看到不同的环境可以有不同的检查或常见的检查
Outputs:
dev = tomap({
"checks-1" = {
"api_method" = "GET"
"api_name" = "Name X"
"custom_headers" = tomap({
"Content-Type" = "application/json"
})
"host" = "foo.com"
}
"checks-A" = {
"api_method" = "GET"
"api_name" = "Name Z"
"custom_headers" = tomap({
"Content-Type" = "application/json"
})
"host" = "foo.com"
}
})
prod = tomap({
"checks-1" = {
"api_method" = "GET"
"api_name" = "Name X"
"custom_headers" = tomap({
"Content-Type" = "application/json"
})
"host" = "foo.com"
}
"checks-B" = {
"api_method" = "POST"
"api_name" = "Name Y"
"custom_headers" = tomap({
"Content-Type" = "application/json"
})
"host" = "example.com"
}
})