1

我们正在使用conftest来验证我们的 terraform 变更集是否适用于某些规则和合规性。我们要验证的一件事是我们的 AWS 资源是否根据 AWS 标记约定进行标记,该约定指定要使用的某些标签(例如 Owner、ApplicationRole、Project)并指定所有标签和值都在 CamelCase 中。

在 terraform 中,变更集在以下(简化的)json 输出中描述:

{
   "resource_changes":{
      "provider_name":"aws",
      "change":{
         "before":{

         },
         "after":{
            "tags":{
               "ApplicationRole":"SomeValue",
               "Owner":"SomeValue",
               "Project":"SomeValue"
            }
         }
      }
   }
}

我现在要做的是验证以下内容:

  1. 检查是否设置了标签。
  2. 验证键和值是否都是驼峰式。
  3. 检查密钥是否至少包含集合(ApplicationRole、Owner、Project)。

但是,我无法在 Rego 中定义它(我对 OPA 很陌生)。

有没有办法“循环”对象的键和值,并验证它们的格式是否正确?

在伪代码中:

for key, value in tags {
  re_match(`([A-Z][a-z0-9]+)+`, key)
  re_match(`([A-Z][a-z0-9]+)+`, value)
}

我尝试了以下方法:

tags_camel_case(tags) {
    some key
    val := tags[key]
    re_match(`^([A-Z][a-z0-9]+)+`, key) # why is key not evaluated?
    re_match(`^([A-Z][a-z0-9]+)+`, val)
}

但是,在针对以下测试 json 进行评估时:

{
  "AppRole": "SomeValue",
  "appRole": "SomeValue"
}

规则返回 true,即使我同时检查键和值与正则表达式

4

1 回答 1

2

tags_camel_case(tags)函数对带有两个键的输入返回 true,因为(默认情况下)Rego 中的变量是存在量化的。这意味着如果对于某些变量绑定集,规则主体中的语句为真,则满足规则主体。在上面的示例中,规则体将满足{key=AppRole, val=SomeValue}

要表达所有内容,您可以使用一个简单的技巧。首先编写一个规则来检查是否有任何标签不是驼峰式。第二个写规则,检查第一个规则是否不满足。

例如:

# checks if all tags are camel case
tags_camel_case(tags) {
  not any_tags_not_camel_case(tags)
}

# checks if any tags are NOT camel case
any_tags_not_camel_case(tags) {
    some key
    val := tags[key]
    not is_camel_case(key, val)
}

# checks if a and b are both camel case
is_camel_case(a, b) {
  re_match(`^([A-Z][a-z0-9]+)+`, a)
  re_match(`^([A-Z][a-z0-9]+)+`, b)
}

有关 Rego 中“所有人”表达的更多信息,请参阅https://www.openpolicyagent.org/docs/latest/how-do-i-write-policies/#universal-quantification-for-all

于 2019-08-16T15:05:16.710 回答