はじめに
起動テンプレートを使ってAuto Scaling Groupを構成しているのですが、先日、下記のような要件を満たす構成を作ろうと思ったらドはまりしました...。
- 起動テンプレートを複数のAuto Scaling Groupで共用したい
- インスタンスタイプは可変にしたい
- スポットインスタンスを使いたい
- CloudFormationテンプレートで定型化したい
忙しい人のために
先にまとめを書いておきます。
- 起動テンプレートにはスポット購入オプション・インスタンスタイプともに設定しない
- インスタンスタイプおよびスポットの指定はAuto Scaling Groupで受け持つ
- CloudFormationで起動テンプレートを指定する手段は
MixedInstancesPolicy
プロパティ。LaunchTemplate
プロパティは使わない
スタート時点
もともと、インスタンスタイプを固定したCloudFormationテンプレートは持っていたんです。
起動テンプレートの中で、マシンイメージ(AMI)に加えて、固定のインスタンスタイプとスポット購入オプションを設定していました。
起動テンプレートのエッセンスをCloudFormationテンプレートで記述するとこんな感じです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
"LaunchTemplate": { "Type": "AWS::EC2::LaunchTemplate", "Properties": { "LaunchTemplateData": { "ImageId": { "Ref": "ImageId" }, "InstanceMarketOptions": { "MarketType": "spot", "SpotOptions": { "SpotInstanceType": "one-time" } }, "InstanceType": "t3.micro" } } } |
ここからインスタンスタイプを可変にしたかった(Auto Scaling Groupでオーバーライドしたかった)だけなのですが、これが苦難の道のりの始まりでした...。
コンソールからAuto Scaling Groupの設定にて先ほどの起動テンプレートを指定し、インスタンスタイプを上書きしようとしたところ、「起動テンプレートを上書きする」のボタンがグレーアウトしています。
起動テンプレートからインスタンスタイプの指定を外してみる
この時、「起動テンプレートでインスタンスタイプを指定しているから上書きできないのだろう」という推測のもとに、インスタンスタイプの指定を外してみました。
同じくエッセンスをCloudFormationテンプレートで記述するとこんな感じです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
"LaunchTemplate": { "Type": "AWS::EC2::LaunchTemplate", "Properties": { "LaunchTemplateData": { "ImageId": { "Ref": "ImageId" }, "InstanceMarketOptions": { "MarketType": "spot", "SpotOptions": { "SpotInstanceType": "one-time" } } } } } |
この状態で先ほどと同じことをしようとすると、今度はコンソールでこんなことを言われてしまいました...。
起動テンプレートにインスタンスタイプがありません。インスタンスタイプが指定されている起動テンプレートを使用するか、またはスポットインスタンスをリクエストしない起動テンプレートを使用して、代わりに Auto Scaling グループのプロパティにスポットインスタンスのリクエストを含めます。
むむむ、まだダメなのか...。
インスタンスタイプに加えてスポットリクエストも指定から外してみる
警告メッセージで言われた通り、「スポットインスタンスをリクエストしない起動テンプレート」を用意しました。CloudFormationテンプレートで記述したものを用意しました。
もちろん、実際には今回の検証に関係しない部分も設定が含まれているのですが、今回の要件に関する部分だけを抜き出すとほぼ無指定に等しい状態ですね。
起動テンプレートの存在意義が危ぶまれるレベルです。
1 2 3 4 5 6 7 8 |
"LaunchTemplate": { "Type": "AWS::EC2::LaunchTemplate", "Properties": { "LaunchTemplateData": { "ImageId": { "Ref": "ImageId" } } } } |
今度こそいける!と思って試してみます。
パチパチパチ。無事ウィザードが進められるようになりました。
次はこれをCloudFormationテンプレートに落とすことです。
コンソールで見えた成果をもとに起動テンプレートを書いてみる
まずは書式に従って必要な部分を書いてみます。
最初に試したのは下記のテンプレートでした。
さて、結果はどうなったかというと...?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
"AutoScalingGroup": { "Type": "AWS::AutoScaling::AutoScalingGroup", "Properties": { "DesiredCapacity": 0, "LaunchTemplate": { "LaunchTemplateId": { "Ref": "LaunchTemplate" }, "Version": { "Fn::GetAtt": [ "LaunchTemplate", "LatestVersionNumber" ] } }, "MaxSize": 1, "MinSize": 0, "MixedInstancesPolicy": { "LaunchTemplate": { "LaunchTemplateSpecification": { "LaunchTemplateId": { "Ref": "LaunchTemplate" }, "Version": { "Fn::GetAtt": [ "LaunchTemplate", "LatestVersionNumber" ] } }, "Overrides": [ { "InstanceType": { "Ref": "InstanceType" } } ] } }, "VPCZoneIdentifier": { "Ref": "Subnets" } } } |
順調に作成されていると思わせてからのエラーメッセージでした...ショボン。
Valid requests must contain either LaunchTemplate, LaunchConfigurationName, InstanceId or MixedInstancesPolicy parameter.
eitherということはどちらかを捨てなきゃいけないということ?...
ドキュメントをよく見ると...ちゃんと書いてありました、二度ショボン。
If you omit this property, you must specify MixedInstancesPolicy, LaunchConfigurationName, or InstanceId.
仕上げ
ここまで道筋が見えてきたので、先ほどのエラーに対する対応と同時に、最後にスポットインスタンスのリクエスト設定を練りこみます。
プロパティ名がMixedInstancesPolicy
とあるのでスポット以外(オンデマンド)も含めなくてはならないように見えますが、つまりは混合率を「スポット100:オンデマンド0」にすることで、純度100%のスポットインスタンス利用設定ができあがりました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
"LaunchTemplate": { "Type": "AWS::EC2::LaunchTemplate", "Properties": { "LaunchTemplateData": { "ImageId": { "Ref": "ImageId" } } } }, "AutoScalingGroup": { "Type": "AWS::AutoScaling::AutoScalingGroup", "Properties": { "MixedInstancesPolicy": { "InstancesDistribution": { "OnDemandBaseCapacity": 0, "OnDemandPercentageAboveBaseCapacity": 0, "SpotAllocationStrategy": "lowest-price" }, "LaunchTemplate": { "LaunchTemplateSpecification": { "LaunchTemplateId": { "Ref": "LaunchTemplate" }, "Version": { "Fn::GetAtt": [ "LaunchTemplate", "LatestVersionNumber" ] } }, "Overrides": [ { "InstanceType": { "Ref": "InstanceType" } } ] } }, "VPCZoneIdentifier": { "Ref": "Subnets" } } } |
これでやっと、当初の目的が実現できました。
思えば壁にぶつかり続けながらの長い道のりでしたが、この記事がみなさんの壁にぶつかる回数を減らす助けになればそれが一番シアワセです。
それではまた!
投稿者プロフィール
- 根っこはインフラ屋な古いおじさん。
最新の投稿
- AWS2024年11月1日【小ネタ】cfnresponseが見つからない?
- CloudFormation2024年10月23日スポットインスタンスな起動テンプレートのインスタンスサイズを可変にしたい
- AWS2023年11月14日DLQを積み重ねる
- SQS2023年10月2日1分より短いサイクルで定期的にLambdaを実行する