AWS CloudFormationでVPCと複数AZにサブネットを構築する

今回はCloudformationを利用したVPCとサブネットの作成のコード化について解説します。

#前提条件
- Windows10を使用。
- PCはDELLを使用。
- ファイルの拡張子は.ymlを使用。
- 東京リージョンを使用。
- アベイラビリティゾーンは1aと1cを使用。

#料金
テンプレート自体には料金は発生しないが、作成後のAWSリソースに関しては料金が発生しますのでご注意下さい。

#事前準備
 
- AWSアカウントを所持していること。
- Amazon VPCへのアクセス権限（書き込み・読み取り）を許可していること。
- AWS Cloudformationへのアクセス権限（書き込み・読み取り）を許可していること。

#構築内容
- 東京リージョンにVPCを作成する。
- プライベートサブネットとパブリックサブネットそれぞれ２つずつ複数AZに作成する。
- インターネットゲートウェイを作成する。
- パブリックサブネット用とプライベートサブネット用のルートテーブルを作成する。
- パブリックサブネット用のルートテーブルにインターネットゲートウェイをアタッチする。
- パブリックサブネット用のルートテーブルに２つのパブリックサブネットを関連付けする。
- プライベートサブネット用のルートテーブルに２つのプライベートサブネットを関連付けする。

#テンプレート

VPCとサブネットの作成のスタックは以下の通りです。

```yml:VPC_create.yml
AWSTemplateFormatVersion: '2010-09-09'
Description:
  VPC & subnet create

Resources:
  MyFirstVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsSupport: 'true'
      EnableDnsHostnames: 'true'
      InstanceTenancy: default
      Tags:
      - Key: Name
        Value: CloudFormation-VPC
  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref MyFirstVPC
      Tags:
      - Key: Name
        Value: CloudFormation-VPC-PublicRT

  PrivateRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref MyFirstVPC
      Tags:
      - Key: Name
        Value: CloudFormation-VPC-PrivateRT

  PublicSubnet1A:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref MyFirstVPC
      CidrBlock: 10.0.0.0/24
      AvailabilityZone: "ap-northeast-1a"
      Tags:
      - Key: Name
        Value: CloudFormation-public-subnet-1a

  PubSubnet1ARouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet1A
      RouteTableId: !Ref PublicRouteTable

  PublicSubnet1C:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref MyFirstVPC
      CidrBlock: 10.0.2.0/24
      AvailabilityZone: "ap-northeast-1c"
      Tags:
      - Key: Name
        Value: CloudFormation-public-subnet-1c

  PubSubnet1CRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet1C
      RouteTableId: !Ref PublicRouteTable

  PrivateSubnet1A:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref MyFirstVPC
      CidrBlock: 10.0.1.0/24
      AvailabilityZone: "ap-northeast-1a"
      Tags:
      - Key: Name
        Value: CloudFormation-private-subnet-1a

  PriSubnet1ARouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet1A
      RouteTableId: !Ref PrivateRouteTable

  PrivateSubnet1C:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref MyFirstVPC
      CidrBlock: 10.0.3.0/24
      AvailabilityZone: "ap-northeast-1c"
      Tags:
      - Key: Name
        Value: CloudFormation-private-subnet-1c

  PriSubnet1CRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet1C
      RouteTableId: !Ref PrivateRouteTable

  myInternetGateway:
    Type: "AWS::EC2::InternetGateway"
    Properties:
      Tags:
      - Key: Name
        Value: CloudFormation-ING
  AttachGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref MyFirstVPC
      InternetGatewayId: !Ref myInternetGateway
  myRoute:
    Type: AWS::EC2::Route
    DependsOn: myInternetGateway
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref myInternetGateway

Outputs:
  StackVPC:
    Description: The ID of the VPC
    Value: !Ref MyFirstVPC
    Export:
      Name: !Sub "${AWS::StackName}-VPCID"

  StackPublicSubnet1A:
    Description: The ID of the VPC Subnet
    Value: !Ref PublicSubnet1A
    Export:
      Name: !Sub "${AWS::StackName}-PublicSubnet1A"

  StackPublicSubnet1C:
    Description: The ID of the VPC Subnet
    Value: !Ref PublicSubnet1C
    Export:
      Name: !Sub "${AWS::StackName}-PublicSubnet1C"

  StackPrivateSubnet1A:
    Description: The ID of the VPC Subnet
    Value: !Ref PrivateSubnet1A
    Export:
      Name: !Sub "${AWS::StackName}-PrivateSubnet1A"

  StackPrivateSubnet1C:
    Description: The ID of the VPC Subnet
    Value: !Ref PrivateSubnet1C
    Export:
      Name: !Sub "${AWS::StackName}-PrivateSubnet1C"

```

#スタック作成後の確認手順
１、東京リージョンにVPCが作成されていることを確認する。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408197/be8e527e-721e-2718-05b5-0a1bac7ace43.png)


２、プライベートサブネットとパブリックサブネットそれぞれ２つずつ複数AZに作成されていることを確認。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408197/7fd589ba-9ec5-dc05-0fe4-b99829d3f096.png)

３、インターネットゲートウェイが作成されていることを確認する。
![IGW.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408197/a6f70886-1f71-0468-ab3a-0d8185746918.png)

４、パブリックサブネット用のルートテーブルにインターネットゲートウェイがアタッチされていることを確認。
![rute1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408197/244f24e1-b5fa-6750-b6e8-bba2fb30208b.png)

５、２つ作成したパブリックサブネットがインターネットゲートウェイにアタッチされているルートテーブルに関連付けされていることを確認。
![関連付け１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408197/60e672aa-b12b-edfc-8773-887a6b810e32.png)

６、２つのプライベートサブネットがルートテーブルに関連付けされていることを確認。
![関連付け２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408197/ad6312b2-55cf-cd31-2e00-3cae50e25947.png)

#終わりに
今回はCloudFormaitonを利用してVPCを作成してみました。
始めてコード化に挑戦した為、分からない点がとても多かったですが何とか完成出来ました。
とても難しかったです。。
今後は他のAWSサービスでもCloudFormaitonを使った構築に挑戦していき、インフラのコード化の技術に踏み込んでいきたいと思います。