はじめに
Launch Templates は EC2 インスタンスを起動するための設定情報を含むテンプレートです。
https://aws.amazon.com/jp/about-aws/whats-new/2017/11/introducing-launch-templates-for-amazon-ec2-instances/
テンプレートを活用すると起動毎にパラメータを指定する必要はありませんし、一部のパラメータのみを
変更して起動といった操作も可能になります。
コンソールで一からパラメータを入力して起動テンプレートを作成してもよいのですが、
既存のEC2インスタンスから設定情報を作成することも可能です。
やってみる
Launch Templates の作成
AWS CLIを使用します。
まず既存のインスタンスからテンプレートの元となるJSONを取得します。
$ aws ec2 get-launch-template-data --instance-id i-xxxxxxxxxxxxxxxxx > instance-data.json
取得したデータは以下のような内容になっていますので、必要に応じてAMI や Subnet 等のIDを書き換えます。
{
"LaunchTemplateData": {
"Monitoring": {
"Enabled": false
},
"TagSpecifications": [
{
"ResourceType": "instance",
"Tags": [
{
"Value": "LauchTemplates-Test",
"Key": "Name"
}
]
}
],
"ImageId": "ami-a77c30c1",
"BlockDeviceMappings": [
{
"DeviceName": "/dev/xvda",
"Ebs": {
"DeleteOnTermination": true
}
}
],
"KeyName": "launch-templates-test-key",
"EbsOptimized": false,
"Placement": {
"Tenancy": "default",
"GroupName": "",
"AvailabilityZone": "ap-northeast-1a"
},
"InstanceType": "t2.micro",
"NetworkInterfaces": [
{
"Description": "Primary network interface",
"NetworkInterfaceId": "eni-xxxxxxxx",
"PrivateIpAddresses": [
{
"Primary": true,
"PrivateIpAddress": "xxx.xxx.xxx.xxx"
}
],
"SubnetId": "subnet-xxxxxxxx",
"DeleteOnTermination": true,
"PrivateIpAddress": "xxx.xxx.xxx.xxx",
"Groups": [
"sg-xxxxxxxx"
],
"Ipv6Addresses": [],
"AssociatePublicIpAddress": false
}
]
}
}
NetworkInterfaces 属性にテンプレート元のインスタンスが使用しているENI-IDやIPアドレスが
含まれており、注意が必要です。テンプレートの作成自体は成功しますが、テンプレートからEC2を
起動する際に指定されたリソースが確保できず、エラーが発生します。
NetworkInterfaces 属性には以下のように Security Group や Subnet のみを定義するのがよいと思います。
"NetworkInterfaces": [
{
"DeviceIndex": 0,
"SubnetId": "subnet-xxxxxxxx",
"DeleteOnTermination": true,
"Groups": [
"sg-xxxxxxx"
],
"AssociatePublicIpAddress": false
}
]
DeviceIndex の指定も必要です。指定を行わない場合、EC2インスタンス作成時にエラーがでます。
次に作成したJSONから起動テンプレートを作成します。
$ aws ec2 create-launch-template --launch-template-name launch_template_test --cli-input-json file://instance-data.json
{
"LaunchTemplate": {
"LatestVersionNumber": 1,
"LaunchTemplateId": "lt-xxxxxxxxxxxxxxxxx",
"LaunchTemplateName": "launch_template_test",
"DefaultVersionNumber": 1,
"CreatedBy": "arn:aws:iam::account-id:user/username",
"CreateTime": "2018-04-03T10:52:39.000Z"
}
}
コンソール上でもテンプレートが作成されていることを確認できます。
LaunchTemplatesからの起動
テンプレート作成時に LaunchTemplateId が返されますので
--launch-template オプションでIDを指定し、run-instances を実行します
$ aws ec2 run-instances --launch-template LaunchTemplateId=lt-xxxxxxxxxxxxxxxxx
出力は省略
テンプレートから起動したインスタンスのタグにはテンプレートの ID と Version が自動で追加されます。
前述の通り、DeviceIndexを指定しない場合はエラーがでます。
$ aws ec2 run-instances --launch-template LaunchTemplateId=lt-xxxxxxxxxxxxxxxxx
An error occurred (InvalidParameterValue) when calling the RunInstances operation: Each network interface requires a device index.
またオプションで指定すれば、テンプレート内の各パラメータを上書きして起動することができます。
$ aws ec2 run-instances --launch-template LaunchTemplateId=lt-xxxxxxxxxxxxxxxxx --instance-type t2.small
出力は省略
プライベートIPアドレス指定時のエラー
2018/4/4 時点で --Launch-template と --private-ip-address を同時に指定して起動するとエラーが発生します。
$ aws ec2 run-instances --launch-template LaunchTemplateId=lt-xxxxxxxxxxxxxxxxx --private-ip-address xxx.xxx.xxx.xxx
An error occurred (InvalidParameterCombination) when calling the RunInstances operation: Network interfaces and an instance-level private IP address may not be specified on the same request
ドキュメント上は、テンプレートパラメータは上書き可能であり、
特にプライベートIPの指定に関する言及がありません。
ドキュメントと挙動が一致していないので不具合である可能性があります。
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2-launch-templates.html#launch-instance-from-launch-template
NetworkInterfaces 属性を丸ごと削除したテンプレートを作成すれば回避できますが、そうすると起動の度に
Subnet や SecurityGroup も追加で指定する必要があるのでテンプレートの使い勝手が悪くなってしまいます。
おまけ
CloudFormation でテンプレートを作成する
2018/3/29 の Update で CloudFormation で LaunchTemplates を作成できるようになりました。
https://aws.amazon.com/jp/about-aws/whats-new/2018/03/aws-cloudformation-now-supports-launch-templates/
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-launchtemplate.html
以下のような定義で作成ができます。
AWSTemplateFormatVersion: '2010-09-09'
Description: LauchTemplates CloudFormation Test
Resources:
LauchTemplateTest:
Type: "AWS::EC2::LaunchTemplate"
Properties:
LaunchTemplateName: Launch_templates_test
LaunchTemplateData:
Monitoring:
Enabled: false
TagSpecifications:
- ResourceType: instance
Tags:
- Value: "LauchTemplates-Test"
Key: Name
ImageId: "ami-a77c30c1"
BlockDeviceMappings:
- DeviceName: "/dev/xvda"
Ebs:
DeleteOnTermination: true
KeyName: "launch-templates-test-key"
EbsOptimized: false
Placement:
Tenancy: default
GroupName: ""
AvailabilityZone: "ap-northeast-1a"
InstanceType: "t2.micro"
NetworkInterfaces:
- DeviceIndex: 0
SubnetId: "subnet-xxxxxxxx"
DeleteOnTermination: true
Groups:
- "sg-xxxxxxxx"
AssociatePublicIpAddress: false
Outputs:
LauchTemplateId:
Description: The physical ID of the launch template
Value: !Ref LauchTemplateTest
LauchTemplateLatest:
Description: The latest version of the launch template
Value: !GetAtt LauchTemplateTest.LatestVersionNumber
LauchTemplateDefault:
Description: The default version of the launch template
Value: !GetAtt LauchTemplateTest.DefaultVersionNumber
注意点としては、デフォルトバージョンは CloudFormation では指定ができないため、コンソール or CLI で
明示的に設定する必要があります。
最新バージョンについてはスタックが更新されれば自動でカウントアップされます。
CloudFormation から起動テンプレートを使用する
AWS::EC2::Instance リソースでは LaunchTemplates を指定できないようです。
AWS::AutoScaling::AutoScalingGroup リソースには LaunchTemplate プロパティが、
AWS::EC2::SpotFleet リソースの SpotFleetRequestConfigData プロパティには LaunchTemplateConfigs が
存在しますので起動テンプレートを利用できます。
以上です。
参考になれば幸いです。