🚱

FISを使ってスポットインスタンスの停止をテストする

2023/06/07に公開

FISとは?

AWS Fault Injection Simulatorの略称です。
AWSサービスに対して疑似障害を起こし、その様子をレポートすることが出来るマネージドサービスです。

https://docs.aws.amazon.com/fis/latest/userguide/what-is.html

対象としているサービスは以下があるそうです。

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コードはこちらです。
https://github.com/not75743/FIS-Terminate-SpotInstance

ポイント

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もつけています。
https://docs.aws.amazon.com/ja_jp/fis/latest/userguide/security-iam-awsmanpol.html

CloudWatchLogsFullAccessは不要な権限が多いため、適宜絞りましょう。

実験テンプレート

FISでは実験テンプレートの作成をAWSコンソール,awscliなどで行うことが出来ます。
既存のテンプレートをエクスポートしその雛形をawscliで使用する、といったことも可能なので両パターン試してみるのがおすすめです。

今回はjson形式でテンプレートを用意し、それをawscliで読み込むことで実験テンプレートを作成しています。

template.json
{
    "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です

参考

https://qiita.com/yoshimi0227/items/ee86141f5b67c6d378c1
https://aws.amazon.com/jp/about-aws/whats-new/2021/10/aws-fault-injection-simulator-injects-spot-instance-interruptions/

Discussion