Terraform 我是否可以在OPA中循环对象的键和值,以验证它们是否符合特定格式(CamelCase)

Terraform 我是否可以在OPA中循环对象的键和值,以验证它们是否符合特定格式(CamelCase),terraform,open-policy-agent,Terraform,Open Policy Agent,我们使用来验证terraform变更集是否适用于某些规则和合规性。我们要验证的一件事是,我们的AWS资源是否根据AWS标记约定进行标记,该约定指定了要使用的特定标记(例如,所有者、应用程序角色、项目),并指定所有标记和值都在CamelCase中 在terraform中,变更集在以下(简化的)json输出中描述: { "resource_changes":{ "provider_name":"aws", "change":{ "before":{

我们使用来验证terraform变更集是否适用于某些规则和合规性。我们要验证的一件事是,我们的AWS资源是否根据AWS标记约定进行标记,该约定指定了要使用的特定标记(例如,所有者、应用程序角色、项目),并指定所有标记和值都在CamelCase中

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

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

         },
         "after":{
            "tags":{
               "ApplicationRole":"SomeValue",
               "Owner":"SomeValue",
               "Project":"SomeValue"
            }
         }
      }
   }
}
我现在要做的是验证以下内容:

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)
}
  • 检查是否设置了标签
  • 验证键和值是否都是camelcase
  • 检查密钥是否至少包含集合(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,即使我正在检查key和value与regex的关系,
    tags\u camel\u case(tags)
    函数对带有两个键的输入返回true,因为(默认情况下)Rego中的变量是存在量化的。这意味着,如果对于某些变量绑定集,规则体中的语句为true,则规则体是满足的。在上面的示例中,规则体将由
    {key=AppRole,val=SomeValue}
    满足

    用一个简单的技巧来表达你所能表达的一切。首先编写一条规则,检查是否有任何标记不是camel大小写。其次,编写规则以检查是否不满足第一条规则

    例如:

    # 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中“For all”表达式的更多信息,请参见

    谢谢您的回答,这确实解决了我的问题!