CloudFormationを使ってNAT Gatewayを構築する


はじめに

本記事では、AWS CloudFormation管理コンソールを使って、NAT Gatewayを構築する手順を説明しています。(初学者向け)

本記事で掲載しているテンプレートの最新版は、下記に置いてます。
https://github.com/okubo-t/aws-cloudformation

構成図

構築するコンポーネント

NATゲートウェイ
EIP(Elastic IP アドレス)
ルーティングテーブルの更新

前提条件

下記の記事の構築手順で、VPCを構築していること。
CloudFormationを使ってVPCを構築する

PJPrefixの値は、同一にすること。

構築手順

1 AWS CloudFormation管理コンソールから、スタックの作成をクリックします。

2 後述のテンプレートを選択します。

3 各パラメータを入力します。

パラメータ名 用途 備考
スタックの名前 テンプレートから作成するリソース一式の名前 例 prd-stack-nat-20180801
PJPrefix 構築するプロジェクトの環境を識別するために各コンポーネントの先頭に付与する識別子 例 qiita-prd
NATGatewayACreate 構成図のPublic SubnetAに作成する場合は、true
構成図のPublic SubnetAに作成しない場合は、false
true(デフォルト)
NATGatewayCCreate 構成図のPublic SubnetCに作成する場合は、true
構成図のPublic SubnetCに作成しない場合は、false
true(デフォルト)

注意事項:NATGatewayACreateとNATGatewayCCreateのどちらか一方は、trueにしない場合、エラーになります。

4 後続は、デフォルトのまま次へ次へで、作成します。
状況が CREATE COMPLETEになれば、NAT Gatewayの構築が完了です。

テンプレート

natgateway.yml
AWSTemplateFormatVersion: "2010-09-09"
Description:
  NAT Gateway Create

Metadata:
  "AWS::CloudFormation::Interface":
    ParameterGroups:
      - Label:
          default: "Project Name Prefix"
        Parameters:
          - PJPrefix

      - Label: 
          default: "NATGateway Configuration"
        Parameters: 
          - NATGatewayACreate
          - NATGatewayCCreate

    ParameterLabels: 
      NATGatewayACreate: 
        default: "NATGatewayACreate"
      NATGatewayCCreate: 
        default: "NATGatewayCCreate"

# ------------------------------------------------------------#
# Input Parameters
# ------------------------------------------------------------# 
Parameters:
  PJPrefix:
    Type: String

  NATGatewayACreate: 
    Default: true
    Type: String
    AllowedValues: 
      - true
      - false

  NATGatewayCCreate:
    Default: true
    Type: String
    AllowedValues:
      - true
      - false

# ------------------------------------------------------------#
# Conditions
# ------------------------------------------------------------# 
Conditions: 
  IsCreateNATGatewayA: !Equals [ !Ref NATGatewayACreate, true ]
  IsCreateNATGatewayAfalse: !Equals [ !Ref NATGatewayACreate, false ]

  IsCreateNATGatewayC: !Equals [ !Ref NATGatewayCCreate, true ]
  IsCreateNATGatewayCfalse: !Equals [ !Ref NATGatewayCCreate, false ]

# ------------------------------------------------------------#
#  NAT Gateway AZ:A
# ------------------------------------------------------------#
Resources:
# NATGatewayA Create
  NATGatewayA: 
    Type: "AWS::EC2::NatGateway"
    Condition: IsCreateNATGatewayA
    Properties: 
      AllocationId: !GetAtt NATGatewayAEIP.AllocationId 
      SubnetId: { "Fn::ImportValue": !Sub "${PJPrefix}-public-subnet-a" }
      Tags: 
        - Key: Name
          Value: !Sub "${PJPrefix}-natgw-a"

# NATGateway For EIP Create
  NATGatewayAEIP: 
    Type: "AWS::EC2::EIP"
    Condition: IsCreateNATGatewayA
    Properties: 
      Domain: vpc

# PrivateRouteA Update
  PrivateRouteA: 
    Type: "AWS::EC2::Route"
    Condition: IsCreateNATGatewayA
    Properties: 
      RouteTableId: { "Fn::ImportValue": !Sub "${PJPrefix}-private-route-a" }
      DestinationCidrBlock: "0.0.0.0/0"
      NatGatewayId: !Ref NATGatewayA

# PrivateRouteC Update (NATGatewayC NO Create)
  PrivateRouteC2: 
    Type: "AWS::EC2::Route"
    Condition: IsCreateNATGatewayCfalse
    Properties: 
      RouteTableId: { "Fn::ImportValue": !Sub "${PJPrefix}-private-route-c" }
      DestinationCidrBlock: "0.0.0.0/0"
      NatGatewayId: !Ref NATGatewayA

# ------------------------------------------------------------#
#  NAT Gateway AZ:C
# ------------------------------------------------------------#
# NATGatewayC Create
  NATGatewayC:
    Type: "AWS::EC2::NatGateway"
    Condition: IsCreateNATGatewayC
    Properties:
      AllocationId: !GetAtt NATGatewayCEIP.AllocationId 
      SubnetId: { "Fn::ImportValue": !Sub "${PJPrefix}-public-subnet-c" }
      Tags:
        - Key: Name
          Value: !Sub "${PJPrefix}-natgw-c"

# NATGateway For EIP Create
  NATGatewayCEIP:
    Type: "AWS::EC2::EIP"
    Condition: IsCreateNATGatewayC
    Properties:
      Domain: vpc

# PrivateRouteC Update
  PrivateRouteC:
    Type: "AWS::EC2::Route"
    Condition: IsCreateNATGatewayC
    Properties:
      RouteTableId: { "Fn::ImportValue": !Sub "${PJPrefix}-private-route-c" }
      DestinationCidrBlock: "0.0.0.0/0"
      NatGatewayId: !Ref NATGatewayC

# PrivateRouteA Update (NATGatewayA NO Create)
  PrivateRouteA2: 
    Type: "AWS::EC2::Route"
    Condition: IsCreateNATGatewayAfalse
    Properties: 
      RouteTableId: { "Fn::ImportValue": !Sub "${PJPrefix}-private-route-a" }
      DestinationCidrBlock: "0.0.0.0/0"
      NatGatewayId: !Ref NATGatewayC

# ------------------------------------------------------------#
# Output Parameters
# ------------------------------------------------------------#                
Outputs:
# NATGateway EIP
  NATGatewayAEIP:
    Condition: IsCreateNATGatewayA
    Value: !Ref NATGatewayAEIP
    Export:
      Name: !Sub "${PJPrefix}-natgw-a-eip"

  NATGatewayCEIP:
    Condition: IsCreateNATGatewayC
    Value: !Ref NATGatewayCEIP
    Export:
      Name: !Sub "${PJPrefix}-natgw-c-eip"