Terraform跨模块传递mssql_server FQDN值报错咨询
报错根因
你遇到的Unsupported argument错误和跨模块传值逻辑无关,核心问题是azurerm_mssql_database资源本身不存在server_fqdn这个可配置参数——FQDN是SQL Server级别的属性,不是SQL Database资源的入参,你把传值逻辑写在了数据库资源的参数块内,自然会触发参数不识别的报错。
问题1解答:跨模块透传输出值完全支持
Terraform原生支持通过模块输出+变量传参的方式跨模块传递属性值,你的整体思路是可行的,只需要调整传值和引用的位置即可,修正步骤如下:
- 打开
modules/mssql_database/main.tf,直接删除azurerm_mssql_database资源块里错误的server_fqdn = var.mssql_server[each.value.sql_server].fqdn行,这个参数不需要传入数据库资源定义。 - 修改
modules/mssql_database/outputs.tf的输出逻辑,不要尝试读取不存在的database.server_fqdn属性,直接在输出层引用传入的server变量对应值即可,修正后的输出代码如下:
output "database" { value = { for db_key, database in azurerm_mssql_database.mssql_database : db_key => ({ "name" = database.name, "id" = database.id, "server_id" = database.server_id, "fqdn" = var.mssql_server[var.mssql_databases[db_key].sql_server].fqdn }) } }
注意:这里要通过
var.mssql_databases[db_key].sql_server取对应数据库关联的server key,因为for遍历的是数据库资源map,资源对象本身不存储你自定义的sql_server配置键值。
问题2解答:更合理的实现方案
根据你的模块拆分目的,可以按需选择更适配的方案:
- 最小改动方案(适配当前模块拆分逻辑):就是上面提到的修正输出逻辑的方案,不需要调整现有模块边界,只需要把属性透传的逻辑从资源参数层移到输出层即可,适合你需要独立复用mssql_server、mssql_database两个模块的场景。
额外建议:给所有变量补全明确的类型约束,比如mssql_server变量可以定义为map(object({id = string, fqdn = string})),既可以在plan阶段提前校验传参类型,也能在写代码时获得IDE的属性提示,减少笔误。 - 模块合并方案(适配强生命周期绑定场景):如果你的SQL Server和下属数据库是固定绑定的生命周期(不会单独复用SQL Server给其他独立场景使用),可以把
azurerm_mssql_database资源直接合并到mssql_server模块内,统一输出server和下属数据库的所有属性,省去跨模块传参的冗余配置。 - 职责拆分优化方案(适配多环境复用场景):不要在数据库模块内拼接连接字符串,把连接字符串的拼接逻辑放到调用两个模块的上层组合层(比如根模块、应用部署层模块)。因为连接字符串通常还包含账号密码、端口、加密开关、连接超时等差异化配置,这些配置不属于数据库资源本身的属性,放在上层拼接可以大幅提升灵活性,不需要为了调整连接串格式反复修改底层资源模块。
内容的提问来源于stack exchange,提问作者TheWellington
相关产品推荐
相关产品推荐

