0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

LambdaでAWS Fault Injection Service アクションを試してみた

Posted at

はじめに

 先日参加したAWS re:Invent2024で聴講した事例セッション(FSI318:Fidelity Investments: Building for mission-critical resilience)において、AWS Fault Injection Service (以下、FIS)のLambda対応の話がありました。(Lambda対応自体はre:Invent前に発表されていました)

 前回のre:Invent2023でFISのワークショップに参加したので、EC2やRDSでのFIS実験の流れはなんとなく(うっすらと)理解していました。昨年のイベント後はFISに触っていなかったのと、セッションを聴講して、Lambdaでの障害試験を試してみたくなったので、実際にやってみました。

AWS Fault Injection Service (AWS FIS)とは

 FISは、AWS上で稼働するアプリケーションの回復力を高めるためのマネージドサービスです。カオスエンジニアリングの概念に基づき、システムに意図的に障害を発生させることで、その挙動や耐性を事前に確認することができます。

実行環境

今回はaws-cdk-examplesのapi-cors-lambda-crud-dynamodbをデプロイして使いました。

以下のようにフロントにAPI Gatewayがあり、そのバックエンドにLambda、DynamoDBがあるというシンプルなサーバレス構成です。
Lambdaは以下の5つが準備されています。
 getOneItem
 getAllItems
 createItem
 updateItem
 deleteItem

fis_000.png

FIS実験のアクションによるLambdaへの障害注入方法

 FIS実験がS3バケットに障害試験の内容を書き出し、追加したLambdaレイヤーが定期的に設定ファイルをチェックして内容を読み取り、障害を発生させるというイメージで理解しました。
fis_001.png

設定方法

ドキュメントはこちらです。

作業の流れ

(1) S3バケット作成
(2) Lambda用IAMポリシー作成、IAMロールにアタッチ
(3) Lambdaレイヤー、環境変数追加
(4) FIS用IAMポリシー作成、IAMロール作成
(5) FIS実験の作成、IAMロールアタッチ
fis_002.png

S3バケット作成

今回の各処理で使用する専用のバケット fis-test-lambda を作成します。

fis_003.png

Lambda用IAMポリシー作成、IAMロールにアタッチ

Lambda関数から先ほど作成したS3へアクセスするための権限が必要になります。
まずはLambda用のIAMポリシー fis-test-policy-for-lambda を作成します。

fis-test-policy-for-lambda
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowListingConfigLocation",
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::fis-test-lambda"
            ],
            "Condition": {
                "StringLike": {
                    "s3:prefix": [
                        "FisConfigs/*"
                    ]
                }
            }
        },
        {
            "Sid": "AllowReadingObjectFromConfigLocation",
            "Effect": "Allow",
            "Action": "s3:GetObject",
            "Resource": [
                "arn:aws:s3:::fis-test-lambda/FisConfigs/*"
            ]
        }
    ]
}

作成したポリシー fis-test-policy-for-lambda をLambda関数に紐づいているIAMロールにアタッチします。
fis_004.png

Lambdaレイヤー、環境変数追加

OS、リージョンによって指定するARNが異なっているのでご注意ください。

今回はap-northeast-1、x86_64の環境になるため、arn:aws:lambda:ap-northeast-1:339712942424:layer:aws-fis-extension-x86_64:9 を使用しました。

fis_005.png

Lambdaにレイヤーを追加していきます。
fis_006.png

「ARNを指定」を選択して、先ほど確認したARNを入力し、「検証」をクリックします。
fis_007.png

説明欄が表示されるので、FISのレイヤーであることを確認して、「追加」をクリックします。
fis_008.png

レイヤーが追加されました。
fis_009.png

続いて環境変数を2つ追加していきます。

キー 変数
AWS_FIS_CONFIGURATION_LOCATION   S3設定フォルダのARNを設定
arn:aws:s3:::fis-test-lambda/FisConfigs/
AWS_LAMBDA_EXEC_WRAPPER       /opt/aws-fis/bootstrap                

fis_010.png

FIS用IAMポリシー作成、IAMロール作成

FIS実験からS3バケットやCloudwatch、Lambdaへアクセスするための権限を付与するため、IAMポリシー fis-test-policy-for-experiments を作成します。

fis-test-policy-for-experiments
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowFisToWriteAndDeleteFaultConfigurations",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:DeleteObject"
            ],
            "Resource": "arn:aws:s3:::fis-test-lambda/FisConfigs/*"
        },
        {
            "Sid": "AllowFisToInspectLambdaFunctions",
            "Effect": "Allow",
            "Action": [
                "lambda:GetFunction"
            ],
            "Resource": "*"
        },
        {
            "Sid": "AllowFisToDoTagLookups",
            "Effect": "Allow",
            "Action": [
                "tag:GetResources"
            ],
            "Resource": "*"
        },
        {
            "Action": [
                "cloudwatch:getMetricWidgetImage"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogDelivery",
                "logs:PutResourcePolicy",
                "logs:DescribeResourcePolicies",
                "logs:DescribeLogGroups"
            ],
            "Resource": "*"
        }
    ]
}

IAMロール fis-test-role を作成して、先ほどのIAMポリシー fis-test-policy-for-experiments をアタッチします。
※既にFIS用にIAMロールを作成している場合は、そちらにアタッチしてもOKです。

fis_011.png

FIS実験の作成、IAMロールアタッチ

最後にFISの実験テンプレートを作成していきます。

Falut Injection Serviceの画面にて「実験テンプレート」を選択し、「実験テンプレートを作成」をクリックします。
fis_012.png

「テンプレートの詳細を指定」画面にて説明欄を記入します。
今回は FIS_Lambda_Add_Delay と記入しました。実験タイプは「このAWSアカウント」を選択し、「次へ」をクリックします。
fis_013.png

「アクションとターゲットを指定」画面にて「+ターゲットを追加」をクリックします。
fis_014.png

「ターゲットを追加」画面で、以下を設定していきます。
 名前:lambda
 リソースタイプ:aws:lambda:function を選択
 ターゲットメソッド:リソースID を選択
 「Add new ARN」をクリックします。
fis_015.png

新たに表示された「Lambda ARN」の項目で対象のLambda関数を選択し、「保存」をクリックします。
fis_016.png

ターゲットが作成されましたので、アクションを追加していきます。
fis_017.png

名前を入力して、アクションタイプでは「LAMBDA」を選択後、 aws:lambda:invocation-add-delay を選択します。
fis_018.png

すると、ターゲット以下の項目が表示されるようになります。
ターゲットは先ほど作成した lambda を選択し、下の各項目に値をセットして「保存」をクリックします。
私がセットしたのは、10分間、100%の起動時に、2500msecのDelayを発生させる形になります。

fis_019.png

※私が実施した2024/12/30時点で日本語版のドキュメントには、各パラメータの説明がありませんでした。英語版のサイトを日本語訳して確認されることをお勧めします。

パラメータ 説明
Duration 障害が継続する時間の長さ
Invocation percentage 関数呼び出し時に障害を発生させる割合
Startup delay milliseconds 関数コードの呼び出しと実行の間に待機する時間(ミリ秒単位、0~900,000)。デフォルトは 1000msec

関数呼び出し時に障害を発生させる割合を指定できるのは便利ですね。中途半端に障害が発生するグレー障害に近い状況が作り出せると思います。

無事、アクションも作成できましたので、「次へ」をクリックします。
fis_020.png

サービスアクセスの設定画面で先ほどFIS実験用に作成したIAMロール fis-test-role を選択し、「次へ」をクリックします。
fis_021.png

オプション設定をしていきます。
停止条件、レポート設定は特に設定しませんでした。
fis_022.png

ログに関しては、チェックを入れて、最初に作成したS3バケットを選択します。Cloudwatch Logsはロググループを新たに作成して指定しました。既存で適切なロググループがある方は、「参照」から選択していただければと思います。
fis_023.png

タグは特に設定せず、「次へ」をクリックします。
fis_024.png

確認画面になりますので、内容を確認して「実験テンプレートを作成」を選択します。
fis_025.png
fis_026.png
fis_027.png

実験テンプレートができました。
fis_029.png

実験を試してみる

実験テンプレートの右上の「実験を開始」をクリックして試してみます。
タグをつける画面が表示されますが、そのまま実験を開始してみます。
fis_030.png

無事に開始されました。状態がRunningになっていれば成功です。
fis_032.png

試しにリクエストを何度か送ってみます。
繰り返しリクエストを送った後なので、Lambda関数がコールドスタートではない状態でも、合計時間が2,500msec超になっています。

% curl -X GET https://XXXXXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/prod/items/d8e26b2b-1346-4734-8d31-35529327510c \
-H 'Content-Type:application/json' -w"\ntime_total: %{time_total}\n"

{"id":"001","name":"FIS test 001","itemId":"d8e26b2b-1346-4734-8d31-35529327510c"}
time_total: 2.874584

Cloudwatch LogsのFISのログも見てみます。先ほど設定したアクションがログに出力されていました。

{
    "id": "EXP237FqDwrp81F2unz",
    "log_type": "action-start",
    "event_timestamp": "2024-12-30T04:06:53.259Z",
    "version": "2",
    "details": {
        "action_name": "lambda_add_delay",
        "action_id": "aws:lambda:invocation-add-delay",
        "action_start_time": "2024-12-30T04:06:53.246Z",
        "action_targets": {
            "Functions": "lambda"
        },
        "parameters": {
            "duration": "PT10M",
            "invocationPercentage": "100",
            "startupDelayMilliseconds": "2500"
        }
    }
}

ちなみにLambda側のログはこちら。
正常時

REPORT RequestId: 7d6186fd-309d-4655-b567-5c35f9f64de8	Duration: 75.48 ms	Billed Duration: 76 ms	Memory Size: 128 MB	Max Memory Used: 92 MB	

アクション実行中

REPORT RequestId: 6869bcb4-f866-48e6-9cc8-f62d56d3ab1a	Duration: 2577.13 ms	Billed Duration: 2578 ms	Memory Size: 128 MB	Max Memory Used: 92 MB	

期待通りに処理時間が延びていることを確認できました。

気づきとつづき

 今回のお試しでFISによるLambdaの障害試験の流れが掴めました。他の2つの障害パターンについても、試して投稿したいと思います。これまでLambdaの障害試験についてはコードを変更しないと実現できない認識でいましたが、コード変更なしで実現できるようになったのはとても良いことだと思います。
 FIS実験では先行アクションを指定できますので、複数のアクションを作成して、繋げて、徐々に障害の発生率を上げて状況を悪化させるといったこともできそうです。また、1つのLambda関数に複数の障害パターンが同時に発生するといった複雑な障害も実現できそうですので、しっかりと試験パターンを検討できれば、FISによる訓練の質を上げられると考えました。
 色々試して、続きは年明けに別の投稿で記載しようと思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?