Terraform中通过JSON映射实现正则匹配与循环获取OU值
问题需求
我有如下ou.json文件(可按需调整结构),选择JSON格式是因其与Terraform兼容性较好。希望在Terraform中遍历该文件内的所有正则表达式,若正则匹配指定测试主机名testcomputer(示例值为nyhyp-p29),则将对应的ou值存入本地变量test_computer_ou。另外,JSON中的转义符\处理可能存在问题,在命令式语言中我会用switch/case处理,但不确定如何用HCL实现。已有部分初始Terraform代码,但不知如何继续完成逻辑:
ou.json:
{ "ProdInf": { "regex": "/^(?i)nyinf-p(\\d+)/", "ou": "OU=Inf,OU=Prod,OU=Servers,DC=example,DC=local" }, "ProdHyperV": { "regex": "/^(?i)nyhyp-p(\\d+)/", "ou": "OU=HyperV,OU=Prod,OU=Servers,DC=example,DC=local" }, "ProdRDS": { "regex": "/^(?i)nyrds-p(\\d+)/", "ou": "OU=RDS,OU=Prod,OU=Servers,DC=example,DC=local" } }
初始Terraform代码:
locals { testcomputer = "nyhyp-p29" map1 = jsondecode(file("./ou.json")) # started to play with loops here, but not really sure how to do what I am want. oulist = [for ou in local.map1 : ou].*.ou regexlist = [for regex in local.map1 : regex].*.regex test_computer_ou = # this is the desired value I am trying to get }
解决方案
1. 处理JSON正则的转义与格式问题
原JSON中的正则表达式带有/包裹和(?i)内联标志,且\\d+经过jsondecode后会变为\d+,符合Terraform正则语法。Terraform的regex()函数支持通过flags参数指定匹配规则(比如不区分大小写),可先从字符串中提取正则模式和标志:
- 去掉首尾的
/ - 提取
(?i)作为不区分大小写的标志,剩余部分作为匹配模式
2. 编写HCL匹配逻辑
使用Terraform的for表达式遍历所有规则,过滤出匹配testcomputer的项,再提取对应的ou值。如果确保只有一个匹配项,可用one()函数返回唯一结果;若允许多个匹配,可直接返回列表。
完整代码
locals { testcomputer = "nyhyp-p29" # 读取并解析JSON文件 ou_rules = jsondecode(file("./ou.json")) # 将map转换为列表,方便遍历 ou_rules_list = values(local.ou_rules) # 过滤出匹配测试主机名的规则 matching_ou = [ for rule in local.ou_rules_list : rule.ou if regex( # 提取正则模式:去掉首尾的/,并移除(?i)内联标志 replace(rule.regex, "/^\\(?i\\)|\\/$/", ""), local.testcomputer, # 指定不区分大小写的匹配标志 "i" ) ] # 获取唯一匹配的OU值(若确保只有一个匹配) test_computer_ou = one(local.matching_ou) # 若允许多个匹配,直接用local.matching_ou即可 }
代码说明
values(local.ou_rules):将JSON解析后的map转为规则列表,方便遍历replace(rule.regex, "/^\\(?i\\)|\\/$/", ""):移除正则字符串首尾的/和开头的(?i)内联标志,得到纯匹配模式regex(..., local.testcomputer, "i"):使用不区分大小写标志匹配主机名one(local.matching_ou):确保返回唯一匹配结果,若没有匹配或多个匹配会抛出错误,符合多数场景需求
内容的提问来源于stack exchange,提问作者rismoney
相关产品推荐
相关产品推荐

