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
相关产品推荐
相关产品推荐

