mcpField
A
aws-fis-experiment-execute

aws-fis-experiment-execute

github.com/panlm云与 DevOps082 次安装4 周前更新
代码仓库

关于 aws-fis-experiment-execute

aws-fis-experiment-execute 是用于在已部署基础设施上运行并评估预备 AWS FIS 实验的技能。它会检查目标健康状况,在产生影响前要求确认,监控服务和日志,并保存结果报告。

主要功能

  1. 01验证实验文件和堆栈元数据
  2. 02检查实验目标资源的健康状况
  3. 03收集应用及托管服务日志
  4. 04监控实验操作和服务恢复
  5. 05将结果报告写入 Markdown 文件

适用场景

  1. 01在已部署基础设施上运行预备 FIS 实验
  2. 02故障注入前检查资源健康状况
  3. 03检查实验后的服务恢复和日志

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/panlm/skills --skill aws-fis-experiment-execute

安装后在 Claude Code 中输入/aws-fis-experiment-execute确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

README_CN.md
README.md
references/
cli-commands.md
report-template.md

详细介绍

AWS FIS 实验执行

验证基础设施已部署,运行 AWS FIS 实验,监控实验进度,并生成结果报告。从准备好的实验目录中读取配置,该目录对应的 CloudFormation 堆栈已部署。

输出语言规则

检测用户对话的语言,并将所有输出使用相同语言。

  • 中文输入 → 中文输出
  • 英文输入 → 英文输出

前提条件

所需工具:

  • AWS CLI — aws fis、aws cloudwatch、aws cloudformation、aws logs
  • kubectl — 已配置为可访问目标 EKS 集群。
  • 已准备好的实验目录(来自 aws-fis-experiment-prepare skill)
  • 此实验的 CloudFormation 堆栈必须已部署

必需子技能: 必须安装 app-service-log-analysis。运行时会加载此技能,以发现应用、收集日志并进行分析。若未安装,实验仍可运行,但会跳过日志分析。

工作流

digraph execute_flow {
    "User input:\npath or template ID?" [shape=diamond];
    "Search CWD for\nmatching directory" [shape=box];
    "Directory found?" [shape=diamond];
    "Ask user for full path" [shape=box, style=bold];
    "Validate files" [shape=box];
    "Read README for stack name" [shape=box];
    "Check CFN stack status" [shape=diamond];
    "Extract template ID from outputs" [shape=box];
    "Display actionIds" [shape=box];
    "Pre-experiment health check" [shape=box, color=blue];
    "All resources healthy?" [shape=diamond];
    "Wait / prompt user" [shape=box];
    "Discover apps + start logs\n(app-service-log-analysis)" [shape=box];
    "User confirms experiment start" [shape=diamond, style=bold, color=red];
    "Start experiment" [shape=box];
    "Monitor experiment\n+ log insights" [shape=box];
    "Experiment complete?" [shape=diamond];
    "Wait 3 min post-baseline" [shape=box];
    "Stop logs + analyze\n(app-service-log-analysis)" [shape=box];
    "Generate results report" [shape=box];

    "User input:\npath or template ID?" -> "Validate files" [label="Full path"];
    "User input:\npath or template ID?" -> "Search CWD for\nmatching directory" [label="Template ID"];
    "Search CWD for\nmatching directory" -> "Directory found?";
    "Directory found?" -> "Validate files" [label="Yes (1 match)"];
    "Directory found?" -> "Ask user for full path" [label="No match"];
    "Ask user for full path" -> "Validate files" [label="User provides path"];
    "Validate files" -> "Read README for stack name";
    "Read README for stack name" -> "Check CFN stack status";
    "Check CFN stack status" -> "Extract template ID from outputs" [label="CREATE_COMPLETE"];
    "Check CFN stack status" -> "Generate results report" [label="Not deployed / failed, abort"];
    "Extract template ID from outputs" -> "Display actionIds";
    "Display actionIds" -> "Pre-experiment health check";
    "Pre-experiment health check" -> "All resources healthy?";
    "All resources healthy?" -> "Discover apps + start logs\n(app-service-log-analysis)" [label="Yes"];
    "All resources healthy?" -> "Wait / prompt user" [label="No"];
    "Wait / prompt user" -> "Pre-experiment health check" [label="Retry (poll 60s,\nmax 10 min non-interactive)"];
    "Wait / prompt user" -> "Discover apps + start logs\n(app-service-log-analysis)" [label="User override"];
    "Wait / prompt user" -> "Generate results report" [label="Abort"];
    "Discover apps + start logs\n(app-service-log-analysis)" -> "User confirms experiment start";
    "User confirms experiment start" -> "Start experiment" [label="Yes, I confirm"];
    "User confirms experiment start" -> "Stop logs + analyze\n(app-service-log-analysis)" [label="No, abort"];
    "Start experiment" -> "Monitor experiment\n+ log insights";
    "Monitor experiment\n+ log insights" -> "Experiment complete?";
    "Experiment complete?" -> "Monitor experiment\n+ log insights" [label="No, poll again"];
    "Experiment complete?" -> "Wait 3 min post-baseline" [label="Yes"];
    "Wait 3 min post-baseline" -> "Stop logs + analyze\n(app-service-log-analysis)";
    "Stop logs + analyze\n(app-service-log-analysis)" -> "Generate results report";
}
步骤 1:解析并验证实验目录

用户提供以下任一内容:

  • (a) 实验目录的完整路径,或
  • (b) FIS 实验模板 ID(例如 EXT1a2b3c4d5e6f7)
步骤 1a:根据模板 ID 解析目录

如果用户提供模板 ID,请在 CWD 中搜索以该 ID 结尾的目录:

find . -maxdepth 1 -type d -name "*${TEMPLATE_ID_INPUT}" 2>/dev/null
  • 找到 1 个匹配项 → 使用该目录并告知用户
  • 找到多个匹配项 → 列出匹配项并请用户选择
  • 未找到匹配项 → 请用户提供完整路径。没有有效路径时,切勿继续。
步骤 1b:从目录名称提取模板 ID

实验目录名称以模板 ID 结尾(例如, 2026-04-11-az-power-int-my-cluster-EXT1a2b3c4d5e6f7)。提取该 ID:

TEMPLATE_ID=$(basename "${EXPERIMENT_DIR}" | grep -oE 'EXT[a-zA-Z0-9]+$')

将其保存为 TEMPLATE_ID。后续所有步骤都会用到它。

步骤 1c:验证必需文件

验证 EXPERIMENT_DIR 中包含:cfn-template.yaml、README.md。

步骤 2:读取 README 并提取实验元数据

从实验目录读取 README.md,提取以下信息:

  1. 场景名称 — 来自 H1 标题(例如,# FIS Experiment: AZ Power Interruption)
  2. 目标区域 — 来自 **Region:** {REGION}
  3. 目标 AZ — 来自 **Target AZ:** {AZ_ID}(如适用)
  4. 预计时长 — 来自 **Estimated Duration:** {DURATION}
  5. 受影响的资源 — 来自 “Affected Resources” 表格
  6. CFN 堆栈名称 — 来自 **CFN Stack:** {STACK_NAME}(仅供清理时参考)

向用户展示包含所有提取信息的摘要。

步骤 3:显示实验操作

使用 TEMPLATE_ID(在步骤 1b 中从目录名称提取)通过 AWS CLI 查询实验模板,并显示所有操作 ID:

aws fis get-experiment-template \
  --id "{TEMPLATE_ID}" \
  --region {REGION} \
  --query 'experimentTemplate.actions' --output json

从操作映射中提取所有 actionId 值,并展示给用户:

Actions found:
  - {actionId_1}
  - {actionId_2}
  ...

直接继续步骤 3.5(资源运行状况检查)。

第 3.5 步:实验前资源健康检查

开始收集日志或执行实验之前,请确认 FIS 实验模板引用的所有目标资源都处于健康的基线状态。针对已降级的资源启动实验会导致结果无法归因,还可能加剧对脆弱基础设施的影响。

**范围:**FIS 实验模板的 targets 映射中列出的所有资源(来自第 3 步的查询)。这包括任何托管服务——RDS、Aurora、MSK、ElastiCache(Redis/Memcached)、EKS 集群和节点组、EC2、OpenSearch、DocumentDB 等——也就是模板所针对的所有资源。

流程:

  1. 对于实验模板中的每个目标,提取其 resourceType(例如 aws:rds:db、aws:msk:cluster、aws:elasticache:replicationgroup)以及实际资源标识符(从 resourceArns 获取,或根据 resourceTags 解析)。

  2. 对于每项资源,调用其服务对应的 AWS describe API,并读取规范状态字段。根据 AWS 服务的特性,选择正确的 API 和正确的“健康”状态值(例如,RDS 为 available、MSK 为 ACTIVE、ElastiCache 为 available、EKS 为 ACTIVE、EC2 为 running 且状态检查为 ok)。

  3. 向用户展示一张表:

    Resource             Type                              Status        Healthy?
    {id_1}               {resourceType_1}                  {status_1}    {✓ or ✗}
    {id_2}               {resourceType_2}                  {status_2}    {✓ or ✗}
    ...
    
  4. 如果资源类型不熟悉或 API 调用失败,则将该资源标记为未检查,并在决策时视为不健康。

决策规则:

  • 所有资源均健康 → 继续执行第 4 步。
  • 一个或多个资源不健康/未检查:
    • 交互式会话(可以提示用户并获取回复): 警告用户,列出有问题的资源及其当前状态,并等待用户明确输入。接受:proceed(覆盖检查结果并继续)、abort(停止工作流)或 retry(立即重新运行健康检查)。
    • 非交互式会话(没有用户可供回复): 自动每 60 秒轮询一次,最长 10 分钟。每轮重新检查所有目标资源。如果所有资源在此时间窗口内都恢复健康,则自动继续执行第 4 步。如果 10 分钟后仍有任何资源不健康,则中止并输出诊断摘要,列出每项不健康资源、其当前状态以及等待时长。

**如何确定会话是交互式还是非交互式:**根据运行时上下文自行判断(例如是否连接了 TTY、是否可以调用交互式提示,或是否存在表明这是 CI/自动化运行的环境信号)。不确定时,默认采用交互式行为。

第 3.9 步:加载 App-Service-Log-Analysis 技能

**必需:**现在必须使用 skill 工具加载 app-service-log-analysis 技能。调用:skill(name="app-service-log-analysis")。

无论用户是否已指定目标 Pod,此技能始终为必需。它负责:

  • 托管服务日志检测(独立于应用 Pod)
  • 日志文件的组织和命名约定
  • 实验后的分析和报告生成

如果未安装此技能或无法加载,请告知用户并跳过日志收集(实验仍可在没有此技能的情况下运行)。

第 4 步:发现 EKS 应用并开始收集日志

此步骤在实验开始之前执行——实验开始后再发现应用,可能会错过被轮转或覆盖的早期日志条目。

从 app-service-log-analysis 技能执行:

  1. 该技能的第 2 步(读取服务列表)——从实验目录的 expected-behavior.md 中提取受影响的 AWS 服务
  2. 该技能的第 2.5 步(检测并收集托管服务日志)——检查托管服务的 CloudWatch 日志记录状态,并记录日志组以供后续分析
  3. 该技能的“多集群 EKS 发现与 kubeconfig 隔离”部分——发现目标区域中的所有 EKS 集群,为每个集群生成独立的 kubeconfig(绝不覆盖 ~/.kube/config),并验证对每个集群的访问权限
  4. 该技能的第 3 步(收集应用依赖项——深度扫描)——解析服务端点,并行深度扫描所有可访问的集群,然后与用户确认发现的依赖项
  5. 该技能的第 4 步(日志收集——实时模式)——为所有集群中已确认的应用启动后台 kubectl logs -f
第 5 步:开始实验(关键确认)

这是最危险的一步。实验将会影响真实资源。

开始前,明确向用户发出警告:

WARNING: Starting this FIS experiment will cause REAL impact:

Scenario:    {SCENARIO_NAME}
Region:      {REGION}
Target AZ:   {AZ_ID}
Duration:    {DURATION}
Stack:       {STACK_NAME} (verified: CREATE_COMPLETE)
Template ID: {TEMPLATE_ID}

Resources that WILL be affected:
  - {list each affected resource type and count from README}

Stop Conditions:
  - {list each alarm that will stop the experiment}

Applications being monitored:
  - {list each namespace/deployment from SERVICE_APP_MAP}

Managed service log collection:
  - {list each service with logging status from MANAGED_LOG_GROUPS}

Log directory: {LOG_DIR}
Post-experiment baseline: 3 minutes (automatic)

Type "Yes, start experiment" to proceed, or "No" to abort.

只有在用户明确确认后才能继续。 如果用户中止,请转到第 7 步,先停止日志收集并进行清理。

保存返回的 experiment.id。

第 6 步:监控实验

轮询实验状态并显示进度。轮询命令和实验状态参考见 references/cli-commands.md。

轮询策略:

  • 前 5 分钟每 30 秒轮询一次
  • 此后每 60 秒轮询一次
  • 每次轮询后显示当前状态
  • 记录时间戳,涵盖每次状态变更和操作状态转换——这些信息将用于最终报告中的逐服务时间线
  • 跟踪逐服务事件:对于实验影响的每项服务,记录其受影响时间(操作开始)、恢复时间以及任何中间状态。监控期间查询特定服务的状态(例如,RDS 实例状态、ElastiCache 复制组状态、EKS 节点状态),以记录详细的观察结果。

每轮轮询期间的日志洞察: 执行 app-service-log-analysis 第 5 步(实时监控展示)——读取近期日志、统计错误和警告数量、显示逐应用摘要,并检测恢复信号。此技能必须已在第 4 步加载。

监控期间提醒用户:

  • 查看 CloudWatch 控制面板以了解实时指标
  • 可随时停止实验(停止命令见 references/cli-commands.md)
第 7 步:实验后基线、停止日志收集并进行分析

实验完成后(处于任何终态):

实验后基线(3 分钟)

实验结束后继续收集日志3 分钟,以捕获恢复情况。应用日志和托管服务日志均适用。向用户显示倒计时:

Experiment completed. Collecting post-experiment baseline logs...
Remaining: {countdown} (3 minutes total)

3 分钟基线时段结束后,开始分析。

生成应用日志分析

执行 app-service-log-analysis 第 7 至 8 步:

  • 该技能的第 7 步(生成分析报告)——分析错误模式、峰值速率和恢复时间,并生成报告中的“应用日志分析”部分。分析时间窗口延伸至实验结束时间之后 3 分钟,以覆盖基线时段。
  • 该技能的第 8 步(清理)——终止后台 kubectl logs 进程

应用日志分析输出将嵌入实验结果报告中(见下文第 10 步),不会另存为独立文件。

步骤 10:将结果报告保存到本地文件

实验完成后(无论处于何种终止状态),生成结果报告,并 直接将其写入实验目录中的本地 Markdown 文件。

完整的报告结构、文件命名规范和时间戳格式规则,请参阅 references/report-template.md。

按服务分析: 从 README 的“受影响资源”表格中找出实验影响的所有服务。为每个服务创建一个小节,包含:(1)时间线事件,(2)观察到的行为,(3)关键发现。包括间接受影响的服务。

保存后,在终端中打印简要摘要:

  • 文件路径、实验 ID、最终状态
  • 开始/结束时间和持续时间(带时区的 ISO 8601 格式)
  • 每项操作的状态(每项一行)
  • 每项服务的恢复状态(每项一行)
  • 应用程序日志摘要 — 每个应用程序的错误总数
  • 需要处理的问题(如有)
  • 清理说明

安全规则

  1. 绝不自动启动实验。 始终要求用户明确确认。
  2. 执行任何 CLI 命令前,都必须显示该命令。
  3. 实验开始前显示影响警告,并列出具体资源。
  4. 每个步骤都提供中止说明。
  5. 未经用户确认,绝不删除资源。
  6. 绝不部署基础设施。 此技能仅检查现有部署。
  7. 建议先进行试运行——建议用户在开始前检查所有文件。
  8. 绝不针对不健康的资源启动实验。 步骤 3.5 会验证每个目标资源是否处于其服务的健康基线状态。在交互模式下,任何不健康或未经检查的资源都需要用户明确覆盖。在非交互模式下,每 60 秒轮询一次,最长持续 10 分钟;如果轮询时限结束时资源仍不健康,则中止。

清理指南

实验结束后,提供清理选项。命令请参阅 references/cli-commands.md。

错误处理

错误原因解决方法
README 中未找到堆栈名称README 缺少 **CFN Stack:** 字段检查实验是否使用较新版本的 aws-fis-experiment-prepare 准备
未找到堆栈(ValidationError)堆栈不存在或已删除先使用 aws-fis-experiment-prepare 部署堆栈
堆栈处于 CREATE_FAILED / ROLLBACK_COMPLETE 状态堆栈部署失败检查堆栈事件以确定失败原因,修复后重新部署
输出中没有 ExperimentTemplateId堆栈模板缺少输出项检查 cfn-template.yaml 中的输出定义
AccessDeniedException权限不足检查 FIS、CloudWatch、CloudFormation 的 IAM 权限
目标上出现 ResourceNotFoundException未找到带标签的资源验证资源标签是否与实验模板匹配
实验卡在 initiating 状态IAM 角色传播延迟等待 30 秒后再次检查
kubectl: command not found未安装 kubectl安装 kubectl 并配置 kubeconfig
error: You must be logged in未配置 kubeconfig运行 aws eks update-kubeconfig --name {cluster}
/.pids: Permission denied&& 链导致 LOG_DIR 变量为空使用包含 export LOG_DIR=... 的多行脚本,不要使用 && 链
未发现 EKS 应用程序没有 Pod 引用受影响的服务端点请用户手动指定命名空间/部署对

评论

支持 Markdown