Terraform自定义域创建失败时密钥库密钥无法生成的解决咨询
当azurerm_static_web_app_custom_domain创建失败时,Terraform无法获取其domain_name值,此时module.myStaticWebApp.custom_domain不是null,而是处于未解析的错误状态。由于你将这个错误值直接放入secrets map中,整个map会被标记为无效,导致依赖它的azurerm_key_vault_secret.secrets因为for_each的集合不可用,最终所有密钥都无法生成。
你之前尝试的coalesce无效,是因为它只处理null或空值,无法处理资源创建失败导致的值不可用状态。
以下是两种可行的解决思路:
思路1:让自定义域名资源可选,输出自动返回null
修改静态Web应用模块,用count控制自定义域名资源的创建状态,同时让custom_domain输出在资源未创建时返回null:
静态Web应用模块内修改:
resource "azurerm_static_web_app_custom_domain" "custom_domain" { # 通过变量控制是否创建自定义域名 count = var.enable_custom_domain ? 1 : 0 static_web_app_id = azurerm_static_web_app.static_web_app.id domain_name = var.custom_domain_name # 其他配置项... } output "default_host_name" { value = azurerm_static_web_app.static_web_app.default_host_name description = "The default URL of the Static Web App." } output "custom_domain" { # 资源未创建时返回null,否则返回域名 value = length(azurerm_static_web_app_custom_domain.custom_domain) > 0 ? azurerm_static_web_app_custom_domain.custom_domain[0].domain_name : null description = "The custom URL of the Static Web App (null if not configured)." }
调用模块时使用coalesce:
module "key_vault_secrets" { source = "../../modules/keyvault_secrets" secrets = merge(var.key_vault_secrets, { "My--Url" = coalesce(module.myStaticWebApp.custom_domain, module.myStaticWebApp.default_host_name) "other_secrets" = "other_values" }) key_vault_id = module.key_vault.id }
此时当自定义域名未创建或创建失败(且count为0),custom_domain输出为null,coalesce会自动使用default_host_name填充,整个secrets map保持有效,密钥库密钥可正常生成。
思路2:用try函数捕获错误,fallback到默认域名
如果无法修改静态Web应用模块,直接在调用时用try函数捕获custom_domain的错误,获取失败时返回默认域名:
module "key_vault_secrets" { source = "../../modules/keyvault_secrets" secrets = merge(var.key_vault_secrets, { "My--Url" = try(module.myStaticWebApp.custom_domain, module.myStaticWebApp.default_host_name) "other_secrets" = "other_values" }) key_vault_id = module.key_vault.id }
try函数会尝试获取第一个值,若失败(比如资源创建失败导致值不可用),则返回第二个值,确保secrets map始终有效,不会因单个值的错误导致所有密钥无法创建。
额外优化:过滤null值的密钥(可选)
如果希望custom_domain为null时直接跳过"My--Url"密钥的创建,可修改密钥库模块的for_each逻辑,过滤值为null的条目:
resource "azurerm_key_vault_secret" "secrets" { for_each = { for k, v in var.secrets : k => v if v != null } key_vault_id = var.key_vault_id name = each.key value = each.value }
这样当coalesce返回默认域名时正常创建密钥;若极端情况默认域名也不可用,则跳过该密钥,其他密钥仍能正常生成。
内容的提问来源于stack exchange,提问作者Ann

