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

Parse AWS security group with jq and add new ingress rule

我要解决的问题是搜索 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*

如果您打算在值为 10.219.0.0/16 时创建新的 CidrIp 规则,请执行以下操作。请注意,这 保留数组中元素的顺序并将新 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)

我最终想出的答案是构建一个简单的 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}