この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
LaunchTemplate(起動テンプレート)、使ってますか?
同じようなEC2をぽこぽこ立ち上げたい時に使える便利なやつです。 LaunchTemplateを使用してAutoScalingグループを作成することもできます。
起動テンプレートを使用して Auto Scaling グループを作成する - Amazon EC2 Auto Scaling
バージョン管理ができることも特徴の一つです。
起動テンプレートのバージョンの管理 - Amazon Elastic Compute Cloud
しかし、LaunchTemplateはバージョン管理ができる故に、CloudFormationで取り扱う時に注意が必要です。
CloudFormationでLaunchTemplateを作る
例えば、こんなCFnテンプレートでLaunchTemplateを作ってみます。
---
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
Ec2ImageId:
Type: AWS::EC2::Image::Id
SecurityGroupId:
Type: AWS::EC2::SecurityGroup::Id
Resources:
SampleLaunchTemplate:
Type: AWS::EC2::LaunchTemplate
Properties:
LaunchTemplateName: sample-launchtemplate
LaunchTemplateData:
BlockDeviceMappings:
- Ebs:
VolumeSize: 8
VolumeType: gp2
DeviceName: /dev/xvda
SecurityGroupIds:
- !Ref SecurityGroupId
EbsOptimized: false
ImageId: !Ref Ec2ImageId
InstanceType: t3.micro
Monitoring:
Enabled: true
UserData:
Fn::Base64: |
#!/bin/bash
yum -y update
# setup httpd
yum install -y httpd
systemctl start httpd.service
systemctl enable httpd.service
ここまでは何も問題無いです。
やっぱりもう少しボリュームサイズを増やしたいってことで、ボリュームサイズを変えてCFnスタックを更新してみます。どうなるでしょう?
そうすると、バージョンが2になります。 CFnで更新した場合でも、LaunchTemplate自体を更新するわけではありません。 バージョンを積み上げていく挙動をします。
CloudFormationでAutoScalingGroupを作る
次にLaunchTemplateを使用したAutoScalingGroupをCFnテンプレートで作ってみます。 LaunchTemplateはバージョンが存在するので、バージョン番号を指定する必要があります。
これがマネジメントコンソールであれば、「デフォルト」「最新」といった選択肢があります。
しかし、CFnの場合はドキュメントに記載されている通り、$Latest, $Defaultを指定することができません。マジカヨ。
Amazon EC2 Auto Scaling AutoScalingGroup LaunchTemplateSpecification - AWS CloudFormation
と、いうことはこんな風にLaunchTemplateのバージョン番号をべた書きして構築しろということでしょうか。
SampleAutoScalingGroup:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
AutoScalingGroupName: sample-ag
DesiredCapacity: '1'
LaunchTemplate:
LaunchTemplateId: !Ref SampleLaunchTemplate
Version: 1
ちょっと便利な解決方法
バージョンが上がるたびに、CFnテンプレートのバージョン番号を修正するとかだるいことはやっていられません。 実はこれを解決する方法があります。
LaunchTemplateのドキュメントを見ると、Fn::GetAtt組み込み関数を使うと最新バージョンが取得できると記載されています。 個人的にはAutoScalingのドキュメントに、ここへのリンクを張って欲しいくらいの重要な情報です。
Fn::GetAtt - AWS CloudFormation
AWS::EC2::LaunchTemplate - AWS CloudFormation
なので、こういうCFnテンプレートを作成すれば、
---
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
Ec2ImageId:
Type: AWS::EC2::Image::Id
SecurityGroupId:
Type: AWS::EC2::SecurityGroup::Id
Resources:
SampleLaunchTemplate:
Type: AWS::EC2::LaunchTemplate
Properties:
LaunchTemplateName: sample-launchtemplate
LaunchTemplateData:
BlockDeviceMappings:
- Ebs:
VolumeSize: 12
VolumeType: gp2
DeviceName: /dev/xvda
SecurityGroupIds:
- !Ref SecurityGroupId
EbsOptimized: false
ImageId: !Ref Ec2ImageId
InstanceType: t3.micro
Monitoring:
Enabled: true
UserData:
Fn::Base64: |
#!/bin/bash
yum -y update
# setup httpd
yum install -y httpd
systemctl start httpd.service
systemctl enable httpd.service
Outputs:
LatestNumber:
Value: !GetAtt SampleLaunchTemplate.LatestVersionNumber
!GetAttを使ってLaunchTemplateの最新バージョンが取得できます。
したがって、こういうCFnテンプレートを作れば、CFnで更新した最新のLaunchTemplateを参照するAutoScalingGroupを作ることができます。
---
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
Ec2ImageId:
Type: AWS::EC2::Image::Id
SecurityGroupId:
Type: AWS::EC2::SecurityGroup::Id
SubnetIdA:
Type: AWS::EC2::Subnet::Id
SubnetIdC:
Type: AWS::EC2::Subnet::Id
Resources:
SampleLaunchTemplate:
Type: AWS::EC2::LaunchTemplate
Properties:
LaunchTemplateName: sample-launchtemplate
LaunchTemplateData:
BlockDeviceMappings:
- Ebs:
VolumeSize: 12
VolumeType: gp2
DeviceName: /dev/xvda
SecurityGroupIds:
- !Ref SecurityGroupId
EbsOptimized: false
ImageId: !Ref Ec2ImageId
InstanceType: t3.micro
Monitoring:
Enabled: true
UserData:
Fn::Base64: |
#!/bin/bash
yum -y update
# setup httpd
yum install -y httpd
systemctl start httpd.service
systemctl enable httpd.service
SampleAutoScalingGroup:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
AutoScalingGroupName: sample-ag
DesiredCapacity: '1'
LaunchTemplate:
LaunchTemplateId: !Ref SampleLaunchTemplate
Version: !GetAtt SampleLaunchTemplate.LatestVersionNumber
MaxSize: '1'
MinSize: '0'
Tags:
- Key: Name
Value: sample-ag
PropagateAtLaunch: true
VPCZoneIdentifier:
- !Ref SubnetIdA
- !Ref SubnetIdC