皆様こんにちは。
AWS CDKを利用してマルチAZ3層アーキテクチャ構築をしていきます。
この記事ではセキュリティグループの作成を行います。
1.セキュリティグループとは
セキュリティグループ(Security Group)は、AWSのネットワークセキュリティ機能で、EC2インスタンスやRDSデータベースなどのリソースに対するトラフィックのアクセス制御を行います。
概要
-
ファイアウォールの役割:セキュリティグループは、AWSの仮想ファイアウォールとして機能し、リソースへの入出力トラフィックを制御します。
-
インバウンドルール: リソースに対する着信トラフィックを制御します。例えば、特定のIPアドレスからのHTTPトラフィックを許可するなど。
-
アウトバウンドルール: リソースからの発信トラフィックを制御します。例えば、特定のIPアドレスへの接続を許可するなど。
-
状態の保持:セキュリティグループは「ステートフル」で、インバウンドルールで許可されたトラフィックは、対応するアウトバウンドルールも自動的に許可されます。逆も同様です。
-
デフォルト設定:新規作成時には、デフォルトで全てのインバウンドトラフィックが拒否され、全てのアウトバウンドトラフィックが許可されます。
-
タグ付け:タグを使用して、セキュリティグループを管理しやすくすることができます。例えば、環境ごとに異なるタグを付けるなど。
-
複数のリソースへの適用:一つのセキュリティグループは複数のEC2インスタンスなどのリソースに適用でき、リソース間でセキュリティ設定を一貫して管理できます。
詳細は公式ドキュメントを参照ください。
2.目的
各リソースごとに通信が必要な最小限の許可ポリシーを設定したセキュリティグループの作成。
①EC2用:ALB、VPCエンドポイント(SSM用)、RDS、EFSのインバウンド通信を許可
②RDS用:EC2のインバウンド通信を許可
③ALB用:HTTP、HTTPSのすべてのインバウンド通信を許可
④EFS用:EC2のインバウンド通信を許可
⑤VPCエンドポイント(SSM)用:EC2のインバウンド通信を許可
※セキュリティグループはステートフルであるためアウトバウンドについては設定不要
3.構成図
4.全体構築ソースコード
# セキュリティグループの作成
ec2_sg = ec2.SecurityGroup(self, "kitaya-sg-ec2",
vpc=vpc,
description="sg for ec2",
allow_all_outbound=True
)
Tags.of(ec2_sg).add("Name", "kitaya-sg-ec2")
rds_sg = ec2.SecurityGroup(self, "kitaya-sg-db",
vpc=vpc,
description="sg for db",
allow_all_outbound=True
)
Tags.of(rds_sg).add("Name", "kitaya-sg-db")
alb_sg = ec2.SecurityGroup(self, "kitaya-sg-alb",
vpc=vpc,
description="sg for alb",
allow_all_outbound=True
)
Tags.of(alb_sg).add("Name", "kitaya-sg-alb")
efs_sg = ec2.SecurityGroup(self, "kitaya-sg-efs",
vpc=vpc,
description="sg for efs",
allow_all_outbound=True
)
Tags.of(efs_sg).add("Name", "kitaya-sg-efs")
ssm_vpce_sg = ec2.SecurityGroup(self, "kitaya-ssm-sg-vpce",
vpc=vpc,
description="sg for ssm vpc endpoint",
allow_all_outbound=True
)
Tags.of(ssm_vpce_sg).add("Name", "kitaya-ssm-sg-vpce")
# 各セキュリティグループにインバウンドルールを追加
# EC2
ec2_sg.connections.allow_from(alb_sg, ec2.Port.tcp(443), "Allow HTTPS access")
ec2_sg.connections.allow_from(ssm_vpce_sg, ec2.Port.tcp(80), "Allow HTTP access")
ec2_sg.connections.allow_from(rds_sg, ec2.Port.tcp(3306), "Allow MySQL access")
ec2_sg.connections.allow_from(efs_sg, ec2.Port.tcp(2049), "Allow NFS access")
# RDS
rds_sg.connections.allow_from(ec2_sg, ec2.Port.tcp(3306), "Allow MySQL access")
# ALB
alb_sg.connections.allow_from(ec2.Peer.any_ipv4(), ec2.Port.tcp(443), "Allow HTTPS access")
alb_sg.connections.allow_from(ec2.Peer.any_ipv4(), ec2.Port.tcp(80), "Allow HTTP access")
# EFS
efs_sg.connections.allow_from(ec2_sg, ec2.Port.tcp(2049), "Allow NFS access")
5.ソースコード詳細
5-1.セキュリティグループの作成
まずは必要なセキュリティグループをすべて作成します。
- "ec2.SecurityGroup"クラスを使用
リソースを作成する際に必要なコンストラクトの指定と論理ID(テンプレート内で一意)の指定をしたのち、詳細のプロパティを指定しています。
※他リソースでも同様
プロパティは下記
使用するプロパティ | 設定値 | 説明 |
---|---|---|
vpc | vpc | セキュリティグループが属するVPCを指定 |
description | ソースコード参照 | セキュリティグループの説明 |
allow_all_outbound | True | すべてのアウトバウンドトラフィックを許可するかどうかを指定 今回はすべて許可のため"True" |
-
"Tags.of()"メソッドを使用してNameタグをつけます(書式は下記)
Tags.of("リソース名").add("キー", "値") -
ソースコード
# VPCの作成
# セキュリティグループの作成
ec2_sg = ec2.SecurityGroup(self, "kitaya-sg-ec2",
vpc=vpc,
description="sg for ec2",
allow_all_outbound=True
)
Tags.of(ec2_sg).add("Name", "kitaya-sg-ec2")
rds_sg = ec2.SecurityGroup(self, "kitaya-sg-db",
vpc=vpc,
description="sg for db",
allow_all_outbound=True
)
Tags.of(rds_sg).add("Name", "kitaya-sg-db")
alb_sg = ec2.SecurityGroup(self, "kitaya-sg-alb",
vpc=vpc,
description="sg for alb",
allow_all_outbound=True
)
Tags.of(alb_sg).add("Name", "kitaya-sg-alb")
efs_sg = ec2.SecurityGroup(self, "kitaya-sg-efs",
vpc=vpc,
description="sg for efs",
allow_all_outbound=True
)
Tags.of(efs_sg).add("Name", "kitaya-sg-efs")
ssm_vpce_sg = ec2.SecurityGroup(self, "kitaya-ssm-sg-vpce",
vpc=vpc,
description="sg for ssm vpc endpoint",
allow_all_outbound=True
)
Tags.of(ssm_vpce_sg).add("Name", "kitaya-ssm-sg-vpce")
5-2.各セキュリティグループにインバウンドルールを追加
- "connections.allow_from"を使用
下記の書式で記載しています。
"ルールを追加するセキュリティグループ".connections.allow_from(許可するソース, ec2.Port."プロトコル"("ポート"), "説明文")
例
ALBからEC2インスタンスへのHTTPS (ポート443) アクセスを許可するセキュリティグループルールを追加
ec2_sg.connections.allow_from(alb_sg, ec2.Port.tcp(443), "Allow HTTPS access")
ec2_sg: EC2インスタンス用のセキュリティグループ
connections: セキュリティグループの接続ルールを管理するプロパティ
allow_from: ソースセキュリティグループからのインバウンドトラフィックを許可するメソッド
alb_sg: ALB用のセキュリティグループ
ec2.Port.tcp(443): TCPプロトコルのポート443 (HTTPS) を指定
"Allow HTTPS access": ルールの説明
- ソースコード
# 各セキュリティグループにインバウンドルールを追加
# EC2
ec2_sg.connections.allow_from(alb_sg, ec2.Port.tcp(443), "Allow HTTPS access")
ec2_sg.connections.allow_from(ssm_vpce_sg, ec2.Port.tcp(80), "Allow HTTP access")
ec2_sg.connections.allow_from(rds_sg, ec2.Port.tcp(3306), "Allow MySQL access")
ec2_sg.connections.allow_from(efs_sg, ec2.Port.tcp(2049), "Allow NFS access")
# RDS
rds_sg.connections.allow_from(ec2_sg, ec2.Port.tcp(3306), "Allow MySQL access")
# ALB
alb_sg.connections.allow_from(ec2.Peer.any_ipv4(), ec2.Port.tcp(443), "Allow HTTPS access")
alb_sg.connections.allow_from(ec2.Peer.any_ipv4(), ec2.Port.tcp(80), "Allow HTTP access")
# EFS
efs_sg.connections.allow_from(ec2_sg, ec2.Port.tcp(2049), "Allow NFS access")
6.感想
インバウンドルールの追加で循環依存関係が発生していまいましたが、connections.allow_fromを使用することで解決できました。
マネジメントコンソールでの構築と違い、選択肢が多いので今後も調べながら進めていこうと思います。