この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
ご機嫌いかがでしょうか、豊崎です。
先日CloudFormationの肩慣らし記事を書きました。
今回は先日作成したstackを更新してリソースを追加していきたいと思います。
準備
環境にリソースを追加する前にCloudFormationの組み込み関数を押さえておきましょう。
CloudFormationを実行するまでわからない値をプロパティに代入するために組み込み関数は使用されます。 今回は「Ref」,「!GetAtt」のみの利用で対応できる内容にしています。
- Fn::Base64
- 条件関数
- Fn::FindInMap
- Fn::GetAtt
- Fn::GetAZs
- Fn::ImportValue
- Fn::Join
- Fn::Select
- Fn::Sub
- Ref
組み込み関数について詳しくは弊社のブログをご参照ください。
AWS CloudFormation テンプレートリファレンス – 組み込み関数(Intrinsic Function)
作成する内容
web3層構造のネットワーク部分の環境とDataSubnetからインターネット通信をするためのNATGatewayを作成します。
*作成したテンプレートを実行すると課金が発生しますので、各自ご判断の上実施ください!!
- VPC(前回作成済み)
- InternetGateway
- NATGateway
- FrontSubnet(1a/1c)
- AppSubnet(1a/1c)
- DataSubnet(1a/1c)
- PublecRouteTableFrontRoute(Front)
- PrivateRouteTableDataRoute(App/Data)
CloudFormationテンプレート
###
AWSTemplateFormatVersion: "2010-09-09"
Resources:
### Create VPC
MyVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsSupport: "true"
EnableDnsHostnames: "true"
InstanceTenancy: default
Tags:
- Key: Name
Value: MyVPC
# ここからが今回の内容です
### CreateInternetGateway
#### InternetGateway
MyIGW:
Type: "AWS::EC2::InternetGateway"
Properties:
Tags:
- Key: Name
Value: IGW
#### AttacheInternetGatewayToVPC
MyIGWAttachVPC:
Type: "AWS::EC2::VPCGatewayAttachment"
Properties:
InternetGatewayId: !Ref MyIGW
VpcId: !Ref MyVPC
# 組み込み関数の「!Ref」を使用してリソース名を取得しています
### CreateNATGateway
#### Elastic IP for NatGateway
MyEIPforNATGW:
Type: "AWS::EC2::EIP"
Properties:
Domain: vpc
#### NatGateway
MyNATGW:
Type: "AWS::EC2::NatGateway"
Properties:
AllocationId:
!GetAtt MyEIPforNATGW.AllocationId
# 組み込み関数の「!GetAtt」を使用してリソースの属性を取得しています
SubnetId:
!Ref MyFrontSubnet1a
### CreateSubnet
#### FrontSubnet1a
MyFrontSubnet1a:
Type: "AWS::EC2::Subnet"
Properties:
VpcId: !Ref MyVPC
AvailabilityZone: ap-northeast-1a
CidrBlock: 10.0.0.0/24
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: MyFrontSubnet1a
#### FrontSubnet1c
MyFrontSubnet1c:
Type: "AWS::EC2::Subnet"
Properties:
VpcId: !Ref MyVPC
AvailabilityZone: ap-northeast-1c
CidrBlock: 10.0.1.0/24
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: MyFrontSubnet1c
#### MyAppSubnet1a
MyAppSubnet1a:
Type: "AWS::EC2::Subnet"
Properties:
VpcId: !Ref MyVPC
AvailabilityZone: ap-northeast-1a
CidrBlock: 10.0.10.0/24
MapPublicIpOnLaunch: false
Tags:
- Key: Name
Value: MyAppSubnet1a
#### MyAppSubnet1c
MyAppSubnet1c:
Type: "AWS::EC2::Subnet"
Properties:
VpcId: !Ref MyVPC
AvailabilityZone: ap-northeast-1c
CidrBlock: 10.0.11.0/24
MapPublicIpOnLaunch: false
Tags:
- Key: Name
Value: MyAppSubnet1c
#### MyDataSubnet1a
MyDataSubnet1a:
Type: "AWS::EC2::Subnet"
Properties:
VpcId: !Ref MyVPC
AvailabilityZone: ap-northeast-1a
CidrBlock: 10.0.20.0/24
MapPublicIpOnLaunch: false
Tags:
- Key: Name
Value: MyDataSubnet1a
#### MyDataSubnet1c
MyDataSubnet1c:
Type: "AWS::EC2::Subnet"
Properties:
VpcId: !Ref MyVPC
AvailabilityZone: ap-northeast-1c
CidrBlock: 10.0.21.0/24
MapPublicIpOnLaunch: false
Tags:
- Key: Name
Value: MyDataSubnet1c
###CreateRouteTable
#### MyPublicRouteTable
MyPublicRouteTable:
Type: "AWS::EC2::RouteTable"
Properties:
VpcId: !Ref MyVPC
Tags:
- Key: Name
Value: MyPublicRouteTable
RouteAddInternet:
Type: "AWS::EC2::Route"
Properties:
DestinationCidrBlock: "0.0.0.0/0"
GatewayId: !Ref MyIGW
RouteTableId: !Ref MyPublicRouteTable
AssociateMyFrontSubnet1aToMyPublicRouteTable:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
RouteTableId: !Ref MyPublicRouteTable
SubnetId: !Ref MyFrontSubnet1a
AssociateMyFrontSubnet1cToMyPublicRouteTable:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
RouteTableId: !Ref MyPublicRouteTable
SubnetId: !Ref MyFrontSubnet1c
#### MyPrivateRouteTable
MyPrivateRouteTable:
Type: "AWS::EC2::RouteTable"
Properties:
VpcId: !Ref MyVPC
Tags:
- Key: Name
Value: MyPrivateRouteTable
RouteAddNATGateway:
Type: "AWS::EC2::Route"
Properties:
DestinationCidrBlock: "0.0.0.0/0"
NatGatewayId: !Ref MyNATGW
RouteTableId: !Ref MyPrivateRouteTable
AssociateMyAppSubnet1aToMyPublicRouteTable:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
RouteTableId: !Ref MyPrivateRouteTable
SubnetId: !Ref MyAppSubnet1a
AssociateMyAppSubnet1cToMyPublicRouteTable:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
RouteTableId: !Ref MyPrivateRouteTable
SubnetId: !Ref MyAppSubnet1c
AssociateMyFrontSubnet1aToMyPrivateRouteTable:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
RouteTableId: !Ref MyPrivateRouteTable
SubnetId: !Ref MyDataSubnet1a
AssociateMyFrontSubnet1cToMyPrivateRouteTable:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
RouteTableId: !Ref MyPrivateRouteTable
SubnetId: !Ref MyDataSubnet1c
ChangeSet(更新箇所の確認)
上記のCloudFormationテンプレートを任意の名前で保存してAWSCLIから更新リソースの確認をします。 ChangeSetはアップデートを実行する前にどのような変更が加えられるかを簡易的に確認することができる機能です。 それでは実際に行いましょう。
$ aws cloudformation create-change-set
--stack-name cm-vpc
--change-set-name cm-updatestack1
--template-body file://cloudformation-update1.yml
### 実際には1行です。
{
"StackId": "arn:aws:cloudformation:ap-northeast-1:XXXXXXXX:stack/cm-vpc/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"Id": "arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:changeSet/cm-updatestack1/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXXXXXX"
}
$ aws cloudformation describe-change-set
--change-set-name cm-updatestack1
--stack-name cm-vpc
### 実際には1行です。
{
"StackId": "arn:aws:cloudformation:ap-northeast-1:XXXXXXXX:stack/cm-vpc/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"Status": "CREATE_COMPLETE",
"ChangeSetName": "cm-updatestack1",
"Changes": [
{
"ResourceChange": {
"Action": "Add",
"ResourceType": "AWS::EC2::SubnetRouteTableAssociation",
"Scope": [],
"Details": [],
"LogicalResourceId": "AssociateMyAppSubnet1aToMyPublicRouteTable"
},
"Type": "Resource"
},
・
・中略
・
{
"ResourceChange": {
"Action": "Add",
"ResourceType": "AWS::EC2::Route",
"Scope": [],
"Details": [],
"LogicalResourceId": "RouteAddInternet"
},
"Type": "Resource"
}
],
"CreationTime": "2017-03-19T02:54:31.281Z",
"Capabilities": [],
"StackName": "cm-vpc",
"NotificationARNs": [],
"ExecutionStatus": "AVAILABLE",
"ChangeSetId": "arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:changeSet/cm-updatestack1/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXXXXXX"
}
今回はリソースの追加だけなので、Actionが「Add」となっていますが、「Modify」、「Remove」があります。 また、Actionが「Modify」の時、リソースの置き換え(作り直し)が発生するかどうかをReplacementで教えてくれます。
コマンドで実行しましたが、もちろんAWSメネジメントコンソールで実行することも可能です。 その場合は以下のように表示されます。さすがにGUIの方がわかりやすいですね。
UpdateStack(実際の更新)
それでは前回作成したStack(VPCのみ)を更新してネットワーク環境を作成しましょう。
*繰り返しになりますが、上記CloudFormationテンプレートを実行すると課金が発生します。
$ aws cloudformation execute-change-set
--change-set-name cm-updatestack1
--stack-name cm-vpc
### 実際には1行です。
さいごに
今回作成したCloudFormationテンプレートでネットワーク環境が作成できます。 ここまで作ってしまえば好きなようにサブネット内にEC2などを構築することができます。 またyaml形式で記載することでコメントの記載や、リソースのブロックごとに行間を開けるなど可読性も高まりますね。