AWS Fault Injection Service

目次

カオスエンジニアリング・障害注入・耐障害性検証プラットフォーム

AWS Fault Injection Service(FIS) は、本番環境で 制御された障害を注入 して、アプリケーション・インフラの耐障害性をテストするマネージドカオスエンジニアリングサービスです。EC2 インスタンス強制終了・RDS フェイルオーバー・AZ 障害シミュレーション・ネットワークレイテンシ注入等を実験テンプレートで定義し、CloudWatch アラームによる自動停止ガードレールで本番環境への影響を最小化します。Well-Architected Framework の「信頼性の柱」・金融規制(FFIEC BCM)・ISO 27001 で要求される DR ドリル・復旧テストを自動化し、年 1 回の訓練から常時運用に転換できます。2025-2026 年は Bedrock AgentCore との統合で AI 推論失敗注入、Organizations multi-account サポート拡張、自動 remediation Lambda 統合により、エンタープライズスケール対応が進化しています。このページでは FIS のアーキテクチャ・実験デザイン・各 AWS サービス別アクション・停止条件・ベストプラクティス・導入ロードマップを網羅したリファレンスとして整理します。


概要と課題

カオスエンジニアリングが解決する課題

1. 「机上の計画」と「実運用」のギャップ

従来:

Planning:
  - RTO = 1 hour(目標)
  - Multi-AZ configure
  - Auto Scaling Group enabled

Real Disaster:
  - AZ-a failure → AZ-b へフェイルオーバー期待
  - 実際:App は AZ-a に硬くバインド → 5時間停止
  - 原因:設定は Multi-AZ だが、アプリが AZ affinity 前提

FIS の改善:

Experiment: "Simulate AZ-a failure"
  → 実際に AZ 障害シミュレーション実行
  → 本当に Multi-AZ フェイルオーバー動くか検証
  → 設定漏れ・アプリ仕様 bug 早期発見
  → 本番障害が起きる前に修正

2. 「信頼性」を定量化できない

課題:

  • RTO 1 時間と言うが、実際の復旧速度は?
  • Auto Scaling のスケールアウト速度はどのくらい?
  • キャッシュ喪失時のレイテンシ増加は?

FIS の解決:

  • 実測値取得:本当の復旧時間を測定
  • ボトルネック特定:どのステップが遅いか特定
  • 改善効果検証:修正後、再実験で改善確認

3. 定期的なテスト(年 1 回)→ 常時運用への移行困難

課題:

  • DR 訓練は年 1 回(月 1 回 → quarterly は high cost)
  • 新規機能・スケール変更時に未検証リスク

FIS の改善:

  • CI/CD パイプライン統合 → 毎デプロイ時に障害テスト
  • 定期自動実行 → 週 1 回の FIS 実験
  • 組織規模スケーリング → 全社的なカオス文化醸成

ユースケース例

  • AZ 障害時に Multi-AZ フェイルオーバー動作検証
  • EC2 インスタンス 30% 強制終了時のアプリ応答性確認
  • RDS Multi-AZ フェイルオーバー復旧時間測定
  • Lambda 同時実行制限到達時の application graceful degradation 確認
  • ECS タスク 50% 強制終了でサービス継続確認
  • ネットワークレイテンシ 500ms 注入時の application 応答性評価
  • Systems Manager State Manager で自動修復動作検証
  • EBS snapshot restore 速度測定

主な特徴

特徴 説明
マネージド実行 AWS API で安全に障害注入、AWS が制御
Stop Conditions CloudWatch alarms で自動停止ガードレール
テンプレート管理 実験シナリオの版管理・再実行
マルチ AWS サービス EC2・RDS・ECS・EKS・Lambda・DynamoDB 等 20+
IAM 統合 タグベース実験範囲制限・最小権限
Organizations 対応 Multi-account 実験(2025 拡張)
Bedrock 統合 AI 推論失敗注入(2026 予定)
Systems Manager 統合 Runbook 自動修復実行
EventBridge 統合 実験完了時自動アクション
CloudFormation IaC で実験テンプレート定義
Cost Optimized $0.10/action/hour(他サービスより低コスト)
自動レポート生成 実験結果・メトリクス集計

アーキテクチャと概念

Chaos Engineering フロー

graph TD
    A["Hypothesis<br/>仮説設定"] -->|"Ex: Multi-AZ failover works<br/>in 5 min"| B["Experiment Design<br/>実験設計"]
    B --> C["Create FIS Template<br/>テンプレート作成"]
    C --> D["Run Experiment<br/>実験実行"]
    D -->|"Stop Condition triggered?<br/>Expected metric impact?"| E{"Outcome Analysis<br/>結果分析"}
    E -->|"Failed"| F["Root Cause Investigation<br/>原因調査"]
    F --> G["Fix Implementation<br/>修正実装"]
    G -->|"Re-test"| D
    E -->|"Success"| H["Knowledge Base Update<br/>組織学習"]
    H --> I["Next Hypothesis"]

Experiment Template 構成

Experiment Template
  ├─ Actions(何をするか)
  │   ├─ Terminate EC2 instances(30%)
  │   ├─ Stop RDS cluster
  │   └─ Add 500ms latency
  │
  ├─ Targets(対象リソース)
  │   ├─ Resource type: EC2 instance
  │   ├─ Filters: Tag env=prod
  │   ├─ Selection: PERCENT(30)
  │   └─ Max concurrency: 5
  │
  ├─ Stop Conditions(停止条件)
  │   ├─ CloudWatch alarm: high-error-rate
  │   ├─ Threshold: 5% error rate
  │   └─ Auto-rollback: YES
  │
  └─ IAM Role(実行権限)
      ├─ ec2:TerminateInstances
      ├─ cloudwatch:DescribeAlarms
      └─ sns:Publish(通知)

安全性ガードレール

┌─ Experiment Start
│
├─ Pre-flight Check
│  ├─ IAM role 権限確認
│  ├─ Target resource 存在確認
│  └─ Stop condition 有効確認
│
├─ Experiment Running
│  ├─ Action 1 実行
│  │  └─ CloudWatch metric 監視(毎秒)
│  ├─ Stop condition 評価
│  │  └─ Threshold 超過 → Auto Stop
│  └─ Action N
│
└─ Experiment Stopped
   ├─ Graceful shutdown
   ├─ Affected resource 復旧確認
   └─ Report generation

コアコンポーネント

1. Experiment Template

{
  "TemplateId": "ext-0123456789abcdef0",
  "TemplateName": "ec2-30pct-termination-test",
  "Description": "Test Auto Scaling response to 30% instance termination",
  "Actions": {
    "terminateInstances": {
      "ActionId": "aws:ec2:terminate-instances",
      "Parameters": {
        "startInstancesAfterDuration": "PT0S"
      },
      "Targets": {"Instances": "targetInstances"},
      "StartAfter": ["prepareCloudwatch"]
    }
  },
  "Targets": {
    "targetInstances": {
      "ResourceType": "aws:ec2:instance",
      "ResourceTags": {"Environment": "staging", "ChaosTest": "true"},
      "Filters": [
        {"Path": "State.Name", "Values": ["running"]},
        {"Path": "Placement.AvailabilityZone", "Values": ["ap-northeast-1a"]}
      ],
      "SelectionMode": "PERCENT(30)",
      "MaxConcurrentResources": 5
    },
    "alarmTargets": {
      "ResourceType": "aws:cloudwatch:alarm",
      "ResourceArns": ["arn:aws:cloudwatch:...:alarm/app-error-rate"]
    }
  },
  "StopConditions": [
    {
      "Source": "aws:cloudwatch:alarm",
      "Value": "arn:aws:cloudwatch:ap-northeast-1:ACCOUNT:alarm/app-error-rate-high"
    }
  ],
  "RoleArn": "arn:aws:iam::ACCOUNT:role/FISExperimentRole",
  "Tags": {
    "Team": "SRE",
    "Purpose": "DR-Test"
  }
}

2. IAM Role 権限設定

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "EC2TerminateTagged",
      "Effect": "Allow",
      "Action": [
        "ec2:TerminateInstances",
        "ec2:DescribeInstances"
      ],
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "aws:ResourceTag/ChaosTest": "true"
        }
      }
    },
    {
      "Sid": "RDSFailover",
      "Effect": "Allow",
      "Action": [
        "rds:FailoverDBCluster",
        "rds:DescribeDBClusters"
      ],
      "Resource": "arn:aws:rds:*:ACCOUNT:cluster/*"
    },
    {
      "Sid": "ECSStopTask",
      "Effect": "Allow",
      "Action": [
        "ecs:UpdateService",
        "ecs:StopTask",
        "ecs:ListTasks",
        "ecs:DescribeTasks"
      ],
      "Resource": [
        "arn:aws:ecs:*:ACCOUNT:service/*/*",
        "arn:aws:ecs:*:ACCOUNT:task/*/*"
      ]
    },
    {
      "Sid": "CloudWatchAccess",
      "Effect": "Allow",
      "Action": [
        "cloudwatch:DescribeAlarms",
        "cloudwatch:GetMetricStatistics"
      ],
      "Resource": "*"
    },
    {
      "Sid": "SNSNotify",
      "Effect": "Allow",
      "Action": ["sns:Publish"],
      "Resource": "arn:aws:sns:*:ACCOUNT:topic/chaos-notifications"
    },
    {
      "Sid": "LogsWrite",
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Resource": "arn:aws:logs:*:ACCOUNT:log-group:/aws/fis/*"
    }
  ]
}

3. Stop Condition 設定

CloudWatch アラームで実験自動停止:

# 「エラー率が 5% 超過」で自動停止
aws cloudwatch put-metric-alarm \
  --alarm-name app-error-rate-high \
  --alarm-description "Stop FIS experiment if error rate > 5%" \
  --metric-name ErrorRate \
  --namespace ApplicationMetrics \
  --statistic Average \
  --period 60 \
  --threshold 5 \
  --comparison-operator GreaterThanThreshold \
  --evaluation-periods 2

# FIS テンプレートで参照
aws fis create-experiment-template \
  --stop-conditions '[{
    "Source": "aws:cloudwatch:alarm",
    "Value": "arn:aws:cloudwatch:ap-northeast-1:ACCOUNT:alarm/app-error-rate-high"
  }]'

対応 AWS サービス別アクション

EC2 アクション

アクション パラメータ 用途
terminate-instances SelectionMode: COUNT/PERCENT インスタンス強制終了(Auto Scaling テスト)
stop-instances Duration: PT5M 一時停止(復旧可能)
reboot-instances - 再起動(kernel panic 検証)
cpu-stress Duration, Cpu% CPU 負荷テスト
memory-stress Duration, Memory% メモリ圧迫テスト
network-stress Latency, Jitter ネットワーク障害注入

RDS アクション

アクション パラメータ 用途
failover-db-cluster Duration Multi-AZ フェイルオーバー
failover-db-instance - Single DB インスタンス failover
stop-db-instance - DB 停止(復旧可能)

ECS / Fargate アクション

アクション パラメータ 用途
stop-task Percentage タスク強制終了
pause-task Duration タスク一時停止

EKS / Kubernetes アクション

アクション パラメータ 用途
terminate-node Percentage ノード強制削除
drain-node Duration ノード drain(graceful shutdown)
pod-termination Percentage Pod 強制削除

VPC / Network アクション

アクション パラメータ 用途
disrupt-connectivity Duration, Scope ネットワーク接続遮断
add-latency Latency, Duration レイテンシ注入
packet-loss PacketLoss%, Duration パケットロス注入

AZ 障害シミュレーション

# AZ-a の全リソース通信を 5 分遮断
aws fis create-experiment-template \
  --actions '{
    "azDisruption": {
      "actionId": "aws:ec2:disrupt-availability-zone-network",
      "parameters": {
        "duration": "PT5M",
        "availabilityZoneIdentifiers": "apne1-az1"
      },
      "targets": {"AvailabilityZones": "targetAZ"}
    }
  }' \
  --targets '{
    "targetAZ": {
      "resourceType": "aws:ec2:availability-zone",
      "resourceArns": ["arn:aws:ec2:ap-northeast-1::availability-zone/ap-northeast-1a"],
      "selectionMode": "ALL"
    }
  }'

主要ユースケース

1. Auto Scaling Group テスト(EC2 30% 終了)

シナリオ:アプリが 10 インスタンス(3AZ)で実行中、30% が強制終了されると復旧するか

# テンプレート作成
aws fis create-experiment-template \
  --template-name "asg-resilience-test" \
  --actions '{
    "terminateInstances": {
      "actionId": "aws:ec2:terminate-instances",
      "targets": {"Instances": "appInstances"}
    }
  }' \
  --targets '{
    "appInstances": {
      "resourceType": "aws:ec2:instance",
      "resourceTags": {"App": "web-app", "Env": "prod"},
      "selectionMode": "PERCENT(30)"
    }
  }' \
  --stop-conditions '[{
    "source": "aws:cloudwatch:alarm",
    "value": "arn:aws:cloudwatch:ap-northeast-1:ACCOUNT:alarm/high-error-rate"
  }]' \
  --role-arn "arn:aws:iam::ACCOUNT:role/FISExperimentRole"

# 実験実行
TEMPLATE_ID=$(aws fis list-experiment-templates --query 'experimentTemplates[0].id' --output text)
aws fis start-experiment --experiment-template-id $TEMPLATE_ID

# 進捗監視
aws fis get-experiment --id EXP-xxxxx --query 'experiment.{Status:state.status, Actions:actions}'

期待される動作

Time 0:00 - インスタンス 3 個(30%)強制終了
Time 0:15 - Auto Scaling Group がスケールアウト検知
Time 1:00 - 新 instan launcher
Time 1:30 - 全インスタンス healthy(3インスタンス復旧)
Time 2:00 - エラー率ゼロ復帰
Result: PASS(RTO = 90 seconds)

2. RDS Multi-AZ フェイルオーバー(復旧時間測定)

シナリオ:RDS Aurora がプライマリ AZ から セカンダリ AZ へ フェイルオーバー、アプリの応答性は?

import boto3
import time
from datetime import datetime

fis = boto3.client('fis', region_name='ap-northeast-1')

# Template 作成
response = fis.create_experiment_template(
    templateName='rds-failover-test',
    description='RDS Aurora Multi-AZ failover recovery test',
    actions={
        'rdsFailover': {
            'actionId': 'aws:rds:failover-db-cluster',
            'targets': {'Clusters': 'prodCluster'}
        }
    },
    targets={
        'prodCluster': {
            'resourceType': 'aws:rds:cluster',
            'resourceArns': ['arn:aws:rds:ap-northeast-1:ACCOUNT:cluster:prod-aurora'],
            'selectionMode': 'ALL'
        }
    },
    stopConditions=[{
        'source': 'aws:cloudwatch:alarm',
        'value': 'arn:aws:cloudwatch:ap-northeast-1:ACCOUNT:alarm/rds-connection-errors'
    }],
    roleArn='arn:aws:iam::ACCOUNT:role/FISExperimentRole'
)

template_id = response['experimentTemplate']['id']

# 実験実行 & メトリクス取得
start_time = datetime.now
exp = fis.start_experiment(experimentTemplateId=template_id)

cloudwatch = boto3.client('cloudwatch', region_name='ap-northeast-1')
while True:
    exp_status = fis.get_experiment(id=exp['experiment']['id'])

    if exp_status['experiment']['state']['status'] in ['COMPLETED', 'STOPPED']:
        break

    # 接続復旧時間測定
    metrics = cloudwatch.get_metric_statistics(
        Namespace='RDS',
        MetricName='DatabaseConnections',
        Dimensions=[
            {'Name': 'DBClusterIdentifier', 'Value': 'prod-aurora'}
        ],
        StartTime=start_time,
        EndTime=datetime.now,
        Period=10,
        Statistics=['Average']
    )

    time.sleep(5)

elapsed = (datetime.now - start_time).total_seconds
print(f"RTO Measured: {elapsed} seconds")

期待値

  • Primary failover detection: < 10 秒
  • Connection retry success: < 30 秒
  • Full recovery: < 60 秒

3. Lambda 同時実行制限テスト

シナリオ:Lambda が 同時実行数 100 に達した時、アプリは graceful degrade するか

# Lambda に artificial throttle を注入
aws fis create-experiment-template \
  --template-name "lambda-throttling-test" \
  --actions '{
    "throttleApi": {
      "actionId": "aws:lambda:throttle-function",
      "parameters": {
        "duration": "PT5M",
        "percentOfConcurrency": "100"
      },
      "targets": {"Functions": "targetLambdas"}
    }
  }' \
  --targets '{
    "targetLambdas": {
      "resourceType": "aws:lambda:function",
      "resourceTags": {"App": "api-backend"},
      "selectionMode": "ALL"
    }
  }' \
  --role-arn "arn:aws:iam::ACCOUNT:role/FISExperimentRole"

検証項目

  • API Gateway timeout 動作
  • SQS dead-letter queue への落ち込み
  • Cloudfront cache hit rate 上昇(キャッシュで緩和)

4. Network Latency テスト(アプリ応答性評価)

シナリオ:VPC 間通信に 500ms レイテンシを追加、アプリは許容できるか

aws fis create-experiment-template \
  --template-name "network-latency-test" \
  --actions '{
    "addLatency": {
      "actionId": "aws:network:add-latency",
      "parameters": {
        "latency": "PT0.5S",
        "duration": "PT10M"
      },
      "targets": {"NetworkInterface": "targetEnis"}
    }
  }' \
  --targets '{
    "targetEnis": {
      "resourceType": "aws:ec2:network-interface",
      "filters": [
        {"path": "Tag:Layer", "values": ["application"]}
      ],
      "selectionMode": "ALL"
    }
  }' \
  --role-arn "arn:aws:iam::ACCOUNT:role/FISExperimentRole"

監視メトリクス

  • API response time (CloudWatch latency metric)
  • User experience score (Synthetic Monitoring)
  • Database query time (RDS Performance Insights)

5. ECS Fargate タスク强制終了(オーケストレーション検証)

シナリオ:ECS サービスの 30% タスク強制終了、ECS が新タスク自動起動するか

import boto3

fis = boto3.client('fis', region_name='ap-northeast-1')

response = fis.create_experiment_template(
    templateName='ecs-task-termination-test',
    actions={
        'stopTasks': {
            'actionId': 'aws:ecs:stop-task',
            'parameters': {
                'duration': 'PT0S'
            },
            'targets': {'Tasks': 'targetTasks'}
        }
    },
    targets={
        'targetTasks': {
            'resourceType': 'aws:ecs:task',
            'resourceArns': [],
            'filters': [
                {'path': 'Service.Name', 'values': ['api-service']}
            ],
            'selectionMode': 'PERCENT(30)'
        }
    },
    stopConditions=[{
        'source': 'aws:cloudwatch:alarm',
        'value': 'arn:aws:cloudwatch:ap-northeast-1:ACCOUNT:alarm/ecs-task-failures-high'
    }],
    roleArn='arn:aws:iam::ACCOUNT:role/FISExperimentRole',
    tags={'Team': 'Platform'}
)

6. Systems Manager 自動修復統合

実験から自動修復へ:

# Systems Manager Runbook で自動修復
aws ssm create-document \
  --content '{
    "schemaVersion": "0.3",
    "description": "Auto-remediate high CPU instance",
    "mainSteps": [
      {
        "name": "DescribeHighCPUInstance",
        "action": "aws:executeScript",
        "inputs": {
          "Runtime": "python3.8",
          "Handler": "find_high_cpu_instance",
          "Script": "def find_high_cpu_instance(events, context):\n    cloudwatch = boto3.client(\"cloudwatch\")\n    metrics = cloudwatch.get_metric_statistics(...)\n    for m in metrics[\"Datapoints\"]:\n        if m[\"Average\"] > 80:\n            return {\"InstanceId\": instance_id}"
        }
      },
      {
        "name": "RollingRestart",
        "action": "aws:executeAwsApi",
        "inputs": {
          "Service": "ec2",
          "Api": "StopInstances",
          "InstanceIds": ["{{ DescribeHighCPUInstance.InstanceId }}"]
        }
      }
    ]
  }' \
  --document-type "Automation"

# FIS experiment → SSM runbook トリガー
aws fis create-experiment-template \
  --template-name "cpu-stress-with-remediation" \
  --actions '{
    "cpuStress": {...},
    "remediate": {
      "actionId": "aws:ssm:start-automation-execution",
      "parameters": {
        "documentArn": "arn:aws:ssm:...:document/RemediateHighCPU"
      },
      "startAfter": ["cpuStress"]
    }
  }'

設定・操作の具体例

CLI:シンプルな EC2 実験

# 1. IAM Role 作成
aws iam create-role \
  --role-name FISExperimentRole \
  --assume-role-policy-document '{
    "Version": "2012-10-17",
    "Statement": [{
      "Effect": "Allow",
      "Principal": {"Service": "fis.amazonaws.com"},
      "Action": "sts:AssumeRole"
    }]
  }'

aws iam attach-role-policy \
  --role-name FISExperimentRole \
  --policy-arn arn:aws:iam::aws:policy/EC2FullAccess

# 2. Template 作成
aws fis create-experiment-template \
  --template-name simple-ec2-stop \
  --actions '{
    "stopInstances": {
      "actionId": "aws:ec2:stop-instances",
      "targets": {"Instances": "ec2Instances"}
    }
  }' \
  --targets '{
    "ec2Instances": {
      "resourceType": "aws:ec2:instance",
      "resourceTags": {"ChaosTest": "true"},
      "selectionMode": "COUNT(1)"
    }
  }' \
  --role-arn arn:aws:iam::ACCOUNT:role/FISExperimentRole

# 3. 実験実行
TEMPLATE_ID="ext-0123456789abcdef0"
aws fis start-experiment --experiment-template-id $TEMPLATE_ID

# 4. 進捗確認
aws fis list-experiments --query 'experiments[*].[id,state.status,creationTime]'

SDK (Python):複雑な多層実験

import boto3
from datetime import datetime

fis = boto3.client('fis', region_name='ap-northeast-1')
cloudwatch = boto3.client('cloudwatch')

# Template 作成
template = fis.create_experiment_template(
    templateName='multi-layer-resilience-test',
    description='Test resilience: EC2 terminate + RDS failover + network latency',
    actions={
        'terminateEC2': {
            'actionId': 'aws:ec2:terminate-instances',
            'parameters': {},
            'targets': {'Instances': 'appServers'},
            'startAfter': []
        },
        'rdsFailover': {
            'actionId': 'aws:rds:failover-db-cluster',
            'targets': {'Clusters': 'prodCluster'},
            'startAfter': ['terminateEC2']  # Sequential
        },
        'networkLatency': {
            'actionId': 'aws:network:add-latency',
            'parameters': {'latency': 'PT0.2S', 'duration': 'PT10M'},
            'targets': {'NetworkInterface': 'appNics'},
            'startAfter': []  # Parallel
        }
    },
    targets={
        'appServers': {
            'resourceType': 'aws:ec2:instance',
            'resourceTags': {'Layer': 'Application', 'Env': 'staging'},
            'filters': [{'path': 'State.Name', 'values': ['running']}],
            'selectionMode': 'PERCENT(20)'
        },
        'prodCluster': {
            'resourceType': 'aws:rds:cluster',
            'resourceArns': ['arn:aws:rds:ap-northeast-1:ACCOUNT:cluster:prod-aurora'],
            'selectionMode': 'ALL'
        },
        'appNics': {
            'resourceType': 'aws:ec2:network-interface',
            'resourceTags': {'Layer': 'Application'},
            'selectionMode': 'ALL'
        }
    },
    stopConditions=[
        {
            'source': 'aws:cloudwatch:alarm',
            'value': 'arn:aws:cloudwatch:ap-northeast-1:ACCOUNT:alarm/app-error-rate-high'
        }
    ],
    roleArn='arn:aws:iam::ACCOUNT:role/FISExperimentRole'
)

# 実験実行
experiment = fis.start_experiment(experimentTemplateId=template['experimentTemplate']['id'])
exp_id = experiment['experiment']['id']

# リアルタイム監視
print(f"Experiment {exp_id} started at {datetime.now}")

for i in range(60):  # 60 秒監視
    exp_status = fis.get_experiment(id=exp_id)
    state = exp_status['experiment']['state']['status']

    if state in ['COMPLETED', 'STOPPED', 'FAILED']:
        print(f"Experiment {state}")
        break

    # CloudWatch Insights query for application metrics
    print(f"Time {i}s: State={state}")
    time.sleep(1)

# 結果分析
exp_final = fis.get_experiment(id=exp_id)
print(f"Final state: {exp_final['experiment']['state']}")

CloudFormation:IaC で実験管理

Resources:
  FISExperimentRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: fis.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/EC2FullAccess
        - arn:aws:iam::aws:policy/RDSFullAccess

  FISExperimentTemplate:
    Type: AWS::FIS::ExperimentTemplate
    Properties:
      TemplateDescription: Multi-layer resilience chaos experiment
      Actions:
        terminateEC2:
          ActionId: aws:ec2:terminate-instances
          Parameters: {}
          Targets:
            Instances: appInstances
        rdsFailover:
          ActionId: aws:rds:failover-db-cluster
          Targets:
            Clusters: prodDatabase
          StartAfter:
            - terminateEC2
      Targets:
        appInstances:
          ResourceType: aws:ec2:instance
          ResourceTags:
            Environment: staging
            ChaosTest: true
          Filters:
            - Path: State.Name
              Values:
                - running
          SelectionMode: PERCENT(30)
        prodDatabase:
          ResourceType: aws:rds:cluster
          ResourceArns:
            - !Sub 'arn:aws:rds:${AWS::Region}:${AWS::AccountId}:cluster:prod-aurora'
          SelectionMode: ALL
      StopConditions:
        - Source: aws:cloudwatch:alarm
          Value: !Sub 'arn:aws:cloudwatch:${AWS::Region}:${AWS::AccountId}:alarm/app-error-rate'
      RoleArn: !GetAtt FISExperimentRole.Arn
      Tags:
        Team: SRE
        Purpose: DR-Testing

Terraform:実験定期実行(EventBridge 統合)

resource "aws_fis_experiment_template" "weekly_chaos" {
  name           = "weekly-auto-scaling-test"
  description    = "Weekly Auto Scaling Group resilience validation"
  role_arn       = aws_iam_role.fis_role.arn

  action {
    name      = "terminate-instances"
    action_id = "aws:ec2:terminate-instances"
    target {
      key   = "Instances"
      value = "app-servers"
    }
  }

  target {
    name         = "app-servers"
    resource_type = "aws:ec2:instance"
    resource_tag {
      key   = "Application"
      value = "web-app"
    }
    selection_mode = "PERCENT(30)"
  }

  stop_condition {
    source = "aws:cloudwatch:alarm"
    value  = aws_cloudwatch_metric_alarm.error_rate_high.arn
  }

  tags = {
    Team    = "SRE"
    Cadence = "Weekly"
  }
}

# EventBridge で 週 1 回(金曜 15:00)自動実行
resource "aws_cloudwatch_event_rule" "fis_weekly" {
  name                = "fis-weekly-schedule"
  schedule_expression = "cron(0 15 ? * FRI *)"  # Fri 15:00 JST
}

resource "aws_cloudwatch_event_target" "fis_start" {
  rule      = aws_cloudwatch_event_rule.fis_weekly.name
  target_id = "StartFISExperiment"
  arn       = "arn:aws:fis:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:experiment-template/${aws_fis_experiment_template.weekly_chaos.id}"

  role_arn = aws_iam_role.eventbridge_fis.arn
}

類似サービス比較表

サービス 管理対象 学習曲線 コスト マネージド 統合度
AWS FIS AWS ネイティブ $0.10/action/h
Chaos Mesh Kubernetes 無料 OSS K8s 専用
LitmusChaos Kubernetes 無料 OSS K8s 専用
Gremlin マルチクラウド $5k-50k/月
Steadybit マルチクラウド $3k-30k/月
Chaos Toolkit マルチクラウド 無料 OSS

ベストプラクティス

✅ やるべきこと

項目 理由 実装
Staging で初回テスト 本番影響最小化 dev → staging → prod 段階的
Stop Condition 必須 実験暴走防止 CloudWatch alarm 必ず設定
Tag ベース実験制限 誤対象化防止 ChaosTest=true タグ限定
定期実行(週 1) 継続的な信頼性向上 EventBridge で自動化
メトリクス記録 継続改善データ化 CloudWatch Insights で分析
チーム訓練 組織学習 月 1 回レビュー会
ドキュメント化 知見共有・監査対応 Runbook・Lesson learned 記録
IAM 最小権限 セキュリティ ChaosTest=true 範囲限定

❌ してはいけないこと

項目 問題 対策
本番で無条件実行 大規模障害リスク 必ず停止条件設定・事前通知
停止条件なし 実験が止まらない CloudWatch alarm 必須
計画なし直感実行 仮説なし・学習ゼロ 事前に仮説・期待値定義
ビジネス時間中実行 ユーザ影響大 深夜・低トラフィック時間帯
広範囲 tag 無関係リソース被害 env=prod && ChaosTest=true 両方必須
ログ無視 原因特定困難 CloudWatch Insights で常時監視

トラブルシューティング

症状 原因 解決策
実験がすぐ STOPPED Stop Condition 評価超過 threshold を緩和(例:5% → 10%)
対象リソース見つからない Tag フィルタ誤り aws ec2 describe-instances --filters "Name=tag:ChaosTest,Values=true" で確認
IAM エラー (Access Denied) Role 権限不足 aws iam get-role-policy --role-name FISExperimentRole で権限確認
アクション実行されない Action id 誤り aws fis list-actions --region ap-northeast-1 で確認
メトリクス がゼロ CloudWatch 送信遅延 数分待機後に再確認
Multi-account 動作しない 組織OU設定漏れ Organizations OU メンバーシップ確認

近年の動向

Bedrock AgentCore との統合(2026 予定)

AI 推論失敗注入:

# Lambda model inference を failure inject
aws fis create-experiment-template \
  --actions '{
    "bedrock-inference-failure": {
      "actionId": "aws:bedrock:simulate-inference-failure",
      "parameters": {
        "failureRate": "50",
        "duration": "PT5M",
        "models": ["anthropic.claude-3-haiku", "meta.llama-2-13b"]
      },
      "targets": {"Models": "targetModels"}
    }
  }'

用途

  • AI アプリの fallback 機能検証
  • Model endpoint 障害時の graceful degradation テスト
  • Inference timeout の application 応答性測定

Organizations Multi-Account サポート拡張(2025)

複数アカウント横断実験:

aws fis create-experiment-template \
  --multi-account-targets [
    {
      "accountId": "111111111111",
      "regions": ["ap-northeast-1"]
    },
    {
      "accountId": "222222222222",
      "regions": ["ap-northeast-1", "us-east-1"]
    }
  ]

Systems Manager との統合強化

実験 → 自動修復パイプライン:

FIS Experiment Failure
  → EventBridge trigger
  → Systems Manager Automation Runbook
  → Automated remediation execution
  → Slack notification

学習リソース・参考文献

公式ドキュメント

ブログ・チュートリアル

オープンソース比較


実装チェックリスト

  • [ ] 計画フェーズ

    • [ ] 仮説定義(Multi-AZ failover / RTO target 等)
    • [ ] 期待値設定(Baseline metric 取得)
    • [ ] 関係者同意(運用チーム・経営)
  • [ ] 準備フェーズ

    • [ ] IAM role 作成(最小権限)
    • [ ] Tagging strategy(ChaosTest=true
    • [ ] CloudWatch alarm 設定(Stop condition)
    • [ ] Slack/PagerDuty 通知統合
  • [ ] Staging 検証

    • [ ] Simple template(EC2 stop)テスト
    • [ ] Stop condition 動作確認
    • [ ] Auto Scaling 応答性測定
    • [ ] RTO/RPO 実測値記録
  • [ ] 本番運用

    • [ ] Prod template デプロイ
    • [ ] EventBridge 週 1 回 schedule
    • [ ] メトリクス監視(継続改善)
    • [ ] Lesson learned documentation
  • [ ] 組織展開

    • [ ] 複数チーム向け template 共有
    • [ ] Runbook 作成(トラブル対応)
    • [ ] 月 1 回レビュー会
    • [ ] 年 1 回テーブルトップエクサイズ

まとめ

AWS Fault Injection Service(FIS) は、本番環境で 制御された障害を注入 して、アプリケーション・インフラの耐障害性を実測・改善するマネージドカオスエンジニアリングサービスです。

適用シーン

✅ Multi-AZ/Multi-region HA テスト ✅ Auto Scaling 自動復旧確認 ✅ RDS・DynamoDB フェイルオーバー検証 ✅ ECS/EKS オーケストレーション確認 ✅ Lambda 同時実行制限テスト ✅ ネットワーク障害対応テスト ✅ 定期 DR ドリル自動化

非適用シーン

❌ Single-AZ 構成のみ ❌ インシデント無履歴環境 ❌ リスク回避文化

導入のポイント

  1. Staging で段階的開始(dev → staging → prod)
  2. Stop Condition 必須 CloudWatch alarm 活用
  3. Tag ベース実験制限 カオステスト対象のみ
  4. 定期実行 CI/CD 統合・週 1 回 schedule
  5. メトリクス駆動 RTO/RPO 継続改善
  6. 組織学習 Lesson learned & Runbook 蓄積

2025-2026年の Bedrock・Organizations 拡張により、AI アプリ・エンタープライズスケール対応が進化します。継続的なカオスエンジニアリング実践で、顧客信頼の高い Always-On Reliable Infrastructure を実現できます。