目次

AWS Fault Injection Service v2.0 完全ガイド

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

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. 概要と課題
  2. 主な特徴
  3. アーキテクチャと概念
  4. コアコンポーネント
  5. 対応 AWS サービス別アクション
  6. 主要ユースケース
  7. 設定・操作の具体例
  8. 類似サービス比較表
  9. ベストプラクティス
  10. トラブルシューティング
  11. 2025-2026 最新動向
  12. 学習リソース・参考文献
  13. 実装チェックリスト
  14. まとめ

概要と課題

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

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 メンバーシップ確認

2025-2026 最新動向

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 を実現できます。


最終更新:2026-04-26 バージョン:v2.0