CloudFormationでVPC/Subnetを構築する方法

# CloudFromationとは
CloudFormationはプログラミング言語やYAML,JSONを使用してAWSリソースを構築出来るサービスです。
AWS環境をテンプレート化しておくことで、同じ環境を作成する時間を削減することができます。

今回はYAMLで作成していきますので、JSONに変換したい方は次の記事をご参照下さい。
<a href="https://qiita.com/kazunobu2211/items/49deda949e97ea86bbf4" rel="nofollow noopener" target="_blank">YAMLからJSONに変換する方法</a>

## 構成図
![スクリーンショット 2022-11-24 21.43.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2983197/0d7177c5-e41b-4ca8-92fa-b023df5b5772.png)


## 完成したテンプレート
```:テンプレート
AWSTemplateFormatVersion: 2010-09-09

Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      -
        Label:
          default: VPC
        Parameters:
          - VPCName
          - VpcCIDR
      -
        Label:
          default: InternetGateway
        Parameters:
          - InternetGatewayName
      -
        Label:
          default:  PublicSubnet
        Parameters:
          - PubSubName1
          - PubSubCIDR1
          - PubSubAZ1
          - PubSubName2
          - PubSubCIDR2
          - PubSubAZ2
      -
        Label:
          default:  PrivateSubnet
        Parameters:
        - PriSubName1
        - PriSubCIDR1
        - PriSubAZ1
        - PriSubName2
        - PriSubCIDR2
        - PriSubAZ2
      -
        Label:
          default:  RouteTable
        Parameters:
        - PubSubRTBName1
        - PubSubRTBName2
        - PriSubRTBName1
        - PriSubRTBName2
Parameters:
# ------------------------------------------------------------#
#  VPC
# ------------------------------------------------------------#    
# VPC
  VPCName:
    Type: String
    Default: 'VPCName' 

  VpcCIDR:
    Type: String
    Default: 10.0.0.0/16
# ------------------------------------------------------------#
#  InternetGateway
# ------------------------------------------------------------#  
# InternetGateway
  InternetGatewayName:
    Type: String
    Default: 'InternetGatewayName'
# ------------------------------------------------------------#
#  Subnet
# ------------------------------------------------------------#    
# PublicSubnet
  PubSubName1:
    Type: String
    Default: 'PubSubName1'

  PubSubCIDR1:
    Type: String
    Default: 10.0.0.0/24
  
  PubSubAZ1:
    Type: String
    Default: 'ap-northeast-1a'

  PubSubName2:
    Type: String
    Default: 'PubSubName2'

  PubSubCIDR2:
    Type: String
    Default: 10.0.1.0/24
  
  PubSubAZ2:
    Type: String
    Default: 'ap-northeast-1c'
# PrilicSubnet
  PriSubName1:
    Type: String
    Default: 'PriSubName1'

  PriSubCIDR1:
    Type: String
    Default: 10.0.2.0/24
  
  PriSubAZ1:
    Type: String
    Default: 'ap-northeast-1a'

  PriSubName2:
    Type: String
    Default: 'PriSubName2'

  PriSubCIDR2:
    Type: String
    Default: 10.0.3.0/24
  
  PriSubAZ2:
    Type: String
    Default: 'ap-northeast-1c'
# ------------------------------------------------------------#
#  RouteTable
# ------------------------------------------------------------#    
  PubSubRTBName1:
    Type: String
    Default: 'PubSubRTBName1'
  
  PubSubRTBName2:
    Type: String
    Default: 'PubSubRTBName2'
  
  PriSubRTBName1:
    Type: String
    Default: 'PriSubRTBName1'

  PriSubRTBName2:
    Type: String
    Default: 'PriSubRTBName2'

Resources:
# ------------------------------------------------------------#
#  VPC
# ------------------------------------------------------------#    
# VPC
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcCIDR
      Tags:
        - Key: Name
          Value: !Ref VPCName
# ------------------------------------------------------------#
#  InternetGateway
# ------------------------------------------------------------#    
# InternetGateway
  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
      - Key: Name
        Value: !Ref InternetGatewayName
  # IGW Attach
  InternetGatewayAttachment: 
    Type: "AWS::EC2::VPCGatewayAttachment"
    Properties: 
      InternetGatewayId: !Ref InternetGateway
      VpcId: !Ref VPC 
# ------------------------------------------------------------#
#  Subnet
# ------------------------------------------------------------#    
# PublicSubnet
  PubSub1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId:
        Ref: VPC
      CidrBlock: !Ref PubSubCIDR1
      AvailabilityZone: !Ref PubSubAZ1
      Tags:
      - Key: Name
        Value: !Ref PubSubName1
  PubSub2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId:
        Ref: VPC
      CidrBlock: !Ref PubSubCIDR2
      AvailabilityZone: !Ref PubSubAZ2
      Tags:
      - Key: Name
        Value: !Ref PubSubName2
#  PrivateSubnet
  PriSub1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId:
        Ref: VPC
      CidrBlock: !Ref PriSubCIDR1
      AvailabilityZone: !Ref PriSubAZ1
      Tags:
      - Key: Name
        Value: !Ref PriSubName1
  PriSub2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId:
        Ref: VPC
      CidrBlock: !Ref PriSubCIDR2
      AvailabilityZone: !Ref PriSubAZ2
      Tags:
      - Key: Name
        Value: !Ref PriSubName2
# ------------------------------------------------------------#
#  RouteTable
# ------------------------------------------------------------#    
# PublicSub-Routetable
  PubSubRouteTable1:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId:  
        Ref: VPC
      Tags:
      - Key: Name
        Value: !Ref PubSubRTBName1

  PubSubRouteTable2:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId:  
        Ref: VPC
      Tags:
      - Key: Name
        Value: !Ref PubSubRTBName2
# PrivateSub-Routetable
  PriSubRouteTable1:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId:  
        Ref: VPC
      Tags:
      - Key: Name
        Value: !Ref PriSubRTBName1

  PriSubRouteTable2:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId:  
        Ref: VPC
      Tags:
      - Key: Name
        Value: !Ref PriSubRTBName2

# ------------------------------------------------------------#
# Routing
# ------------------------------------------------------------# 
# PublicRouteA Create
  PublicRoute1: 
    Type: "AWS::EC2::Route"
    Properties: 
      RouteTableId: !Ref PubSubRouteTable1
      DestinationCidrBlock: "0.0.0.0/0"
      GatewayId: !Ref InternetGateway
  
  PublicRoute2: 
    Type: "AWS::EC2::Route"
    Properties: 
      RouteTableId: !Ref PubSubRouteTable2
      DestinationCidrBlock: "0.0.0.0/0"
      GatewayId: !Ref InternetGateway
# ------------------------------------------------------------#
# RouteTable Associate
# ------------------------------------------------------------# 
# PublicRouteTable Associate Subnet
  PublicSubnetARouteTableAssociation: 
    Type: "AWS::EC2::SubnetRouteTableAssociation"
    Properties: 
      SubnetId: !Ref PubSub1
      RouteTableId: !Ref PubSubRouteTable1

  PublicSubnetCRouteTableAssociation: 
    Type: "AWS::EC2::SubnetRouteTableAssociation"
    Properties: 
      SubnetId: !Ref PubSub2
      RouteTableId: !Ref PubSubRouteTable2
# PrivateRouteTable Associate Subnet
    Type: "AWS::EC2::SubnetRouteTableAssociation"
    Properties: 
      SubnetId: !Ref PriSub1
      RouteTableId: !Ref PriSubRouteTable1

  PrivateSubnetCRouteTableAssociation: 
    Type: "AWS::EC2::SubnetRouteTableAssociation"
    Properties: 
      SubnetId: !Ref PriSub2
      RouteTableId: !Ref PriSubRouteTable2
```
## 構築手順
### １ スタックの新規作成 
AWS CloudFormation管理コンソールから、スタックの作成をクリックし、[新しいリソースを使用(標準)]を選択。
![スクリーンショット 2022-11-22 20.44.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2983197/47bb1ae7-a91c-5f62-c620-850cc285d438.png)


### ２ テンプレートアップロード 
[スタックの作成]で、[テンプレートの準備完了]を選択し、[テンプレートファイルのアップロード]>
[ファイルの選択]で、テンプレートを選択。
![スクリーンショット 2022-11-22 20.45.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2983197/6334bb44-c5c2-617e-656d-a71daadb9056.png)

### ３ パラメータ入力 
各パラメータを入力します。`スタックの名前は任意の名前を入れる`
![スクリーンショット 2022-11-24 20.56.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2983197/9edc2b0a-17bc-5d4e-d51d-8aa52d520e87.png)
![スクリーンショット 2022-11-24 20.56.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2983197/e29077b1-e30d-2c36-eb70-24419215fbe0.png)
![スクリーンショット 2022-11-24 20.57.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2983197/38da80e2-9151-f373-08db-ed72d3bdc33d.png)



### 4 CloudFormation詳細設定 
次へを選択。`CloudFormationの詳しい設定について次の記事をご覧下さい。`
<a href="https://qiita.com/kazunobu2211/items/3fd42d5482a3331332d0#cloudformation%E6%96%B0%E8%A6%8F%E4%BD%9C%E6%88%90%E6%89%8B%E9%A0%86" target="_blank rel="nofollow noopener"">CloudFormationの詳しい設定について</a>

### 5 最終確認
最終確認を行い`送信`を選択
![スクリーンショット 2022-11-22 22.02.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2983197/8ce53f29-daec-d456-5905-fb39a0001fda.png)

### 6 正常終了確認 
ステータスがCREATE_COMPLETEになったらスタック正常終了です。


## パラメータの詳細
|パラメータ名|用途|備考|
|-|-|-|
|VPCName|VPCの名前|例:CF-VPC|
|VpcCIDR|VPCのIPv4ネットワーク範囲|例:10.0.0.0/24|
|InternetGatewayName|IGWの名前|例:CF-IGW|
|PubSubName1|パブリックサブネット1の名前|例:CF-PubSub1|
|PubSubCIDR1|パブリックサブネット１のIPv4ネットワーク範囲|例:10.0.0.0/24|
|PubSubAZ1|パブリックサブネット1のAZを入力|例:ap-northeast-1a|
|PubSubName2|パブリックサブネット2の名前|例:CF-PubSub2|
|PubSubCIDR2|パブリックサブネット2のIPv4ネットワーク範囲|例:10.0.1.0/24|
|PubSubAZ2|パブリックサブネット2のAZを入力|例:ap-northeast-1c|
|PriSubName1|プライベートサブネット1の名前|例:CF-PriSub1|
|PriSubCIDR1|プライベートサブネット1のIPv4ネットワーク範囲|例:10.0.2.0/24|
|PriSubAZ1|プライベートサブネット1のAZを入力|例:ap-northeast-1a|
|PriSubName2|プライベートサブネット2の名前|例:CF-PriSub2|
|PriSubCIDR2|プライベートサブネット2のIPv4ネットワーク範囲|例:10.0.3.0/24|
|PriSubAZ2|プライベートサブネット2のAZを入力|例:ap-northeast-1c|
|PubSubRTBName1|パブリックサブネット1のルートテーブルの名前|例:CF-PubSubRTB1|
|PubSubRTBName2|パブリックサブネット2のルートテーブルの名前|例:CF-PubSubRTB2|
|PriSubRTBName1|プライベートサブネット1のルートテーブルの名前|例:CF-PriSubRTB1|
|PriSubRTBName2|プライベートサブネット2のルートテーブルの名前|例:CF-PriSubRTB2|


## 公式ドキュメント
<a href="https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc.html" target="_blank rel="nofollow noopener">CloudFormation VPCのAWS公式ドキュメント</a>
<a href="https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-internetgateway.html" target="_blank rel="nofollow noopener">CloudFormation IGWのAWS公式ドキュメント</a>
<a href="https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet.html" target="_blank rel="nofollow noopener">CloudFormation サブネットのAWS公式ドキュメント</a>
<a href="https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html" target="_blank rel="nofollow noopener">CloudFormation RTBのAWS公式ドキュメント</a>
<a href="https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html" target="_blank rel="nofollow noopener">CloudFormation ルート作成AWS公式ドキュメント</a>
<a href="https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnetroutetableassociation.html" target="_blank rel="nofollow noopener">CloudFormation RTBのサブネット関連付けAWS公式ドキュメント</a>