この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので十分ご注意ください。
前提
・NATGatewayを作成しない。
・各VPCが2AZ(Private Subnet:2個、Public Subnet:2個)で構成される。
・CloudFormationのテンプレートをyaml形式とする。
・AWSの管理者ユーザで検証しています。
・AWS CloudShellよりCLI実行することでCloudFormationスタックを作成します。
・AWS CloudShellの使い方を割愛します。
NATGatewayの料金について
NATGatewayを作成しない理由としては、料金が高いからです。
Private SubnetでNATGatewayを使ってインターネットに接続する場合、NATGateway料金が発生します。逆にPublic Subnetでインターネットゲートウェイ(InternetGateway)を使ってインターネットに接続する場合、別途InternetGatewayの料金が発生しません。
検証などで、インターネットに出れる必要がある場合、Public SubnetでEC2などを作成します。インターネットに接続できない場合の検証はPrivate Subnetで作成します。
NAT ゲートウェイの料金(AWS公式より抜粋)
https://aws.amazon.com/jp/vpc/pricing/
VPC 内に NAT ゲートウェイを作成することを選択した場合は、ゲートウェイがプロビジョニングされ利用可能であった "NAT ゲートウェイ時間" に対して料金が請求されます。データ処理料金は、トラフィックの送信元か送信先にかかわらず、NAT ゲートウェイで処理されたギガバイト単位で適用されます。1 時間未満の NAT ゲートウェイ時間は、1 時間分として請求されます。また、NAT ゲートウェイを介して転送されるすべてのデータに対して標準的な AWS データ転送料金が発生します。NAT ゲートウェイへの課金を止めたい場合は、AWS マネジメントコンソール、コマンドラインインターフェイス、API を使用して NAT ゲートウェイを削除します。
リージョン:東京
NAT ゲートウェイあたりの料金 (USD/時) 処理データ 1 GB あたりの料金 (USD)
0.062USD 0.062USD
構成図
CloudFormationテンプレートとパラメーター
テンプレート
パラメーターを設定して再利用可能なテンプレートを作成します。
ファイル名:VPC_NoNatGateway.yaml
AWSTemplateFormatVersion: '2010-09-09'
Description: 'VPC'
Parameters:
# ----------------------------------------------------------------------------#
# Environment Parameters
# ----------------------------------------------------------------------------#
Environment:
Type: String
Description: "Environment"
# ----------------------------------------------------------------------------#
# VPC Parameters
# ----------------------------------------------------------------------------#
VpcCidrBlock:
Type: String
Description: "VpcCidrBlock"
VpcName:
Type: String
Description: "VpcName"
# ----------------------------------------------------------------------------#
# DHCPOptions Parameters
# ----------------------------------------------------------------------------#
DomainName:
Type: String
Description: "DomainName"
DhcpOptionsName:
Type: String
Description: "DhcpOptionsName"
# ----------------------------------------------------------------------------#
# InternetGateway Parameters
# ----------------------------------------------------------------------------#
InternetGatewayName:
Type: String
Description: "InternetGatewayName"
# ----------------------------------------------------------------------------#
# Subnet Parameters
# ----------------------------------------------------------------------------#
#PublicSubnet01 Parameters
PublicSubnet01AvailabilityZone:
Type: String
Description: "PublicSubnet01AvailabilityZone"
PublicSubnet01CidrBlock:
Type: String
Description: "PublicSubnet01CidrBlock"
PublicSubnet01Name:
Type: String
Description: "PublicSubnet01Name"
#PublicSubnet02 Parameters
PublicSubnet02AvailabilityZone:
Type: String
Description: "PublicSubnet02AvailabilityZone"
PublicSubnet02CidrBlock:
Type: String
Description: "PublicSubnet02CidrBlock"
PublicSubnet02Name:
Type: String
Description: "PublicSubnet02Name"
#PrivateSubnet01 Parameters
PrivateSubnet01AvailabilityZone:
Type: String
Description: "PrivateSubnet01AvailabilityZone"
PrivateSubnet01CidrBlock:
Type: String
Description: "PrivateSubnet01CidrBlock"
PrivateSubnet01Name:
Type: String
Description: "PrivateSubnet01Name"
#PrivateSubnet02 Parameters
PrivateSubnet02AvailabilityZone:
Type: String
Description: "PrivateSubnet02AvailabilityZone"
PrivateSubnet02CidrBlock:
Type: String
Description: "PrivateSubnet02CidrBlock"
PrivateSubnet02Name:
Type: String
Description: "PrivateSubnet02Name"
# ----------------------------------------------------------------------------#
# RouteTable Parameters
# ----------------------------------------------------------------------------#
#PublicSubnet01RouteTable Parameters
PublicSubnet01RouteTableName:
Type: String
Description: "PublicSubnet01RouteTableName"
#PublicSubnet02RouteTable Parameters
PublicSubnet02RouteTableName:
Type: String
Description: "PublicSubnet02RouteTableName"
#PrivateSubnet01RouteTable Parameters
PrivateSubnet01RouteTableName:
Type: String
Description: "PrivateSubnet01RouteTableName"
#PrivateSubnet02RouteTable Parameters
PrivateSubnet02RouteTableName:
Type: String
Description: "PrivateSubnet02RouteTableName"
# ----------------------------------------------------------------------------#
# IAMRole Parameters
# ----------------------------------------------------------------------------#
VPCFlowLogsRoleDescription:
Type: String
Description: "VPCFlowLogsRoleDescription"
RoleName:
Type: String
Description: "RoleName. The name created will be 'RoleName-Region'"
# ----------------------------------------------------------------------------#
# IAM Managed Policy Parameters
# ----------------------------------------------------------------------------#
PolicyDescription:
Type: String
Description: "PolicyDescription"
ManagedPolicyName:
Type: String
Description: "PolicyName. The name created will be 'PolicyName-Region'"
# ----------------------------------------------------------------------------#
# LogGroupName Parameters
# ----------------------------------------------------------------------------#
LogGroupName:
Type: String
Description: "VPCFlowLogs LogGroupName"
# ----------------------------------------------------------------------------#
# FlowLog Parameters
# ----------------------------------------------------------------------------#
FlowLogName:
Type: String
Description: "VPCFlowLogsName"
Resources:
# ----------------------------------------------------------------------------#
# VPC
# ----------------------------------------------------------------------------#
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VpcCidrBlock
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: !Ref VpcName
- Key: Env
Value: !Ref Environment
# ----------------------------------------------------------------------------#
# DHCPOptions
# ----------------------------------------------------------------------------#
DHCPOptions:
Type: AWS::EC2::DHCPOptions
Properties:
DomainName: !Ref DomainName
DomainNameServers:
- AmazonProvidedDNS
Tags:
- Key: Name
Value: !Ref DhcpOptionsName
- Key: Env
Value: !Ref Environment
# ----------------------------------------------------------------------------#
# VPC DHCPOptions Association
# ----------------------------------------------------------------------------#
InfraDev1TyoDHCPOptionsAssociation:
Type: AWS::EC2::VPCDHCPOptionsAssociation
Properties:
VpcId: !Ref VPC
DhcpOptionsId: !Ref DHCPOptions
# ----------------------------------------------------------------------------#
# InternetGateway
# ----------------------------------------------------------------------------#
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: !Ref InternetGatewayName
- Key: Env
Value: !Ref Environment
# ----------------------------------------------------------------------------#
# VPC Gateway Attachment
# ----------------------------------------------------------------------------#
IGWAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref InternetGateway
# ----------------------------------------------------------------------------#
# Subnet
# ----------------------------------------------------------------------------#
#PublicSubnet01
PublicSubnet01:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: !Ref PublicSubnet01AvailabilityZone
CidrBlock: !Ref PublicSubnet01CidrBlock
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Ref PublicSubnet01Name
- Key: Env
Value: !Ref Environment
#PublicSubnet02
PublicSubnet02:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: !Ref PublicSubnet02AvailabilityZone
CidrBlock: !Ref PublicSubnet02CidrBlock
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Ref PublicSubnet02Name
- Key: Env
Value: !Ref Environment
#PrivateSubnet01
PrivateSubnet01:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: !Ref PrivateSubnet01AvailabilityZone
CidrBlock: !Ref PrivateSubnet01CidrBlock
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Ref PrivateSubnet01Name
- Key: Env
Value: !Ref Environment
#PrivateSubnet02
PrivateSubnet02:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: !Ref PrivateSubnet02AvailabilityZone
CidrBlock: !Ref PrivateSubnet02CidrBlock
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Ref PrivateSubnet02Name
- Key: Env
Value: !Ref Environment
# ----------------------------------------------------------------------------#
# RouteTable
# ----------------------------------------------------------------------------#
#PublicSubnet01RouteTable
PublicSubnet01RouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Ref PublicSubnet01RouteTableName
- Key: Env
Value: !Ref Environment
#PublicSubnet02RouteTable
PublicSubnet02RouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Ref PublicSubnet02RouteTableName
- Key: Env
Value: !Ref Environment
#PrivateSubnet01RouteTable
PrivateSubnet01RouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Ref PrivateSubnet01RouteTableName
- Key: Env
Value: !Ref Environment
#PrivateSubnet02RouteTable
PrivateSubnet02RouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Ref PrivateSubnet02RouteTableName
- Key: Env
Value: !Ref Environment
# ----------------------------------------------------------------------------#
# Route
# ----------------------------------------------------------------------------#
#PublicSubnet01Route01
PublicSubnet01Route01:
Type: AWS::EC2::Route
DependsOn: IGWAttachment
Properties:
RouteTableId: !Ref PublicSubnet01RouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
#PublicSubnet02Route01
PublicSubnet02Route01:
Type: AWS::EC2::Route
DependsOn: IGWAttachment
Properties:
RouteTableId: !Ref PublicSubnet02RouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
# ----------------------------------------------------------------------------#
# Subnet RouteTable Association
# ----------------------------------------------------------------------------#
#PublicSubnet01RouteTableAssociation
PublicSubnet01RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet01
RouteTableId: !Ref PublicSubnet01RouteTable
#PublicSubnet02RouteTableAssociation
PublicSubnet02RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet02
RouteTableId: !Ref PublicSubnet02RouteTable
#PrivateSubnet01RouteTableAssociation
PrivateSubnet01RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PrivateSubnet01
RouteTableId: !Ref PrivateSubnet01RouteTable
#PrivateSubnet02RouteTableAssociation
PrivateSubnet02RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PrivateSubnet02
RouteTableId: !Ref PrivateSubnet02RouteTable
# ----------------------------------------------------------------------------#
# IAM Role
# ----------------------------------------------------------------------------#
VPCFlowLogsRole:
Type: AWS::IAM::Role
Properties:
Description: !Ref VPCFlowLogsRoleDescription
# RoleName must be set considering multiple regions.
# https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html#cfn-iam-role-rolename
RoleName:
!Join
- '-'
-
- !Ref RoleName
- !Ref AWS::Region
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: "vpc-flow-logs.amazonaws.com"
Action: "sts:AssumeRole"
Path: /
Tags:
- Key: Name
Value:
!Join
- '-'
-
- !Ref RoleName
- !Ref AWS::Region
- Key: Env
Value: !Ref Environment
# ----------------------------------------------------------------------------#
# IAM Managed Policy
# ----------------------------------------------------------------------------#
VPCFlowLogsManagedPolicy:
Type: AWS::IAM::ManagedPolicy
Properties:
Description: !Ref PolicyDescription
# ManagedPolicyName must be set considering multiple regions.
# https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-iam-managedpolicy.html#cfn-iam-managedpolicy-managedpolicyname
ManagedPolicyName:
!Join
- '-'
-
- !Ref ManagedPolicyName
- !Ref AWS::Region
Path: /
Roles:
- !Ref VPCFlowLogsRole
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- "logs:CreateLogGroup"
- "logs:CreateLogStream"
- "logs:PutLogEvents"
- "logs:DescribeLogGroups"
- "logs:DescribeLogStreams"
Resource: "*"
# ----------------------------------------------------------------------------#
# LogGroup
# ----------------------------------------------------------------------------#
VPCFlowLogsLogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Ref LogGroupName
# ----------------------------------------------------------------------------#
# FlowLog
# ----------------------------------------------------------------------------#
FlowLog:
Type: AWS::EC2::FlowLog
Properties:
ResourceType: VPC
ResourceId: !Ref VPC
TrafficType: ALL
LogDestinationType: cloud-watch-logs
LogGroupName: !Ref VPCFlowLogsLogGroup
DeliverLogsPermissionArn: !GetAtt VPCFlowLogsRole.Arn
MaxAggregationInterval: 600
Tags:
- Key: Name
Value: !Ref FlowLogName
- Key: Env
Value: !Ref Environment
Outputs:
# ----------------------------------------------------------------------------#
# VPC Outputs
# ----------------------------------------------------------------------------#
VPC:
Value: !Ref VPC
Export:
Name: !Ref VpcName
# ----------------------------------------------------------------------------#
# Subnet Outputs
# ----------------------------------------------------------------------------#
#PublicSubnet01
PublicSubnet01:
Value: !Ref PublicSubnet01
Export:
Name: !Ref PublicSubnet01Name
#PublicSubnet02
PublicSubnet02:
Value: !Ref PublicSubnet02
Export:
Name: !Ref PublicSubnet02Name
#PrivateSubnet01
PrivateSubnet01:
Value: !Ref PrivateSubnet01
Export:
Name: !Ref PrivateSubnet01Name
#PrivateSubnet02
PrivateSubnet02:
Value: !Ref PrivateSubnet02
Export:
Name: !Ref PrivateSubnet02Name
# ----------------------------------------------------------------------------#
# RouteTable Outputs
# ----------------------------------------------------------------------------#
#PublicSubnet01RouteTable
PublicSubnet01RouteTable:
Value: !Ref PublicSubnet01RouteTable
Export:
Name: !Ref PublicSubnet01RouteTableName
#PublicSubnet02RouteTable
PublicSubnet02RouteTable:
Value: !Ref PublicSubnet02RouteTable
Export:
Name: !Ref PublicSubnet02RouteTableName
#PrivateSubnet01RouteTable
PrivateSubnet01RouteTable:
Value: !Ref PrivateSubnet01RouteTable
Export:
Name: !Ref PrivateSubnet01RouteTableName
#PrivateSubnet02RouteTable
PrivateSubnet02RouteTable:
Value: !Ref PrivateSubnet02RouteTable
Export:
Name: !Ref PrivateSubnet02RouteTableName
パラメーター(Inputファイル)
ファイル名:KbyDev3-Tyo-VPC_NoNatGateway.yaml
StackName: 'KbyDev3-Tyo-VPC'
Parameters:
- ParameterKey: 'Environment'
ParameterValue: 'KbyDev3'
- ParameterKey: 'VpcCidrBlock'
ParameterValue: '10.30.0.0/16'
- ParameterKey: 'VpcName'
ParameterValue: 'KbyDev3-Tyo-Vpc'
- ParameterKey: 'DomainName'
ParameterValue: 'ap-northeast-1.compute.internal'
- ParameterKey: 'DhcpOptionsName'
ParameterValue: 'KbyDev3-Tyo-DhcpOptions'
- ParameterKey: 'InternetGatewayName'
ParameterValue: 'KbyDev3-Tyo-Igw01'
- ParameterKey: 'PublicSubnet01AvailabilityZone'
ParameterValue: 'ap-northeast-1c'
- ParameterKey: 'PublicSubnet01CidrBlock'
ParameterValue: '10.30.0.0/23'
- ParameterKey: 'PublicSubnet01Name'
ParameterValue: 'KbyDev3-Tyo-Subnet-Front01'
- ParameterKey: 'PublicSubnet02AvailabilityZone'
ParameterValue: 'ap-northeast-1a'
- ParameterKey: 'PublicSubnet02CidrBlock'
ParameterValue: '10.30.100.0/23'
- ParameterKey: 'PublicSubnet02Name'
ParameterValue: 'KbyDev3-Tyo-Subnet-Front02'
- ParameterKey: 'PrivateSubnet01AvailabilityZone'
ParameterValue: 'ap-northeast-1c'
- ParameterKey: 'PrivateSubnet01CidrBlock'
ParameterValue: '10.30.2.0/23'
- ParameterKey: 'PrivateSubnet01Name'
ParameterValue: 'KbyDev3-Tyo-Subnet-Back01'
- ParameterKey: 'PrivateSubnet02AvailabilityZone'
ParameterValue: 'ap-northeast-1a'
- ParameterKey: 'PrivateSubnet02CidrBlock'
ParameterValue: '10.30.102.0/23'
- ParameterKey: 'PrivateSubnet02Name'
ParameterValue: 'KbyDev3-Tyo-Subnet-Back02'
- ParameterKey: 'PublicSubnet01RouteTableName'
ParameterValue: 'KbyDev3-Tyo-Rt-Front01'
- ParameterKey: 'PublicSubnet02RouteTableName'
ParameterValue: 'KbyDev3-Tyo-Rt-Front02'
- ParameterKey: 'PrivateSubnet01RouteTableName'
ParameterValue: 'KbyDev3-Tyo-Rt-Back01'
- ParameterKey: 'PrivateSubnet02RouteTableName'
ParameterValue: 'KbyDev3-Tyo-Rt-Back02'
- ParameterKey: 'VPCFlowLogsRoleDescription'
ParameterValue: 'IAMRole associated with the KbyDev3-Tyo-Vpc flow log'
- ParameterKey: 'RoleName'
ParameterValue: 'KbyDev3-Tyo-IamRole-VPCFlowLogs'
- ParameterKey: 'PolicyDescription'
ParameterValue: 'KbyDev3-Tyo-Vpc VPCFlowLogs IAM Managed Policy'
- ParameterKey: 'ManagedPolicyName'
ParameterValue: 'KbyDev3-Tyo-ManagedPolicy-VPCFlowLogs'
- ParameterKey: 'LogGroupName'
ParameterValue: 'KbyDev3-Tyo-Clwlog-VPCFlowLogs'
- ParameterKey: 'FlowLogName'
ParameterValue: 'KbyDev3-Tyo-VPCFlowLogs'
Tags:
- Key: 'Name'
Value: 'VPC'
- Key: 'Env'
Value: 'KbyDev3-Tyo'
CLIでスタックの作成手順
1.予め必要なファイルをAWS CloudShellにアップします。
2.テンプレートファイルとパラメーターファイルが存在していることを確認
[cloudshell-user@ip-10-0-81-133 ~]$ ls -l
total 20
-rw-rw-r-- 1 cloudshell-user cloudshell-user 2506 Jul 16 06:43 KbyDev3-Tyo-VPC_NoNatGateway.yaml
-rw-rw-r-- 1 cloudshell-user cloudshell-user 16034 Jul 16 06:44 VPC_NoNatGateway.yaml
2.スタックの作成
コマンド:
aws cloudformation create-stack --template-body file://テンプレートファイル.yaml --cli-input-yaml file://パラメーターファイル.yaml --capabilities CAPABILITY_NAMED_IAM
コマンド例:
[cloudshell-user@ip-10-0-81-133 ~]$ aws cloudformation create-stack --template-body file://VPC_NoNatGateway.yaml --cli-input-yaml file://KbyDev3-Tyo-VPC_NoNatGateway.yaml --capabilities CAPABILITY_NAMED_IAM
{
"StackId": "arn:aws:cloudformation:ap-northeast-1:887233683286:stack/KbyDev3-Tyo-VPC/a41e8eb0-04d3-11ed-b4e3-0e60318394c1"
}
[cloudshell-user@ip-10-0-81-133 ~]$
作成後の確認
1.スタックの確認
1-1.イベント画面の確認
1-2.リソース画面の確認
1-3.出力画面の確認
VPCのテンプレートで下記の画像のように後続で利用したいリソースをエクスポートしています。
後続のSGやEC2作成する時に「参照例」のように参照できます。
参照例:
VpcId: !ImportValue KbyDev3-Tyo-Vpc
2.VPCコンソールの確認
2-1.NATGatewayがないことを確認
2-2.InternetGatewayがあることを確認
2-3.Private Subnetのルートが1つであることを確認
2-4.Public Subnetのルートが2つであることを確認
まとめ
テンプレートを利用する時、名前の命名ルールを自分の環境に読み替えでください。
VPCのテンプレートで後続で利用したいリソースをエクスポートしています。
後続のSGやEC2作成する時に参照できます。次回の記事は、VPCのエクスポート名を参照してSGを作成したいと思います。
少しでもお役に立てれば幸いです。
参考
CloudFormation でよく使うAWS CLIコマンド
AWS CloudFormationでEC2AutoScalingを作成してみました(CLI)
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc.html
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html