AWSのVPC周りをCloudFormationで作成


はじめに

以前この記事でAWS CLIを操ってVPC周りの作成を行いましたけど、
そもそもCloudFormationあるんだから、そっち使えるようになること必須だと思うので並行してCLIでやったことを、
CloudFormationでも実現するようにしていきたいと思います

CloudFormationってそもそも何?

AWSのシステム構成をJSONないしはYAMLで記述してテンプレート化し、構成の管理、修正、再利用を簡単にするサービスです。
構成情報がテンプレート化されるので、変更箇所などが後からログで追跡することができるので変更管理も容易です。
書き方などはJSON/YAMLともにAWSにてサンプルでの記載方法があるので、プログラム言語など少ししか齧ったことしかない人でもすぐに書けると思います。

AWSサイトのサンプルコードが書かれているURLになります。
また組み込み関数のRefも本テンプレートでは扱っているのでRefについてはこちらを参照してください。

今回は手始めにVPC周りのネットワーク作成を行いたいと思います。

で、実際に作ったYAML

各項目に説明を記載しています。

# 最新のテンプレートの形式バージョンは 2010-09-09 であり、現時点で唯一の有効な値です。

AWSTemplateFormatVersion: 2010-09-09

# 本テンプレートの説明です。

Description:
  VPC Network Create

# VPCの作成です。CidrBlockに作成したいネットワーク、Tagsにつけたい名前をつけてください。

Resources:
  nnagashimaVPC:
    Type: 'AWS::EC2::VPC'
    Properties:
      CidrBlock: 10.40.0.0/16
      Tags:
        - Key: Name
          Value: nnagashima

# インターネットに出るRouteTableを作成し、先ほど上で作成したVPCに紐付けます。
  PublicRouteTable:
    Type: 'AWS::EC2::RouteTable'
    DependsOn: AttachGateway
    Properties:
      VpcId: !Ref nnagashimaVPC
      Tags:
        - Key: Name
          Value: nnagashima-PublicRoute

# プライベートで利用するRouteTableを作成し、先ほど上で作成したVPCに紐付けます。
  PrivateRouteTable:
    Type: 'AWS::EC2::RouteTable'
    DependsOn: AttachGateway
    Properties:
      VpcId: !Ref nnagashimaVPC
      Tags:
        - Key: Name
          Value: nnagashima-PrivateRoute

# パブリックサブネット/プライベートサブネットをAZ毎に作成します。今回はTokyoRegionにて作成しています。
# CidrBlockに作成したいネットワーク、AZにはResionに存在するAZをを記載し、先ほど作成したVPC上に作成します。
# MapPublicIpOnLaunchでは、インスタンスがパブリック IPv4 アドレスを受け取るかどうかを示します。デフォルト値はfalseです。

  PublicSubnetA:
    Type: 'AWS::EC2::Subnet'
    Properties:
      CidrBlock: 10.40.1.0/24
      AvailabilityZone: ap-northeast-1a
      MapPublicIpOnLaunch: 'true'
      VpcId: !Ref nnagashimaVPC
      Tags:
        - Key: Name
          Value: nnagashima-publicA

# 作成したPublicSubnetAをPublicRouteTableに紐付けます。
  PubSubnetARouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnetA
      RouteTableId: !Ref PublicRouteTable

  PublicSubnetC:
    Type: 'AWS::EC2::Subnet'
    DependsOn: AttachGateway
    Properties:
      CidrBlock: 10.40.2.0/24
      AvailabilityZone: ap-northeast-1c
      MapPublicIpOnLaunch: 'true'
      VpcId: !Ref nnagashimaVPC
      Tags:
        - Key: Name
          Value: nnagashima-publicC

  PubSubnetCRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnetC
      RouteTableId: !Ref PublicRouteTable

  PublicSubnetD:    
    Type: 'AWS::EC2::Subnet'
    DependsOn: AttachGateway
    Properties:
      CidrBlock: 10.40.3.0/24
      AvailabilityZone: ap-northeast-1d
      MapPublicIpOnLaunch: 'true'
      VpcId: !Ref nnagashimaVPC
      Tags:
        - Key: Name
          Value: nnagashima-publicD

  PubSubnetDRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnetD
      RouteTableId: !Ref PublicRouteTable

  PrivateSubnetA:
    Type: 'AWS::EC2::Subnet'
    Properties:
      CidrBlock: 10.40.4.0/24
      AvailabilityZone: ap-northeast-1a
      MapPublicIpOnLaunch: 'true'
      VpcId: !Ref nnagashimaVPC
      Tags:
        - Key: Name
          Value: nnagashima-privateA

  PriSubnetARouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnetA
      RouteTableId: !Ref PrivateRouteTable

  PrivateSubnetC:
    Type: 'AWS::EC2::Subnet'
    DependsOn: AttachGateway
    Properties:
      CidrBlock: 10.40.5.0/24
      AvailabilityZone: ap-northeast-1c
      MapPublicIpOnLaunch: 'true'
      VpcId: !Ref nnagashimaVPC
      Tags:
        - Key: Name
          Value: nnagashima-privateC

  PriSubnetCRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnetC
      RouteTableId: !Ref PrivateRouteTable

  PrivateSubnetD:    
    Type: 'AWS::EC2::Subnet'
    DependsOn: AttachGateway
    Properties:
      CidrBlock: 10.40.6.0/24
      AvailabilityZone: ap-northeast-1d
      MapPublicIpOnLaunch: 'true'
      VpcId: !Ref nnagashimaVPC
      Tags:
        - Key: Name
          Value: nnagashima-privateD

  PriSubnetDRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnetD
      RouteTableId: !Ref PrivateRouteTable

# インターネットゲートウェイを作成します。

  InternetGateway:
    Type: "AWS::EC2::InternetGateway"
    Properties:
      Tags:
      - Key: Name
        Value: nnagashima-IGW

# 作成したインターネットゲートウェイを上で作成したVPCに紐付けします。

  AttachGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref nnagashimaVPC
      InternetGatewayId: !Ref InternetGateway

# インターネットゲートウェイ経由でインターネットにアクセスできるようにするためにDestinationCidrBlockを
# 0.0.0.0/0としてルートテーブルのルートに追加します。

  RouteTable:
    Type: AWS::EC2::Route
    DependsOn: InternetGateway
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway

# 最後にCloudFormation上で作成した各サブネットとVPCのIDを表示させます。

Outputs:
  nnagashimaVPC:
    Value: !Ref nnagashimaVPC
    Export:
     Name: nnagashimaVPC
  PublicSubnetA:
    Value: !Ref PublicSubnetA
    Export:
     Name: PublicSubnetA
  PublicSubnetC:
    Value: !Ref PublicSubnetC
    Export:
     Name: PublicSubnetC
  PublicSubnetD:
    Value: !Ref PublicSubnetD
    Export:
     Name: PublicSubnetD

  PrivateSubnetA:
    Value: !Ref PrivateSubnetA
    Export:
     Name: PrivateSubnetA
  PrivateSubnetC:
    Value: !Ref PrivateSubnetC
    Export:
     Name: PrivateSubnetC
  PrivateSubnetD:
    Value: !Ref PrivateSubnetD
    Export:
     Name: PrivateSubnetD

最後に

今回これを取り組むにあたって事前にCLIなどは結構前から触っていたので、なんとなくの感覚でサンプルを見ながら作れてしまいました。
そしていざ作れると本当便利だなと実感です!!自分もまだまだだなと痛感しました。。。
またこれを機会にGithubとVisualStadioCodeを真面目に使うようになりました。
今回VPCだけですが、他のサービス関連も作っていき最終的にはGitHubでコードを公開していきたいと思います。