CloudFormation個人メモ：VPC、6つのサブネット、IGW、ルートテーブル、NAT、ALB、EC2のコード化

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

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

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

https://qiita.com/free-honda/items/960458cc17c8612c1a32

このプラットフォーム上に自分専用の備忘録記録を積み重ねていく予定です。

**あらかじめご了承いただければ幸いです。**

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

前回の続きです。

https://qiita.com/free-honda/items/6a6a254937028ff28e18

https://qiita.com/free-honda/items/a33bf86f1a26a2ee9e6e

- **AWSプロバイダー設定**
  - 東京リージョンでリソースを構築する設定。

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

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

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

- **インターネットゲートウェイ設定**
  - パブリックサブネットのインターネットアクセスを提供。

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

- **NATゲートウェイ設定**
  - Elastic IPを割り当てたNATゲートウェイを作成。
  - プライベートサブネットのアウトバウンド通信をサポート。

- **サブネットとルートテーブルの関連付け**
  - 各サブネットを対応するルートテーブルに関連付け。

- **セキュリティグループ設定**
  - SSH（22番）とALB（80番）のインバウンド通信を許可。。
  - 全アウトバウンドトラフィックを許可。。

- **EC2インスタンス作成**
  - プライベートサブネット1にAmazon Linux 2の`t2.micro`インスタンスを作成。
  - Apacheをインストールして簡易的なWebサーバーをセットアップ。
  - セキュリティグループを適用して通信を制御。

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

- **EC2インスタンスの登録**
  - プライベートサブネット内のEC2インスタンスをターゲットグループに登録し、ALBを介してリクエストを転送。

## 作ったコードについて

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

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

  # セキュリティグループの作成（プライベートサブネット用）
  PrivateInstanceSG:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: "Security group for private instances"
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: "tcp"
          FromPort: 22
          ToPort: 22
          CidrIp: "0.0.0.0/0" # 必要に応じてCIDRを制限
        - IpProtocol: "tcp"
          FromPort: 80
          ToPort: 80
          CidrIp: "0.0.0.0/0" # 必要に応じてCIDRを制限
      SecurityGroupEgress:
        - IpProtocol: "-1"
          FromPort: 0
          ToPort: 0
          CidrIp: "0.0.0.0/0"
      Tags:
        - Key: Name
          Value: "CloudFormation-private-instance-sg"

  # プライベートサブネット1にEC2インスタンス作成
  PrivateApacheEC2:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: "ami-0b6fe957a0eb4c1b9" # Amazon Linux 2 の AMI（要確認）
      InstanceType: "t2.micro" # インスタンスタイプ
      SubnetId: !Ref PrivateSubnet1
      SecurityGroupIds:
        - !GetAtt PrivateInstanceSG.GroupId
      UserData: !Base64 |
        #!/bin/bash
        yum update -y
        yum install -y httpd
        systemctl start httpd
        systemctl enable httpd
        echo "<html><body><h1>プライベートインスタンスでホスティング中</h1></body></html>" > /var/www/html/index.html
      Tags:
        - Key: Name
          Value: "CloudFormation-private-apache-ec2"

  # パブリック用セキュリティグループ作成
  PublicSG:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: "Public security group for ALB"
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: "tcp"
          FromPort: 80
          ToPort: 80
          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: 80
      Protocol: "HTTP"
      VpcId: !Ref VPC
      HealthCheckIntervalSeconds: 30
      HealthCheckPath: "/"
      HealthCheckProtocol: "HTTP"
      HealthCheckTimeoutSeconds: 5
      HealthyThresholdCount: 3
      UnhealthyThresholdCount: 3
      TargetType: "instance"
      Targets:
        - Id: !Ref PrivateApacheEC2
          Port: 80
      Tags:
        - Key: Name
          Value: "cloudformation-main-target-group"

  # ALBのリスナー作成
  HttpListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      LoadBalancerArn: !Ref MainALB
      Port: 80
      Protocol: "HTTP"
      DefaultActions:
        - Type: "forward"
          TargetGroupArn: !Ref MainTargetGroup
```

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

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

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

## おまけ
今回作成したALBのDNS名でアクセスすると、ブラウザで以下のように表示されることを確認できます。

![Screenshot 2025-01-23 at 7.57.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/14200ab7-98b5-c837-cac7-1576ec6c095e.png)