使用JQ过滤云形式堆栈资源

时间:2015-12-05 12:43:53

标签: json amazon-cloudformation jq

我试图编写一个JQ过滤器,用于根据资源属性从AWS云信息模板中过滤特定资源。

例如,从以下(缩短的)cloudformation模板开始时:

{
"Resources": {
"vpc001": {
  "Type": "AWS::EC2::VPC",
  "Properties": {
    "CidrBlock": "10.1.0.0/16",
    "InstanceTenancy": "default",
    "EnableDnsSupport": "true",
    "EnableDnsHostnames": "true"
  }
},
"ig001": {
  "Type": "AWS::EC2::InternetGateway",
  "Properties": {
    "Tags": [
      {
        "Key": "Name",
        "Value": "ig001"
      }
    ]
  }
}
}
}

我想构建一个jq-filter,使我能够根据属性字段的(一个或多个)筛选出特定的资源。

例如:

过滤Type =" AWS :: EC2 :: InternetGateway"结果应该是

{
 "Resources": {
"ig001": {
  "Type": "AWS::EC2::InternetGateway",
  "Properties": {
    "Tags": [
      {
        "Key": "Name",
        "Value": "ig001"
      }
    ]
  }
}
}
}

额外的好处是能够过滤“或”组合的值。 作为" AWS :: EC2 :: InternetGateway"的过滤器或者" AWS :: EC2 :: VPC"应该产生原始文件。

非常感谢任何建议或见解。

的Tx!

4 个答案:

答案 0 :(得分:1)

@ hek2mgl的建议可能足以满足您的目的,但它并不能完全满足您的要求。这是一个非常类似的解决方案。它使用jq的map()和map_values()过滤器的泛化,这通常很有用:

def mapper(f):
  if type == "array" then map(f)
  elif type == "object" then
  . as $in
  | reduce keys[] as $key
      ({};
       [$in[$key] | f ] as $value
       | if $value | length == 0 then . else . + {($key): $value[0]}
         end)
  else .
  end;

.Resources |= mapper(select(.Type=="AWS::EC2::VPC"))

使用您的示例输入:

$ jq -f resources.jq resources.json
{
  "Resources": {
    "vpc001": {
      "Type": "AWS::EC2::VPC",
      "Properties": {
        "CidrBlock": "10.1.0.0/16",
        "InstanceTenancy": "default",
        "EnableDnsSupport": "true",
        "EnableDnsHostnames": "true"
      }
    }
  }

正如@ hek2mgl指出的那样,现在指定一个更复杂的选择标准是微不足道的。     }

答案 1 :(得分:0)

使用select()功能:

jq '.Resources[]|select(.Type=="AWS::EC2::VPC")' aws.json

如果您想按多个条件进行过滤,则可以使用or,如下所示:

jq '.Resources[]|select(.Type=="AWS::EC2::VPC" or .Type=="foo")' aws.json

答案 2 :(得分:0)

使用aws cli的--query参数。 完全消除了对jq的需求。 http://docs.aws.amazon.com/cli/latest/userguide/controlling-output.html#controlling-output-filter

答案 3 :(得分:0)

这是一个解决方案,它使用一个单独的函数来选择匹配指定条件的所有资源,该条件为每个资源传递一个{key,value}对。

def condition:
  .value.Type == "AWS::EC2::VPC"
;

{
  Resources: .Resources | with_entries(select(condition))
}

样本数据的输出:

{
  "Resources": {
    "vpc001": {
      "Type": "AWS::EC2::VPC",
      "Properties": {
        "CidrBlock": "10.1.0.0/16",
        "InstanceTenancy": "default",
        "EnableDnsSupport": "true",
        "EnableDnsHostnames": "true"
      }
    }
  }
}