使用jq解析AWS安全组并添加新的入口规则

时间:2018-07-11 21:55:43

标签: json jq aws-security-group

我要解决的问题是搜索AWS SG组并将新规则(例如:10.10.0.0/16)添加到相同的入口规则块(端口,协议,cidr)中,其中模式是“ CidrIp”:匹配“ 10.219.0.0/16”。

找到匹配项:-https://gist.github.com/mfang329/49575d6eb7ddb93e8f926648f9ba06e9

{
    "PrefixListIds": [],
    "FromPort": -1,
    "IpRanges": [{
            "CidrIp": "10.219.0.0/16"
        },
        {
            "Description": "testing for vpc transit connectivity",
            "CidrIp": "0.0.0.0/0"
        }
    ],
    "ToPort": -1,
    "IpProtocol": "icmp",
    "UserIdGroupPairs": [{
        "UserId": "abcde80269151",
        "Description": "default SG VPC - peering ",
        "GroupId": "sg-33511e41"
    }],
    "Ipv6Ranges": []
}

更改为-https://gist.github.com/mfang329/b5e892cf2fee2da4b7e67106cd15b3b2

{
    "PrefixListIds": [],
    "FromPort": -1,
    "IpRanges": [{
            "CidrIp": "10.219.0.0/16"
        },
        {
            "CidrIp": "10.10.0.0/16"
        },
        {
            "Description": "testing for vpc transit connectivity",
            "CidrIp": "0.0.0.0/0"
        }
    ],
    "ToPort": -1,
    "IpProtocol": "icmp",
    "UserIdGroupPairs": [{
        "UserId": "abcde80269151",
        "Description": "default SG VPC - peering ",
        "GroupId": "sg-33511e41"
    }],
    "Ipv6Ranges": []
}

使用以下命令修改SG,但是如何表达jq来查询这些信息,并将其用作后续aws cli的输入?我知道JQ中有命令标志,但是我想攻击这个问题的最简单的解决方案是什么?

aws ec2 revoke-security-group-ingress \
 — group-id sg-33511e41 \
 — port -1 \
 — protocol icmp \
 — cidr 10.10.0.0/16;

完整的安全组JSON格式-https://gist.github.com/mfang329/a1871731fe82e5255ccc571648ad4886 *

2 个答案:

答案 0 :(得分:1)

如果您打算创建一个新的CidrIp规则(当值为10.219.0.0/16时添加),请执行以下操作。请注意,这 not 不会保留数组中元素的顺序,并将新IP添加到尾端

jq 'if   .IpRanges[] | select(.CidrIp | contains("10.219.0.0/16") )
    then .IpRanges += [ { "cidrIp" : "10.10.0.0/16" } ]
    else . end' ingressJSON

要将此输出存储在变量中并稍后在aws命令中使用,请将上面的输出存储到shell变量中。并将其传递给命令,并带有正确的引号,例如"$awsRule"

awsRule=$(jq 'if   .IpRanges[] | select(.CidrIp | contains("10.219.0.0/16") )
              then .IpRanges += [ { "cidrIp" : "10.10.0.0/16" } ]
              else . end' ingressJSON)

答案 1 :(得分:1)

我最终想出的答案是构造一个简单的SG json格式,我将其反馈给aws ec2语句。这种方法花了我一段时间才能弄清楚,但是它非常优雅,我认为这就是我想要的。

# search for the matching pattern and write to the output file
aws ec2 describe-security-groups --region ${i} |   \
  jq -r --arg e_cidr "${existing_cidr}" \
     --arg n_cidr "${new_cidr}" \
     '.SecurityGroups[] | .GroupId as $gid | .IpPermissions[] | .FromPort as $port | .IpProtocol as $protocol | 
     .IpRanges[] | select(.CidrIp == $e_cidr) | .Description as $desc |
     [{ GroupId:$gid, IpProtocol:$protocol, FromPort:$port, ToPort:$port, IpRanges:[{CidrIp:$n_cidr, Description:$desc}] }] ' -c   \
     | tee -a ${regional_file} 

这将产生一个与此格式相似的json文件,

[{
"GroupId": "sg-60d78e12",
"IpProtocol": "tcp",
"FromPort": 443,
"ToPort": 443,
"IpRanges": [
  {
    "CidrIp": "12.179.53.18/32",
    "Description": "Chicago Primary"
  }
]
}]

然后,我要做的是从json语句中删除“ GroupId”键值,然后馈入aws ec2命令行以使用与原始cidr块相同的协议和端口添加新的入口规则。这项工作很好,花了一些时间才得出结论。

        while read -r sg_pattern
        do
        gid=$( echo $sg_pattern | jq '.[]|.GroupId' -r )

        # remove the GroupId key to prepare the ip_permissions json
        ip_permissions=$( echo $sg_pattern | jq '.[] | [ del(.GroupId) ]' -r )
        echo " ---> adding new SG rule for ${ip_permissions}." 
        aws ec2 authorize-security-group-ingress --group-id $gid --ip-permissions "${ip_permissions}"

    done < ${regional_file}