最初見たとき「は?」ってなった
AWS のセキュリティグループのインバウンドルールを設定するとき、ソース(送信元)の欄には普通 IP アドレスを入れますよね。0.0.0.0/0 とか 10.0.1.0/24 とか。
でもある日、他のチームが作った設定を見ていたら、ソースの欄に IPアドレスではなくセキュリティグループのIDっぽいもの(sg-0123456789abcdef0 みたいなやつ)が入っていました。
正直、最初は意味がわかりませんでした。
「セキュリティグループのソースにセキュリティグループ……? グループがグループを参照してるってどういうこと?」と、しばらく画面を見つめていた記憶があります。
結論:セキュリティグループは「そのSGがアタッチされているインスタンス全部」を指す
調べてみると、そんなに難しい話ではありませんでした。
セキュリティグループのソースに別のセキュリティグループを指定すると、それは「そのセキュリティグループがアタッチされているすべてのリソース」を送信元として許可する、という意味になります。
つまり、IP アドレスの代わりに 「そのSGが付いているインスタンスかどうか」でフィルタしているということです。
具体的にイメージするとこうなります。
[App-SG] というセキュリティグループがアタッチされたEC2インスタンスが 3台ある
→ app-server-1 (10.0.1.10)
→ app-server-2 (10.0.1.20)
→ app-server-3 (10.0.1.30)[DB-SG] のインバウンドルールで、ソースを [App-SG] に設定する
→ app-server-1, 2, 3 からの接続だけが許可される
→ IPアドレスは一切書いていない
app-server が増えても減っても、IPアドレスが変わっても、DB-SG のルールは一切変更する必要がないというのがポイントです。
なんでこれが「便利やん」ってなったのか
実際に使ってみて「あ、これ地味にありがたいな」と感じたポイントをまとめます。
1. オートスケーリングと相性が良すぎる
Auto Scaling グループでインスタンスが増減する環境だと、IPアドレスは常に変動します。IPベースでルールを組んでいたら、インスタンスが増えるたびにセキュリティグループを手動で更新する羽目になります。
でもソースをセキュリティグループにしておけば、新しく起動したインスタンスに同じSGがアタッチされてさえいれば、ルールは自動的に適用されます。IPアドレスの変動を一切気にしなくていい、というのはかなり大きいです。
2. IPアドレスの管理から解放される
「このサーバー、IPアドレス変わったからセキュリティグループの設定も直さなきゃ」みたいな作業が発生しません。サーバーを再作成しても、同じSGを付ける限り通信は許可されたままです。
インフラを触っていると、地味にこの「IPアドレス管理」がストレスだったりするので、これがなくなるだけで運用がだいぶ楽になります。
3. 「役割」で通信を許可する設計になる
IPベースの設定だと「このIPからの通信を許可する」という書き方になりますが、SGベースだと「Appサーバーからの通信を許可する」という書き方になります。
これは地味に大きな違いで、インフラの構成が変わってもルールの意味が崩れません。IPアドレスは環境によって変わりますが、「役割」は変わらないからです。設定を見返したときの可読性も上がります。
# IPベースの設定(読んでも何のための許可かわからない)
Source: 10.0.1.0/24# SGベースの設定(意図が読み取れる)
Source: app-server-sg(Appサーバーからの通信を許可)
4. VPC内で完結していれば同一VPC内どこからでも参照できる
同じVPC内であれば、サブネットをまたいでいてもセキュリティグループを参照できます。「同じサブネットにいないと使えないんじゃないか」と最初思っていましたが、そんなことはありませんでした。
実際の設定例
3層構成(ALB → Appサーバー → RDS)を例に、セキュリティグループ同士の参照関係を組んでみます。
構成イメージ
[Internet]
↓
[ALB] (alb-sg)
↓
[App サーバー] (app-sg)
↓
[RDS] (db-sg)
ALB用セキュリティグループ(alb-sg)
インターネットからの HTTPS のみ許可します。ここは通常通り IP ベースです。
aws ec2 authorize-security-group-ingress \ --group-id sg-alb0123456789abc \ --protocol tcp \ --port 443 \ --cidr 0.0.0.0/0
App サーバー用セキュリティグループ(app-sg)
ソースは IP ではなく、ALB のセキュリティグループを指定します。
aws ec2 authorize-security-group-ingress \ --group-id sg-app0123456789abc \ --protocol tcp \ --port 8080 \ --source-group sg-alb0123456789abc
これで「ALBにアタッチされているリソースからの通信だけ」を許可できます。ALBのIPアドレスは変動することがありますが、気にする必要は一切ありません。
RDS用セキュリティグループ(db-sg)
同様に、ソースを App サーバーのセキュリティグループ にします。
aws ec2 authorize-security-group-ingress \ --group-id sg-db0123456789abc \ --protocol tcp \ --port 3306 \ --source-group sg-app0123456789abc
これで、App サーバーが何台に増えても、IPアドレスが何であっても、「app-sg がついているインスタンスからの接続だけ」を DB が受け付ける状態になります。
確認コマンド
設定した内容は以下で確認できます。
aws ec2 describe-security-groups \ --group-ids sg-db0123456789abc \ --query 'SecurityGroups[0].IpPermissions'
出力の UserIdGroupPairs にソースとして指定したセキュリティグループのIDが表示されていれば設定完了です。
{
"IpProtocol": "tcp",
"FromPort": 3306,
"ToPort": 3306,
"UserIdGroupPairs": [
{
"GroupId": "sg-app0123456789abc",
"Description": ""
}
]
}
使うときにちょっと気をつけたいこと
便利な反面、いくつか注意点もあります。
別アカウントのSGを参照する場合はアカウントIDの指定が必要
同一アカウント内であれば単純にSG IDだけで参照できますが、別アカウントのセキュリティグループを参照する場合は –source-group に加えてオーナーのアカウントIDを指定する必要があります。
参照先のSGが削除されるとルールが機能しなくなる
参照しているセキュリティグループそのものが削除されると、そのルールは実質意味をなさなくなります。「このSGは他から参照されているから安易に消せない」という依存関係が見えにくくなりがちなので、命名規則やドキュメントで管理しておくと安心です。
ルールの意図が伝わりにくくなることもある
慣れていないメンバーが見ると、今回の自分のように「セキュリティグループがソースに入っている……?」と一瞬固まる可能性があります。チームに導入する際は、一言説明を添えておくと親切です(この記事のリンクを送りつけるのも手です)。
まとめ
セキュリティグループのソースにセキュリティグループを指定する設定は、初見だと「何をしているのか」がパッとイメージしづらいものの、実際に使ってみると
- IPアドレスの変動を一切気にしなくていい
- オートスケーリング環境と相性が良い
- 「役割」ベースでルールが書けて可読性が上がる
という、地味だけど確実にありがたい機能でした。IPベースでセキュリティグループを組んでいる環境があれば、一度SG参照への置き換えを検討してみる価値は十分にあると思います。
参考リンク


