いつも、セキュリティグループのルールをコピーしたいと思っているのだが、今のAWS CLIであれば、以前にやったRDSのパラメータグループをコピーしたのと同じ方法でできるのではないかと思ったので、やってみた。
$ aws ec2 describe-security-groups \ --filters 'Name=group-name,Values=src-sg' \ --query 'SecurityGroups[].IpPermissions[]' \ | tr -d '\d' \ | xargs -I{} -- aws ec2 authorize-security-group-ingress --group-id sg-deadbeaf --ip-permissions '{}' A client error (MissingParameter) occurred when calling the AuthorizeSecurityGroupIngress operation: Missing source specification: include source security group or CIDR information
エラーになってしまった。色々調べてみたら、以下の様な原因であることがわかった。
describe-security-groupsで取得したJSONには、IpRangesとUserIdGroupPairsの両方が項目として含まれている。セキュリティグループのルールは、対象としてCIDRを渡す他に、他のセキュリティグループを指定することができる。IpRangesには、IPアドレスが、UserIdGroupPairsには、セキュリティグループのIDが含まれる。
しかし、一つのルールにそれらが同時に含まれることはない。下記は、80/tcpを、IPアドレスとセキュリティグループを指定して定義したセキュリティグループのルールを取得したJSONの出力。別々のルールとして出力されていることが分かる。
% aws ec2 describe-security-groups --group-id 'sg-deadbeaf' --query 'SecurityGroups[].IpPermissions[]' [ { "ToPort": 80, "IpProtocol": "tcp", "IpRanges": [ { "CidrIp": "192.0.2.1/32" } ], "UserIdGroupPairs": [], "FromPort": 80 }, { "ToPort": 80, "IpProtocol": "tcp", "IpRanges": [], "UserIdGroupPairs": [ { "UserId": "nnnnnnnnnnnn", "GroupId": "sg-cafebabe" } ], "FromPort": 80 } ]
authorize-security-group-ingressに渡す前に、値が含まれていない項目を除去すれば使うことができる。ということで、ちょっとしたフィルタを作った。
このフィルタを通すと、IpRangesまたはUserIdGroupPairsのうち、値が含まれていない項目を削除してくれる。また、xargsで処理しやすいように、1ルール1行に変換する。
% aws ec2 describe-security-groups --group-id 'sg-deadbeaf' --query 'SecurityGroups[].IpPermissions[]' | ruby ./repos/sgfilter/sgfilter.rb '{"ToPort":80,"IpProtocol":"tcp","IpRanges":[{"CidrIp":"1n2.0.2.1/32"}],"FromPort":80}' '{"ToPort":80,"IpProtocol":"tcp","UserIdGroupPairs":[{"UserId":"nnnnnnnnnnnn","GroupId":"sg-cafebabe"}],"FromPort":80}'
これを使って、下記のように、xargsを使って実行する。
$ aws ec2 describe-security-groups \ --filters 'Name=group-name,Values=src-sg' \ --query 'SecurityGroups[].IpPermissions[]' \ | ruby sgfilter.rb \ | xargs -I{} -- aws ec2 authorize-security-group-ingress --group-id sg-deadbeaf --ip-permissions '{}'
これで、src-sgに含まれる許可ルールが、sg-deadbeafに対してコピーされることになる。
元記事はこちらです。
「[AWS] AWS CLIでセキュリティグループのルールをコピーする」