Terraform中使用count控制Azure密钥获取及模板渲染的报错解决
问题分析与修正方案
错误原因
你遇到的错误由三个核心问题导致:
- 数据源名称错误:Terraform中没有
template_files数据源,正确名称是template_file(单数形式)。 - 属性引用错误:你错误引用了Key Vault的ID,而非密钥的明文值,应该取
azurerm_key_vault_secret的value属性。 - 语法格式错误:Terraform中
count赋值无需用${}包裹变量,直接写count = var.cnt即可。
修正方案(基础版)
以下代码修复了上述问题,通过var.cnt(0或1)控制是否执行密钥获取与模板生成:
# 假设已正确定义data.azurerm_key_vault.keyvault data "azurerm_key_vault_secret" "win_admin_pass" { count = var.cnt # 0=不执行,1=执行 name = "vm-winpw" key_vault_id = data.azurerm_key_vault.keyvault.id } data "template_file" "wininv" { count = var.cnt template = file("ansible/inventory.tpl") vars = { winpw = data.azurerm_key_vault_secret.win_admin_pass[count.index].value } } resource "local_file" "wininv" { count = var.cnt content = data.template_file.wininv[count.index].rendered filename = "ansible/inventory.cfg" }
简化方案(推荐)
用Terraform内置的templatefile函数替代template_file数据源,减少代码层级:
# 假设已正确定义data.azurerm_key_vault.keyvault data "azurerm_key_vault_secret" "win_admin_pass" { count = var.cnt name = "vm-winpw" key_vault_id = data.azurerm_key_vault.keyvault.id } resource "local_file" "wininv" { count = var.cnt content = templatefile("ansible/inventory.tpl", { winpw = data.azurerm_key_vault_secret.win_admin_pass[count.index].value }) filename = "ansible/inventory.cfg" }
进阶方案:自动判断密钥是否存在
如果不想手动传入var.cnt,可以通过Azure CLI判断密钥是否存在,自动控制流程:
# 通过az cli检查密钥是否存在 data "external" "secret_exists" { program = ["az", "keyvault", "secret", "show", "--name", "vm-winpw", "--vault-name", data.azurerm_key_vault.keyvault.name, "--query", "id", "--output", "tsv"] lifecycle { ignore_changes = all } } # 推导密钥存在状态 locals { secret_exists = try(length(data.external.secret_exists.result) > 0, false) } # 仅当密钥存在时获取密钥 data "azurerm_key_vault_secret" "win_admin_pass" { count = local.secret_exists ? 1 : 0 name = "vm-winpw" key_vault_id = data.azurerm_key_vault.keyvault.id } # 仅当密钥存在时生成模板文件 resource "local_file" "wininv" { count = local.secret_exists ? 1 : 0 content = templatefile("ansible/inventory.tpl", { winpw = data.azurerm_key_vault_secret.win_admin_pass[0].value }) filename = "ansible/inventory.cfg" }
注意事项
- 进阶方案需要环境中已配置Azure CLI并授权访问Key Vault。
- 若使用Terraform 0.13+版本,
try函数可用于捕获命令执行失败的情况,避免流程中断。
内容的提问来源于stack exchange,提问作者Nullpointer
相关产品推荐
相关产品推荐

