【CloudFormation】AWSマルチAZ3層アーキテクチャの構築_セキュリティグループ

皆様、お世話になっております。鈴木と申します。
今回はAWS CloudFormationを使用してセキュリティグループを作成していきたいと思います。

1.目次

目次はこちら

2.要件

  • 基本的にはセキュリティグループをソースとして指定する
  • RDSはプライベートサブネットからのみのアクセスとする(プロテクトサブネット)
  • 付与先(EC2・ALB・RDS・EFS・EFSマウントターゲット・SSM)

3.セキュリティグループについて

簡単にセキュリティグループについてご説明致します。

AWSセキュリティグループは、AWSクラウド内のリソース(EC2インスタンス、SSMエンドポイント、RDSなど)のセキュリティを管理するための仮想ファイアウォールです。セキュリティグループを使用することで、リソース間や外部とのトラフィックの許可や拒否を細かく設定できます。

セキュリティグループの主な特徴としては5つ挙げられます。

  1. ステートフルなファイアウォール
    →セキュリティグループはステートフルで、インバウンドトラフィックが許可されると、それに関連するアウトバウンドトラフィックも自動的に許可されます。

  2. インバウンドおよびアウトバウンドのルール設定
    →セキュリティグループはインバウンド(受信)およびアウトバウンド(送信)のトラフィックに対するルールを設定できます。ルールはIPアドレス、ポート番号、プロトコルで指定可能です。

  3. 動的なルールの適用
    →セキュリティグループのルールを変更すると、その変更は即座に適用され、関連するリソース(EC2インスタンス、SSMエンドポイント、RDSなど)にリアルタイムで反映されます。

  4. リソース単位の設定
    →セキュリティグループはEC2インスタンス、SSMエンドポイント、RDSなどのリソースに適用され、同じセキュリティグループを複数のリソースに設定することで、一貫したセキュリティポリシーを維持できます。

  5. 複数セキュリティグループの組み合わせ
    →1つのリソースには複数のセキュリティグループを設定でき、これにより複数のセキュリティポリシーを組み合わせた柔軟なセキュリティ設定が可能です。

ネットワークACL (Network ACL)との違い

類似サービスとしてネットワークACLがあるため違いを表にまとめます。

特徴 ネットワークACL (Network ACL) セキュリティグループ (Security Group)
役割 サブネット単位でトラフィックを制御 インスタンス単位でトラフィックを制御
適用範囲 サブネット EC2インスタンス、ELB、RDSなど
ステートフル/ステートレス ステートレス ステートフル
ルール 許可ルールと拒否ルール、番号付きで順序がある 許可ルールのみ設定、ルールに順序はない
デフォルト設定 デフォルトで全てのトラフィックを許可 デフォルトで全てのインバウンドトラフィックを拒否し、アウトバウンドを全て許可
ルールの適用 各ルールが個別に評価される 設定したルールが全て適用され、自動的に適用される

今回が付与先がEC2やRDSとなるためセキュリティグループを付与していきます。

4.構成図

file

セキュリティグループ設定

  1. SSMエンドポイント用

    • EC2インスタンスの操作にAWS Systems Manager (SSM) を使用します。
    • SSMエンドポイントに対してセキュリティグループを適用します。
    • EC2からのHTTPSトラフィックを許可し、ソースをEC2のセキュリティグループに指定します。
  2. ALB用

    • インターネットからのアクセスを許可する必要があります(HTTPとHTTPS)。
    • HTTP (ポート80) と HTTPS (ポート443) のトラフィックを許可し、ソースを0.0.0.0/0に指定します。
  3. RDS用

    • RDSはプロテクトサブネットに配置されるため、通信はプライベートサブネット内のEC2とのみ行います。
    • MySQL (ポート3306) のトラフィックを許可し、ソースをEC2のセキュリティグループに指定します。
  4. EC2用

    1. ALBからのHTTPアクセスを許可します。VPC内部では通信は暗号化されるため、HTTPを許可します。ソースをALBのセキュリティグループに指定します。
    2. SSMからのHTTPSアクセスを許可します。SSMエンドポイントとの通信ではHTTPSを使用しますので、ソースをSSMのセキュリティグループに指定します。
    3. RDSからのMySQL (ポート3306) トラフィックを許可します。RDSのエンジンがMySQLであるため、ソースをRDSのセキュリティグループに指定します。
    4. EFSからのNFS (ポート2049) トラフィックを許可します。EFSとの通信に必要なポートです。ソースをEFSのセキュリティグループに指定します。
  5. EFS用

    • EFS用とマウントターゲット用のセキュリティグループ設定は同一です。
    • EC2からのNFS (ポート2049) トラフィックを許可し、ソースをEC2のセキュリティグループに指定します。

作成の順番によっては依存関係のエラーが発生するケースがあります。
そのため上記順番にて作成しております。

5.全体のソースコード

AWSTemplateFormatVersion: '2010-09-09'
Description: |
  CloudFormation template to create security groups with specified rules.

Parameters:
  VpcId:
    Type: AWS::EC2::VPC::Id
    Description: The ID of the existing VPC.

Resources:
  # SSM VPCエンドポイント用セキュリティグループ
  NaokiSsmSgVpce:
    Type: AWS::EC2::SecurityGroup
    Properties: 
      GroupName: naoki-ssm-sg-vpce
      GroupDescription: sg for ssm vpc endpoint
      VpcId: !Ref VpcId
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 443
          ToPort: 443
          SourceSecurityGroupId: !Ref NaokiSgEc2
          Description: EC2
      SecurityGroupEgress:
        - IpProtocol: -1
          CidrIp: 0.0.0.0/0
      Tags:
        - Key: Name
          Value: naoki-ssm-sg-vpce

  # ALB用セキュリティグループ
  NaokiSgAlb:
    Type: AWS::EC2::SecurityGroup
    Properties: 
      GroupName: naoki-sg-alb
      GroupDescription: sg for alb
      VpcId: !Ref VpcId
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: 443
          ToPort: 443
          CidrIp: 0.0.0.0/0
      SecurityGroupEgress:
        - IpProtocol: -1
          CidrIp: 0.0.0.0/0
      Tags:
        - Key: Name
          Value: naoki-sg-alb

  # DB用セキュリティグループ
  NaokiSgDb:
    Type: AWS::EC2::SecurityGroup
    Properties: 
      GroupName: naoki-sg-db
      GroupDescription: sg for db
      VpcId: !Ref VpcId
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 3306
          ToPort: 3306
          SourceSecurityGroupId: !Ref NaokiSgEc2
          Description: MYSQL
      SecurityGroupEgress:
        - IpProtocol: -1
          CidrIp: 0.0.0.0/0
      Tags:
        - Key: Name
          Value: naoki-sg-db

  # EC2用セキュリティグループ
  NaokiSgEc2:
    Type: AWS::EC2::SecurityGroup
    Properties: 
      GroupName: naoki-sg-ec2
      GroupDescription: sg for ec2
      VpcId: !Ref VpcId
      SecurityGroupIngress: []
      SecurityGroupEgress:
        - IpProtocol: -1
          CidrIp: 0.0.0.0/0
      Tags:
        - Key: Name
          Value: naoki-sg-ec2

  # EFS用セキュリティグループ
  NaokiSgEfs:
    Type: AWS::EC2::SecurityGroup
    Properties: 
      GroupName: naoki-sg-efs
      GroupDescription: sg for efs
      VpcId: !Ref VpcId
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 2049
          ToPort: 2049
          SourceSecurityGroupId: !Ref NaokiSgEc2
          Description: EFS
      SecurityGroupEgress:
        - IpProtocol: -1
          CidrIp: 0.0.0.0/0
      Tags:
        - Key: Name
          Value: naoki-sg-efs

  # EC2用のインバウンドルール
  NaokiEc2IngressSsm:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      GroupId: !Ref NaokiSgEc2
      IpProtocol: tcp
      FromPort: 443
      ToPort: 443
      SourceSecurityGroupId: !Ref NaokiSsmSgVpce
      Description: SSM

  NaokiEc2IngressAlb:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      GroupId: !Ref NaokiSgEc2
      IpProtocol: tcp
      FromPort: 80
      ToPort: 80
      SourceSecurityGroupId: !Ref NaokiSgAlb
      Description: ALB

  NaokiEc2IngressDb:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      GroupId: !Ref NaokiSgEc2
      IpProtocol: tcp
      FromPort: 3306
      ToPort: 3306
      SourceSecurityGroupId: !Ref NaokiSgDb
      Description: RDS

  NaokiEc2IngressEfs:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      GroupId: !Ref NaokiSgEc2
      IpProtocol: tcp
      FromPort: 2049
      ToPort: 2049
      SourceSecurityGroupId: !Ref NaokiSgEfs
      Description: EFS

  # EFS用のインバウンドルール
  NaokiEfsIngressEc2:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      GroupId: !Ref NaokiSgEfs
      IpProtocol: tcp
      FromPort: 2049
      ToPort: 2049
      SourceSecurityGroupId: !Ref NaokiSgEc2
      Description: EFS

Outputs:
  SecurityGroupIdForEfs:
    Description: The ID of the security group for EFS
    Value: !Ref NaokiSgEfs
  SecurityGroupIdForEc2:
    Description: The ID of the security group for EC2
    Value: !Ref NaokiSgEc2

6.ソースコード詳細

6-1.SSMエンドポイント用セキュリティグループの作成

上記でも説明の通りEC2用のHTTPSトラフィックを許可します。
送信は全トラフィックを許可します。

使用するオプション 設定値 説明
Type AWS::EC2::SecurityGroup セキュリティグループを作成するためのデフォルトの定義
GroupName naoki-ssm-sg-vpce セキュリティグループの名前を指定
GroupDescription sg for ssm vpc endpoint 説明
VpcId !Ref VpcId セキュリティグループが属するVPCのIDを指定
SecurityGroupIngress IpProtocol: tcp
FromPort: 443
ToPort: 443
SourceSecurityGroupId: !Ref NaokiSgEc2
Description: EC2
受信ルールを設定
SecurityGroupEgress IpProtocol: -1
CidrIp: 0.0.0.0/0
送信ルールを設定
Tags Key: Name
Value: naoki-ssm-sg-vpce
タグのキーと値を設定
 # SSM VPCエンドポイント用セキュリティグループ
  NaokiSsmSgVpce:
    Type: AWS::EC2::SecurityGroup
    Properties: 
      GroupName: naoki-ssm-sg-vpce
      GroupDescription: sg for ssm vpc endpoint
      VpcId: !Ref VpcId
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 443
          ToPort: 443
          SourceSecurityGroupId: !Ref NaokiSgEc2
          Description: SSM Access
      SecurityGroupEgress:
        - IpProtocol: -1
          CidrIp: 0.0.0.0/0
      Tags:
        - Key: Name
          Value: naoki-ssm-sg-vpce

6-2.ALB用セキュリティグループの作成

インターネットからのアクセスを許可する必要があります(HTTPとHTTPS)
送信は全トラフィックを許可。

使用するオプション 設定値 説明
Type AWS::EC2::SecurityGroup セキュリティグループを作成するためのデフォルトの記述
GroupName naoki-sg-alb セキュリティグループの名前を指定
GroupDescription sg for alb 説明
VpcId !Ref VpcId セキュリティグループが属するVPCのIDを指定
SecurityGroupIngress IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
①受信ルールを設定
SecurityGroupIngress IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
②受信ルールを設定
SecurityGroupEgress IpProtocol: -1
CidrIp: 0.0.0.0/0
送信ルールを設定
Tags Key: Name
Value: naoki-sg-alb
タグのキーと値を設定
  # ALB用セキュリティグループ
  NaokiSgAlb:
    Type: AWS::EC2::SecurityGroup
    Properties: 
      GroupName: naoki-sg-alb
      GroupDescription: sg for alb
      VpcId: !Ref VpcId
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: 443
          ToPort: 443
          CidrIp: 0.0.0.0/0
      SecurityGroupEgress:
        - IpProtocol: -1
          CidrIp: 0.0.0.0/0
      Tags:
        - Key: Name
          Value: naoki-sg-alb

6-3.RDS用セキュリティグループ

RDS(MySQL)の通信をEC2からのみ許可する設定です。送信は全トラフィックを許可します。

使用するオプション 設定値 説明
Type AWS::EC2::SecurityGroup セキュリティグループを作成するためのデフォルトの記述
GroupName naoki-sg-db セキュリティグループの名前を指定
GroupDescription sg for db 説明
VpcId !Ref VpcId セキュリティグループが属するVPCのIDを指定
SecurityGroupIngress IpProtocol: tcp
FromPort: 3306
ToPort: 3306
SourceSecurityGroupId: !Ref NaokiSgEc2
Description: MYSQL
受信ルールを設定
SecurityGroupEgress IpProtocol: -1
CidrIp: 0.0.0.0/0
送信ルールを設定
Tags Key: Name
Value: naoki-sg-db
タグのキーと値を設定
  # DB用セキュリティグループ
  NaokiSgDb:
    Type: AWS::EC2::SecurityGroup
    Properties: 
      GroupName: naoki-sg-db
      GroupDescription: sg for db
      VpcId: !Ref VpcId
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 3306
          ToPort: 3306
          CidrIp: 0.0.0.0/0
          Description: MYSQL
      SecurityGroupEgress:
        - IpProtocol: -1
          CidrIp: 0.0.0.0/0
      Tags:
        - Key: Name
          Value: naoki-sg-db

6-4.EC2用セキュリティグループの作成

EC2に対するルールを設定します。ALBやSSM、RDS、EFSからのトラフィックを受け入れる設定です。送信は全トラフィックを許可します。

使用するオプション 設定値 説明
Type AWS::EC2::SecurityGroup セキュリティグループを作成するためのデフォルトの記述
GroupName naoki-sg-ec2 セキュリティグループの名前を指定
GroupDescription sg for ec2 説明
VpcId !Ref VpcId セキュリティグループが属するVPCのIDを指定
SecurityGroupIngress [] 受信ルールを設定
[]は別で作成
SecurityGroupEgress IpProtocol: -1
CidrIp: 0.0.0.0/0
送信ルールを設定
Tags Key: Name
Value: naoki-sg-ec2
タグのキーと値を設定
  NaokiSgEc2:
    Type: AWS::EC2::SecurityGroup
    Properties: 
      GroupName: naoki-sg-ec2
      GroupDescription: sg for ec2
      VpcId: !Ref VpcId
      SecurityGroupIngress: []
      SecurityGroupEgress:
        - IpProtocol: -1
          CidrIp: 0.0.0.0/0
      Tags:
        - Key: Name
          Value: naoki-sg-ec2

6-5.EFS用のセキュリティグループの設定

EFSに対してEC2からのNFSトラフィックを許可する設定です。送信は全トラフィックを許可します。

使用するオプション 設定値 説明
Type AWS::EC2::SecurityGroup セキュリティグループを作成するためのデフォルトの記述
GroupName naoki-sg-efs セキュリティグループの名前を指定
GroupDescription sg for efs 説明
VpcId !Ref VpcId セキュリティグループが属するVPCのIDを指定
SecurityGroupIngress [] 受信ルールを設定
[]は別で作成
SecurityGroupEgress IpProtocol: -1
CidrIp: 0.0.0.0/0
送信ルールを設定
Tags Key: Name
Value: naoki-sg-efs
タグのキーと値を設定
  NaokiSgEfs:
    Type: AWS::EC2::SecurityGroup
    Properties: 
      GroupName: naoki-sg-efs
      GroupDescription: sg for efs
      VpcId: !Ref VpcId
      SecurityGroupIngress: []
      SecurityGroupEgress:
        - IpProtocol: -1
          CidrIp: 0.0.0.0/0
      Tags:
        - Key: Name
          Value: naoki-sg-efs

6-6.EC2用のインバウンドルールの設定

EC2用セキュリティグループに対して、各種インバウンドルールを追加するリソースです。各セキュリティグループからのアクセスを許可します。

  1. ALBからのHTTPアクセスを許可します。VPC内部では通信は暗号化されるため、HTTPを許可します。ソースをALBのセキュリティグループに指定します。
  2. SSMからのHTTPSアクセスを許可します。SSMエンドポイントとの通信ではHTTPSを使用しますので、ソースをSSMのセキュリティグループに指定します。
  3. RDSからのMySQL (ポート3306) トラフィックを許可します。RDSのエンジンがMySQLであるため、ソースをRDSのセキュリティグループに指定します。
  4. EFSからのNFS (ポート2049) トラフィックを許可します。EFSとの通信に必要なポートです。ソースをEFSのセキュリティグループに指定します。
使用するオプション 設定値 説明
Type AWS::EC2::SecurityGroupIngress セキュリティグループ受信ルールを設定するためのデフォルトの記述
GroupId !Ref NaokiSgEc2 参照先セキュリティグループを指定
FromPort
ToPort
ポート番号入力 ポートの指定
SourceSecurityGroupId !Ref セキュリティグループを指定 ソース先を指定
Description 下記ソースコード指定 説明
  # EC2用のインバウンドルール
  NaokiEc2IngressSsm:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      GroupId: !Ref NaokiSgEc2
      IpProtocol: tcp
      FromPort: 443
      ToPort: 443
      SourceSecurityGroupId: !Ref NaokiSsmSgVpce
      Description: SSM

  NaokiEc2IngressAlb:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      GroupId: !Ref NaokiSgEc2
      IpProtocol: tcp
      FromPort: 80
      ToPort: 80
      SourceSecurityGroupId: !Ref NaokiSgAlb
      Description: ALB

  NaokiEc2IngressDb:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      GroupId: !Ref NaokiSgEc2
      IpProtocol: tcp
      FromPort: 3306
      ToPort: 3306
      SourceSecurityGroupId: !Ref NaokiSgDb
      Description: RDS

  NaokiEc2IngressEfs:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      GroupId: !Ref NaokiSgEc2
      IpProtocol: tcp
      FromPort: 2049
      ToPort: 2049
      SourceSecurityGroupId: !Ref NaokiSgEfs
      Description: EFS

6-7.EFS用のインバウンドルールの設定

EFS用セキュリティグループに対して、EC2からのNFSトラフィックを許可する設定です。

使用するオプション 設定値 説明
Type AWS::EC2::SecurityGroupIngress セキュリティグループ受信ルールを設定するためのデフォルトの記述
GroupId !Ref NaokiSgEfs 参照先セキュリティグループを指定
IpProtocol
FromPort
ToPort
tcp
2049
2049
プロトコル,ポートの指定
SourceSecurityGroupId !Ref NaokiSgEc2 ソース先を指定
Description EFS 説明

6-8.Outputsセクション

作成したセキュリティグループのIDを出力する設定です。

使用するオプション 設定値 説明
Value !Ref NaokiSgEfs
!Ref NaokiSgEc2
ソースの指定
Outputs:
  SecurityGroupIdForEfs:
    Description: The ID of the security group for EFS
    Value: !Ref NaokiSgEfs
  SecurityGroupIdForEc2:
    Description: The ID of the security group for EC2
    Value: !Ref NaokiSgEc2

7.感想

IaCでのセキュリティグループ作成では、リソース間の依存関係やセキュリティポリシーを正確に反映する必要があります。これにより、設定ミスによるセキュリティリスクを防ぎつつ、効率的なネットワーク設計が実現できます。IaCを活用することで、一貫性のあるセキュリティグループの管理が可能であると実感しました。

Last modified: 2024-07-31

Author