LoginSignup
1
1

More than 3 years have passed since last update.

AWS CloudFormationで2層ネットワークを構築しよう

Last updated at Posted at 2020-10-27

はじめに

AWS CloudFormationを利用して、2層ネットワークを構築するテンプレートのサンプルです。

テンプレートの概要が分からない場合は、はじめてのAWS CloudFormationテンプレートを理解するを参考にしてください。

コードはGitHubにもあります。

今回は、akane というシステムの dev 環境を想定しています。
同じ構成で違う環境を作成する場合は、{環境名}-parameters.jsonを別途作成します。

ディレクトリ構成
akane (システム)
  └─ network (スタック)
      ├─ network.yml (CFnテンプレート)
      └─ dev-parameters.json (dev 環境のパラメータ)

AWS リソース構築内容

  • VPC (10.0.0.0/16)
  • Publicサブネット1 (10.0.1.0/24)
  • Publicサブネット2 (10.0.2.0/24)
  • Privateサブネット1 (10.0.11.0/24)
  • Privateサブネット2 (10.0.12.0/24)
  • インターネットゲートウェイ
  • Publicルートテーブル
  • Elastic IP (NATゲートウェイ用)
  • NATゲートウェイ
  • Privateルートテーブル

AWS システム構成図

network.png

実行環境の準備

AWS CloudFormationを動かすためのAWS CLIの設定を参考にしてください。

AWS リソース構築手順

  1. 下記を実行してスタックを作成

    ./create_stacks.sh
    
  2. 下記を実行してスタックを削除

    ./delete_stacks.sh
    

構築テンプレート

1. networkスタック

network.yml
AWSTemplateFormatVersion: 2010-09-09
Description: Network For Akane

# Metadata:

Parameters:
  SystemName:
    Type: String
    AllowedPattern: '[a-zA-Z0-9-]*'
  EnvType:
    Description: Environment type.
    Type: String
    AllowedValues: [all, dev, stg, prod]
    ConstraintDescription: must specify all, dev, stg, or prod.
  VPCCidrBlock:
    Type: String
    AllowedPattern: (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/16
  PublicSubnet1:
    Type: String
    AllowedPattern: (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/24
  PublicSubnet2:
    Type: String
    AllowedPattern: (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/24
  PrivateSubnet1:
    Type: String
    AllowedPattern: (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/24
  PrivateSubnet2:
    Type: String
    AllowedPattern: (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/24

Mappings: 
  AzMap: 
    ap-northeast-1:
      1st: ap-northeast-1a
      2nd: ap-northeast-1c
      3rd: ap-northeast-1d

# Conditions

# Transform

Resources:
  # VPC作成
  akaneVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VPCCidrBlock
      EnableDnsSupport: true
      EnableDnsHostnames: true
      InstanceTenancy: default
      Tags:
        - Key: Name
          Value: !Sub
          - ${SystemName}-${EnvType}-vpc
          - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
        - Key: SystemName
          Value: !Ref SystemName
        - Key: EnvType
          Value: !Ref EnvType

###########################################################################
# Publicサブネット関連
###########################################################################
  # Publicサブネット作成
  akanePublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref akaneVPC
      CidrBlock: !Ref PublicSubnet1
      AvailabilityZone: !FindInMap [AzMap, !Ref AWS::Region, 1st]
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Sub
          - ${SystemName}-${EnvType}-public-subnet1
          - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
        - Key: SystemName
          Value: !Ref SystemName
        - Key: EnvType
          Value: !Ref EnvType
  akanePublicSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref akaneVPC
      CidrBlock: !Ref PublicSubnet2
      AvailabilityZone: !FindInMap [AzMap, !Ref AWS::Region, 3rd]
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Sub
          - ${SystemName}-${EnvType}-public-subnet2
          - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
        - Key: SystemName
          Value: !Ref SystemName
        - Key: EnvType
          Value: !Ref EnvType
  # インターネットゲートウェイ作成
  akaneInternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: !Sub
          - ${SystemName}-${EnvType}-igw
          - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
        - Key: SystemName
          Value: !Ref SystemName
        - Key: EnvType
          Value: !Ref EnvType
  # インターネットゲートウェイをVPCにアタッチ
  akaneVPCGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref akaneVPC
      InternetGatewayId: !Ref akaneInternetGateway
  # Publicルートテーブル作成
  akanePublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref akaneVPC
      Tags:
        - Key: Name
          Value: !Sub
          - ${SystemName}-${EnvType}-public-route
          - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
        - Key: SystemName
          Value: !Ref SystemName
        - Key: EnvType
          Value: !Ref EnvType
  # Publicルートテーブル サブネット関連付け
  akanePublicSubnetRouteTableAssociation1:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref akanePublicSubnet1
      RouteTableId: !Ref akanePublicRouteTable
  akanePublicSubnetRouteTableAssociation2:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref akanePublicSubnet2
      RouteTableId: !Ref akanePublicRouteTable
  # Publicルートテーブル ルートにインターネットゲートウェイを関連付ける
  akanePublicRoute:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref akanePublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref akaneInternetGateway

###########################################################################
# Privateサブネット関連
###########################################################################
  # Privateサブネット作成
  akanePrivateSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref akaneVPC
      CidrBlock: !Ref PrivateSubnet1
      AvailabilityZone: !FindInMap [AzMap, !Ref AWS::Region, 1st]
      MapPublicIpOnLaunch: false
      Tags:
        - Key: Name
          Value: !Sub
          - ${SystemName}-${EnvType}-private-db-1
          - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
        - Key: SystemName
          Value: !Ref SystemName
        - Key: EnvType
          Value: !Ref EnvType
  akanePrivateSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref akaneVPC
      CidrBlock: !Ref PrivateSubnet2
      AvailabilityZone: !FindInMap [AzMap, !Ref AWS::Region, 3rd]
      MapPublicIpOnLaunch: false
      Tags:
        - Key: Name
          Value: !Sub
          - ${SystemName}-${EnvType}-private-db-2
          - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
        - Key: SystemName
          Value: !Ref SystemName
        - Key: EnvType
          Value: !Ref EnvType
  # Privateルートテーブル作成
  akanePrivateRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref akaneVPC
      Tags:
        - Key: Name
          Value: !Sub
          - ${SystemName}-${EnvType}-private-route
          - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
        - Key: SystemName
          Value: !Ref SystemName
        - Key: EnvType
          Value: !Ref EnvType
  # Privateルートテーブル サブネット関連付け
  akanePrivateSubnetRouteTableAssociation1:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref akanePrivateSubnet1
      RouteTableId: !Ref akanePrivateRouteTable
  akanePrivateSubnetRouteTableAssociationWeb2:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref akanePrivateSubnet2
      RouteTableId: !Ref akanePrivateRouteTable
  # NATゲートウェイ用ElasticIP作成
  akaneNATGatewayEIP:
    Type: AWS::EC2::EIP
    Properties:
      Domain: vpc
      Tags:
      - Key: Name
        Value: !Sub
        - ${SystemName}-${EnvType}-natgw-eip
        - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
      - Key: SystemName
        Value: !Ref SystemName
      - Key: EnvType
        Value: !Ref EnvType
  # NATゲートウェイ作成
  akaneNATGateway:
    Type: AWS::EC2::NatGateway
    Properties:
      AllocationId: !GetAtt akaneNATGatewayEIP.AllocationId
      SubnetId: !Ref akanePrivateSubnet1
      Tags:
      - Key: Name
        Value: !Sub
        - ${SystemName}-${EnvType}-natgw
        - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
      - Key: SystemName
        Value: !Ref SystemName
      - Key: EnvType
        Value: !Ref EnvType        
  # Privateルートテーブル ルートにNATゲートウェイを関連付ける
  akanePrivateRoute:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref akanePrivateRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      NatGatewayId: !Ref akaneNATGateway

Outputs:
  akaneVPC:
    Value: !Ref akaneVPC
    Export:
      Name: !Sub
        - ${SystemName}-${EnvType}-vpc
        - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
  akanePublicSubnet1:
    Value: !Ref akanePublicSubnet1
    Export:
      Name: !Sub
        - ${SystemName}-${EnvType}-public-subnet1
        - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
  akanePublicSubnet2:
    Value: !Ref akanePublicSubnet2
    Export:
      Name: !Sub
        - ${SystemName}-${EnvType}-public-subnet2
        - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
  akanePrivateSubnet1:
    Value: !Ref akanePrivateSubnet1
    Export:
      Name: !Sub
        - ${SystemName}-${EnvType}-private-subnet1
        - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
  akanePrivateSubnet2:
    Value: !Ref akanePrivateSubnet2
    Export:
      Name: !Sub
        - ${SystemName}-${EnvType}-private-subnet2
        - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
  akanePublicRouteTable:
    Value: !Ref akanePublicRouteTable
    Export:
      Name: !Sub
        - ${SystemName}-${EnvType}-public-route-table
        - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
  akanePrivateRouteTable:
    Value: !Ref akanePrivateRouteTable
    Export:
      Name: !Sub
        - ${SystemName}-${EnvType}-private-route-table
        - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
dev-parameters.json
{
    "Parameters": [
        {
            "ParameterKey": "SystemName",
            "ParameterValue": "akane"
        },
        {
            "ParameterKey": "EnvType",
            "ParameterValue": "dev"
        },
        {
            "ParameterKey": "VPCCidrBlock",
            "ParameterValue": "10.0.0.0/16"
        },
        {
            "ParameterKey": "PublicSubnet1",
            "ParameterValue": "10.0.1.0/24"
        },
        {
            "ParameterKey": "PublicSubnet2",
            "ParameterValue": "10.0.2.0/24"
        },
        {
            "ParameterKey": "PrivateSubnet1",
            "ParameterValue": "10.0.11.0/24"
        },
        {
            "ParameterKey": "PrivateSubnet2",
            "ParameterValue": "10.0.12.0/24"
        }
    ]
}

2. 実行ファイル

create_stacks.sh
#!/bin/sh
SYSTEM_NAME=akane
ENV_TYPE=dev
STACK_NAME=network

aws cloudformation create-stack \
--stack-name ${SYSTEM_NAME}-${ENV_TYPE}-${STACK_NAME} \
--template-body file://./${SYSTEM_NAME}/${STACK_NAME}/${STACK_NAME}.yml \
--cli-input-json file://./${SYSTEM_NAME}/${STACK_NAME}/${ENV_TYPE}-parameters.json
delete_stacks.sh
#!/bin/sh
SYSTEM_NAME=akane
ENV_TYPE=dev
STACK_NAME=network

aws cloudformation delete-stack \
--stack-name ${SYSTEM_NAME}-${ENV_TYPE}-${STACK_NAME}
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1