最近、相談されたことを備忘録として、記事化します。
発生している事象
- 身に覚えのないEC2インスタンスが大量に起動・停止を繰り返している
背景
- 開発環境として、EC2のスポットインスタンスを利用
- 管理ツールとして、CloudFormationを利用
- EBSは暗号化しており、KMSを利用
- 前日、EC2を更新するため、CloudFormationで指定しているAMIIDを変更
結論から
- スポットインスタンスを利用する場合、
スポットフリートロールにKMSの権限を付与する必要あり
- 不要になった、スポットインスタンスは、スポットリクエストをキャンセルする
- 今回は、CloudFormationで展開しており、裏でリクエストが行われている
- キャンセルは手動で行う必要があった
調査内容
EC2が大量に起動/停止をしているエラーについて
起動時に以下のエラーが発生している
Client.InvalidKMSKey.InvalidState: The KMS key provided is in an incorrect state
指定しているAMI自体は、KMSを使っておらず、暗号化されていない。
何が起きているかさっぱりだった。
とりあえず、起動できないAMIを手動で起動してみる
⇒起動できた。手動だとOK?
起動時のログ確認
CloudTrailを確認
なぜ、起動できていないのか手掛かりになるログを探す
⇒ユーザーが、InstanceLaunchになっている。
そんなユーザーはいない、、何者?
下の方の、イベントレコードを確認したところ、arnに以下が入っていた。
arn:aws:iam::{accountID}:role/aws-service-role/spot.amazonaws.com/AWSServiceRoleForEC2Spot
⇒上記のマネージドロールがEC2を起動しようとしている。
KMSの権限には、上記ロールへ権限付与されておらず。。
EC2を立ち上げようとして、指定しているKMSで暗号化しようとしたところ、
権限がなく、起動⇒エラー⇒再試行⇒大量の起動できなかったEC2たちがリストにというのが結果だった。
InstanceLaunchというユーザーは、スポットインスタンスという特性上、
入札額を上回ったり下回ったりした際に、停止・起動するユーザーだと思われる。
回避するためには
- KMSに以下のロールで、権限を付与する
arn:aws:iam::{accountID}:role/aws-service-role/spot.amazonaws.com/AWSServiceRoleForEC2Spot
- CloudFormationでスポットインスタンスを利用する場合には、
スポットリクエストを手動キャンセルするか、カスタムリソースを作成する
参考
最近、私がスポットインスタンスをCloudFormationで利用する場合は、
上記のカスタムリソースを一緒に組み込んでいます
AMIが変更されて、新しいスポットリクエストができた後に、
旧スポットインスタンスのリクエストをキャンセルしてくれるLambdaが作られます。
とても便利なので、CloudFormation × スポットインスタンスを利用する場合は、
組み込んでおいた方がよいでしょう
それでは、また!