使用 JQ 过滤 cloudformation 堆栈资源
Filtering cloudformation stack resources using JQ
我正在尝试编写一个 JQ 过滤器,用于根据资源属性从 AWS cloudformation 模板中过滤特定资源。
例如,当从以下(缩短的)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"
}
]
}
}
}
}
一个额外的好处是能够过滤 'OR' 值的组合。
因此 "AWS::EC2::InternetGateway" 或 "AWS::EC2::VPC" 的过滤器应该产生原始文档。
如有任何建议或见解,我们将不胜感激。
Tx!
使用select()
函数:
jq '.Resources[]|select(.Type=="AWS::EC2::VPC")' aws.json
如果你想按多个条件过滤,你可以使用or
,像这样:
jq '.Resources[]|select(.Type=="AWS::EC2::VPC" or .Type=="foo")' aws.json
@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 所指出的,现在指定更复杂的选择标准变得微不足道了。
}
使用 aws cli 的 --query 参数。
完全不需要jq。
http://docs.aws.amazon.com/cli/latest/userguide/controlling-output.html#controlling-output-filter
这是一个解决方案,它使用一个单独的函数 select 匹配指定条件的所有资源,该条件为每个资源传递一个 {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"
}
}
}
}
我正在尝试编写一个 JQ 过滤器,用于根据资源属性从 AWS cloudformation 模板中过滤特定资源。
例如,当从以下(缩短的)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"
}
]
}
}
}
}
一个额外的好处是能够过滤 'OR' 值的组合。 因此 "AWS::EC2::InternetGateway" 或 "AWS::EC2::VPC" 的过滤器应该产生原始文档。
如有任何建议或见解,我们将不胜感激。
Tx!
使用select()
函数:
jq '.Resources[]|select(.Type=="AWS::EC2::VPC")' aws.json
如果你想按多个条件过滤,你可以使用or
,像这样:
jq '.Resources[]|select(.Type=="AWS::EC2::VPC" or .Type=="foo")' aws.json
@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 所指出的,现在指定更复杂的选择标准变得微不足道了。 }
使用 aws cli 的 --query 参数。 完全不需要jq。 http://docs.aws.amazon.com/cli/latest/userguide/controlling-output.html#controlling-output-filter
这是一个解决方案,它使用一个单独的函数 select 匹配指定条件的所有资源,该条件为每个资源传递一个 {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"
}
}
}
}