Terraform variable引用locals值不生效问题排查
问题原因
你遇到的DNS解析报错核心是三个配置错误:
- 你在
app_environments_vars变量的默认值中,将local.grafana-db-address、local.gra-db-user这类Terraform表达式写在了双引号内,Terraform会将其识别为普通字符串,不会做表达式求值,最终传给容器的数据库主机值就是字面量local.grafana-db-address,自然无法通过DNS解析。 - 数据库地址拼接的分隔符使用错误,MySQL连接要求主机和端口用冒号
:分隔,你当前用.拼接,就算表达式引用正确,最终得到的地址格式也是数据库端点.3306,不符合连接格式要求。 - Terraform的
variable默认值只支持静态常量,不支持引用其他资源、local值或其他变量的动态结果,你把动态引用写在variable默认值里本身就不符合Terraform的语法逻辑。
另外terraform plan不报错是因为plan阶段只会校验Terraform配置的语法合法性,不会校验你传入容器的环境变量业务值是否有效,所以这类运行时配置错误不会在plan阶段暴露。
修复方案
- 保留原有数据库用户名、密码、端口的变量定义,将动态环境变量的生成逻辑从variable块移到local块中,修正地址拼接分隔符。
- 修改任务定义中的引用,指向local块生成的最终环境变量列表。
修正后的配置代码如下:
// 原有变量定义保持不变,修改app_environments_vars的默认值为空列表即可 variable "username_grafana" { description = "The username for the DB grafana user" type = string sensitive = true } variable "password_grafana" { description = "The password for the DB grafana password" type = string sensitive = true } variable "db-port" { description = "Port for the sql db" type = string default = "3306" } variable "app_environments_vars" { type = list(map(string)) description = "Extra custom environment variables needed by Grafana" default = [] } // 统一在local块处理所有动态值计算 locals { gra-db-user = var.username_grafana gra-db-password = var.password_grafana db-address = aws_db_instance.grafana-db.address // 修正分隔符为冒号,符合MySQL HOST:PORT格式要求 grafana-db-address = "${local.db-address}:${var.db-port}" // 合并自定义环境变量和数据库默认环境变量,这里的Terraform表达式会被正常求值 app_runtime_envs = concat(var.app_environments_vars, [ { name = "GF_DATABASE_TYPE", value = "mysql" }, { name = "GF_DATABASE_HOST", value = local.grafana-db-address }, { name = "GF_DATABASE_USER", value = local.gra-db-user }, { name = "GF_DATABASE_PASSWORD", value = local.gra-db-password } ]) }
修改任务定义中的环境变量引用,替换为local生成的动态列表:
"environment": ${jsonencode(local.app_runtime_envs)},
修改完成后重新执行terraform plan就能看到GF_DATABASE_HOST等值已经被替换为真实的数据库端点和端口,应用配置后容器就能正常连接数据库了。
内容的提问来源于stack exchange,提问作者Christine M
相关产品推荐
相关产品推荐

