Cloudformation使ってみた

## はじめに
こんにちは！小林です。
AWS認定試験を勉強中なんですが、Cloudformationの理解を深める目的でVPC、サブネット、ルートテーブル、NATGateway、InternetGatewayを構築してみました。
Cloudformation初学者の方はよかったら参考にしてみてください。

## システム構成
今回は下記のリソースを構築するYamlテンプレートを作成しました。
※PrivateSubnetに配置するリソースは記載していません。別の機会でEC2などを配置していろいろ検証したいな、と考えています。

### システム構成図
![AWS_構成図_NATGateway.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3722085/8b3bae01-4620-d0bd-2817-797a2a94f4db.png)

### 構築対象のリソース
・VPC
・プライベートサブネット
・パブリックサブネット
・NATGateway
・InternetGateway
・ルートテーブル



## yamlテンプレート
下記が今回作成したCloudformation用のYamlテンプレートになります。
コメントで簡単な説明をつけたので、設定を変えたい場合は該当の箇所の記載を修正することでテンプレートを使いまわすことができます。

```ruby:CloudformationYaml
AWSTemplateFormatVersion: '2010-09-09'
Description: 'VPC、パブリックサブネット、プライベートサブネット、ルートテーブル、NATゲートウェイ、インターネットゲートウェイを作成するテンプレート'

#Parametersセクションを記載すると構築時に設定値を指定できます。
Parameters:
  VpcCidr:
    Type: String
    Default: '10.0.0.0/16'
  PublicSubnetCidr:
    Type: String
    Default: '10.0.1.0/24'
  PrivateSubnetCidr:
    Type: String
    Default: '10.0.2.0/24'

#Resourcesセクションに構築するリソースの設定値を記入します。
Resources:

#下記にVPCの設定を記載
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcCidr
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: !Sub '${AWS::StackName}-VPC'

#下記にInternetGatewayの設定を記載
  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: !Sub '${AWS::StackName}-InternetGateway'

  AttachInternetGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref InternetGateway

#下記にサブネットの設定を記載
  PublicSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: !Ref PublicSubnetCidr
      MapPublicIpOnLaunch: true
      AvailabilityZone: !Select [ 0, !GetAZs '' ]
      Tags:
        - Key: Name
          Value: !Sub '${AWS::StackName}-PublicSubnet'

  PrivateSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: !Ref PrivateSubnetCidr
      AvailabilityZone: !Select [ 0, !GetAZs '' ]
      Tags:
        - Key: Name
          Value: !Sub '${AWS::StackName}-PrivateSubnet'

#下記にルートテーブルの設定を記載
  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub '${AWS::StackName}-PublicRouteTable'

  PrivateRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub '${AWS::StackName}-PrivateRouteTable'

#下記にルートテーブルのルールを記載
  PublicRoute:
    Type: AWS::EC2::Route
    DependsOn: AttachInternetGateway
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: '0.0.0.0/0'
      GatewayId: !Ref InternetGateway

  PrivateRoute:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PrivateRouteTable
      DestinationCidrBlock: '0.0.0.0/0'
      NatGatewayId: !Ref NatGateway

  PublicSubnetRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet
      RouteTableId: !Ref PublicRouteTable

  PrivateSubnetRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet
      RouteTableId: !Ref PrivateRouteTable

#下記にNATGatewayの設定を記載
  NatGatewayEIP:
    Type: AWS::EC2::EIP
    Properties:
      Domain: vpc

  NatGateway:
    Type: AWS::EC2::NatGateway
    Properties:
      AllocationId: !GetAtt NatGatewayEIP.AllocationId
      SubnetId: !Ref PublicSubnet
      Tags:
        - Key: Name
          Value: !Sub '${AWS::StackName}-NatGateway'

```
## おわりに
今回は使用しませんでしたが、Outputセクションを記載すると、ほかのテンプレートから、今回作成したテンプレートの設定を参照できるので活用していきたいと思いました。