はじめに
今回はCloudFormationのクロススタック参照を試してみたいと思います。
前回作成したVPCテンプレートを修正し、S3&VPCエンドポイントのテンプレートから参照できるようにいたします。
AWS CloudFormation で YAML テンプレートとクロススタックリファレンスをサポート
#テンプレートファイル
VPC作成テンプレートでOutputsセクションを追加し、
ルートテーブルとサブネットをエクスポートするように記載しております。
※Exportする名前はAWSアカウントおよびリージョンで一意にする必要があるので
被らないように命名規則を作ってください。
今回はリソース同様、<環境>-<システム名>-<リソース名>という形にしてます。
以下、VPC作成テンプレート
CFn_CreateVPCsubnet.yaml
AWSTemplateFormatVersion: '2010-09-09'
Description:
VPC & subnet create
Parameters:
EnvType:
Description: Environment type.
Default: dev
Type: String
AllowedValues:
- dev
- mnt
- prd
ConstraintDescription: must specify dev or mnt or prd.
ProjectId:
Description: Project name id.
Type: String
MinLength: "3"
MaxLength: "3"
AllowedPattern: "[a-zA-Z0-9]*"
ConstraintDescription: must specify Project id.
Resources:
# Create VPC
MyVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/24
EnableDnsSupport: 'true'
EnableDnsHostnames: 'true'
InstanceTenancy: default
Tags:
- Key: Name
Value: !Join [ "-", [ "Ref":"EnvType" , "Ref":"ProjectId" ,"vpc" ] ]
# Create Public RouteTable
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref MyVPC
Tags:
- Key: Name
Value: !Join [ "-", [ "Ref":"EnvType" , "Ref":"ProjectId" ,"pub-route" ] ]
# Create Private RouteTable
PrivateRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref MyVPC
Tags:
- Key: Name
Value: !Join [ "-", [ "Ref":"EnvType" , "Ref":"ProjectId" ,"pri-route" ] ]
# Create Public Subnet A
PublicSubnetA:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MyVPC
CidrBlock: 10.0.0.0/27
AvailabilityZone: "ap-northeast-1a"
Tags:
- Key: Name
Value: !Join [ "-", [ "Ref":"EnvType" , "Ref":"ProjectId" ,"PublicSunetA" ] ]
PubSubnetARouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnetA
RouteTableId: !Ref PublicRouteTable
# Create Public Subnet C
PublicSubnetC:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MyVPC
CidrBlock: 10.0.0.32/27
AvailabilityZone: "ap-northeast-1c"
Tags:
- Key: Name
Value: !Join [ "-", [ "Ref":"EnvType" , "Ref":"ProjectId" ,"PublicSunetC" ] ]
PubSubnetCRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnetC
RouteTableId: !Ref PublicRouteTable
# Create Private Subnet A
PrivateSubnetA:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MyVPC
CidrBlock: 10.0.0.64/27
AvailabilityZone: "ap-northeast-1a"
Tags:
- Key: Name
Value: !Join [ "-", [ "Ref":"EnvType" , "Ref":"ProjectId" ,"PrivateSubnetA" ] ]
PriSubnetARouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PrivateSubnetA
RouteTableId: !Ref PrivateRouteTable
# Create Private Subnet C
PrivateSubnetC:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MyVPC
CidrBlock: 10.0.0.96/27
AvailabilityZone: "ap-northeast-1c"
Tags:
- Key: Name
Value: !Join [ "-", [ "Ref":"EnvType" , "Ref":"ProjectId" ,"PrivateSubnetC" ] ]
PriSubnetCRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PrivateSubnetC
RouteTableId: !Ref PrivateRouteTable
# Create InternetGateway
myInternetGateway:
Type: "AWS::EC2::InternetGateway"
Properties:
Tags:
- Key: Name
Value: !Join [ "-", [ "Ref":"EnvType" , "Ref":"ProjectId" ,"igw" ] ]
AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref MyVPC
InternetGatewayId: !Ref myInternetGateway
# Create VPNGateway
myVPNGateway:
Type: "AWS::EC2::VPNGateway"
Properties:
Type: ipsec.1
Tags:
- Key: Name
Value: !Join [ "-", [ "Ref":"EnvType" , "Ref":"ProjectId" ,"vgw" ] ]
AttachVpnGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref MyVPC
VpnGatewayId: !Ref myVPNGateway
# Route for InternetGateway or VPNGateway
myRoute:
Type: AWS::EC2::Route
DependsOn: myInternetGateway
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref myInternetGateway
#GatewayId: !Ref myVPNGateway
Outputs:
StackVPC:
Description: The ID of the VPC
Value: !Ref MyVPC
Export:
Name: !Join [ "-", [ "Ref":"EnvType", "Ref":"ProjectId" , "vpcid"]]
PublicRouteTable:
Description: The ID of the PublicRouteTable
Value: !Ref PublicRouteTable
Export:
Name: !Join [ "-", [ "Ref":"EnvType", "Ref":"ProjectId", "PublicRouteTable"]]
PrivateRouteTable:
Description: The ID of the PrivateRouteTable
Value: !Ref PrivateRouteTable
Export:
Name: !Join [ "-", [ "Ref":"EnvType", "Ref":"ProjectId", "PrivateRouteTable"]]
StackPubSubnetA:
Description: The ID of the VPC Subnet
Value: !Ref PublicSubnetA
Export:
Name: !Join [ "-", [ "Ref":"EnvType", "Ref":"ProjectId", "PublicSubnetA"]]
StackPubSubnetB:
Description: The ID of the VPC Subnet
Value: !Ref PublicSubnetC
Export:
Name: !Join [ "-", [ "Ref":"EnvType", "Ref":"ProjectId", "PublicSubnetC"]]
StackPriSubnetA:
Description: The ID of the VPC Subnet
Value: !Ref PrivateSubnetA
Export:
Name: !Join [ "-", [ "Ref":"EnvType", "Ref":"ProjectId", "PrivateSubnetA"]]
StackPriSubnetB:
Description: The ID of the VPC Subnet
Value: !Ref PrivateSubnetC
Export:
Name: !Join [ "-", [ "Ref":"EnvType", "Ref":"ProjectId", "PrivateSubnetC"]]
"Fn::ImportValue"の箇所で、上記のエクスポートした情報をインポートしています。
VPCとルートテーブルを利用しています。
以下、S3&VCPエンドポイント作成
CFn_CreateS3.yaml
AWSTemplateFormatVersion: '2010-09-09'
Description:
S3 & VPC Endpoint create
Parameters:
EnvType:
Description: Environment type.
Default: dev
Type: String
AllowedValues:
- dev
- mnt
- prd
ConstraintDescription: must specify dev or mnt or prd.
ProjectId:
Description: Project name id.
Type: String
MinLength: "3"
MaxLength: "3"
AllowedPattern: "[a-zA-Z0-9]*"
ConstraintDescription: must specify Project id.
Resources:
# Create S3 by log
LogS3:
Type: "AWS::S3::Bucket"
Properties:
BucketName: !Join [ "-", [ "Ref":"EnvType" , "Ref":"ProjectId" ,"logbucket" ] ]
Tags:
- Key: Name
Value: !Join [ "-", [ "Ref":"EnvType" , "Ref":"ProjectId" ,"LogBucket" ] ]
LogS3Endpoint:
Type: "AWS::EC2::VPCEndpoint"
Properties:
RouteTableIds:
- { "Fn::ImportValue": !Join [ "-", [ "Ref":"EnvType", "Ref":"ProjectId", "PublicRouteTable"]] }
- { "Fn::ImportValue": !Join [ "-", [ "Ref":"EnvType", "Ref":"ProjectId", "PrivateRouteTable"]] }
ServiceName:
!Sub "com.amazonaws.${AWS::Region}.s3"
VpcId: { "Fn::ImportValue": !Join [ "-", [ "Ref":"EnvType", "Ref":"ProjectId" , "vpcid"]] }
Outputs:
LogS3:
Description: Log S3 Bucket
Value: !Ref LogS3
Export:
Name: !Join [ "-", [ "Ref":"EnvType", "Ref":"ProjectId", "LogBucket"]]
ちなみに短縮形多用しておりますが、ImportValueのところは以下のエラーがでたため、短縮形の利用を諦めました。
Template validation error: Template format error: YAML not well-formed. (line 36, column 26)
# まとめ
組み込み関数の組み合わせでエラーが多発して手こずりましたが、なんとかできました。
次はEC2インスタンスに挑戦したいと思います!
ちなみにエンドポイント作成はクロススタック参照せず、
VPC作成テンプレートに入れたほうがよいと後から思いました笑