You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Terraform使用regex时报错:字符串模板需传入字符串类型

问题描述

使用Terraform处理sops导入的密钥数据时遇到以下问题:

  • sops导入后密钥键的分隔符从/变为.,已通过replace将.转回/并修正.yaml格式
  • 尝试用正则提取键的最后一段作为Vault密钥名称时,报错:Cannot include the given value in a string template: string required
  • 但在Terraform控制台单独测试该正则时,能正常返回预期结果

相关数据结构与代码

原始sops数据结构

+ data_output = [
      + "key=ASA/DCSDCS value=secret1",
      + "key=CEFD/CDSSD value=secret2",
      + "key=SDFSDF/CSDCSSCD Id value=secret5",
      + "key=BBB/CSDCSSC.yaml value=secret4",
      + "key=sdfksdflk/sfsdfsdf/sdfsdf/kjfdsakhfsd.yaml value=secret6"
    ]

Terraform导入后的数据结构

+ data_output = [
      + "key=ASA.DCSDCS value=secret1",
      + "key=CEFD.CDSSD value=secret2",
      + "key=SDFSDF.CSDCSSCD Id value=secret5",
      + "key=BBB.CSDCSSC.yaml value=secret4",
      + "key=sdfksdflk.sfsdfsdf.sdfsdf.kjfdsakhfsd.yaml value=secret6"
    ]

初始处理代码(正常运行)

output "data_output" {
  value = [for k, v in nonsensitive(data.sops_file.secrets.data) : "key=${replace(replace(k, ".", "/"), "/yaml", ".yaml")} value=${v}"]
}

报错的代码

output "secret_output" {
  value = [for k, v in nonsensitive(data.sops_file.account_secrets.data) : "path=${regex("/([^/]+)/?$", replace(replace(k, ".", "/"), "/yaml", ".yaml"))} | data = ${v}"]
}

Terraform控制台测试结果

> regex("/([^/]+)/?$", "fgdfsdf/sfsdfsdfsd/dsfsdfsdfs/gff0fff-fff-ff-dsfssd-cscsd.yaml")
[
  "gff0fff-fff-ff-dsfssd-cscsd.yaml",
]

问题原因与解决办法

原因

Terraform的regex()函数返回的是匹配结果的列表,而非单个字符串。控制台测试时可见列表形式,但字符串模板要求传入单个字符串值,因此触发类型不匹配报错。

解决方法

通过提取列表首个元素,将正则结果转为字符串即可:

方法1:用element()提取列表首项

output "secret_output" {
  value = [for k, v in nonsensitive(data.sops_file.account_secrets.data) : 
    "path=${element(regex("/([^/]+)/?$", replace(replace(k, ".", "/"), "/yaml", ".yaml")), 0)} | data = ${v}"
  ]
}

方法2:改用regexall()并取索引0

output "secret_output" {
  value = [for k, v in nonsensitive(data.sops_file.account_secrets.data) : 
    "path=${regexall("/([^/]+)/?$", replace(replace(k, ".", "/"), "/yaml", ".yaml"))[0]} | data = ${v}"
  ]
}

优化可读性建议

可以用let简化嵌套的replace调用:

output "secret_output" {
  value = [for k, v in nonsensitive(data.sops_file.account_secrets.data) : 
    let processed_key = replace(replace(k, ".", "/"), "/yaml", ".yaml")
    in "path=${element(regex("/([^/]+)/?$", processed_key), 0)} | data = ${v}"
  ]
}

内容的提问来源于stack exchange,提问作者PsySkeletor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 03:23:31