はじめに
AWS CloudFormationを利用してVPC構築のテンプレートのサンプルです。
テンプレートの概要が分からない場合は、はじめてのAWS CloudFormationテンプレートを理解するを参考にしてください。
コードはGitHubにもあります。
今回は、akane というシステムの dev 環境を想定しています。
同じ構成で違う環境を作成する場合は、{環境名}-parameters.jsonを別途作成します。
ディレクトリ構成
akane (システム)
├── network (スタック)
│ ├── dev-parameters.json (dev 環境のパラメータ)
│ └── network.yml (CFnテンプレート)
└── cloud9 (スタック)
├── dev-parameters.json (dev 環境のパラメータ)
└── cloud9.yml (CFnテンプレート)
AWS リソース構築内容
-
networkスタック
- VPC (10.0.0.0/16)
- Publicサブネット1 (10.0.1.0/24)
- Publicサブネット2 (10.0.2.0/24)
- インターネットゲートウェイ
- Publicルートテーブル -
Cloud9スタック
- Cloud9
実行環境の準備
AWS CloudFormationを動かすためのAWS CLIの設定を参考にしてください。
AWS リソース構築手順
-
下記を実行してスタックを作成
./create_stacks.sh
-
下記を実行してスタックを削除
./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
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, 2nd]
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
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}
akanePublicRouteTable:
Value: !Ref akanePublicRouteTable
Export:
Name: !Sub
- ${SystemName}-${EnvType}-public-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.0.0/24"
},
{
"ParameterKey": "PublicSubnet2",
"ParameterValue": "10.0.1.0/24"
}
]
}
2. Cloud9スタック
cloud9.yml
AWSTemplateFormatVersion: 2010-09-09
Description: Cloud9 For Akane
# Metadata:
Parameters:
SystemName:
Type: String
AllowedPattern: '[a-zA-Z0-9-]*'
EnvType:
Description: Environment type.
Type: String
AllowedValues: [dev, stg, prod]
ConstraintDescription: must specify dev, stg or prod.
InstanceType:
Type: String
AllowedPattern: '^[a-z][1-9][.][a-z0-9]+$'
Mappings:
AzMap:
ap-northeast-1:
1st: ap-northeast-1a
2nd: ap-northeast-1d
3rd: ap-northeast-1c
# Conditions
# Transform
Resources:
# Cloud9を作成
akaneCloud9:
Type: AWS::Cloud9::EnvironmentEC2
Properties:
AutomaticStopTimeMinutes: 30
ConnectionType: CONNECT_SSH
Description: !Sub
- ${SystemName}-${EnvType}-cloud9
- {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
InstanceType: !Ref InstanceType
Name: !Sub
- ${SystemName}-${EnvType}-cloud9
- {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
SubnetId:
Fn::ImportValue: !Sub
- ${SystemName}-${EnvType}-public-subnet1
- {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
Tags:
- Key: SystemName
Value: !Ref SystemName
- Key: EnvType
Value: !Ref EnvType
Outputs:
akaneCloud9:
Value: !GetAtt akaneCloud9.Arn
Export:
Name: !Sub
- ${SystemName}-${EnvType}-cloud9-arn
- {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
dev-parameters.json
{
"Parameters": [
{
"ParameterKey": "SystemName",
"ParameterValue": "akane"
},
{
"ParameterKey": "EnvType",
"ParameterValue": "dev"
},
{
"ParameterKey": "InstanceType",
"ParameterValue": "t2.micro"
}
]
}
3. 実行ファイル
create_stacks.sh
#!/bin/sh
SYSTEM_NAME=akane
ENV_TYPE=dev
function create_stack() {
STACK_NAME=$1
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
aws cloudformation wait stack-create-complete \
--stack-name ${SYSTEM_NAME}-${ENV_TYPE}-${STACK_NAME}
}
create_stack network
create_stack cloud9
delete_stacks.sh
#!/bin/sh
SYSTEM_NAME=akane
ENV_TYPE=dev
function delete_stack() {
STACK_NAME=$1
aws cloudformation delete-stack \
--stack-name ${SYSTEM_NAME}-${ENV_TYPE}-${STACK_NAME}
aws cloudformation wait stack-delete-complete \
--stack-name ${SYSTEM_NAME}-${ENV_TYPE}-${STACK_NAME}
}
delete_stack cloud9
delete_stack network