FISを使ってスポットインスタンスの停止をテストする
FISとは?
AWS Fault Injection Simulatorの略称です。
AWSサービスに対して疑似障害を起こし、その様子をレポートすることが出来るマネージドサービスです。
対象としているサービスは以下があるそうです。
Amazon Elastic Compute Cloud (Amazon EC2)
Amazon Elastic Container Service (Amazon ECS)
Amazon Elastic Kubernetes Service (Amazon EKS)
Amazon Relational Database Service (Amazon RDS)
今回たしかめること
FISで出来る実験の中に、スポットインスタンスを停止させるもの(send-spot-instance-interruptions)がありました。
今回はそれを試してみます。
今回の構成
FISはawscliで用意して、それ以外のリソースをTerraformで用意します。

コード
環境再現用のTerraformコードはこちらです。
ポイント
FIS用のCloudwatchLogsグループ
tfファイルでいうと以下です
resource "aws_cloudwatch_log_group" "log" {
name = "/fis/logs/"
retention_in_days = 1
}
/fis/logsを作成しており、FISの実験テンプレートで指定することで実験のログが格納されるようになります。
ログはこんな感じで実験の開始や終了、対象の特定などが記載されるようです。

FIS用のIAMロール
こちらです
resource "aws_iam_role" "FISRole" {
name = "FISRole"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "fis.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
}
resource "aws_iam_role_policy_attachment" "FIS-policy-attachment" {
role = aws_iam_role.FISRole.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSFaultInjectionSimulatorEC2Access"
}
resource "aws_iam_role_policy_attachment" "FIS-Logs-policy-attachment" {
role = aws_iam_role.FISRole.name
policy_arn = "arn:aws:iam::aws:policy/CloudWatchLogsFullAccess"
}
FIS用のマネージドポリシーが提供されているため、今回はありがたくそれを使用します。
またCloudwatchLogsへの書き込みのため、CloudWatchLogsFullAccessもつけています。
※CloudWatchLogsFullAccessは不要な権限が多いため、適宜絞りましょう。
実験テンプレート
FISでは実験テンプレートの作成をAWSコンソール,awscliなどで行うことが出来ます。
既存のテンプレートをエクスポートしその雛形をawscliで使用する、といったことも可能なので両パターン試してみるのがおすすめです。
今回はjson形式でテンプレートを用意し、それをawscliで読み込むことで実験テンプレートを作成しています。
{
"description": "test template",
"targets": {
"SpotInstances-Target-1": {
"resourceType": "aws:ec2:spot-instance",
"resourceTags": {
"Name": "SpotTest"
},
"selectionMode": "ALL"
}
},
"actions": {
"terminate_spot_instance": {
"actionId": "aws:ec2:send-spot-instance-interruptions",
"parameters": {
"durationBeforeInterruption": "PT2M"
},
"targets": {
"SpotInstances": "SpotInstances-Target-1"
}
}
},
"stopConditions": [
{
"source": "none"
}
],
"roleArn": "arn:aws:iam::<AccountID>:role/FISRole",
"logConfiguration": {
"cloudWatchLogsConfiguration": {
"logGroupArn": "arn:aws:logs:ap-northeast-1:<AccountID>:log-group:/fis/logs/:*"
},
"logSchemaVersion": 2
},
"tags": {
"Name": "terminate_spot_instance"
}
}
aws fis create-experiment-template --cli-input-json file://template.json
テンプレートのポイントは以下です
- Nameタグに
SpotTestとあるインスタンスを対象にしています。 - 実験内容は
aws:ec2:send-spot-instance-interruptionsで指定します。 -
roleArn,logGroupArnでFISが使用するIAMロール、ロググループを指定しています。
確認
スポットインスタンスがTerminateされ、スポットリクエストもclosedとなっていればOKです

参考
Discussion