🎄

クリスマスイヴなので AWS Fault Injection Service を触ってみる

2023/12/24に公開

はじめに

ずっと気になっていた AWS のサービスである AWS Fault Injection Service を触ってみたいと思います。

この記事は、毎度お馴染みの YAMAP エンジニア Advent Calendar 2023 二十四日目の記事です。

https://qiita.com/advent-calendar/2023/yamap-engineers

AWS Fault Injection Service とは

概要

AWS Fault Injection Service (以後、FIS) とは、リリースは 2021 年 3 月まで遡ります。

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

リリース当初は AWS Fault Injection Simulator と呼ばれていて、意図的に障害を発生させて、システムで何を起きるのか確認したり、そのシステムの回復力を検証してアプリケーションの耐障害性を評価する為のサービスです。

https://aws.amazon.com/jp/blogs/aws/aws-fault-injection-simulator-use-controlled-experiments-to-boost-resilience/

現在は AWS Resilience Hub の一部として提供されており、AWS Well-Architected Tool 等と連携してシステムのリスクを評価して改善策を提供しています。

登場人物

FIS を利用するには、experiment template (以後、実験テンプレート) を作成する必要があります。実験テンプレートは以下のような項目で構成されます。

  • Actions (以後、アクション)
  • Targets (以後、ターゲット)
  • Stop conditions (以後、停止条件)


https://docs.aws.amazon.com/ja_jp/fis/latest/userguide/what-is.html より引用

アクションは、その名の通り、FIS がターゲットの中で実行するアクションが定義されています。

https://docs.aws.amazon.com/ja_jp/fis/latest/userguide/fis-actions-reference.html

前後してしまいますが、ターゲットは障害を発生させる (アクションを実行する) 対象の AWS リソースです。

https://docs.aws.amazon.com/ja_jp/fis/latest/userguide/targets.html

そして、停止条件は、安全に実験を実施する為、CloudWatch Alarm で指定したしきい値を超えた場合に実験を停止する仕組みです。

https://docs.aws.amazon.com/ja_jp/fis/latest/userguide/stop-conditions.html

サポートされる AWS サービス

FIS で障害実験出来る AWS サービスは以下の通りです。

  • Amazon CloudWatch
  • Amazon EBS
  • Amazon EC2
  • Amazon ECS
  • Amazon EKS
  • Amazon RDS
  • AWS Systems Manager

費用

FIS の利用料金は、1 アクション 1 分あたり 0.10USD となっています。

The AWS FIS price is $0.10 per action-minute plus an additional $0.10 per action-minute for each additional account, for all regions except AWS GovCloud (US-East and US-West), where the price is $0.12 per action-minute, plus an additional $0.12 per action-minute for each additional account.

ん、結構なお値段ですかね(汗)。やはり、安心はお金で買えということでしょうか。

実験してみよう

実験の内容

EC2 へのネットワーク遅延を発生させてみたいと思います。ネットワーク遅延のシナリオについては、シナリオライブラリから実験テンプレートを生成することが出来ます。

が、今回はシナリオライブラリを参考にして、自分で実験テンプレートを作成したいと思います。(アクション 5 分を 3 回実行するので費用が掛かる) 実験にあたって、事前に以下の準備をしておく必要がありました。

  • EC2 の起動
    • セキュリティグループで ICMP と SSH を許可
    • インスタンスロールに SSMManagedInstanceCore ポリシーをアタッチ
  • SSM Agent が適切に動作しているか確認
    • EC2 起動直後だと Run Command 出来なかったので SSM Agent を再起動した
  • tc コマンドをインストール
    • sudo yum install iproute-tc

実験テンプレートの作成

マネジメントコンソールからポチポチとやっていきます。

実験テンプレートは JSON フォーマットでエクスポート出来ます。エクスポートした JSON は以下の通りです。

{
    "description": "FIS-Test-20231224-01",
    "targets": {
        "Instances-Target-1": {
            "resourceType": "aws:ec2:instance",
            "resourceArns": [
                "arn:aws:ec2:ap-northeast-1:XXXXXXXXXXXX:instance/i-xxxxxxxxxxxxxxxxx"
            ],
            "selectionMode": "ALL"
        }
    },
    "actions": {
        "FIS-Test-20231224-01": {
            "actionId": "aws:ssm:send-command",
            "parameters": {
                "documentArn": "arn:aws:ssm:ap-northeast-1::document/AWSFIS-Run-Network-Latency",
                "documentParameters": "{\"DelayMilliseconds\":\"1000\", \"Interface\":\"enX0\", \"DurationSeconds\":\"60\", \"InstallDependencies\":\"True\"}",
                "duration": "PT1M"
            },
            "targets": {
                "Instances": "Instances-Target-1"
            }
        }
    },
    "stopConditions": [
        {
            "source": "none"
        }
    ],
    "roleArn": "arn:aws:iam::XXXXXXXXXXXX:role/service-role/AWSFISIAMRole-1703405852690",
    "tags": {
        "Name": "FIS-Test-20231224-01"
    },
    "experimentOptions": {
        "accountTargeting": "single-account",
        "emptyTargetResolutionMode": "fail"
    }
}

SSM の Run Command を利用するので、documentParameters にはコマンドドキュメント (AWSFIS-Run-Network-Latency) のオプションを設定します。

  • DelayMilliseconds: 1000 ミリ秒 (1 秒)
  • Interface: enX0 (eth0 じゃないので注意)
  • DurationSeconds: 60 秒
  • InstallDependencies: True

実験

実験を開始すると、下図のように ping のレスポンスが遅延します。

約 1 分程遅延の状態が続いた後、正常のレスポンスに戻ります。

FIS のコンソールを見ると正常に実験が終了したことが判ります。

以上

今夜は聖夜、クリスマスイヴということで FIS を触ってみました。今回は EC2 をターゲットとする実験だったので、自前でも環境を用意出来そうなものでしたが、他の AWS リソースをターゲットとする実験もやってみたいと思いました。

以上、メリークリスマスでございます。

参考

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

https://docs.aws.amazon.com/ja_jp/wellarchitected/latest/reliability-pillar/rel_testing_resiliency_failure_injection_resiliency.html

おまけ

FIS に付与されたロール

  • 信頼ポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "fis.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
  • 許可ポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowFISExperimentRoleSSMReadOnly",
            "Effect": "Allow",
            "Action": [
                "ssm:GetAutomationExecution",
                "ssm:ListCommands"
            ],
            "Resource": "*"
        },
        {
            "Sid": "AllowFISExperimentRoleSSMSendCommand",
            "Effect": "Allow",
            "Action": [
                "ssm:SendCommand"
            ],
            "Resource": [
                "arn:aws:ec2:ap-northeast-1:XXXXXXXXXXXX:instance/*",
                "arn:aws:ssm:ap-northeast-1:*:document/*"
            ]
        },
        {
            "Sid": "AllowFISExperimentRoleSSMCancelCommand",
            "Effect": "Allow",
            "Action": [
                "ssm:CancelCommand"
            ],
            "Resource": "*"
        },
        {
            "Sid": "AllowFISExperimentRoleSSMAutomation",
            "Effect": "Allow",
            "Action": [
                "ssm:StartAutomationExecution",
                "ssm:StopAutomationExecution"
            ],
            "Resource": "arn:aws:ssm:ap-northeast-1:*:automation-definition/*"
        },
        {
            "Sid": "AllowFISExperimentRoleSSMAutomationPassRole",
            "Effect": "Allow",
            "Action": [
                "iam:PassRole"
            ],
            "Resource": "arn:aws:iam::XXXXXXXXXXXX:role/AWSFISIAMRole-1703405852690",
            "Condition": {
                "StringEquals": {
                    "iam:PassedToService": "ssm.amazonaws.com"
                }
            }
        }
    ]
}
YAMAP テックブログ

Discussion