0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

CloudFormation個人メモ:VPC、6つのサブネット、IGW、RT、NAT、ALB、SG、ACM、ECS、RDSのコード化

Last updated at Posted at 2025-01-23

はじめに

ここから先は、現在キャッチアップ中のCloudFormationを活用し、自分用のコードを書きながら進めていきます。

【補足事項】
※内容は完全に自分向けとなっています。

また、過去にTerraformを使って構築した環境を、CloudFormationで再現する形で進めています。

このプラットフォーム上に自分専用の備忘録記録を積み重ねていく予定です。あらかじめご了承いただければ幸いです。

実際にコードで行っていること

前回の続きです。

  • AWSプロバイダー設定

    • 東京リージョンでリソースを構築する設定。
  • VPC作成

    • CIDRブロック範囲 10.0.0.0/16 のVPCを作成。
    • DNSサポートとDNSホスト名を有効化。
  • パブリックサブネット作成

    • 2つのパブリックサブネットを異なるアベイラビリティゾーンで作成。
    • インターネットゲートウェイを通じてインターネットにアクセス可能。
  • プライベートサブネット作成

    • 4つのプライベートサブネットを異なるCIDRブロックとアベイラビリティゾーンで作成。
    • NATゲートウェイを経由してインターネットにアクセス可能。
  • インターネットゲートウェイ設定

    • パブリックサブネットのインターネットアクセスを提供。
  • ルートテーブルの設定

    • パブリックサブネット用のルートテーブルを作成し、インターネットゲートウェイをルートに設定。
    • プライベートサブネット用のルートテーブルを作成し、NATゲートウェイをルートに設定。
  • NATゲートウェイ設定

    • Elastic IPを割り当てたNATゲートウェイを作成。
    • プライベートサブネットのアウトバウンド通信をサポート。
  • サブネットとルートテーブルの関連付け

    • 各サブネットを対応するルートテーブルに関連付け。
  • セキュリティグループ設定

    • SSH(22番)とALB(443番)のインバウンド通信を許可。
    • 全アウトバウンドトラフィックを許可。
  • ALBとターゲットグループの設定

    • 外部公開用のALBを作成し、HTTPリクエストを処理するターゲットグループを設定(ヘルスチェックとスティッキーセッションを有効化)。
  • ECSインスタンスの登録

    • プライベートサブネット内のECSインスタンスをターゲットグループに登録し、ALBを介してリクエストを転送。
  • ECSクラスターとタスク実行ロールの作成

    • ECSクラスター:
      ECSサービスを実行するためのクラスターを作成。
    • タスク実行ロール:
      ECRアクセスやログ送信権限を付与するIAMロール。
  • ECSタスク定義の作成

    • リソース名:Fargate用のタスク(コンテナ)設定を定義。
      • CPU: 256
      • メモリ: 512
      • コンテナ: ECRイメージを使用し、ポート1323を開放。
  • ECSサービスの作成

    • リソース名:ECSクラスター内でタスクを実行するサービスを作成。
      • ALBとターゲットグループを使用してアクセスを管理。
      • タスクをFargateで1つ実行(desired_count = 1)。
  • ACMによるHTTPS通信の有効化

    • リソース名:ACM (AWS Certificate Manager) を利用して SSL/TLS 証明書を設定し、HTTPS 通信を暗号化。
      • ユーザーがアクセスするすべてのトラフィックが HTTPS によって保護。
  • RDSインスタンスの作成

    • リソース名:RDSインスタンスを作成。
      • MySQL 8.0を使用したシングルAZのRDSインスタンスをプライベートサブネット内にデプロイ。
      • プライベートサブネットを指定して、RDSインスタンスが配置可能なサブネットグループを作成

事前準備と補足事項

1. お名前.comで購入したドメインを使用してSSL証明書を取得する方法

AWS ACMとRoute53を利用してSSL証明書を取得する手順については、以下の記事をご参照ください:

2. ALBのAレコードをRoute53のホストゾーンに追加する方法

Terraformで自動デプロイ後、ALBのAレコードをRoute53に追加する手順については、以下の記事をご参照ください:

作ったコードについて

test.yaml
AWSTemplateFormatVersion: "2010-09-09"
Description: CloudFormation template for creating a VPC, subnets, NAT gateway, and related resources.

# 変数の定義
Parameters:
  ACMCertificate:
    Type: String
    Default: "arn:aws:acm:ap-northeast-1:xxx:certificate/d09e0200-6c2e-49d5-a52f-15a1100f8c2a"
    Description: "ARN of the ACM Certificate"

Resources:
  # VPCの作成
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: "10.0.0.0/16"
      InstanceTenancy: "default"
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: "CloudFormation-vpc-vpc"

  # パブリックサブネット1の作成
  PublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: "10.0.0.0/20"
      AvailabilityZone: "ap-northeast-1a"
      Tags:
        - Key: Name
          Value: "CloudFormation-vpc-subnet-public1-ap-northeast-1a"

  # パブリックサブネット2の作成
  PublicSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: "10.0.16.0/20"
      AvailabilityZone: "ap-northeast-1c"
      Tags:
        - Key: Name
          Value: "CloudFormation-vpc-subnet-public2-ap-northeast-1c"

  # プライベートサブネット1の作成
  PrivateSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: "10.0.128.0/20"
      AvailabilityZone: "ap-northeast-1a"
      Tags:
        - Key: Name
          Value: "CloudFormation-vpc-subnet-private1-ap-northeast-1a"

  # プライベートサブネット2の作成
  PrivateSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: "10.0.144.0/20"
      AvailabilityZone: "ap-northeast-1c"
      Tags:
        - Key: Name
          Value: "CloudFormation-vpc-subnet-private2-ap-northeast-1c"

  # プライベートサブネット3の作成
  PrivateSubnet3:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: "10.0.160.0/20"
      AvailabilityZone: "ap-northeast-1a"
      Tags:
        - Key: Name
          Value: "CloudFormation-vpc-subnet-private3-ap-northeast-1a"

  # プライベートサブネット4の作成
  PrivateSubnet4:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: "10.0.176.0/20"
      AvailabilityZone: "ap-northeast-1c"
      Tags:
        - Key: Name
          Value: "CloudFormation-vpc-subnet-private4-ap-northeast-1c"

  # インターネットゲートウェイの作成
  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: "CloudFormation-vpc-igw"

  # VPCへのインターネットゲートウェイのアタッチ
  AttachInternetGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref InternetGateway

  # パブリックルートテーブルの作成
  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: "CloudFormation-vpc-rtb-public"

  # パブリックルートの設定
  PublicRoute:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: "0.0.0.0/0"
      GatewayId: !Ref InternetGateway

  # パブリックサブネット1をルートテーブルに関連付け
  PublicRouteTableAssociation1:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet1
      RouteTableId: !Ref PublicRouteTable

  # パブリックサブネット2をルートテーブルに関連付け
  PublicRouteTableAssociation2:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet2
      RouteTableId: !Ref PublicRouteTable

  # NATゲートウェイ用のElastic IPの作成
  NatEIP:
    Type: AWS::EC2::EIP
    Properties:
      Domain: "vpc"
      Tags:
        - Key: Name
          Value: "CloudFormation-vpc-eip-ap-northeast-1a"

  # NATゲートウェイの作成
  NatGateway:
    Type: AWS::EC2::NatGateway
    Properties:
      SubnetId: !Ref PublicSubnet1
      AllocationId: !GetAtt NatEIP.AllocationId
      Tags:
        - Key: Name
          Value: "CloudFormation-vpc-nat-public1-ap-northeast-1a"

  # プライベートルートテーブル1の作成
  PrivateRouteTable1:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: "CloudFormation-vpc-rtb-private1-ap-northeast-1a"

  # プライベートルート1の設定
  PrivateRoute1:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PrivateRouteTable1
      DestinationCidrBlock: "0.0.0.0/0"
      NatGatewayId: !Ref NatGateway

  # プライベートサブネット1をルートテーブルに関連付け
  PrivateRouteTableAssociation1:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet1
      RouteTableId: !Ref PrivateRouteTable1

  # プライベートルートテーブル2の作成
  PrivateRouteTable2:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: "CloudFormation-vpc-rtb-private2-ap-northeast-1c"

  # プライベートルート2の設定
  PrivateRoute2:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PrivateRouteTable2
      DestinationCidrBlock: "0.0.0.0/0"
      NatGatewayId: !Ref NatGateway

  # プライベートサブネット2をルートテーブルに関連付け
  PrivateRouteTableAssociation2:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet2
      RouteTableId: !Ref PrivateRouteTable2

  # プライベートルートテーブル3の作成
  PrivateRouteTable3:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: "CloudFormation-vpc-rtb-private3-ap-northeast-1a"

  # プライベートルート3の設定
  PrivateRoute3:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PrivateRouteTable3
      DestinationCidrBlock: "0.0.0.0/0"
      NatGatewayId: !Ref NatGateway

  # プライベートサブネット3をルートテーブルに関連付け
  PrivateRouteTableAssociation3:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet3
      RouteTableId: !Ref PrivateRouteTable3

  # プライベートルートテーブル4の作成
  PrivateRouteTable4:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: "CloudFormation-vpc-rtb-private4-ap-northeast-1c"

  # プライベートルート4の設定
  PrivateRoute4:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PrivateRouteTable4
      DestinationCidrBlock: "0.0.0.0/0"
      NatGatewayId: !Ref NatGateway

  # プライベートサブネット4をルートテーブルに関連付け
  PrivateRouteTableAssociation4:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet4
      RouteTableId: !Ref PrivateRouteTable4

  # ECS用セキュリティグループ
  ECSGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: "Security group for ECS instances"
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: "tcp"
          FromPort: 1323
          ToPort: 1323
          SourceSecurityGroupId: !GetAtt PublicSG.GroupId
      SecurityGroupEgress:
        - IpProtocol: "-1"
          FromPort: 0
          ToPort: 0
          CidrIp: "0.0.0.0/0"
      Tags:
        - Key: Name
          Value: "CloudFormation-private-instance-sg"

  # ECSクラスターの作成
  ECSCluster:
    Type: AWS::ECS::Cluster
    Properties:
      ClusterName: "my-ecs-cluster"

  # ECSタスク実行ロールの作成
  ECSExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: "ecs-task-execution-role"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Principal:
              Service: "ecs-tasks.amazonaws.com"
            Action: "sts:AssumeRole"
      Policies:
        - PolicyName: "ecs-task-execution-policy"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: "Allow"
                Action:
                  - "ecr:GetAuthorizationToken"
                  - "ecr:GetDownloadUrlForLayer"
                  - "ecr:BatchGetImage"
                  - "logs:CreateLogStream"
                  - "logs:PutLogEvents"
                  - "s3:GetObject"
                Resource: "*"

  # ECSタスク定義の作成
  ECSTaskDefinition:
    Type: AWS::ECS::TaskDefinition
    Properties:
      Family: "my-app-task"
      NetworkMode: "awsvpc"
      RequiresCompatibilities:
        - "FARGATE"
      Cpu: "256"
      Memory: "512"
      ExecutionRoleArn: !GetAtt ECSExecutionRole.Arn
      ContainerDefinitions:
        - Name: "my-app-repo"
          Image: "xxx.dkr.ecr.ap-northeast-1.amazonaws.com/my-app-repo"
          PortMappings:
            - ContainerPort: 1323
              HostPort: 1323
              Protocol: "tcp"

  # ECSサービスの作成
  ECSService:
    Type: AWS::ECS::Service
    Properties:
      ServiceName: "my-ecs-service"
      Cluster: !Ref ECSCluster
      TaskDefinition: !Ref ECSTaskDefinition
      DesiredCount: 1
      LaunchType: "FARGATE"
      NetworkConfiguration:
        AwsvpcConfiguration:
          Subnets:
            - !Ref PublicSubnet1
          SecurityGroups:
            - !GetAtt ECSGroup.GroupId
          AssignPublicIp: "ENABLED"
      LoadBalancers:
        - TargetGroupArn: !Ref MainTargetGroup
          ContainerName: "my-app-repo"
          ContainerPort: 1323
    DependsOn:
      - HttpsListener # HttpListenerではなく、HttpsListenerを指定

  # パブリック用セキュリティグループ作成
  PublicSG:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: "Public security group for ALB"
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: "tcp"
          FromPort: 443
          ToPort: 443
          CidrIp: "0.0.0.0/0"
      SecurityGroupEgress:
        - IpProtocol: "-1"
          FromPort: 0
          ToPort: 0
          CidrIp: "0.0.0.0/0"
      Tags:
        - Key: Name
          Value: "CloudFormation-public-sg"

  # アプリケーションロードバランサー(ALB)作成
  MainALB:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: "cloudformation-main-alb"
      Scheme: "internet-facing"
      Type: "application"
      SecurityGroups:
        - !GetAtt PublicSG.GroupId
      Subnets:
        - !Ref PublicSubnet1
        - !Ref PublicSubnet2
      Tags:
        - Key: Name
          Value: "cloudformation-main-alb"

  # ターゲットグループ作成
  MainTargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      Name: "cloudformation-main-target-group"
      Port: 1323
      Protocol: "HTTP"
      VpcId: !Ref VPC
      HealthCheckIntervalSeconds: 30
      HealthCheckPath: "/"
      HealthCheckProtocol: "HTTP"
      HealthCheckTimeoutSeconds: 5
      HealthyThresholdCount: 3
      UnhealthyThresholdCount: 3
      TargetType: "ip" # ターゲットタイプをIPに設定
      Tags:
        - Key: Name
          Value: "cloudformation-main-target-group"

  # ALBのリスナー作成 (HTTPS)
  HttpsListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      LoadBalancerArn: !Ref MainALB
      Port: 443
      Protocol: "HTTPS"
      Certificates:
        - CertificateArn: !Ref ACMCertificate
      DefaultActions:
        - Type: "forward"
          TargetGroupArn: !Ref MainTargetGroup

  # RDS用セキュリティグループ
  RDSSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: "Security group for RDS"
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: "tcp"
          FromPort: 3306
          ToPort: 3306
          CidrIp: "10.0.0.0/16"
      SecurityGroupEgress:
        - IpProtocol: "-1"
          FromPort: 0
          ToPort: 0
          CidrIp: "0.0.0.0/0"
      Tags:
        - Key: Name
          Value: "CloudFormation-rds-sg"

  # RDS用サブネットグループ
  RDSSubnetGroup:
    Type: AWS::RDS::DBSubnetGroup
    Properties:
      DBSubnetGroupDescription: "Subnet group for RDS"
      SubnetIds:
        - !Ref PrivateSubnet1
        - !Ref PrivateSubnet2
      Tags:
        - Key: Name
          Value: "CloudFormation-rds-subnet-group"

  # RDSインスタンス
  RDSInstance:
    Type: AWS::RDS::DBInstance
    DeletionPolicy: Delete
    Properties:
      AllocatedStorage: "20" # 無料利用枠に合わせたストレージ
      StorageType: "gp2"
      Engine: "mysql"
      EngineVersion: "8.0.39"
      DBInstanceClass: "db.t4g.micro" # Graviton2プロセッサを使用したインスタンス
      MasterUsername: "admin"
      MasterUserPassword: "mypassword123"
      DBParameterGroupName: "default.mysql8.0"
      DBSubnetGroupName: !Ref RDSSubnetGroup
      VPCSecurityGroups:
        - !GetAtt RDSSecurityGroup.GroupId
      PubliclyAccessible: false
      MultiAZ: false
      Tags:
        - Key: Name
          Value: "CloudFormation-rds-instance"
      DeletionProtection: false

まとめ

この記事は、自分用の備忘録としてまとめたものです。その点をご理解いただけると幸いです。

もし、この記事の内容が少しでも参考になれば嬉しく思います。

今後も同様の内容を継続して投稿していきますので、温かく見守っていただけるとありがたいです。

おまけ

お名前.comで取得したドメイン名を使用してアクセスしたところ、以下のようにブラウザで正常に表示されることを確認しました。コード化は大成功です!

Screenshot 2025-01-23 at 12.53.45.png

また、今回作成したALBのDNS名でも、以下のように正常に表示されることを確認しています。

Screenshot 2025-01-23 at 12.53.20.png

今回追加で実装したRDSインスタンスについても、マネジメントコンソール上で正しく作成されていることを確認しました。

Screenshot 2025-01-22 at 19.05.43.png

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?