野良セキュリティグループはありませんか
組織で共用しているAWSの開発環境・テスト環境では、使われなくなったまま放置されているリソースが出てくるもので、管理者のみなさまは定期的に棚卸しをされていることと思います。
しかし、セキュリティグループが棚卸しされていない環境は少なくないのではないか、と思っています。
というのも、セキュリティグループ側からは紐付いているインスタンス・ネットワークインタフェースを辿れないので、なかなか手間がかかります。しかもインスタンスを作る時にできた launch-wizard-xxx
が山ほどあって、一覧を見るだけで心が折れそうになります。
最後には、どうせセキュリティグループはあっても課金されないから、という理由で見棚卸しの対象外にされる、と。
でも整理できるものなら整理したいですよね。
なので、ここはひとつツールを使って整理しちゃいましょう。
まずリストアップする
1. すべてのセキュリティグループ
AWS CLI を使ってすべてのセキュリティグループを all.txt
に保存します。
aws ec2 describe-security-groups --query 'SecurityGroups[].[GroupId, GroupName]' --output text > all.txt
2. 使われているセキュリティグループ
すべてのネットワークインターフェイス(ENI)で使っているセキュリティグループを using.txt
に保存します。
aws ec2 describe-network-interfaces --query 'NetworkInterfaces[].[Groups]' --output text > using.txt
洗い出し
あとはフィルタをちょこっとかけます。
sort all.txt using.txt | uniq -u
default
を使わない人(環境)も多いと思うので、それを削ってしまうのもいいかもしれません。
sort all.txt using.txt | grep -v default | uniq -u
以上です。簡単ですね。
1と2の出力が同じ形式なのがみそです。この結果を同時に出力すると、使われているセキュリティグループは重複します。ここで uniq -u
して重複していない行だけ表示すれば、使われていないものだけ洗い出せるというわけです。
(おまけ)
弊社の環境で試してみました。
$ cat all.txt | wc -l
176
$ sort all.txt using.txt | grep -v default | uniq -u | wc -l
117
$ perl -le 'print 117/174'
0.672413793103448
default
を除くと、使われていないセキュリティグループが67%……( ^o^)ノ
(ちなみにVPCが37個ありました。これも棚卸しがいりそうです)
では、消しましょうか
あとは消すだけですが、手で消すのは面倒ですし、といってスクリプトで一括削除するには勇気がいります。ここでは、セキュリティグループを削除するためのシェルスクリプトを作ることにしました。
まず、使われていないセキュリティグループの一覧を保存します。
この段階で、本当に消しても大丈夫なものかを目視で確認するといいと思います。
sort all.txt using.txt | grep -v default | uniq -u > targets.txt
シェルスクリプトは Perl のワンライナーで作ります。
念には念を入れて、まず dry-run1 用のものを作ります。
dryrun="--dry-run" perl -lane 'print "# $F[1]\naws $ENV{dryrun} ec2 delete-security-group --group-id $F[0]\n"' targets.txt > delete_sgs.sh
中身はというと、
$ head delete_sgs.sh
# adtest-site02
aws --dry-run ec2 delete-security-group --group-id sg-0011eb5bcXXXXXXXX
# launch-wizard-35
aws --dry-run ec2 delete-security-group --group-id sg-004c8e17bXXXXXXXX
# AD-DCsg-hoge
aws --dry-run ec2 delete-security-group --group-id sg-0078856e3XXXXXXXX
# test-hoge-auth-sg
よさそうですね。
dry-run なので遠慮なく bash -x delete_sgs.sh
で実行してみましょう。
$ bash -x delete_sgs.sh
+ aws --dry-run ec2 delete-security-group --group-id sg-0011eb5bcXXXXXXXX
An error occurred (DryRunOperation) when calling the DeleteSecurityGroup operation: Request would have succeeded, but DryRun flag is set.
+ aws --dry-run ec2 delete-security-group --group-id sg-004c8e17bXXXXXXXX
An error occurred (DryRunOperation) when calling the DeleteSecurityGroup operation: Request would have succeeded, but DryRun flag is set.
+ aws --dry-run ec2 delete-security-group --group-id sg-0078856e3XXXXXXXX
An error occurred (DryRunOperation) when calling the DeleteSecurityGroup operation: Request would have succeeded, but DryRun flag is set.
:
:
これで問題なければ、dry-run
ではないものを作りましょう。
さきほどの先頭の dryrun="--dry-run"
を取り除いて実行します。
perl -lane 'print "# $F[1]\naws $ENV{dryrun} ec2 delete-security-group --group-id $F[0]\n"' targets.txt > delete_sgs.sh
中を確認します。
$ head delete_sgs.sh
# adtest-site02
aws ec2 delete-security-group --group-id sg-0011eb5bcXXXXXXXX
# launch-wizard-35
aws ec2 delete-security-group --group-id sg-004c8e17bXXXXXXXX
# AD-DCsg-hoge
aws ec2 delete-security-group --group-id sg-0078856e3XXXXXXXX
# test-hoge-auth-sg
よさそうですか? よさそうですね?
では、あとは実行するのみです。
祈りながら bash -x delete_sgs.sh
と叩きましょう!
God bless you!
-
dry run とは「リハーサル」「予行演習」といった意味で、実際の変更は行われないのですが、それまでの部分(構文のチェックや対象の存在確認)をきっちり実行することです。だいたいの場合、dry run が成功したときは本番も成功するように作られています。 ↩