【初心者向け】VPC+PublicSubnetをCloudFormationを使って構築する 前編

記事タイトルとURLをコピーする

IaC っていいですよね。
ということで今回は CloudFormation を触ってみます。

記事目安...15 分

事前知識

CloudFormation とは

AWS リソースやサードパーティ製アプリケーションリソースをコードのように定義して作成するサービスです。 AWS 上で IaC を実現したい場合は欠かせないサービスとなります。

CloudFormation の利用料金はなんと無料です。 しかし、当然 CloudFormation を経由して構築されたリソースには、そのサービスごとに利用料金が掛かりますのでご注意ください。

参考: AWS CloudFormation

ゴール

今回は前編・後編に分けてやっていきます。

前編では以下のリソースのテンプレートファイルを作成することに注力し、 後編では実際にデプロイしてみようと思います。

Resource Number
VPC 1
PublicSubnet 1
InternetGW 1
RouteTable 1

最終的に出来上がる構成図イメージは以下です。

f:id:swx-sugaya:20200813132940p:plain

Cfn テンプレート作成の流れ

ここから Cfn テンプレート作成の流れと各ポイントを解説しながらすすめます。

最終的に出来上がる Cfn テンプレートは 本記事の 付録 > cfn-template_vpc-and-pubsub.yaml をご参考ください。

セクションの定義

そもそもの前提として、CloudFormation テンプレートの記述は "セクション" という単位に分かれています。

今回は以下 2 セクションを扱います。

Key Value
Parameters ユーザが独自のパラメータを定義するセクション
Resources 各 AWS リソースを定義するセクション



したがって、まずは Yaml に各セクションを記載します。

Parameters:

Resources:

※作成過程をわかりやすくするためにあえてこのように書いてます。
これだけでは Yaml シンタックスとしては誤りなので注意してください。

VPC の定義

ここから各種 AWS リソースを定義します。




まずは、VPCを定義します。

以下ページに載っている VPC を定義するのに必要な項目を確認して、貼り付けましょう。 なお、値には許容される型が記述されています。

参考: AWS::EC2::VPC

Parameters:

Resources:
  MyVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: String
      EnableDnsHostnames: Boolean
      EnableDnsSupport: Boolean
      InstanceTenancy: String
      Tags:
        - Tag




各Resourceには論理IDと呼ばれる一意の名前を付けることができます。 ここではMyVPCとしました。

Resources:
  MyVPC:




続いて各項目を編集します。

各項目と値の詳細については先ほどの AWS 公式ページ(AWS::EC2::VPC)をご確認ください。

Parameters:

Resources:
  MyVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcCidrBlock
      EnableDnsHostnames: true
      EnableDnsSupport: true
      InstanceTenancy: default
      Tags:
        - Key: Name
          Value: !Ref VpcName




ここで突然でてきた "!Ref" に皆さん困惑されたのではないでしょうか。

    Properties:
      CidrBlock: !Ref VpcCidrBlock
~省略~
      Tags:
        - Key: Name
          Value: !Ref VpcName

これは CloudFormation で組み込み関数の一つ Ref 関数です。(※1)
機能は指定したパラメータの値を参照できます。

組み込み関数 Ref は、指定したパラメータまたはリソースの値を返します。
引用元: https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-ref.html

ここでは、ユーザ定義のパラメータとして以下の値を参照させます。(このパラメータ自体の定義はのちほど定義します。)

  • VPC の CIDR を格納する VpcCidrBlock
  • VPC の名前を格納する VpcName



※1 CloudFormationにはたくさんの関数が用意されているので、気になった人は確認してみてください。
参考: 組み込み関数リファレンス

※2 Ref 関数の完全系は "Ref: xxx" であり、"!Ref" は短縮系となります。

短縮形の構文
引用元: https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-ref.html




今回は、事前に用意されていない VpcName を Ref 関数で参照したため、参照先を定義する必要があります。(※3)

この定義は、Parameter セクションにて行います。

パラメータ ドキュメントを参考に、以下値をそれぞれ記述します。

Key Value
Description パラメータの説明
Type パラメータの型
Default デフォルトで入力されるパラメータの値
Parameters:
  VpcCidrBlock:
    Description: Input a VPC IPv4 CidrBlock. ex) 192.168.2.0/24
    Type: String
  VpcName:
    Description: Input a VPC name. This Parameter will be a Name tag.
    Type: String
    Default: ""

Resources:
  MyVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcCidrBlock
      EnableDnsHostnames: true
      EnableDnsSupport: true
      InstanceTenancy: default
      Tags:
        - Key: Name
          Value: !Ref VpcName

※3 パラメータの中には事前に AWS により用意されたパラメータもございます。

擬似パラメータは、AWS CloudFormation によって事前定義されたパラメータです。
引用元: https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/pseudo-parameter-reference.html




これでVPCが完成です。

Public Subnet の定義

続いて Public Subnet を定義します。




以下ページにサブネットの定義パラメータがあるので、確認しながら進めてください。

参考:AWS::EC2::Subnet

今回は論理 ID を MyPublicSubnet で定義します。

Parameters:
~省略~

Resources:
~省略~

  MyPublicSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      AssignIpv6AddressOnCreation: Boolean
      AvailabilityZone: String
      CidrBlock: String
      Ipv6CidrBlock: String
      MapPublicIpOnLaunch: Boolean
      Tags:
        - Tag
      VpcId: String




先ほどの公式ドキュメントを確認しながら、各項目を編集します。

Parameters:
~省略~

Resources:
~省略~
  MyPublicSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Ref AZ
      CidrBlock: !Ref PublicSubnetCidrBlock
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Ref PublicSubnetName
      VpcId: !Ref MyVPC

今回は、PublicSubnetCidrBlock, PublicSubnetName AZ の 3 つのユーザ定義パラメータを追加しました。


ここで新しい Ref 関数の使い方が出てきたので解説します。

VpcId: !Ref MyVPC

Ref 関数はパラメータだけでなく、論理 ID を参照できます。この場合、リソースごとに決まった値を返します。

例えば、参照する論理 ID が VPC リソースの場合、 VPC ID を返してくれます。

Return values Ref When you pass the logical ID of this resource to the intrinsic Ref function, Ref returns the ID of the VPC.
引用元: https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc.html

リソースごとに、どんな値を参照するかは、各リソースドキュメントをご確認ください。




ユーザ定義パラメータを追加したので、Parameters セクションも変更します。

今回は、PublicSubnetCidrBlock, PublicSubnetName AZ の 3 つのユーザ定義パラメータを追加しました。

Parameters:
~省略~
  AZ:
    Description: Input a AZ where Public Subnet will be created.
    Type: AWS::EC2::AvailabilityZone::Name
  PublicSubnetCidrBlock:
    Description: Input a Public Subnet IPv4 CidrBlock.  ex) 192.168.2.0/25
    Type: String
  PublicSubnetName:
    Description: Input a Public Subnet name. This Parameter will be a Name tag.
    Type: String
    Default: ""

Resources:
~省略~
  MyPublicSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Ref AZ
      CidrBlock: !Ref PublicSubnetCidrBlock
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Ref PublicSubnetName
      VpcId: !Ref MyVPC




ここでポイントとなるのは AWS::EC2::AvailabilityZone::Name です。

  AZ:
    Description: Input a AZ where Public Subnet will be created.
    Type: AWS::EC2::AvailabilityZone::Name

AWS::EC2::AvailabilityZone::Name は AWS 固有の型となります。

通常の String 型などとは異なり、アベイラビリティゾーンを表す型となります。
この型を宣言することで、対象のパラメータ値は、マネコンの現在のリージョンをもとにアベイラビリティゾーン一覧の中から選択が可能です。

AWS 固有の型は他にも色々あるため、利用してみてください。

AWS 固有のパラメータタイプ
引用元: https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html#aws-specific-parameter-types)




これでサブネットの定義も完成です。

InternetGateway の定義

InternetGateway(以下 IGW)を定義します。




以下を参考に IGW に必要なパラメータ値を定義します。

参考:AWS::EC2::InternetGateway

今までと同じ流れなので詳細は割愛します。

Parameters:
~省略~
  InternetGwName:
    Description: Input a IntenetGW name. This Parameter will be a Name tag.
    Type: String
    Default: ""

Resources:
~省略~
  MyInternetGW:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: !Ref InternetGwName




IGW を作成したので VPC と関連付けます。

IGW と VPC を関連付けるためには VPCGatewayAttachment と呼ばれるリソースが必要です。(マネコンで構築する場合は暗黙的に作成されるリソースとなります。)

こちらも以下を参考に、今までと同様に定義します。

参考: AWS::EC2::VPCGatewayAttachment

Parameters:
~省略~

Resources:
~省略~
  MyVPCGatewayAttachment:
  Type: AWS::EC2::VPCGatewayAttachment
  Properties:
    InternetGatewayId: !Ref MyInternetGW
    VpcId: !Ref MyVPC

これで IGW まわりの定義は完了です。

RouteTable の定義

RouteTable を定義します。

こちらも以下を参考に、今までと同様に定義します。

参考:AWS::EC2::RouteTable

Parameters:
~省略~
  RouteTableName:
    Description: Input a RouteTable name. This Parameter will be a Name tag.
    Type: String
    Default: ""

Resources:
~省略~
  MyRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      Tags:
        - Key: Name
          Value: !Ref RouteTableName
      VpcId: !Ref MyVPC




次にルートテーブルのルーティングを定義します。以下を参考に同様に定義してください。

※local ターゲットへのルーティングは自動で設定されます。明示的な定義は不要です。

参考: AWS::EC2::Route

~省略~
Resources:
~省略~
  MyPublicRoute:
    Type: AWS::EC2::Route
    Properties:
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref MyInternetGW
      RouteTableId: !Ref MyRouteTable




さらに RouteTable と Subnet を関連付けます。

VPC と IGW を関連付けるリソースが必要だったのと同様、Subnet と RouteTable も関連付けるためのリソースが必要です。

以下を参考に定義します。

参考: AWS::EC2::SubnetRouteTableAssociation

~省略~
Resources:
~省略~
  MySubnetRouteTableAssociation:
      Type: AWS::EC2::SubnetRouteTableAssociation
      Properties:
        RouteTableId: !Ref MyRouteTable
        SubnetId: !Ref MyPublicSubnet

これで RouteTable の定義も完了です。

確認

ということでテンプレートファイルができました。

完成版は本記事の 付録 > cfn-template_vpc-and-pubsub.yaml をご確認ください。

まとめ

前編では CloudFormation で使うテンプレートファイルの書き方についてまとめました。

基本は AWS ドキュメントの見方さえわかってしまえば記述自体はすぐできそうですが、RouteTable のように複数にリソースに分割して定義するのはちょっと大変だなあという印象です。

後半では、実際に作ったテンプレート流していきます。

【初心者向け】VPC+PublicSubnet を CloudFormation を使って構築する 後編

ご覧いただきありがとうございました。

付録

cfn-template_vpc-and-pubsub.yaml

Parameters:
  # VPC
  VpcCidrBlock:
    Description: Input a VPC IPv4 CidrBlock. ex) 192.168.2.0/24
    Type: String
  VpcName:
    Description: Input a VPC name. This Parameter will be a Name tag.
    Type: String
    Default: ""

  # Public Subnet
  AZ:
    Description: Input a AZ where Public Subnet will be created.
    Type: AWS::EC2::AvailabilityZone::Name
  PublicSubnetCidrBlock:
    Description: Input a Public Subnet IPv4 CidrBlock.  ex) 192.168.2.0/25
    Type: String
  PublicSubnetName:
    Description: Input a Public Subnet name. This Parameter will be a Name tag.
    Type: String
    Default: ""

  # Internet GW
  InternetGwName:
    Description: Input a IntenetGW name. This Parameter will be a Name tag.
    Type: String
    Default: ""

  # RouteTable for Public Subnet
  RouteTableName:
    Description: Input a RouteTable name. This Parameter will be a Name tag.
    Type: String
    Default: ""

Resources:
  # VPC
  MyVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcCidrBlock
      EnableDnsHostnames: true
      EnableDnsSupport: true
      InstanceTenancy: default
      Tags:
        - Key: Name
          Value: !Ref VpcName

  # PublicSubnet
  MyPublicSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Ref AZ
      CidrBlock: !Ref PublicSubnetCidrBlock
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Ref PublicSubnetName
      VpcId: !Ref MyVPC

  # InternetGW
  MyInternetGW:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: !Ref InternetGwName

  MyVPCGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      InternetGatewayId: !Ref MyInternetGW
      VpcId: !Ref MyVPC

  # RouteTable for Public Subnet
  MyRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      Tags:
        - Key: Name
          Value: !Ref RouteTableName
      VpcId: !Ref MyVPC

  MyPublicRoute:
    Type: AWS::EC2::Route
    Properties:
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref MyInternetGW
      RouteTableId: !Ref MyRouteTable

  MySubnetRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref MyRouteTable
      SubnetId: !Ref MyPublicSubnet

菅谷 歩 (記事一覧)