AWSでカオスエンジニアリング「AWS Fault Injection Simulator」とは?

AWS Fault Injection Simulator (以下FISとします。)はクラウド障害のシミュレーションを行うサービスです。
FISを利用することで、システム障害を意図的に発生させて何が起こるかの確認や障害への対策を練ることができます。システム障害に対しシステムの回復力、信頼性、パフォーマンスをあげていくことが目的です。
当コラムではFISの概要説明と実践の紹介をします。

はじめにカオスエンジニアリングとは?

カオスエンジニアリングとは稼働中のシステムに対し、擬似的な障害を起こすことで、実際の障害に耐えられるようにする手段です。
小規模の障害を意図的に発生させ、特定のサーバーが一時的に使用できなくなったときにシステムがどう対応するかを把握します。このようなシステムのトラブル処理のパターンを蓄積し、サービスを大規模化したときの安定的な運用につなげます。

FISとは?

2021/03/15より、FISが利用可能となりました。
大阪と中国の2つのリージョンを除くすべての商用AWSリージョンで利用可能です。
FISはサービス名の通り「フォールト(障害を)インジェクション(注入する)シミュレーション(実験)」するためのフルマネージドサービスです。

リンク:AWS Fault Injection Simulator別ウィンドウで開きます

AWSで稼働しているシステムに対し、意図的に障害を発生させることでシステムに何が起こるのかを確認するとともに、障害に対しどのような反応するかを学ぶ事によりシステムの回復力、信頼性、パフォーマンスをあげていくことが目的です。

実際にどのようなことができる?

FISでは特定のAWSリソースに対し、アクションとして定義した障害を設定し、シミュレーションを行います。
1アクションにつき1分ごとに$0.1の利用料金が発生します。
詳しい料金は公式ドキュメントを参照してください。

リンク:AWS Fault Injection Simulator pricing別ウィンドウで開きます

現在は以下のアクションが行えます。

AmazonEC2のアクション
アクション名「aws:ec2:reboot-instances」
  • 指定したEC2インスタンスを再起動します。
アクション名「aws:ec2:stop-instances」
  • 指定したEC2インスタンスを停止します。
アクション名「aws:ec2:terminate-instances」
  • 指定したEC2インスタンスを終了します。
アクション名「aws:ec2:terminate-instances」
  • 指定したEC2インスタンスを終了します。
AmazonECSのアクション
アクション名「aws:ecs:drain-container-instances」
  • ECSのコンテナインスタンスを削除する割合をパーセンテージで指定し、削除します。
AmazonEKSのアクション
アクション名「aws:eks:terminate-nodegroup-instance」
  • ノードグループでインスタンスをシャットダウンする割合をパーセンテージで指定し、シャットダウンします。
AmazonRDSのアクション
アクション名「aws:rds:failover-db-cluster」
  • 指定したdb-clusterをフェイルオーバーします。
アクション名「aws:rds:reboot-db-instances」
  • 指定したdb-instancesを再起動します。
SystemsManagerのアクション
アクション名「aws:ssm:send-command」
  • 指定したdb-instancesを再起動します。
    ※SSMドキュメントはSystemsManagerが管理対象インスタンスに対して実行するアクションを定義できます。AWSが事前に用意したドキュメントを使用することや独自のドキュメント作成が可能です。
    事前に設定されているドキュメントは以下の通りです。
SSMドキュメント名「AWSFIS-Run-CPU-Stress」
  • stress-ngを使用し、インスタンスのCPUに負荷をかけます。

リンク:AWSFIS-Run-CPU-Stress別ウィンドウで開きます

SSMドキュメント名「AWSFIS-Run-Kill-Process」
  • killallを使用し、インスタンス内の指定したプロセスを強制終了します。

リンク:AWSFIS-Run-Kill-Process別ウィンドウで開きます

SSMドキュメント名「AWSFIS-Run-Memory-Stress」
  • stress-ngを使用し、インスタンスのメモリに負荷をかけます。

リンク:AWSFIS-Run-Memory-Stress別ウィンドウで開きます

SSMドキュメント名「AWSFIS-Run-Network-Latency」
  • ネットワークに遅延を発生させます。

リンク:AWSFIS-Run-Network-Latency別ウィンドウで開きます

独自のSSMドキュメントの作成の詳細については、 「AWS Systems Managerユーザーガイド」の「SystemsManagerドキュメントの作成別ウィンドウで開きます」を参照してください

実践例

今回はFISで指定したインスタンスを停止させる実験、ランダムに1つのインスタンスをシャットダウンさせる実験を行います。
以下は手順です。

---

IAMロールの作成

IAMポリシーの作成

検証用EC2インスタンスの作成

実験テンプレートの作成

実験の実施

---

FISを使用するための権限付与として、IAMロール、ポリシーの作成を行います。
以下のドキュメントにはFIS用のIAMロール、ポリシーの作成方法が記載されています。

リンク:Set up IAM permissions別ウィンドウで開きます

IAMロールの作成

AWSマネジメントコンソールで「IAM」を検索し、サービス「IAM」をクリックします。

左側のメニュー欄から「ロール」をクリックし、「ロールを作成」をクリックします。

信頼されたエンティティの種類に「AWSサービス」、ユースケースの選択に「EC2」を選択し、「次のステップ:アクセス権限」をクリックします。

ポリシーは後の手順で作成しアタッチするため、変更せず「次のステップ:タグ」をクリックします。

タグの追加は行わず、「次のステップ:確認」をクリックします。

ロール名、ロールの説明欄に「FIS_Kenshou_Role」と入力し、「IAMロールの作成」をクリックします。

画面上部に以下の画像が表示されれば作成完了です。

「FIS_Kenshou_Role」をクリックします。

「信頼関係」タブをクリックし、「信頼関係の編集」をクリックします。

以下のJSONに変更し、「信頼ポリシーの変更」をクリックします。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": [
                  "fis.amazonaws.com"
                ]
            },
            "Action": "sts:AssumeRole",
            "Condition": {}
        }
    ]
}

後の手順に必要となるため、アイコンをクリックし、ロールARNをコピーし控えておきます。

IAMポリシーの作成

FISを利用するために必要なポリシーを2つ作成します。

FISAccessPolicy

IAMユーザーがFISにアクセスできるポリシーを作成します。
左側のメニュー欄から「ポリシー」をクリックし、「ポリシーを作成」をクリックします。

「JSON」タブをクリックし、以下のJSONに変更します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "FISPermissions",
            "Effect": "Allow",
            "Action": [
                "fis:*"
            ],
            "Resource": "*"
        },
        {
            "Sid": "ReadOnlyActions",
            "Effect": "Allow",
            "Action": [
                "ssm:Describe*",
                "ssm:Get*",
                "ssm:List*",
                "ec2:DescribeInstances",
                "rds:DescribeDBClusters",
                "ecs:DescribeClusters",
                "ecs:ListContainerInstances",
                "eks:DescribeNodegroup",
                "cloudwatch:DescribeAlarms",
                "iam:ListRoles"
            ],
            "Resource": "*"
        },
        {
            "Sid": "IAMPassRolePermissions",
            "Effect": "Allow",
            "Action": [
                "iam:PassRole"
            ],
            "Resource": "arn:aws:iam::111122223333:role/roleName"
        },
        {
            "Sid": "PermissionsToCreateServiceLinkedRole",
            "Effect": "Allow",
            "Action": "iam:CreateServiceLinkedRole",
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "iam:AWSServiceName": "fis.amazonaws.com"
                }
            }
        }
    ]
}

※上記のJSONに記載されている以下の行は、「IAMロールの作成」の手順内でコピーしたARNに変更します。

"Resource": "arn:aws:iam::111122223333:role/roleName"

ARN変更後、「次のステップ:タグ」をクリックします。

タグの追加は行わず、「次のステップ:確認」をクリックします。

名前、説明欄に「FISAccessPolicy」と入力し、「ポリシーの作成」をクリックします。

画面上部に以下の画像が表示されれば作成完了です。

FISAllowService

FISへ他のサービスのアクション実行を許可するポリシーを作成します。
「ポリシーを作成」をクリックします。

「JSON」タブをクリックし、以下のJSONに変更し、「次のステップ:タグ」をクリックします。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowFISExperimentRoleReadOnly",
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeInstances",
                "ecs:DescribeClusters",
                "ecs:ListContainerInstances",
                "eks:DescribeNodegroup",
                "iam:ListRoles",
                "rds:DescribeDBInstances",
                "rds:DescribeDbClusters",
                "ssm:ListCommands"
            ],
            "Resource": "*"
        },
        {
            "Sid": "AllowFISExperimentRoleEC2Actions",
            "Effect": "Allow",
            "Action": [
                "ec2:RebootInstances",
                "ec2:StopInstances",
                "ec2:StartInstances",
                "ec2:TerminateInstances"
            ],
            "Resource": "arn:aws:ec2:*:*:instance/*"
        },
        {
            "Sid": "AllowFISExperimentRoleECSActions",
            "Effect": "Allow",
            "Action": [
                "ecs:UpdateContainerInstancesState",
                "ecs:ListContainerInstances"
            ],
            "Resource": "arn:aws:ecs:*:*:container-instance/*"
        },
        {
            "Sid": "AllowFISExperimentRoleEKSActions",
            "Effect": "Allow",
            "Action": [
                "ec2:TerminateInstances"
            ],
            "Resource": "arn:aws:ec2:*:*:instance/*"
        },
        {
            "Sid": "AllowFISExperimentRoleFISActions",
            "Effect": "Allow",
            "Action": [
                "fis:InjectApiInternalError",
                "fis:InjectApiThrottleError",
                "fis:InjectApiUnavailableError"
            ],
            "Resource": "arn:*:fis:*:*:experiment/*"
        },
        {
            "Sid": "AllowFISExperimentRoleRDSReboot",
            "Effect": "Allow",
            "Action": [
                "rds:RebootDBInstance"
            ],
            "Resource": "arn:aws:rds:*:*:db:*"
        },
        {
            "Sid": "AllowFISExperimentRoleRDSFailOver",
            "Effect": "Allow",
            "Action": [
                "rds:FailoverDBCluster"
            ],
            "Resource": "arn:aws:rds:*:*:cluster:*"
        },
        {
            "Sid": "AllowFISExperimentRoleSSMSendCommand",
            "Effect": "Allow",
            "Action": [
                "ssm:SendCommand"
            ],
            "Resource": [
                "arn:aws:ec2:*:*:instance/*",
                "arn:aws:ssm:*:*:document/*"
            ]
        },
        {
            "Sid": "AllowFISExperimentRoleSSMCancelCommand",
            "Effect": "Allow",
            "Action": [
                "ssm:CancelCommand"
            ],
            "Resource": "*"
        }
    ]
}

タグの追加は行わず、「次のステップ:確認」をクリックします。

名前、説明欄に「FISAllowService」と入力し、「ポリシーの作成」をクリックします。

画面上部に以下の画像が表示されれば作成完了です。

ロールにポリシーをアタッチ

さきほど作成したIAMロール「FIS_Kenshou_Role」に2つのポリシー「FISAccessPolicy」「FISAllowService」をアタッチします。
左側のメニュー欄から「ロール」をクリックし、検索欄に「FIS_Kenshou_Role」と入力、「FIS_Kenshou_Role」をクリックします。

「ポリシーをアタッチします」をクリックします。

検索欄に「FISAccessPolicy FISAllowService」と入力し、2つのポリシーを選択し、「ポリシーのアタッチ」をクリックします。

ポリシー名に「FISAccessPolicy FISAllowService」のポリシー名が確認でき、アタッチに成功しました。

検証用EC2インスタンスの作成

検証用にEC2インスタンスを2つ作成します。
以下の条件でインスタンスを作成します。(具体的な作成手順は割愛します。)
AMI の選択:Amazon Linux 2 AMI
インスタンスタイプの選択:t2.micro
後の手順で必要なため、作成したインスタンス IDをコピーし控えます。

実験テンプレートの作成

2つのテンプレートを作成します。

インスタンスストップテンプレート

指定したインスタンスを停止させるテンプレートを作成します。
AWSマネジメントコンソールで「FIS」を検索し、サービス「FIS」をクリックします。

「実験テンプレートを作成」をクリックします。

説明欄に「onestopinstance」と入力し、IAMロールに「FIS_Kenshou_Role」を選択します。

「アクションを追加」をクリックし、名前に「onestopinstance」と入力、アクションタイプに「aws:ec2:stop-instances」を選択し、「保存」をクリックします。

ターゲットの「編集」をクリックします。

名前欄に「onestopinstance」と入力し、リソースIDは「検証用EC2インスタンスの作成」の手順内で確認したインスタンスIDを一つ選択し、「保存」をクリックします。

停止条件、タグは変更せず「実験テンプレートを作成」をクリックします。

「作成」と入力し、「実験テンプレートを作成」をクリックします。

画面上部に以下の画像が表示されれば作成完了です。

インスタンスシャットダウンテンプレート

ランダムに1つのインスタンスをシャットダウンさせるテンプレートを作成します。
左側のメニュー欄から「実験テンプレート」をクリックし、「実験テンプレートを作成」をクリックします。

説明欄に「randomoneterminated」と入力し、IAMロールに「FIS_Kenshou_Role」を選択します。

「アクションを追加」をクリックし、名前に「randomoneterminated」と入力、アクションタイプに「aws:ec2:terminate-instances」を選択し、「保存」をクリックします。

ターゲットの「編集」をクリックします。

名前欄に「randomoneterminated」と入力、リソースIDに「検証用EC2インスタンスの作成」手順で確認したインスタンスIDを2つ選択し、選択モードに「数」を選択、リソースの数に「1」を選択して「保存」をクリックします。

停止条件、タグは変更せず「実験テンプレートを作成」をクリックします。

「作成」と入力し、「実験テンプレートを作成」をクリックします。

画面上部に以下の画像が表示されれば作成完了です。

実験の実施

作成したテンプレートを使用し、実験を行います。

インスタンスストップの実験

左側のメニュー欄から「実験テンプレート」をクリックし、説明に「onestopinstance」と書かれているテンプレートをクリックします。

アクション欄の「開始」をクリックします。

「実験を開始」をクリックします。

「開始」と入力し、「実験を開始」をクリックします。

状態「Initiating」から「Completed」に表示が変われば成功です。

指定したインスタンスの停止を確認できました。

インスタンスシャットダウンの実験

左側のメニュー欄から「実験テンプレート」をクリックし、説明に「randomoneterminated」と書かれているテンプレートをクリックします。

アクション欄の「開始」をクリックします。

「実験を開始」をクリックします。

「開始」と入力し、「実験を開始」をクリックします。

状態「Initiating」から「Completed」に表示が変われば成功です。

1つのインスタンスのシャットダウンを確認できました。

おわりに

万が一、利用しているシステムに障害が発生した場合、ビジネスに大きな影響を与える可能性があります。
事前の障害対策としてFISは選択肢の一つです。
トラブル処理のパターンを蓄積し、対策を行うことで危機的な事態を回避し、障害に強いサービスとして運用ができます。
トラブルが起きた場合に迅速に対応できるようなシステムを作りましょう。

Amazon Web Services(AWS)、Microsoft Azureの
導入支援サービスのご相談、お問い合わせをお待ちしております。

ページ上部へ戻る