如何通过Terraform自动迭代AWS WAF规则优先级数值?
自动生成WAF RuleGroup规则优先级
我当前使用Terraform动态创建WAF RuleGroup规则,代码片段如下:
dynamic "rule" { for_each = toset(var.external_endpoints) content { name = rule.value.name priority = rule.value.priority statement { byte_match_statement { positional_constraint = "STARTS_WITH" search_string = rule.value.path field_to_match { uri_path {} } text_transformation { priority = 0 type = "NONE" } } } action { allow {} } visibility_config { cloudwatch_metrics_enabled = true metric_name = rule.value.name sampled_requests_enabled = true } } }
但每次新增规则时,都需要手动修改external_endpoints变量中所有现有规则的优先级值:
external_endpoints = [ {"name" = "App1Access", "path" = "/api/", "priority" = 5}, {"name" = "App2Access", "path" = "/random", "priority" = 6}, {"name" = "App3Access", "path" = "/tech", "priority" = 7}, {"name" = "App4Access", "path" = "/condition", "priority" = 8}, {"name" = "App5Access", "path" = "/account-id", "priority" = 9}, {"name" = "App6Access", "path" = "/password", "priority" = 10}, ]
希望通过Terraform内置的range函数自动处理优先级,不清楚具体实现方式或是否有更直接的方案。
解决方案
方法1:基于列表索引自动生成连续优先级
首先修改变量定义,移除priority字段,只保留必要的name和path:
variable "external_endpoints" { type = list(object({ name = string path = string })) default = [ {"name" = "App1Access", "path" = "/api/"}, {"name" = "App2Access", "path" = "/random"}, {"name" = "App3Access", "path" = "/tech"}, {"name" = "App4Access", "path" = "/condition"}, {"name" = "App5Access", "path" = "/account-id"}, {"name" = "App6Access", "path" = "/password"}, ] }
然后在dynamic "rule"块中,通过for循环保留列表顺序并结合索引生成优先级:
dynamic "rule" { # 将列表转为带索引的映射,确保顺序稳定 for_each = { for idx, ep in var.external_endpoints : ep.name => { idx = idx, ep = ep } } content { name = rule.value.ep.name # 从指定起始值开始生成连续优先级,这里起始值为5 priority = rule.value.idx + 5 statement { byte_match_statement { positional_constraint = "STARTS_WITH" search_string = rule.value.ep.path field_to_match { uri_path {} } text_transformation { priority = 0 type = "NONE" } } } action { allow {} } visibility_config { cloudwatch_metrics_enabled = true metric_name = rule.value.ep.name sampled_requests_enabled = true } } }
新增规则时只需在列表末尾添加条目,优先级会自动递增,无需手动修改现有值。
方法2:自定义优先级起始值与步长
如果需要自定义起始值或间隔(比如步长为2),可以用range函数生成对应优先级序列,再与端点列表配对:
dynamic "rule" { # 生成从5开始、步长1、长度与端点列表一致的优先级序列 for_each = zipmap( [for ep in var.external_endpoints : ep.name], [for idx, ep in var.external_endpoints : { ep = ep priority = range(5, 5 + length(var.external_endpoints))[idx] }] ) content { name = rule.value.ep.name priority = rule.value.priority # 其余代码与方法1一致 statement { byte_match_statement { positional_constraint = "STARTS_WITH" search_string = rule.value.ep.path field_to_match { uri_path {} } text_transformation { priority = 0 type = "NONE" } } } action { allow {} } visibility_config { cloudwatch_metrics_enabled = true metric_name = rule.value.ep.name sampled_requests_enabled = true } } }
若要设置步长为2,只需将range参数改为range(5, 5 + length(var.external_endpoints)*2, 2),即可生成[5,7,9,...]的优先级序列。
注意事项
- 必须保证
external_endpoints列表顺序稳定,避免Terraform因顺序变化重建规则。如需按特定顺序排序,可在for_each前对列表排序:for_each = { for idx, ep in sort(var.external_endpoints, by = ep.name) : ep.name => { idx = idx, ep = ep } } - 不要用
toset处理列表,集合是无序结构,会导致索引混乱,优先级生成不可预测。
内容的提问来源于stack exchange,提问作者Ravichandran
相关产品推荐
相关产品推荐

