
Aws Well Architected Review
- 17 installs
- 9 repo stars
- Updated July 29, 2026
- aws-samples/sample-aws-resilience-skill
aws-well-architected-review is a skill that runs an automated, read-only AWS Well-Architected review across all six pillars and generates a prioritized remediation report.
About
aws-well-architected-review runs an automated AWS Well-Architected Framework review across all six pillars using read-only AWS API calls. A developer uses it to assess an environment for security, cost, reliability, performance, operational excellence, and sustainability, classify risks, and get a prioritized remediation roadmap. It runs in autopilot mode after a bootstrap phase and halts if the credential carries write permissions.
- Runs an automated AWS Well-Architected review across all six pillars
- Security-first, read-only programmatic scan with mandatory credential-boundary check
- Produces a Markdown report with risk classification and a 3-phase roadmap
Aws Well Architected Review by the numbers
- 17 all-time installs (skills.sh)
- Ranked #824 of 1,039 Cloud & Infrastructure skills by installs in the Skillselion catalog
- Data as of Jul 30, 2026 (Skillselion catalog sync)
aws-well-architected-review capabilities & compatibility
- Capabilities
- well architected review · cloud audit · cost optimization · reliability review · security audit
- Works with
- aws
- Use cases
- devops · security audit
What aws-well-architected-review says it does
programmatically assess infrastructure against all six WAF pillars, classify risks, and generate a structured Markdown report with a prioritized improvement roadmap and remediation commands.
Execute pillar checks in **Security-First** order.
npx skills add https://github.com/aws-samples/sample-aws-resilience-skill --skill aws-well-architected-reviewAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 17 |
|---|---|
| repo stars | ★ 9 |
| Last updated | July 29, 2026 |
| Repository | aws-samples/sample-aws-resilience-skill ↗ |
What it does
Run an automated six-pillar AWS Well-Architected review and produce a prioritized remediation roadmap.
Who is it for?
Architects and platform teams auditing an AWS environment against the Well-Architected Framework
Skip if: Credentials with write permissions, which cause the skill to halt and request a read-only role
When should I use this skill?
Requesting a full architecture review, security assessment, cost optimization, reliability check, or performance audit of AWS
What you get
A structured Markdown report with HRI/MRI risk classification and a three-phase improvement roadmap
- a six-pillar Well-Architected report
- HRI/MRI risk classification
- a three-phase remediation roadmap
By the numbers
- 6 Well-Architected pillars
- 4-phase workflow
- security-first pillar order
Files
Language / 语言
- If the user speaks English, follow SKILL_EN.md
- 如果用户使用中文,请遵循 SKILL_ZH.md
Detect the language from the user's message and load the corresponding instruction file.
**中文** | English
---
AWS Well-Architected 自动化评审 Skill
一个自动化的 AWS Well-Architected Framework 评审 Skill,通过只读 API 调用对 AWS 环境进行 6 大 WAF 支柱的编程式评估。
安装
方式 A: npx skills(推荐)
npx skills add aws-samples/sample-aws-resilience-skill --skill aws-well-architected-review方式 B: Git clone
git clone https://github.com/aws-samples/sample-aws-resilience-skill.git特性
- ✅ 6 大支柱全覆盖:安全、卓越运营、可靠性、性能效率、成本优化、可持续性
- ✅ Security-First:安全支柱始终第一个评估,作为其他支柱的基础
- ✅ 49 项编程式检查:全部使用只读 AWS CLI 命令(仅 Describe/Get/List)
- ✅ 自动驾驶模式:确认凭证后全自动执行,无需人工干预
- ✅ 风险分级:HRI(高风险)/ MRI(中风险)/ LRI(低风险)严重性分级
- ✅ 双格式报告:Markdown + HTML,含支柱计分卡和改进路线图
- ✅ 凭证安全:强制只读权限边界——阻止有写权限的凭证
- ✅ WA Tool 同步:可选将评估结果同步到 AWS WA Tool 控制台
工作流程
阶段 1: 环境引导 (~2 分钟) → 凭证验证 + 范围确认
阶段 2: 发现扫描 (~15-30 分钟) → 6 支柱编程式检查
阶段 3: 风险分析 (~5 分钟) → 风险识别 + 优先级排序
阶段 4: 报告生成 (~2 分钟) → Markdown + HTML 报告各支柱检查项
| 支柱 | 检查数 | 关键领域 |
|---|---|---|
| 🔒 安全 | 12 | GuardDuty、Security Hub、CloudTrail、IAM、加密、网络 |
| ⚙️ 卓越运营 | 8 | AWS Config、CloudWatch、补丁管理、CFN 健康 |
| 🔄 可靠性 | 9 | Multi-AZ、备份、ASG、健康检查、PITR |
| ⚡ 性能效率 | 7 | 实例类型、EBS、Compute Optimizer |
| 💰 成本优化 | 8 | 闲置资源、Savings Plans、生命周期策略 |
| 🌱 可持续性 | 5 | Graviton 采用率、利用率、Right-sizing |
快速开始
1. 确保 AWS CLI 已配置只读凭证 2. 对 AI 助手说 "开始架构评审" 或 "Start WA Review" 3. 确认目标账户、Region 和评估范围 4. 等待约 20-30 分钟完成自动评估 5. 查看 wafr-reports/ 目录中的报告
前置条件
- AWS CLI v2 已安装并配置
- 具有
ReadOnlyAccess或等效只读策略的 IAM 角色/用户 - 完整 6 支柱评估约需 30 分钟
输出示例
总体健康度: 2.7/5 ★★★☆☆
| 支柱 | 分数 | CRITICAL | HIGH | MEDIUM | LOW |
|-------------------|------|----------|------|--------|-----|
| 🔒 安全 | 2/5 | 0 | 4 | 3 | 0 |
| ⚙️ 卓越运营 | 3/5 | 0 | 1 | 0 | 0 |
| 🔄 可靠性 | 2/5 | 0 | 3 | 0 | 0 |
| ⚡ 性能效率 | 4/5 | 0 | 0 | 1 | 0 |
| 💰 成本优化 | 4/5 | 0 | 0 | 1 | 0 |
| 🌱 可持续性 | 4/5 | 0 | 0 | 0 | 1 |与其他 Skill 集成
| Skill | 集成方式 |
|---|---|
| aws-resilience-modeling | 对 HRI 发现做深度可靠性分析 |
| chaos-engineering-on-aws | 从风险清单生成混沌工程测试计划 |
| aws-rma-assessment | 组织级韧性成熟度评估 |
许可证
本项目采用 MIT-0 许可证。详见 LICENSE 文件。
English | 中文
---
AWS Well-Architected Review Skill
An automated AWS Well-Architected Framework Review skill that programmatically assesses your AWS environment across all 6 WAF pillars using read-only API calls.
Installation
Option A: npx skills (Recommended)
npx skills add aws-samples/sample-aws-resilience-skill --skill aws-well-architected-reviewOption B: Git clone
git clone https://github.com/aws-samples/sample-aws-resilience-skill.gitFeatures
- ✅ 6-Pillar Assessment: Security, Operational Excellence, Reliability, Performance, Cost Optimization, Sustainability
- ✅ Security-First: Security pillar always assessed first as the foundation
- ✅ 49 Programmatic Checks: All using read-only AWS CLI commands (Describe/Get/List only)
- ✅ Autopilot Mode: Minimal human interaction — confirm credentials, then fully automated
- ✅ Risk Classification: HRI/MRI/LRI severity-based risk portfolio
- ✅ Dual Reports: Markdown + HTML with pillar scorecards and improvement roadmap
- ✅ Credential Safety: Enforces read-only permission boundary — blocks write-capable credentials
- ✅ WA Tool Sync: Optional sync findings to AWS WA Tool console
How It Works
Phase 1: Bootstrap (~2 min) → Credential validation + scope confirmation
Phase 2: Discover (~15-30 min) → 6-pillar programmatic scan
Phase 3: Analysis (~5 min) → Risk identification + prioritization
Phase 4: Report (~2 min) → Markdown + HTML report generationPillar Checks Summary
| Pillar | Checks | Key Areas |
|---|---|---|
| 🔒 Security | 12 | GuardDuty, Security Hub, CloudTrail, IAM, encryption, network |
| ⚙️ Ops Excellence | 8 | AWS Config, CloudWatch, patching, CFN health |
| 🔄 Reliability | 9 | Multi-AZ, backups, ASG, health checks, PITR |
| ⚡ Performance | 7 | Instance types, EBS, Compute Optimizer |
| 💰 Cost | 8 | Idle resources, Savings Plans, lifecycle policies |
| 🌱 Sustainability | 5 | Graviton adoption, utilization, right-sizing |
Quick Start
1. Ensure AWS CLI is configured with read-only credentials 2. Say "Start WA Review" or "开始架构评审" to your AI assistant 3. Confirm target account, region, and scope 4. Wait ~20-30 minutes for the automated assessment 5. Review the generated report in wafr-reports/
Prerequisites
- AWS CLI v2 installed and configured
- IAM role/user with
ReadOnlyAccessor equivalent read-only policy - ~30 minutes for a full 6-pillar assessment
Output Example
Overall Health: 2.7/5 ★★★☆☆
| Pillar | Score | CRITICAL | HIGH | MEDIUM | LOW |
|---------------------|-------|----------|------|--------|-----|
| 🔒 Security | 2/5 | 0 | 4 | 3 | 0 |
| ⚙️ Ops Excellence | 3/5 | 0 | 1 | 0 | 0 |
| 🔄 Reliability | 2/5 | 0 | 3 | 0 | 0 |
| ⚡ Performance | 4/5 | 0 | 0 | 1 | 0 |
| 💰 Cost | 4/5 | 0 | 0 | 1 | 0 |
| 🌱 Sustainability | 4/5 | 0 | 0 | 0 | 1 |Integration with Other Skills
| Skill | Integration |
|---|---|
| aws-resilience-modeling | Deep-dive reliability analysis on HRI findings |
| chaos-engineering-on-aws | Generate chaos test plans from risk inventory |
| aws-rma-assessment | Organizational maturity scoring |
License
This project is licensed under the MIT-0 License. See the LICENSE file.
Credential Permission Boundary
Principle
The WA Review assessment operates in strict read-only mode. Credentials MUST NOT have any write, modify, or delete permissions.
Allowed IAM Policies
| Policy ARN | Description |
|---|---|
arn:aws:iam::aws:policy/ReadOnlyAccess | Full read-only across all services |
arn:aws:iam::aws:policy/ViewOnlyAccess | View-only (slightly more restrictive) |
arn:aws:iam::aws:policy/SecurityAudit | Security-focused read-only |
| Custom read-only policy | Must contain ONLY Describe/Get/List actions |
Blocked IAM Policies
| Policy ARN | Reason |
|---|---|
arn:aws:iam::aws:policy/AdministratorAccess | Full admin — NEVER acceptable |
arn:aws:iam::aws:policy/PowerUserAccess | Write access to most services |
Any *:Create*, *:Update*, *:Delete*, *:Put* | Write actions |
Validation Logic
ALLOWED_PREFIXES = {'Describe', 'Get', 'List', 'BatchGet'}
BLOCKED_PREFIXES = {'Create', 'Update', 'Delete', 'Put', 'Modify',
'Start', 'Stop', 'Terminate', 'Reboot', 'Run',
'Invoke', 'Execute', 'Send', 'Publish', 'Tag',
'Untag', 'Attach', 'Detach', 'Associate', 'Disassociate'}
def is_read_only(actions: list) -> bool:
for action in actions:
verb = action.split(':')[1] if ':' in action else action
if verb == '*':
return False
if any(verb.startswith(p) for p in BLOCKED_PREFIXES):
return False
return TrueViolation Warning
If credentials fail validation, display:
🚨 PERMISSION BOUNDARY VIOLATION
Your credentials ({arn}) have write permissions that exceed
the read-only boundary required for this assessment.
Detected policies: {policy_list}
The assessment CANNOT proceed with these credentials because:
• Write permissions could accidentally modify your infrastructure
• This assessment is designed to be 100% non-destructive
• Read-only ensures zero risk to your production environment
ACTION REQUIRED:
1. Create a new IAM role with ReadOnlyAccess policy
2. Assume that role or configure new credentials
3. Re-run the assessment
Example:
aws iam create-role --role-name WAReviewReadOnly \
--assume-role-policy-document file://trust-policy.json
aws iam attach-role-policy --role-name WAReviewReadOnly \
--policy-arn arn:aws:iam::aws:policy/ReadOnlyAccessExceptions
The following write-like actions are ALLOWED (metadata only, no infrastructure changes):
sts:GetCallerIdentity— identity verificationsts:GetSessionToken— session managementiam:GenerateCredentialReport— generates a report, does not modify IAM
Environment Bootstrap Guide
Step 1: AWS CLI Detection
which aws 2>/dev/null && aws --version 2>/dev/nullIf found: Record version, proceed to Step 2.
If not found: Guide installation:
# macOS
brew install awscli
# Linux (pip)
pip3 install awscli --user
# Linux (official)
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip && sudo ./aws/installIf user declines: Switch to questionnaire-only mode (no programmatic checks).
Step 2: Credential Verification
aws sts get-caller-identity --output jsonRecord:
Account: Target AWS accountArn: Role/User ARNUserId: Session identifier
If fails: Guide credential setup: 1. Option A: aws configure with access key 2. Option B: aws configure --profile wa-review with named profile 3. Option C: Source environment file (source ~/.aws-creds.sh) 4. Option D: Skip → questionnaire-only mode
Step 3: Permission Boundary Validation (MANDATORY)
See credential-boundary.md for the full boundary definition.
Quick validation:
# For IAM Role
ROLE_NAME=$(aws sts get-caller-identity --query 'Arn' --output text | grep -oP '(?<=role/)[\w-]+')
aws iam list-attached-role-policies --role-name "$ROLE_NAME" --output json
# For IAM User
USER_NAME=$(aws sts get-caller-identity --query 'Arn' --output text | grep -oP '(?<=user/)[\w-]+')
aws iam list-attached-user-policies --user-name "$USER_NAME" --output jsonAllowed policies (any of):
arn:aws:iam::aws:policy/ReadOnlyAccessarn:aws:iam::aws:policy/ViewOnlyAccessarn:aws:iam::aws:policy/SecurityAudit- Custom policy with only Describe/Get/List actions
Blocked policies (any of):
arn:aws:iam::aws:policy/AdministratorAccessarn:aws:iam::aws:policy/PowerUserAccess- Any policy containing write/modify/delete actions
If boundary violated: Display warning and HALT. Do NOT proceed.
Step 4: Region and Scope Detection
# Current region
aws configure get region
# List available regions
aws ec2 describe-regions --query 'Regions[].RegionName' --output json
# List VPCs in target region
aws ec2 describe-vpcs --query 'Vpcs[].{VpcId:VpcId,Cidr:CidrBlock,Name:Tags[?Key==`Name`].Value|[0]}' --output tablePresent to user for confirmation:
📋 ASSESSMENT SCOPE
Account: 123456789012
Region: ap-northeast-1
VPCs: vpc-abc123 (Production), vpc-def456 (Staging)
Framework: General WA Framework (6 pillars)
Mode: Autopilot (Security-First)
Proceed? (Y/N)Step 5: Environment Summary
After all checks pass, log:
[BOOTSTRAP] Environment Ready:
• AWS CLI: {version} ✅
• Credentials: {arn} ✅
• Permission Boundary: ReadOnly ✅
• Region: {region}
• VPCs: {count} VPCs in scope
• Framework: General WA (6 pillars, Security-First)
• Mode: Autopilot---
Context Budget — DON'T-FETCH List
来源:service-screener-v2 wa-summarizer prompt 的 negative scope 设计。Agent 最常见失败是一口气拉下大 dump 把上下文窗口吃光。以下 API/输出默认不调,需要时走 subagent 或写文件。
默认禁调的大输出类 API
| Forbidden by default | 代替方案 |
|---|---|
aws cloudtrail lookup-events(动辄上百万行) | 需要查安全事件时用 Athena + S3 trail logs、或限定 --start-time 几小时 + --max-results 50 |
aws ec2 describe-snapshots --owner-ids self(账号老上千条) | 限定 --filters "Name=start-time,..." 只看近 30 天 |
aws s3api list-objects-v2(文件多的 bucket 极易爆炸) | 只针对明确小 bucket,加 --max-items 100 |
aws config get-resource-config-history(按资源个数 × 添加频率) | 限定 --resource-id + --limit 10 |
aws ec2 describe-instances(大账号上千台) | 加 --filters Name=instance-state-name,Values=running + --query 'Reservations[].Instances[].{Id:InstanceId,Type:InstanceType,AZ:Placement.AvailabilityZone,State:State.Name}',不要拉全量字段 |
aws iam get-account-authorization-details(返回全账号 IAM dump) | 拆分:list-users / list-roles / 按需 get-policy-version |
aws lambda list-functions 不加 --query(FunctionVersion 可能上千) | 加 --query 'Functions[].{Name:FunctionName,Runtime:Runtime,Memory:MemorySize}' |
aws ce get-cost-and-usage 不限定 granularity/group-by | 限定 --granularity DAILY --time-period 近 30 天 --group-by Type=DIMENSION,Key=SERVICE |
| 任何返回 >500KB 的单次调用 | 走 subagent:spawn 个子 session 调用、提炼后只拿总结回主 session |
动手前的 3 个必问
1. 调用返回多少条记录? 不确定先加 --max-items 5 探路 2. 返回体多大? >50KB 的单次输出不要 read 到主 context 3. 这条 finding 需要这么多详情吗? Severity + count 差不多了,完整资源 ID 列表走 Appendix
subagent 隔离原则
- 3+ 个服务同时调 list · 单个输出 >150 行 · 需要多轮过滤聚合 → spawn subagent
- 主 session 只拿结论 + 决策,不拿原始 dump
- subagent 带回的 finding 表格限 50 行,超出走附件
WA Question → BP → Local Check Mapping
三层映射:AWS WA Framework Question → Best Practice → 本地 programmatic check ID。
让 coverage gap 显式化:哪些 BP 是程序化覆盖、哪些靠访谈/文档评估。
来源:AWS Well-Architected Framework + service-screener-v2 WAFS/map.json 结构启发。
---
Coverage Legend
- ✅ 程序化覆盖 — 有对应 SEC-/REL-/COST-/OPS-/PERF-/SUS- check
- 📝 访谈/文档评估 — 需通过 questionnaire 或 design doc review 评估
- ⚠️ 部分覆盖 — 程序化能查一部分,关键决策仍需访谈
- ❌ 未覆盖 — 当前 skill 未实现,归入未来 backlog
---
🔒 Security Pillar (SEC01-SEC11)
| Question | BP Title | Coverage | Local Check |
|---|---|---|---|
| SEC01 Securely operate workload | BP01 Separate workloads using accounts | 📝 | — |
| BP02 Secure account root user | ✅ | SEC-06 | |
| BP03 Identify and validate control objectives | 📝 | — | |
| BP04 Stay up to date with security threats / recommendations | ⚠️ | SEC-01, SEC-02 (partial) | |
| BP05 Reduce security management scope | 📝 | — | |
| BP06 Automate testing and validation of security controls | ❌ | — | |
| BP07 Identify threats and prioritize mitigations | 📝 | — | |
| BP08 Evaluate and implement new security services | 📝 | — | |
| SEC02 Manage identities | BP01 Use strong sign-in mechanisms | ✅ | SEC-04 |
| BP02 Use temporary credentials | ⚠️ | SEC-05 (key age proxy) | |
| BP03 Store and use secrets securely | ❌ | — | |
| BP04 Rely on centralized identity provider | 📝 | — | |
| BP05 Audit and rotate credentials periodically | ✅ | SEC-05 | |
| BP06 Leverage user groups and attributes | 📝 | — | |
| SEC03 Manage permissions | BP01 Define access requirements | 📝 | — |
| BP02 Grant least privilege access | 📝 | — | |
| BP03 Establish emergency access process | 📝 | — | |
| BP04 Reduce permissions continuously | ❌ | — | |
| BP05 Define permission guardrails | 📝 | — | |
| BP06 Manage access based on lifecycle | 📝 | — | |
| BP07 Analyze public and cross-account access | ✅ | SEC-07 | |
| BP08 Share resources securely within organization | 📝 | — | |
| BP09 Share resources securely with third parties | 📝 | — | |
| SEC04 Detect and investigate events | BP01 Configure service and application logging | ✅ | SEC-03, SEC-11 |
| BP02 Capture logs, findings, metrics centrally | 📝 | — | |
| BP03 Correlate and enrich security events | ❌ | — | |
| BP04 Initiate remediation for non-compliant resources | ✅ | SEC-01, SEC-02 | |
| SEC05 Protect network resources | BP01 Create network layers | 📝 | — |
| BP02 Control traffic at all layers | ✅ | SEC-09 | |
| BP03 Implement inspection-based protection | ❌ | — | |
| BP04 Automate network protection | ❌ | — | |
| SEC06 Protect compute resources | BP01-BP06 | 📝 | — |
| SEC07 Classify your data | BP01-BP04 | 📝 | — |
| SEC08 Protect data at rest | BP01 Implement secure key management | ✅ | SEC-12 |
| BP02 Enforce encryption at rest | ✅ | SEC-08, SEC-10 | |
| BP03 Automate data at rest protection | 📝 | — | |
| BP04 Enforce access control | 📝 | — | |
| SEC09 Protect data in transit | BP01-BP04 | ❌ | — (TLS check 待补) |
| SEC10 Incident response | BP01-BP07 | 📝 | (整体靠访谈) |
| SEC11 Application security | BP01-BP08 | 📝 | (整体靠访谈) |
Security 覆盖率小结:核心 11 个 ✅ check 覆盖 8 个 BP;其余靠访谈或文档评估。
---
🔄 Reliability Pillar (REL01-REL11)
| Question | BP Title | Coverage | Local Check |
|---|---|---|---|
| REL01 Manage service quotas and constraints | BP01-BP06 | ❌ | — |
| REL02 Plan network topology | BP01-BP05 | 📝 | — |
| REL03 Design workload service architecture | BP01-BP04 | 📝 | — |
| REL04 Design interactions to prevent failures | BP01-BP05 | 📝 | — |
| REL05 Design interactions for failures | BP01-BP07 | 📝 | — |
| REL06 Monitor workload resources | BP01 Monitor all components | ⚠️ | OPS-02 (alarms proxy) |
| BP02-BP07 | 📝 | — | |
| REL07 Adapt to demand changes | BP01 Use automation when obtaining or scaling resources | ✅ | REL-02, SUS-05 |
| BP02 Obtain resources on detection of impairment | ✅ | REL-02, REL-03 | |
| BP03-BP04 | 📝 | — | |
| REL08 Implement change | BP01-BP05 | 📝 | — |
| REL09 Back up data | BP01 Identify and back up all data | ✅ | REL-04 |
| BP02 Secure and encrypt backups | ⚠️ | REL-04 (existence only) | |
| BP03 Perform data backup automatically | ✅ | REL-04 | |
| BP04 Perform periodic recovery testing | 📝 | — | |
| REL10 Use fault isolation | BP01 Deploy across multiple locations | ✅ | REL-01, REL-02, REL-06 |
| BP02 Select appropriate locations for multi-location deployment | 📝 | — | |
| BP03 Automate recovery for components constrained to single location | 📝 | — | |
| REL11 Design for failures | BP01 Monitor all components | ✅ | REL-03 |
| BP02 Fail over to healthy resources | ✅ | REL-05, REL-08 | |
| BP03 Use static stability | 📝 | — | |
| BP04 Rely on data plane (not control plane) | 📝 | — | |
| BP05 Send notifications when events impact availability | ⚠️ | OPS-02 | |
| BP06 Automate the recovery | ⚠️ | REL-09 | |
| BP07 Architect for fault isolation | 📝 | — |
---
⚙️ Operational Excellence (OPS01-OPS11)
| Question | BP Title | Coverage | Local Check |
|---|---|---|---|
| OPS01-03 Organization | BP01-BP* | 📝 | — |
| OPS04 Implement observability | BP01 Identify key performance indicators | ⚠️ | OPS-02 |
| BP02 Implement application telemetry | ❌ | — | |
| BP03 Implement infrastructure telemetry | ✅ | OPS-01, OPS-03 | |
| OPS05 Reduce defects, ease remediation, improve flow | BP01-BP* | ⚠️ | OPS-05 (CFN drift proxy) |
| OPS06 Mitigate deployment risks | BP01-BP* | 📝 | — |
| OPS07 Ready to support | BP01 Ensure personnel capability | 📝 | — |
| BP02 Enable team to take action | ✅ | OPS-04 (SSM patch capability) | |
| BP03 Use runbooks | 📝 | — | |
| BP04 Use playbooks | 📝 | — | |
| OPS08 Understand workload health | BP01-BP* | ⚠️ | OPS-02 |
| OPS09 Understand operational health | BP01-BP* | ⚠️ | OPS-08 (Health events) |
| OPS10 Manage workload events | BP01-BP* | ⚠️ | OPS-07 (EventBridge) |
| OPS11 Evolve operations | BP01-BP* | 📝 | (postmortem 文化访谈) |
---
⚡ Performance Efficiency (PERF01-PERF05)
| Question | BP Title | Coverage | Local Check |
|---|---|---|---|
| PERF01 Architecture selection | BP01-BP07 | 📝 | — |
| PERF02 Compute and hardware | BP01 Select best compute options | ✅ | PERF-01, PERF-04 |
| BP02 Understand available options | ✅ | PERF-03 | |
| BP03 Collect compute metrics | ⚠️ | PERF-03 | |
| BP04 Configure and right-size | ✅ | PERF-03 | |
| BP05 Scale compute config | ⚠️ | REL-02 | |
| PERF03 Data management | BP01 Use purpose-built data store | 📝 | — |
| BP02 Evaluate available config options | ✅ | PERF-02, PERF-06 | |
| BP03 Collect data store metrics | ⚠️ | OPS-02 | |
| BP04 Implement strategies to improve query performance | 📝 | — | |
| BP05 Implement data access patterns | 📝 | — | |
| PERF04 Networking | BP01 Understand network impact | ⚠️ | PERF-05 (CDN) |
| BP02-BP07 | 📝 | — | |
| PERF05 Process and culture | BP01-BP* | 📝 | — |
---
💰 Cost Optimization (COST01-COST11)
| Question | BP Title | Coverage | Local Check |
|---|---|---|---|
| COST01 Cloud financial management | BP01-BP* | 📝 | — |
| COST02 Govern usage | BP01-BP* | 📝 | — |
| COST03 Monitor usage and cost | BP01 Configure detailed information sources | ⚠️ | COST-01 (anomaly detection) |
| BP02-BP* | 📝 | — | |
| COST04 Decommission resources | BP01 Track resources over their lifetime | 📝 | — |
| BP02 Implement decommission process | ✅ | COST-03 (unattached EBS), COST-04 (unassociated EIP) | |
| COST05 Evaluate cost when selecting services | BP01-BP* | 📝 | — |
| COST06 Meet cost targets | BP01-BP* | 📝 | — |
| COST07 Use the most cost-effective resource | BP01 Perform pricing model analysis | ✅ | COST-06 (SP/RI) |
| BP02 Choose Regions based on cost | 📝 | (考虑 SUS-01 region 选择) | |
| BP03 Select third-party agreements | 📝 | — | |
| BP04 Implement geographic selection | 📝 | — | |
| BP05 Right-size resources | ✅ | COST-02, COST-05 | |
| COST08 Plan for data transfer | BP01-BP* | ✅ | COST-07 (NAT data transfer) |
| COST09 Manage demand and supply | BP01-BP* | ⚠️ | SUS-05 (auto-scaling) |
| COST10 Evaluate new services | BP01-BP* | 📝 | — |
| COST11 Quantify cost optimization | BP01-BP* | 📝 | — |
---
🌱 Sustainability (SUS01-SUS06)
| Question | BP Title | Coverage | Local Check |
|---|---|---|---|
| SUS01 Region selection | BP01 Choose Region based on business requirements and sustainability goals | 📝 | — |
| SUS02 User behavior patterns | BP01-BP06 | ⚠️ | SUS-05 (scaling), SUS-02 (utilization) |
| SUS03 Software and architecture | BP01-BP05 | ⚠️ | SUS-03 (Lambda runtime/arch) |
| SUS04 Data | BP01-BP08 | ⚠️ | SUS-04 (Intelligent Tiering) |
| SUS05 Hardware and services | BP01 Use minimum hardware to meet needs | ✅ | SUS-01 (Graviton), PERF-01 |
| BP02 Use instance types with the least impact | ✅ | SUS-01 | |
| BP03 Use managed services | 📝 | — | |
| BP04 Optimize geographic placement | 📝 | — | |
| BP05 Optimize team equipment for awareness | 📝 | — | |
| SUS06 Process and culture | BP01-BP* | 📝 | — |
---
Coverage 总结
| Pillar | Total BPs | ✅ 程序化 | ⚠️ 部分 | 📝 访谈 | ❌ 未覆盖 |
|---|---|---|---|---|---|
| Security | ~50 | 8 | 4 | ~30 | ~8 |
| Reliability | ~40 | 7 | 5 | ~25 | ~3 |
| Ops Excellence | ~35 | 4 | 6 | ~25 | — |
| Performance | ~25 | 5 | 4 | ~16 | — |
| Cost | ~30 | 5 | 2 | ~22 | ~1 |
| Sustainability | ~25 | 2 | 3 | ~20 | — |
| TOTAL | ~205 | 31 | 24 | ~138 | ~12 |
核心结论:
- 程序化 check 覆盖约 15% 的 BP — 这是 预期内的,因为大多数 WA BP 涉及组织流程、文化、设计决策,无法通过 API 检测
- 使用本 skill 的正确方式:programmatic-checks 跑完 → pillar-assessment-guide 的 4 子主题 grid 强制覆盖访谈类问题 → 最终 report 同时包含两类 finding
- 不要把"程序化 check 全 ✅"等同于"WA 评审通过"
---
维护说明
- 新增 check 时同步更新本表
- AWS WA Framework 更新(每年一次)后核对 BP 编号
- 参考真值源:service-screener-v2
frameworks/WAFS/map.json(Security only, 其他 pillar 需自查 WA Framework 官方文档)
Pillar Assessment Guide
审阅优先级原则(Top-N + IAM 强制)
来源:service-screener-v2 wa-summarizer prompt 的经验值。避免 Agent 平均用力、重点不突出。
Top-5 服务优先原则
- 完成所有 pillar checks 后,按 finding 总数排序服务,重点讲 Top-5
- 其他服务在 Appendix 里一笔带过,不占 Executive Summary 篧幅
- Top-5 中每个服务最多讲 3 个 finding(从 HIGH 以上选)
IAM 强制纳入
无论 IAM 在 Top-5 里排多少,报告中都必须为它保留独立一节。原因:
- IAM 是 blast radius 最大的服务,一个 wildcard policy 可以贯穿所有 pillar
- 客户 PA 汇报时 IAM 是必问项
Quick Wins 提炼
从所有 finding 中提炼 5-10 个 High Impact + Low Effort项,独立一节。评判标准:
- Severity ≥ HIGH
downtime=0且needFullTest=0→快修- 修复命令 ≤ 3 行 bash
---
6 支柱 × 固定子主题 Grid(强制覆盖)
每个支柱必须覆盖以下 4 个子主题。哪个子主题没 finding 也要写一句"已体检与未发现问题"。避免 Agent 逆向合理化只报容易领域。
| 支柱 | 子主题 1 | 子主题 2 | 子主题 3 | 子主题 4 |
|---|---|---|---|---|
| 🔒 Security | Identity & Access | Data Protection | Network Security | Detection & Incident Response |
| 🔄 Reliability | Foundations (Quota/Network) | Workload Architecture | Change Management | Failure Management (Backup/DR) |
| ⚙️ Operational Excellence | Organization | Prepare (Telemetry/IaC) | Operate (Monitoring/Runbook) | Evolve (Postmortem/Improvement) |
| ⚡ Performance | Selection (Compute/Storage/DB) | Review (Right-sizing) | Monitoring (Metrics/APM) | Trade-offs (Cache/Async) |
| 💰 Cost | Cloud Financial Management | Cost-effective Resources | Manage Demand & Supply | Optimize Over Time |
| 🌱 Sustainability | Region Selection | User Behavior Patterns | Software & Architecture | Data / HW / Process |
每个子主题下至少列 1-3 个 finding或明确标 "No findings"。
---
Per-Pillar Output Structure
After each pillar's programmatic checks complete, produce this structured output:
## {Pillar Name} Assessment
### Summary
- Checks executed: {N}
- Findings: {critical} CRITICAL, {high} HIGH, {medium} MEDIUM, {low} LOW
- Pillar health: {★★★★☆} ({score}/5)
### Findings by Sub-theme
#### {子主题 1}
| ID | Check | Severity | Finding | Down | Slow | Cost | Test | Remediation |
|----|-------|----------|---------|------|------|------|------|-------------|
| SEC-01 | GuardDuty | 🔴 CRITICAL | Not enabled | 0 | 0 | 1 | 0 | `aws guardduty create-detector --enable` |
#### {子主题 2}
...
### Pillar Score Rationale
{Brief explanation of why this score was given}Scoring Rubric (5-Star)
| Stars | Rating | Criteria |
|---|---|---|
| ★★★★★ | Excellent | 0 CRITICAL, 0 HIGH, ≤2 MEDIUM |
| ★★★★☆ | Good | 0 CRITICAL, ≤1 HIGH, ≤4 MEDIUM |
| ★★★☆☆ | Adequate | 0 CRITICAL, ≤3 HIGH, any MEDIUM |
| ★★☆☆☆ | Needs Improvement | ≤1 CRITICAL, any HIGH |
| ★☆☆☆☆ | Critical Risk | 2+ CRITICAL findings |
Radar Chart Data
After all pillars complete, generate a Mermaid radar-like visualization:
### Overall Health Score
| Pillar | Score | Rating |
|--------|-------|--------|
| Security | 3/5 | ★★★☆☆ |
| Ops Excellence | 4/5 | ★★★★☆ |
| Reliability | 2/5 | ★★☆☆☆ |
| Performance | 4/5 | ★★★★☆ |
| Cost Optimization | 3/5 | ★★★☆☆ |
| Sustainability | 3/5 | ★★★☆☆ |
| **Overall** | **3.2/5** | **★★★☆☆** |Assessment Adaptations
When Check Cannot Execute
- API permission denied → mark as
UNABLE_TO_ASSESS(not a finding) - Service not in region → mark as
NOT_APPLICABLE - Timeout → retry once, then
UNABLE_TO_ASSESS
When Service Not Present
- No RDS → skip REL-01, PERF-04 → mark as
NOT_APPLICABLE - No EKS → skip REL-06 → mark as
NOT_APPLICABLE - No Lambda → skip PERF-07, SUS-03 → mark as
NOT_APPLICABLE
Quick Scan Mode
If user requests "quick scan" or "security only":
- Execute only Security pillar
- Skip all other pillars
- Generate abbreviated report
Cost Optimization Pillar — Programmatic Checks
Record findings with severity: CRITICAL / HIGH / MEDIUM / LOW / INFO
---
COST-01: Cost Explorer Anomaly Detection
aws ce get-anomaly-monitors --query 'AnomalyMonitors[].{Name:MonitorName,Type:MonitorType}' --output json 2>/dev/null| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | No monitors | MEDIUM | No Cost Anomaly Detection — unexpected spend won't be caught aws ce create-anomaly-monitor --anomaly-monitor MonitorName=service-anomaly,MonitorType=DIMENSIONAL,MonitorDimension=SERVICE | | Monitors active | INFO | Cost Anomaly Detection active ✅ — |
---
COST-02: Idle EC2 Instances (Low CPU)
# Check for instances with <5% avg CPU over 14 days
for inst in $(aws ec2 describe-instances --filters Name=instance-state-name,Values=running --query 'Reservations[].Instances[].InstanceId' --output text); do
cpu=$(aws cloudwatch get-metric-statistics --namespace AWS/EC2 --metric-name CPUUtilization \
--dimensions Name=InstanceId,Value=$inst --start-time $(date -d '14 days ago' -u +%Y-%m-%dT%H:%M:%S) \
--end-time $(date -u +%Y-%m-%dT%H:%M:%S) --period 86400 --statistics Average \
--query 'Datapoints | sort_by(@, &Timestamp) | [-1].Average' --output text 2>/dev/null)
if [ "$cpu" != "None" ] && [ "$(echo "$cpu < 5" | bc -l 2>/dev/null)" = "1" ]; then
echo "IDLE: $inst avg_cpu=${cpu}%"
fi
done| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | Instances < 5% CPU avg | HIGH | {count} potentially idle EC2 instances (avg CPU < 5%) # ⚠️ verify before run: aws ec2 stop-instances --instance-ids {id} then evaluate termination after 7 days idle | | All utilized | INFO | No idle instances detected ✅ — |
---
COST-03: Unattached EBS Volumes
aws ec2 describe-volumes --filters Name=status,Values=available \
--query 'Volumes[].{VolumeId:VolumeId,Size:Size,Type:VolumeType,CreateTime:CreateTime}' --output json| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | Unattached volumes | MEDIUM | {count} unattached EBS volumes ({total_gb} GB) — wasting ${est_monthly}/mo # snapshot first: aws ec2 create-snapshot --volume-id {vol} --description 'pre-deletion'; aws ec2 delete-volume --volume-id {vol} | | No unattached | INFO | No unattached EBS volumes ✅ — |
---
COST-04: Elastic IPs Not Associated
aws ec2 describe-addresses --query 'Addresses[?AssociationId==null].{PublicIp:PublicIp,AllocationId:AllocationId}' --output json| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | Unassociated EIPs | LOW | {count} unassociated Elastic IPs ($3.65/mo each) aws ec2 release-address --allocation-id {alloc-id} | | All associated | INFO | All Elastic IPs associated ✅ — |
---
COST-05: Old Generation Instances (Cost Angle)
# Reuse PERF-01 data — old gen instances cost more per vCPU
aws ec2 describe-instances --filters Name=instance-state-name,Values=running \
--query 'Reservations[].Instances[?starts_with(InstanceType, `t2`) || starts_with(InstanceType, `m4`) || starts_with(InstanceType, `c4`) || starts_with(InstanceType, `r4`)].{Id:InstanceId,Type:InstanceType}' --output json| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | Old gen instances | MEDIUM | {count} old-gen instances — newer generations offer 20-40% better price/perf Stop+modify: aws ec2 modify-instance-attribute --instance-id {id} --instance-type '{Value=m6i.large}'. Save 10-20% | | All current gen | INFO | All instances on cost-efficient current gen ✅ — |
---
COST-06: Savings Plans / Reserved Instances Coverage
aws ce get-savings-plans-coverage --time-period Start=$(date -d '30 days ago' -u +%Y-%m-%d),End=$(date -u +%Y-%m-%d) \
--query 'SavingsPlansCoverages[-1].CoveragePercentage' --output json 2>/dev/null
aws ce get-reservation-coverage --time-period Start=$(date -d '30 days ago' -u +%Y-%m-%d),End=$(date -u +%Y-%m-%d) \
--query 'Total.CoverageHours.CoverageHoursPercentage' --output text 2>/dev/null| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | Coverage < 50% | HIGH | Savings Plans/RI coverage at {pct}% — significant savings opportunity aws ce get-savings-plans-purchase-recommendation --savings-plans-type COMPUTE_SP --term-in-years ONE_YEAR --payment-option NO_UPFRONT --lookback-period-in-days SIXTY_DAYS then commit | | Coverage 50-80% | MEDIUM | Savings Plans/RI coverage at {pct}% — room for improvement Increase commit per Cost Explorer recommendation; aim for 70%+ baseline | | Coverage > 80% | INFO | Good Savings Plans/RI coverage at {pct}% ✅ — |
---
COST-07: NAT Gateway Data Transfer
aws ec2 describe-nat-gateways --filter Name=state,Values=available \
--query 'NatGateways[].{Id:NatGatewayId,SubnetId:SubnetId,VpcId:VpcId}' --output json| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | Multiple NAT GWs | LOW | {count} NAT Gateways — review if all needed ($32/mo each + data transfer) Add VPC Gateway endpoint for S3 (free): aws ec2 create-vpc-endpoint --vpc-id {vpc} --service-name com.amazonaws.{region}.s3 --route-table-ids {rt}; Interface endpoints for chatty services | | Single NAT GW | INFO | NAT Gateway configuration noted — |
---
COST-08: S3 Storage Classes
aws s3api list-buckets --query 'Buckets[].Name' --output text | tr '\t' '\n' | head -20 | while read b; do
lc=$(aws s3api get-bucket-lifecycle-configuration --bucket "$b" 2>/dev/null)
if [ $? -ne 0 ]; then echo "NO_LIFECYCLE: $b"; fi
done| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | Buckets without lifecycle | MEDIUM | {count} S3 buckets without lifecycle rules — no automatic tiering aws s3api put-bucket-lifecycle-configuration --bucket {bucket} --lifecycle-configuration file://lifecycle.json (transition >30d to IA, >90d to Glacier IR) | | All with lifecycle | INFO | All S3 buckets have lifecycle policies ✅ — |
---
Summary
| Check | ID | Key Question |
|---|---|---|
| Cost Anomaly | COST-01 | Spend monitoring active? |
| Idle EC2 | COST-02 | Unused compute resources? |
| Unattached EBS | COST-03 | Orphaned storage? |
| Unused EIPs | COST-04 | Idle IP addresses? |
| Old Gen Instances | COST-05 | Outdated instance types? |
| SP/RI Coverage | COST-06 | Commitment discounts? |
| NAT Gateways | COST-07 | Data transfer costs? |
| S3 Lifecycle | COST-08 | Storage tiering? |
Total checks: 8 | Expected time: ~3-5 minutes
Operational Excellence Pillar — Programmatic Checks
Execute these checks in order. Record findings with severity: CRITICAL / HIGH / MEDIUM / LOW / INFO
---
OPS-01: AWS Config Status
aws configservice describe-configuration-recorders --query 'ConfigurationRecorders[].{Name:name,Recording:recordingGroup.allSupported}' --output json
aws configservice describe-configuration-recorder-status --query 'ConfigurationRecordersStatus[].{Name:name,Recording:recording,LastStatus:lastStatus}' --output json| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | No recorder | HIGH | AWS Config not enabled — no configuration drift detection aws configservice put-configuration-recorder --configuration-recorder name=default,roleARN={role-arn} --recording-group allSupported=true,includeGlobalResourceTypes=true && aws configservice put-delivery-channel --delivery-channel name=default,s3BucketName={bucket} && aws configservice start-configuration-recorder --configuration-recorder-name default | | Recorder not recording | HIGH | AWS Config recorder stopped aws configservice start-configuration-recorder --configuration-recorder-name default | | Recording, allSupported=true | INFO | AWS Config active, recording all resources ✅ — |
---
OPS-02: CloudWatch Alarms
aws cloudwatch describe-alarms --state-value ALARM --query 'MetricAlarms[].{Name:AlarmName,Metric:MetricName,State:StateValue}' --output json
aws cloudwatch describe-alarms --query 'MetricAlarms | length(@)' --output text| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | Zero alarms configured | HIGH | No CloudWatch alarms — no proactive monitoring Create baseline: CPU, status check, billing, error rate per service via CloudFormation/CDK | | Active ALARM state alarms | MEDIUM | {count} alarms currently in ALARM state | Investigate root cause: aws cloudwatch describe-alarms --state-value ALARM --query 'MetricAlarms[].{Name:AlarmName,Reason:StateReason}' then fix underlying metric source | | Alarms configured, none firing | INFO | CloudWatch alarms healthy ✅ — |
---
OPS-03: CloudWatch Log Groups Retention
aws logs describe-log-groups --query 'logGroups[?retentionInDays==null].{Name:logGroupName,StoredBytes:storedBytes}' --output json| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | Groups with no retention | MEDIUM | {count} log groups with no retention policy (unlimited storage cost) aws logs put-retention-policy --log-group-name {name} --retention-in-days 90 (adjust 30/90/365 per compliance) | | All have retention | INFO | All log groups have retention policies ✅ — |
---
OPS-04: Systems Manager Patch Compliance
aws ssm describe-instance-patch-states --query 'InstancePatchStates[?MissingCount>`0`].{InstanceId:InstanceId,Missing:MissingCount,Failed:FailedCount}' --output json 2>/dev/null| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | Instances with missing patches | MEDIUM | {count} instances with missing patches aws ssm send-command --document-name AWS-RunPatchBaseline --targets Key=instanceids,Values={id} --parameters Operation=Install | | No SSM data | LOW | SSM patch compliance not configured Install SSM Agent (Amazon Linux/Ubuntu pre-installed); attach AmazonSSMManagedInstanceCore to instance role | | All compliant | INFO | All instances patch compliant ✅ — |
---
OPS-05: CloudFormation Stack Health
aws cloudformation list-stacks --stack-status-filter ROLLBACK_COMPLETE UPDATE_ROLLBACK_COMPLETE CREATE_FAILED --query 'StackSummaries[].{Name:StackName,Status:StackStatus,Time:LastUpdatedTimestamp}' --output json| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | Failed/rollback stacks | MEDIUM | {count} CloudFormation stacks in failed state Investigate: aws cloudformation describe-stack-events --stack-name {name}; fix root cause then aws cloudformation continue-update-rollback | | No failed stacks | INFO | All CloudFormation stacks healthy ✅ — |
---
OPS-06: Trusted Advisor Open Checks
aws support describe-trusted-advisor-checks --language en --query 'checks[].{Id:id,Name:name,Category:category}' --output json 2>/dev/null
# Note: Requires Business/Enterprise support plan| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | Not available (Basic plan) | LOW | Trusted Advisor limited — consider upgrading support plan Upgrade to Business support tier (>$100/mo) for full TA checks | | Open warnings | MEDIUM | {count} Trusted Advisor warnings Manual: review and address each TA warning | | All green | INFO | Trusted Advisor all green ✅ — |
---
OPS-07: EventBridge Rules
aws events list-rules --query 'Rules | length(@)' --output text
aws events list-rules --query 'Rules[?State==`DISABLED`].{Name:Name,State:State}' --output json| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | No rules | LOW | No EventBridge rules — limited event-driven automation Define event-driven rules: aws events put-rule --name {name} --event-pattern '{...}' --state ENABLED | | Disabled rules | LOW | {count} disabled EventBridge rules aws events enable-rule --name {name} after verifying still needed, otherwise aws events delete-rule | | Active rules | INFO | EventBridge automation active ✅ — |
---
OPS-08: AWS Health Events
aws health describe-events --filter 'eventStatusCodes=open,upcoming' --query 'events[].{Service:service,Type:eventTypeCode,Status:statusCode,Region:region}' --output json 2>/dev/null| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | Open/upcoming events | MEDIUM | {count} active AWS Health events affecting your account Manual: review Health Dashboard; act on scheduled changes (RDS minor versions etc.) before forced window | | No events | INFO | No active AWS Health events ✅ — |
---
Summary
| Check | ID | Key Question |
|---|---|---|
| AWS Config | OPS-01 | Is configuration drift tracked? |
| CloudWatch Alarms | OPS-02 | Is monitoring proactive? |
| Log Retention | OPS-03 | Are logs managed cost-effectively? |
| Patch Compliance | OPS-04 | Are systems patched? |
| CFN Stack Health | OPS-05 | Is IaC deployment healthy? |
| Trusted Advisor | OPS-06 | Are AWS recommendations addressed? |
| EventBridge | OPS-07 | Is event automation in place? |
| Health Events | OPS-08 | Are there active AWS issues? |
Total checks: 8 | Expected time: ~2-3 minutes
Performance Efficiency Pillar — Programmatic Checks
Record findings with severity: CRITICAL / HIGH / MEDIUM / LOW / INFO
---
PERF-01: EC2 Instance Generation
aws ec2 describe-instances --filters Name=instance-state-name,Values=running \
--query 'Reservations[].Instances[].{Id:InstanceId,Type:InstanceType,Name:Tags[?Key==`Name`].Value|[0]}' --output jsonCheck instance type generation — older generations (t2, m4, c4, r4) should be upgraded.
| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | Instances on gen ≤ 4 (t2, m4, c4) | MEDIUM | {count} instances on old generation — missing performance + cost improvements Stop+modify: aws ec2 modify-instance-attribute --instance-id {id} --instance-type '{Value=m7i.large}'. Typically 15-30% perf gain at same cost | | All current generation | INFO | All instances on current generation ✅ — |
---
PERF-02: EBS Volume Types
aws ec2 describe-volumes --query 'Volumes[].{VolumeId:VolumeId,Type:VolumeType,Size:Size,Iops:Iops,State:State}' --output json| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | gp2 volumes exist | MEDIUM | {count} gp2 volumes — migrate to gp3 for better price/performance aws ec2 modify-volume --volume-id {vol} --volume-type gp3 (online change, free baseline 3000 IOPS) | | io1 volumes exist | LOW | {count} io1 volumes — consider io2 for better durability Migrate to io2 or gp3: aws ec2 modify-volume --volume-id {vol} --volume-type io2 | | All gp3/io2 | INFO | All EBS volumes on latest types ✅ — |
---
PERF-03: Compute Optimizer Recommendations
aws compute-optimizer get-enrollment-status --query 'Status' --output text
aws compute-optimizer get-ec2-instance-recommendations --query 'instanceRecommendations[?finding!=`OPTIMIZED`].{InstanceId:instanceArn,Finding:finding,CurrentType:currentInstanceType,Recommended:recommendationOptions[0].instanceType}' --output json 2>/dev/null| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | Not enrolled | MEDIUM | Compute Optimizer not enrolled — missing right-sizing insights aws compute-optimizer update-enrollment-status --status Active --include-member-accounts | | Over-provisioned instances | MEDIUM | {count} over-provisioned instances identified Apply CO recommendation: aws compute-optimizer get-ec2-instance-recommendations then modify per top recommendation | | Under-provisioned instances | HIGH | {count} under-provisioned instances — performance risk Upsize per CO recommendation; performance risk requires faster action | | All optimized | INFO | All instances optimized ✅ — |
---
PERF-04: RDS Instance Classes
aws rds describe-db-instances --query 'DBInstances[].{DBId:DBInstanceIdentifier,Class:DBInstanceClass,Engine:Engine,EngineVersion:EngineVersion}' --output json| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | Old-gen classes (db.m4, db.r4, db.t2) | MEDIUM | {count} RDS instances on old generation classes aws rds modify-db-instance --db-instance-identifier {id} --db-instance-class db.r7g.large --apply-immediately (Graviton 20%+ price/perf) | | All current generation | INFO | All RDS on current generation ✅ — |
---
PERF-05: CloudFront Distributions
aws cloudfront list-distributions --query 'DistributionList.Items[].{Id:Id,Domain:DomainName,HTTP2:IsIPV6Enabled,PriceClass:PriceClass}' --output json 2>/dev/null| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | No CloudFront | LOW | No CDN — consider CloudFront for static content delivery aws cloudfront create-distribution --distribution-config file://dist.json with S3/ALB origin | | PriceClass_All | INFO | CloudFront with global edge locations ✅ — |
---
PERF-06: ElastiCache Engine Versions
aws elasticache describe-cache-clusters --query 'CacheClusters[].{Id:CacheClusterId,Engine:Engine,Version:EngineVersion,NodeType:CacheNodeType}' --output json 2>/dev/null| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | Outdated engine version | LOW | ElastiCache {id} on old engine version aws elasticache modify-replication-group --replication-group-id {id} --engine-version 7.1 --apply-immediately | | Current versions | INFO | All ElastiCache on current versions ✅ — |
---
PERF-07: Lambda Memory Configuration
aws lambda list-functions --query 'Functions[].{Name:FunctionName,Memory:MemorySize,Timeout:Timeout,Runtime:Runtime}' --output json| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | Functions at 128MB default | LOW | {count} Lambda functions at minimum 128MB — may benefit from more memory Use Lambda Power Tuning to find sweet spot, then aws lambda update-function-configuration --function-name {name} --memory-size {N} | | Deprecated runtimes | MEDIUM | {count} Lambda functions on deprecated runtimes aws lambda update-function-configuration --function-name {name} --runtime python3.12 (test compat first) | | Optimized configs | INFO | Lambda configurations look reasonable ✅ — |
---
Summary
| Check | ID | Key Question |
|---|---|---|
| EC2 Generation | PERF-01 | Latest instance types? |
| EBS Types | PERF-02 | Optimal storage types? |
| Compute Optimizer | PERF-03 | Right-sized instances? |
| RDS Classes | PERF-04 | Current-gen databases? |
| CloudFront | PERF-05 | CDN for content delivery? |
| ElastiCache | PERF-06 | Current cache engines? |
| Lambda Memory | PERF-07 | Optimal function config? |
Total checks: 7 | Expected time: ~2-3 minutes
Reliability Pillar — Programmatic Checks
Record findings with severity: CRITICAL / HIGH / MEDIUM / LOW / INFO
---
REL-01: Multi-AZ RDS
aws rds describe-db-instances --query 'DBInstances[].{DBId:DBInstanceIdentifier,MultiAZ:MultiAZ,Engine:Engine,Status:DBInstanceStatus}' --output json| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | Production DB not Multi-AZ | HIGH | RDS instance {id} is single-AZ — no automatic failover aws rds modify-db-instance --db-instance-identifier {id} --multi-az --apply-immediately | | All Multi-AZ | INFO | All RDS instances are Multi-AZ ✅ — |
---
REL-02: Auto Scaling Groups
aws autoscaling describe-auto-scaling-groups --query 'AutoScalingGroups[].{Name:AutoScalingGroupName,Min:MinSize,Max:MaxSize,Desired:DesiredCapacity,AZs:AvailabilityZones}' --output json| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | ASG in single AZ | HIGH | ASG {name} spans only 1 AZ — no cross-AZ resilience aws autoscaling update-auto-scaling-group --auto-scaling-group-name {name} --vpc-zone-identifier {subnet1},{subnet2},{subnet3} | | Min=Max=1 | MEDIUM | ASG {name} has min=max=1 — no horizontal scaling aws autoscaling update-auto-scaling-group --auto-scaling-group-name {name} --min-size 2 --max-size 6 --desired-capacity 2 | | ASG spans 2+ AZs | INFO | ASG spans multiple AZs ✅ — |
---
REL-03: ELB Health Checks
aws elbv2 describe-target-groups --query 'TargetGroups[].{Name:TargetGroupName,HealthCheck:HealthCheckPath,Protocol:Protocol,Port:Port}' --output json
aws elbv2 describe-target-health --target-group-arn {arn} --query 'TargetHealthDescriptions[].{Target:Target.Id,Health:TargetHealth.State}' --output json| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | Unhealthy targets | HIGH | {count} unhealthy targets in target group {name} Investigate via aws elbv2 describe-target-health --target-group-arn {arn}; common fixes: open SG to ALB, fix /health endpoint | | No health check path | MEDIUM | Target group {name} uses TCP health check (not application-level) aws elbv2 modify-target-group --target-group-arn {arn} --health-check-protocol HTTP --health-check-path /health --health-check-interval-seconds 30 | | All healthy | INFO | All targets healthy ✅ — |
---
REL-04: AWS Backup Plans
aws backup list-backup-plans --query 'BackupPlansList[].{Name:BackupPlanName,Id:BackupPlanId}' --output json
aws backup list-protected-resources --query 'Results | length(@)' --output text| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | No backup plans | HIGH | No AWS Backup plans configured — data loss risk aws backup create-backup-plan --backup-plan file://backup-plan.json (quickstart) | | Plans exist but few resources | MEDIUM | Only {count} resources protected by AWS Backup aws backup create-backup-selection --backup-plan-id {id} --backup-selection file://selection.json | | Comprehensive coverage | INFO | AWS Backup protecting {count} resources ✅ — |
---
REL-05: Route 53 Health Checks
aws route53 list-health-checks --query 'HealthChecks[].{Id:Id,Type:HealthCheckConfig.Type,FQDN:HealthCheckConfig.FullyQualifiedDomainName}' --output json| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | No health checks | MEDIUM | No Route 53 health checks — no DNS-level failover aws route53 create-health-check --caller-reference $(date +%s) --health-check-config Type=HTTPS,FullyQualifiedDomainName={domain},Port=443,ResourcePath=/health,RequestInterval=30,FailureThreshold=3 | | Health checks configured | INFO | Route 53 health checks active ✅ — |
---
REL-06: EKS Node Groups (if EKS present)
for cluster in $(aws eks list-clusters --query 'clusters[]' --output text); do
aws eks list-nodegroups --cluster-name "$cluster" --query 'nodegroups[]' --output text | tr '\t' '\n' | while read ng; do
aws eks describe-nodegroup --cluster-name "$cluster" --nodegroup-name "$ng" \
--query '{Name:nodegroupName,Min:scalingConfig.minSize,Max:scalingConfig.maxSize,Desired:scalingConfig.desiredSize,Subnets:subnets}' --output json
done
done| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | Single-AZ nodegroup | HIGH | EKS nodegroup {name} in single AZ Recreate: aws eks create-nodegroup --cluster-name {cluster} --nodegroup-name v2 --subnets {s1} {s2} {s3} --instance-types m6i.large --scaling-config minSize=2,maxSize=10,desiredSize=3 --node-role {role} (cannot modify AZs in-place) | | Min=Desired=1 | MEDIUM | EKS nodegroup {name} has no scaling headroom aws eks update-nodegroup-config --cluster-name {cluster} --nodegroup-name {ng} --scaling-config minSize=2,maxSize=10,desiredSize=3 | | Multi-AZ, scaling configured | INFO | EKS nodegroup properly configured ✅ — |
---
REL-07: S3 Versioning
aws s3api list-buckets --query 'Buckets[].Name' --output text | tr '\t' '\n' | while read b; do
ver=$(aws s3api get-bucket-versioning --bucket "$b" --query 'Status' --output text)
if [ "$ver" != "Enabled" ]; then echo "WARN: $b — versioning $ver"; fi
done| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | Critical buckets unversioned | MEDIUM | {count} S3 buckets without versioning aws s3api put-bucket-versioning --bucket {bucket} --versioning-configuration Status=Enabled | | All versioned | INFO | All S3 buckets have versioning ✅ — |
---
REL-08: DynamoDB Point-in-Time Recovery
aws dynamodb list-tables --query 'TableNames[]' --output text | tr '\t' '\n' | while read t; do
pitr=$(aws dynamodb describe-continuous-backups --table-name "$t" --query 'ContinuousBackupsDescription.PointInTimeRecoveryDescription.PointInTimeRecoveryStatus' --output text)
if [ "$pitr" != "ENABLED" ]; then echo "WARN: $t — PITR $pitr"; fi
done| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | Tables without PITR | MEDIUM | {count} DynamoDB tables without point-in-time recovery aws dynamodb update-continuous-backups --table-name {name} --point-in-time-recovery-specification PointInTimeRecoveryEnabled=true | | All PITR enabled | INFO | All DynamoDB tables have PITR ✅ — |
---
REL-09: Lambda Reserved/Provisioned Concurrency
aws lambda list-functions --query 'Functions[].FunctionName' --output text | tr '\t' '\n' | while read fn; do
conc=$(aws lambda get-function-concurrency --function-name "$fn" --query 'ReservedConcurrentExecutions' --output text 2>/dev/null)
echo "$fn: reserved=$conc"
done| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | Critical functions unreserved | LOW | Lambda {fn} has no reserved concurrency — throttling risk under load aws lambda put-function-concurrency --function-name {name} --reserved-concurrent-executions {N} | | Reserved concurrency set | INFO | Lambda concurrency configured ✅ — |
---
Summary
| Check | ID | Key Question |
|---|---|---|
| Multi-AZ RDS | REL-01 | Database failover capability? |
| Auto Scaling | REL-02 | Horizontal scaling + multi-AZ? |
| ELB Health | REL-03 | Are backends healthy? |
| AWS Backup | REL-04 | Is data protected? |
| Route 53 | REL-05 | DNS-level failover? |
| EKS Nodes | REL-06 | Container resilience? |
| S3 Versioning | REL-07 | Object recovery? |
| DynamoDB PITR | REL-08 | Table recovery? |
| Lambda Concurrency | REL-09 | Function throttling protection? |
Total checks: 9 | Expected time: ~3-5 minutes
Security Pillar — Programmatic Checks
Execute these checks in order. Each check uses AWS CLI (read-only).
Record findings with severity: CRITICAL / HIGH / MEDIUM / LOW / INFO
---
SEC-01: GuardDuty Status
WA Mapping: SEC04.BP04 (Initiate remediation for non-compliant resources / Detect threats)
aws guardduty list-detectors --query 'DetectorIds' --output json
# If empty → CRITICAL: GuardDuty not enabled
# If found → check each detector:
aws guardduty get-detector --detector-id {id} --query '{Status:Status,FindingPublishingFrequency:FindingPublishingFrequency}' --output json| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | No detectors | CRITICAL | GuardDuty not enabled — no threat detection aws guardduty create-detector --enable --finding-publishing-frequency FIFTEEN_MINUTES | | Status=DISABLED | CRITICAL | GuardDuty detector disabled aws guardduty update-detector --detector-id {id} --enable | | Status=ENABLED | INFO | GuardDuty active ✅ — |
---
SEC-02: Security Hub Status
WA Mapping: SEC04.BP04 (Initiate remediation for non-compliant resources)
aws securityhub describe-hub --output json 2>/dev/null
# If error → Security Hub not enabled
aws securityhub get-findings --filters '{"SeverityLabel":[{"Value":"CRITICAL","Comparison":"EQUALS"}]}' --max-items 5 --query 'Findings[].{Title:Title,Severity:Severity.Label,Resource:Resources[0].Id}' --output json| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | Not enabled | HIGH | Security Hub not enabled — no centralized security view aws securityhub enable-security-hub --enable-default-standards | | Enabled, CRITICAL findings | HIGH | {count} unresolved CRITICAL Security Hub findings | Manual: triage in Security Hub console; for each finding follow its Remediation.Recommendation.Url. Bulk update via aws securityhub batch-update-findings after fix | | Enabled, no CRITICAL | INFO | Security Hub active, no critical findings ✅ — |
---
SEC-03: CloudTrail Status
WA Mapping: SEC04.BP01 (Configure service and application logging)
aws cloudtrail describe-trails --query 'trailList[].{Name:Name,IsMultiRegion:IsMultiRegionTrail,IsLogging:HasCustomEventSelectors,S3Bucket:S3BucketName}' --output json
aws cloudtrail get-trail-status --name {trail-name} --query '{IsLogging:IsLogging,LatestDeliveryTime:LatestDeliveryTime}' --output json| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | No trails | CRITICAL | CloudTrail not configured — no API audit logging aws cloudtrail create-trail --name org-trail --s3-bucket-name {bucket} --is-multi-region-trail --enable-log-file-validation && aws cloudtrail start-logging --name org-trail | | Trail exists but not logging | HIGH | CloudTrail trail exists but logging stopped aws cloudtrail start-logging --name {trail} | | Multi-region trail active | INFO | CloudTrail active with multi-region ✅ — |
---
SEC-04: IAM Password Policy
WA Mapping: SEC02.BP01 (Use strong sign-in mechanisms)
aws iam get-account-password-policy --output json 2>/dev/null| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | No policy set | MEDIUM | No IAM password policy — weak password risk aws iam update-account-password-policy --minimum-password-length 14 --require-symbols --require-numbers --require-uppercase-characters --require-lowercase-characters --max-password-age 90 --password-reuse-prevention 24 | | MinPasswordLength < 14 | MEDIUM | Password minimum length below 14 characters aws iam update-account-password-policy --minimum-password-length 14 --require-symbols --require-numbers --require-uppercase-characters --require-lowercase-characters --max-password-age 90 --password-reuse-prevention 24 | | RequireSymbols=false | LOW | Password policy does not require symbols aws iam update-account-password-policy --require-symbols --require-numbers | | All strong | INFO | Password policy meets best practices ✅ — |
---
SEC-05: IAM Access Keys Age
WA Mapping: SEC02.BP05 (Audit and rotate credentials periodically)
aws iam generate-credential-report >/dev/null 2>&1; sleep 2
aws iam get-credential-report --query 'Content' --output text | base64 -d | awk -F',' 'NR>1 && $9!="N/A" {split($9,a,"T"); if (systime()-mktime(gensub(/-/," ","g",a[1])" 0 0 0") > 7776000) print $1": key age > 90 days"}'| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | Keys > 90 days | HIGH | {count} IAM users with access keys older than 90 days # rotate: aws iam create-access-key --user-name {user} then aws iam update-access-key --access-key-id {old} --status Inactive --user-name {user} | | Keys > 180 days | CRITICAL | {count} IAM users with access keys older than 180 days # ⚠️ verify before run: aws iam delete-access-key --access-key-id {key} --user-name {user} | | All < 90 days | INFO | All access keys within rotation policy ✅ — |
---
SEC-06: Root Account MFA
WA Mapping: SEC01.BP02 (Secure account root user and properties)
aws iam get-account-summary --query 'SummaryMap.AccountMFAEnabled' --output text| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | 0 | CRITICAL | Root account MFA not enabled Manual: sign in as root → IAM console → My security credentials → Assign virtual MFA. CLI cannot enable root MFA. | | 1 | INFO | Root account MFA enabled ✅ — |
---
SEC-07: S3 Public Access
WA Mapping: SEC03.BP07 (Analyze public and cross-account access)
aws s3control get-public-access-block --account-id $(aws sts get-caller-identity --query Account --output text) --output json 2>/dev/null
# Per-bucket check:
aws s3api list-buckets --query 'Buckets[].Name' --output text | tr '\t' '\n' | while read b; do
result=$(aws s3api get-public-access-block --bucket "$b" 2>/dev/null)
if [ $? -ne 0 ]; then echo "WARN: $b — no public access block"; fi
done| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | Account-level block disabled | HIGH | Account-level S3 public access block not enabled aws s3control put-public-access-block --account-id {account} --public-access-block-configuration BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true | | Buckets without block | MEDIUM | {count} S3 buckets without public access block aws s3api put-public-access-block --bucket {bucket} --public-access-block-configuration BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true | | All blocked | INFO | S3 public access blocked at account level ✅ — |
---
SEC-08: EBS Encryption Default
WA Mapping: SEC08.BP02 (Enforce encryption at rest)
aws ec2 get-ebs-encryption-by-default --query 'EbsEncryptionByDefault' --output text| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | false | MEDIUM | EBS encryption by default not enabled aws ec2 enable-ebs-encryption-by-default --region {region} | | true | INFO | EBS encryption by default enabled ✅ — |
---
SEC-09: Security Groups — Public Ingress
WA Mapping: SEC05.BP02 (Control traffic at all layers)
aws ec2 describe-security-groups --filters Name=ip-permission.cidr,Values=0.0.0.0/0 --query 'SecurityGroups[].{GroupId:GroupId,GroupName:GroupName,Rules:IpPermissions[?IpRanges[?CidrIp==`0.0.0.0/0`]].{Proto:IpProtocol,FromPort:FromPort,ToPort:ToPort}}' --output json| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | SG allows 0.0.0.0/0 to SSH (22) | CRITICAL | Security Group {id} allows SSH from internet # ⚠️ verify before run: aws ec2 revoke-security-group-ingress --group-id {sg} --protocol tcp --port 22 --cidr 0.0.0.0/0 then add restricted CIDR or use SSM Session Manager | | SG allows 0.0.0.0/0 to RDP (3389) | CRITICAL | Security Group {id} allows RDP from internet # ⚠️ verify before run: aws ec2 revoke-security-group-ingress --group-id {sg} --protocol tcp --port 3389 --cidr 0.0.0.0/0 then use SSM/bastion | | SG allows 0.0.0.0/0 to all ports | CRITICAL | Security Group {id} allows all traffic from internet | # ⚠️ verify before run: aws ec2 revoke-security-group-ingress --group-id {sg} --ip-permissions IpProtocol=-1,IpRanges='[{CidrIp=0.0.0.0/0}]' then add restricted rules per service | | SG allows 0.0.0.0/0 to 443/80 only | LOW | Security Group {id} allows HTTP/HTTPS from internet (may be intentional) Acceptable for ALB/CloudFront origins; for direct EC2 add WAF or restrict to ALB SG | | No public ingress | INFO | No security groups with unrestricted public ingress ✅ — |
---
SEC-10: RDS Encryption
WA Mapping: SEC08.BP02 (Enforce encryption at rest)
aws rds describe-db-instances --query 'DBInstances[].{DBId:DBInstanceIdentifier,Encrypted:StorageEncrypted,Engine:Engine}' --output json
aws rds describe-db-clusters --query 'DBClusters[].{ClusterId:DBClusterIdentifier,Encrypted:StorageEncrypted,Engine:Engine}' --output json| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | Unencrypted instances | HIGH | {count} RDS instances without encryption at rest Snapshot+restore: aws rds create-db-snapshot --db-instance-identifier {id} --db-snapshot-identifier {id}-pre; aws rds copy-db-snapshot --source-db-snapshot-identifier {id}-pre --target-db-snapshot-identifier {id}-enc --kms-key-id alias/aws/rds; aws rds restore-db-instance-from-db-snapshot --db-instance-identifier {id}-new --db-snapshot-identifier {id}-enc | | All encrypted | INFO | All RDS instances encrypted ✅ — |
---
SEC-11: VPC Flow Logs
WA Mapping: SEC04.BP01 (Configure service and application logging)
aws ec2 describe-vpcs --query 'Vpcs[].VpcId' --output text | tr '\t' '\n' | while read vpc; do
logs=$(aws ec2 describe-flow-logs --filter Name=resource-id,Values=$vpc --query 'FlowLogs[0].FlowLogId' --output text)
if [ "$logs" = "None" ]; then echo "WARN: $vpc — no flow logs"; fi
done| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | VPC without flow logs | MEDIUM | VPC {id} has no flow logs — limited network visibility aws ec2 create-flow-logs --resource-type VPC --resource-ids {vpc} --traffic-type ALL --log-destination-type cloud-watch-logs --log-group-name /aws/vpc/flowlogs --deliver-logs-permission-arn {role-arn} | | All VPCs have flow logs | INFO | All VPCs have flow logs enabled ✅ — |
---
SEC-12: KMS Key Rotation
WA Mapping: SEC08.BP01 (Implement secure key management)
aws kms list-keys --query 'Keys[].KeyId' --output text | tr '\t' '\n' | while read key; do
mgr=$(aws kms describe-key --key-id "$key" --query 'KeyMetadata.KeyManager' --output text)
if [ "$mgr" = "CUSTOMER" ]; then
rot=$(aws kms get-key-rotation-status --key-id "$key" --query 'KeyRotationEnabled' --output text)
if [ "$rot" = "False" ]; then echo "WARN: $key — rotation disabled"; fi
fi
done| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | Customer keys without rotation | MEDIUM | {count} KMS customer keys without automatic rotation aws kms enable-key-rotation --key-id {key-id} | | All rotated | INFO | All customer KMS keys have rotation enabled ✅ — |
---
Summary
| Check | ID | Key Question |
|---|---|---|
| GuardDuty | SEC-01 | Is threat detection active? |
| Security Hub | SEC-02 | Is there a centralized security view? |
| CloudTrail | SEC-03 | Are API calls audited? |
| Password Policy | SEC-04 | Are passwords strong? |
| Access Key Age | SEC-05 | Are keys rotated regularly? |
| Root MFA | SEC-06 | Is root protected? |
| S3 Public Access | SEC-07 | Is data exposure prevented? |
| EBS Encryption | SEC-08 | Is storage encrypted by default? |
| Public SGs | SEC-09 | Is network access restricted? |
| RDS Encryption | SEC-10 | Is database data encrypted? |
| VPC Flow Logs | SEC-11 | Is network traffic logged? |
| KMS Rotation | SEC-12 | Are encryption keys rotated? |
Total checks: 12 | Expected time: ~3-5 minutes
Sustainability Pillar — Programmatic Checks
Record findings with severity: CRITICAL / HIGH / MEDIUM / LOW / INFO
---
SUS-01: Graviton (ARM64) Adoption
aws ec2 describe-instances --filters Name=instance-state-name,Values=running \
--query 'Reservations[].Instances[].{Id:InstanceId,Type:InstanceType,Arch:Architecture}' --output jsonCount instances by architecture. Graviton (arm64) instances use ~60% less energy per compute unit.
| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | 0% Graviton adoption | MEDIUM | No Graviton instances — significant energy efficiency opportunity Migrate to Graviton (m7g/c7g/r7g): rebuild ARM-compatible AMIs/containers, then aws ec2 modify-instance-attribute --instance-id {id} --instance-type '{Value=m7g.large}'. ~20% less energy + 20% cheaper. | | < 30% Graviton | LOW | {pct}% Graviton adoption — room for improvement Migrate to Graviton (m7g/c7g/r7g): rebuild ARM-compatible AMIs/containers, then aws ec2 modify-instance-attribute --instance-id {id} --instance-type '{Value=m7g.large}'. ~20% less energy + 20% cheaper. | | > 30% Graviton | INFO | Good Graviton adoption at {pct}% ✅ Migrate to Graviton (m7g/c7g/r7g): rebuild ARM-compatible AMIs/containers, then aws ec2 modify-instance-attribute --instance-id {id} --instance-type '{Value=m7g.large}'. ~20% less energy + 20% cheaper. |
---
SUS-02: EC2 Instance Utilization
# Average CPU across all instances over 7 days
for inst in $(aws ec2 describe-instances --filters Name=instance-state-name,Values=running --query 'Reservations[].Instances[].InstanceId' --output text | tr '\t' '\n' | head -10); do
cpu=$(aws cloudwatch get-metric-statistics --namespace AWS/EC2 --metric-name CPUUtilization \
--dimensions Name=InstanceId,Value=$inst --start-time $(date -d '7 days ago' -u +%Y-%m-%dT%H:%M:%S) \
--end-time $(date -u +%Y-%m-%dT%H:%M:%S) --period 604800 --statistics Average \
--query 'Datapoints[0].Average' --output text 2>/dev/null)
echo "$inst: avg_cpu=${cpu}%"
done| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | Average CPU < 10% fleet-wide | MEDIUM | Fleet under-utilized — right-sizing reduces energy waste Right-size aggressively or terminate idle instances | | Average CPU 10-40% | LOW | Moderate utilization — some right-sizing opportunity Apply Compute Optimizer right-sizing recommendations | | Average CPU > 40% | INFO | Fleet well-utilized ✅ — |
---
SUS-03: Lambda Runtime Efficiency
aws lambda list-functions --query 'Functions[].{Name:FunctionName,Runtime:Runtime,Arch:Architectures[0],Memory:MemorySize}' --output json| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | Functions on x86_64 | LOW | {count} Lambda functions on x86_64 — arm64 is 20% more energy efficient aws lambda update-function-configuration --function-name {name} --architectures arm64 (rebuild deps), ~20% perf/$ improvement | | Functions on deprecated runtimes | LOW | {count} functions on older runtimes (less efficient) aws lambda update-function-configuration --function-name {name} --runtime python3.12 | | arm64 + current runtimes | INFO | Lambda using efficient configurations ✅ — |
---
SUS-04: S3 Intelligent Tiering
aws s3api list-buckets --query 'Buckets[].Name' --output text | tr '\t' '\n' | head -20 | while read b; do
it=$(aws s3api get-bucket-intelligent-tiering-configuration --bucket "$b" --id default 2>/dev/null)
if [ $? -ne 0 ]; then echo "NO_IT: $b"; fi
done| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | Large buckets without intelligent tiering | LOW | {count} buckets without Intelligent Tiering — cold data uses unnecessary storage aws s3api put-bucket-intelligent-tiering-configuration --bucket {bucket} --id default --intelligent-tiering-configuration Id=default,Status=Enabled,Tierings=[{Days=90,AccessTier=ARCHIVE_ACCESS},{Days=180,AccessTier=DEEP_ARCHIVE_ACCESS}] | | Tiering configured | INFO | S3 Intelligent Tiering in use ✅ — |
---
SUS-05: Auto Scaling Efficiency
aws autoscaling describe-auto-scaling-groups --query 'AutoScalingGroups[].{Name:AutoScalingGroupName,Min:MinSize,Max:MaxSize,Desired:DesiredCapacity}' --output json| Result | Severity | Finding | Remediation | |--------|----------|----------------------| | Min == Max (no scaling) | LOW | ASG {name} cannot scale — over-provisioning wastes energy aws autoscaling put-scaling-policy --auto-scaling-group-name {name} --policy-name cpu-target --policy-type TargetTrackingScaling --target-tracking-configuration file://policy.json | | Dynamic scaling active | INFO | Auto Scaling configured for demand-driven capacity ✅ — |
---
Summary
| Check | ID | Key Question |
|---|---|---|
| Graviton Adoption | SUS-01 | Using energy-efficient processors? |
| Instance Utilization | SUS-02 | Right-sized compute? |
| Lambda Efficiency | SUS-03 | Efficient serverless config? |
| S3 Tiering | SUS-04 | Optimized storage? |
| Auto Scaling | SUS-05 | Demand-driven capacity? |
Total checks: 5 | Expected time: ~2-3 minutes
Report Template
Assessment Metadata
| Field | Value |
|---|---|
| Assessment Date | {YYYY-MM-DD} |
| Account ID | {account_id} |
| Region | {region} |
| Framework | AWS Well-Architected Framework (General) |
| Pillars Assessed | {pillar_list} |
| Assessment Mode | Autopilot (Programmatic) |
| Assessor | AI-Powered WA Review Skill v1.0 |
| Credential | {role_arn} (ReadOnly) |
---
Executive Summary
Overall Health: {overall_score}/5 {star_rating}
{2-3 sentence summary of the environment's health. Highlight the strongest and weakest pillars.}
Top 5 Risks
| # | Risk | Pillar | Severity | Quick Fix? |
|---|---|---|---|---|
| 1 | {risk} | {pillar} | CRITICAL | {yes/no} |
| 2 | {risk} | {pillar} | HIGH | {yes/no} |
| 3 | {risk} | {pillar} | HIGH | {yes/no} |
| 4 | {risk} | {pillar} | MEDIUM | {yes/no} |
| 5 | {risk} | {pillar} | MEDIUM | {yes/no} |
Key Recommendations
1. {Recommendation 1 — immediate action} 2. {Recommendation 2 — short-term} 3. {Recommendation 3 — strategic}
---
Pillar Scorecards
| Pillar | Score | CRITICAL | HIGH | MEDIUM | LOW |
|---|---|---|---|---|---|
| 🔒 Security | {x}/5 | {n} | {n} | {n} | {n} |
| ⚙️ Ops Excellence | {x}/5 | {n} | {n} | {n} | {n} |
| 🔄 Reliability | {x}/5 | {n} | {n} | {n} | {n} |
| ⚡ Performance | {x}/5 | {n} | {n} | {n} | {n} |
| 💰 Cost Optimization | {x}/5 | {n} | {n} | {n} | {n} |
| 🌱 Sustainability | {x}/5 | {n} | {n} | {n} | {n} |
---
Detailed Findings
🔒 Security Pillar ({score}/5)
{Per-check findings table from security-checks.md execution}
⚙️ Operational Excellence Pillar ({score}/5)
{Per-check findings table from ops-excellence-checks.md execution}
🔄 Reliability Pillar ({score}/5)
{Per-check findings table from reliability-checks.md execution}
⚡ Performance Efficiency Pillar ({score}/5)
{Per-check findings table from performance-checks.md execution}
💰 Cost Optimization Pillar ({score}/5)
{Per-check findings table from cost-checks.md execution}
🌱 Sustainability Pillar ({score}/5)
{Per-check findings table from sustainability-checks.md execution}
---
Risk Portfolio
HRI — High Risk Issues ({count})
| ID | Risk | Pillar(s) | Impact | Fix Effort | Priority |
|---|
{HRI rows}
MRI — Medium Risk Issues ({count})
| ID | Risk | Pillar(s) | Impact | Fix Effort | Priority |
|---|
{MRI rows}
LRI — Low Risk Issues ({count})
{Summary list — not full table}
---
Improvement Roadmap
三段时间盒框架(来源 service-screener-v2 wa-summarizer)。每个 finding 必须被放入以下其中一个时间盒,不要留 "待定"。
gantt
title WA Improvement Roadmap (0-30 / 1-6m / 6-24m)
dateFormat YYYY-MM-DD
section 0-30 days (Critical Fixes)
{task1} :crit, t1, {start}, 7d
{task2} :crit, t2, {start}, 14d
section 1-6 months (Architectural)
{task3} :t3, after t1, 60d
{task4} :t4, after t2, 90d
section 6-24 months (Strategic / Modernization)
{task5} :t5, after t3, 180d
{task6} :t6, after t5, 360dPhase 1: 0-30 days — Critical Fixes
进入条件:任何 CRITICAL finding 必进 · 公网暴露 · root MFA · 数据未加密 · 无备份
例:
- 启用 GuardDuty / Security Hub
- root MFA + remove root access keys
- 公网暴露服务加 ALB/CloudFront/WAF
- prod RDS 打开 Multi-AZ + automated backup
- 收敛 SG
0.0.0.0/0非必要规则
Phase 2: 1-6 months — Architectural Improvements
进入条件:HIGH finding · 需要架构调整但不需重写 · 能在季度内交付
例:
- ASG / EKS 改为 Multi-AZ
- 建立 AWS Backup Plan · 跨区域备份
- IAM Identity Center / SSO 迁移
- 建立中枢化日志·告警体系(CloudWatch + SNS + Composite Alarms)
- 启用 KMS CMK 加密所有 RDS / S3 / EBS
Phase 3: 6-24 months — Strategic / Modernization
进入条件:平台级改造 · 需 budget approval · 跨团队协作 · 依赖人员能力升级
例:
- Serverless / Container 现代化(EC2 → ECS/EKS/Lambda)
- FinOps 体系建立(CUR + QuickSight + Anomaly Detection)
- 多账号 Landing Zone (Control Tower / Org SCP)
- DR 体系升级到 Pilot Light / Warm Standby
- Sustainability 优化(Graviton / Spot / Region 选择)
Roadmap 填充原则
- 每个 finding 在表格里加一列
Phase: 0-30d / 1-6m / 6-24m - Phase 1 任务不能超过 10 项(超过就说明环境处于高风险)
- Phase 3 任务要带 ROI 估算(年节省 USD / RMB 两者)
- 不要用“未来”“后续”这种模糊表述,全部放进具体 phase
Phase 1: 0-30 days (报告填充)
{Critical security + reliability fixes with specific commands}
Phase 2: 1-6 months (报告填充)
{High-priority architectural improvements}
Phase 3: 6-24 months (报告填充)
{Strategic transformations + modernization roadmap with ROI}
---
Implementation Guide (Top 10 Fixes)
Fix 1: {Title}
- Pillar: {pillar}
- Severity: {severity}
- Estimated time: {time}
- Steps:
{specific aws cli commands}{Repeat for top 10}
---
Appendix
A. Full Check Results
{Complete raw output from all checks}
B. Checks Unable to Assess
{List of checks that failed due to permissions or unavailability}
C. Assessment Methodology
- Framework: AWS Well-Architected Framework (2025)
- Assessment type: Programmatic (API-based, read-only)
- Total checks: {N} across 6 pillars
- Checks executed: {N} | Skipped: {N} | Failed: {N}
Risk Classification Guide
Severity Levels (per finding)
Color contract: report rendering MUST use these colors so 审阅人 visual scan 一致。
| Level | Color | Emoji | Description | Examples |
|---|---|---|---|---|
| CRITICAL | 🔴 red | 🔴 | Immediate security/reliability threat. Exploitable now. | GuardDuty disabled, SSH open to internet, root no MFA, public-facing prod resource without WAF |
| HIGH | 🟠 orange | 🟠 | Significant risk, needs attention within days. | Unencrypted databases, no backups, stale access keys, single-AZ prod, IAM wildcard policies |
| MEDIUM | 🟡 yellow | 🟡 | Notable gap, address within weeks. | Missing log retention, single-AZ non-prod databases, no lifecycle policies, default SG in use |
| LOW | 🔵 blue | 🔵 | Minor improvement opportunity. | Old instance types, unused Elastic IPs, missing tags, naming inconsistency |
| INFO | ⚪ gray | ⚪ | Informational — passing check or recommendation. | Everything configured correctly, advisory note |
Fix Impact Dimensions (每个 finding 必填)
客户 PA 决策时最关心的 4 个维度。Severity 只回答"问题多严重",这 4 个字段回答"修复代价多大"。来源:service-screener-v2 reporter.json schema。
| Field | Values | Meaning |
|---|---|---|
downtime | 0 / 1 / -1 | 修复是否造成服务中断。0=无停机;1=有停机;-1=取决于实施方式 |
slowness | 0 / 1 / -1 | 修复期间是否性能下降。0=无影响;1=会变慢;-1=depends |
additionalCost | 0 / 1 / -1 | 修复是否产生新的持续成本。0=无;1=有(如 Multi-AZ、跨区域备份);-1=depends |
needFullTest | 0 / 1 / -1 | 是否需要全量回归测试。0=配置改动可灰度;1=需要 full regression(如加密 / 引擎升级);-1=depends |
评分指引
常见 finding 类型的参考评分:
| Finding 类型 | downtime | slowness | additionalCost | needFullTest |
|---|---|---|---|---|
| RDS 启用 Multi-AZ | 0(在线转换) | 1(短暂) | 1(×2 实例费) | 0 |
| RDS 启用静态加密 | 1(需 snapshot+restore) | 0 | 0 | 1 |
| S3 启用 Versioning | 0 | 0 | 1(旧版本存储费) | 0 |
| S3 Public Access Block | 0 | 0 | 0 | -1(依赖业务是否真公开) |
| EC2 SG 收敛 0.0.0.0/0 | -1(误删可能断连) | 0 | 0 | 1 |
| 启用 GuardDuty | 0 | 0 | 1(按事件计费) | 0 |
| ASG 改 Multi-AZ | 0 | 0 | 1(跨 AZ 流量费) | 0 |
| EKS 升级到 supported version | 1(控制面 + 节点滚动) | 1 | 0 | 1 |
| Lambda 加 reserved concurrency | 0 | 0 | 0 | 0 |
| RDS 引擎大版本升级 | 1 | 1 | 0 | 1 |
在 finding 表格里的呈现
| Result | Severity | Finding | Down | Slow | Cost | Test |
|--------|----------|---------|------|------|------|------|
| Single-AZ prod RDS | 🟠 HIGH | RDS {id} 无自动故障切换 | 0 | 1 | 1 | 0 |值用 0/1/-1 简记,可粘贴回 reporter.json schema。
Risk Issue Classification (aggregated)
HRI — High Risk Issue
- Any CRITICAL finding
- Any HIGH finding with blast radius > 1 service
- Cluster of 3+ MEDIUM findings in the same pillar
- Cross-pillar issue (affects 2+ pillars)
MRI — Medium Risk Issue
- Isolated HIGH findings (single service impact)
- MEDIUM findings with cost or performance impact
- Missing best practices in non-critical areas
LRI — Low Risk Issue
- LOW findings
- Optimization opportunities
- Informational recommendations
Priority Scoring Matrix
Priority Score = Impact Score × (1 / Fix Effort Score)
Impact Score (1-5):
5 = Data loss or security breach potential
4 = Service outage potential
3 = Degraded performance or high cost waste
2 = Non-compliance or operational friction
1 = Minor improvement
Fix Effort Score (1-5):
1 = One CLI command / console toggle (minutes)
2 = Configuration change (hours)
3 = Architecture modification (days)
4 = Multi-service redesign (weeks)
5 = Major migration (months)
Quick Wins = High Impact (4-5) + Low Effort (1-2)Cross-Pillar Impact Map
| Primary Pillar | Commonly Affects | Example |
|---|---|---|
| Security | All pillars | Missing encryption affects reliability + compliance |
| Reliability | Performance, Cost | Under-provisioned = poor performance AND cost spikes |
| Performance | Cost, Reliability | Over-provisioned = cost waste; under = reliability risk |
| Cost | Sustainability | Idle resources = wasted energy |
| Ops Excellence | Reliability | No monitoring = slow incident response |
| Sustainability | Cost | Energy-inefficient = higher cloud bill |
Security-First Assessment Guide
Why Security First?
Security forms the foundation of all Well-Architected principles:
1. Prevents catastrophic loss: A single security breach can cost more than all other optimizations save 2. Enables visibility: Security services (GuardDuty, CloudTrail, Security Hub) provide monitoring that other pillars depend on 3. Compliance prerequisite: Most regulatory frameworks require security controls before anything else 4. Trust foundation: Stakeholders need confidence in security before evaluating performance or cost
Security Assessment Order
1. Security Services Enablement — Are detection services active?
- GuardDuty, Security Hub, Inspector, Macie, CloudTrail
2. IAM Security — Who has access to what?
- Role/policy analysis, privilege escalation paths, wildcard permissions
3. Infrastructure Protection — How is the network protected?
- Security Groups, NACLs, public exposure, WAF/Shield
4. Data Protection — Is data encrypted?
- Encryption at rest (KMS, S3, EBS, RDS), encryption in transit (TLS)
5. Detective Controls — Can you detect issues?
- Logging, monitoring, alerting, anomaly detection
Security-First Flow
flowchart TD
S1[Security Services] --> S2[IAM Analysis]
S2 --> S3[Network Protection]
S3 --> S4[Data Encryption]
S4 --> S5[Detective Controls]
S5 --> R{Critical Gaps?}
R -->|Yes| W[⚠️ Flag HRI — Continue to Other Pillars]
R -->|No| G[✅ Proceed to Other Pillars]
W --> P2[Ops Excellence]
G --> P2Security Findings Impact on Other Pillars
| Security Finding | Affected Pillar | Impact |
|---|---|---|
| CloudTrail disabled | Ops Excellence | Cannot audit changes |
| No encryption at rest | Reliability | Backup data exposed |
| Public S3 buckets | Cost | Data exfiltration = incident cost |
| Overly permissive SGs | Performance | Attack traffic consumes bandwidth |
| No GuardDuty | All | No threat detection baseline |
AWS WA Tool Sync — Optional Post-Assessment
This step is OPTIONAL. It requires write permissions to the AWS WA Tool API (wellarchitected:*).Use separate credentials from the read-only assessment credentials.
Prerequisites
- Completed WA Review assessment with findings
- IAM role/user with
wellarchitected:*permissions - AWS CLI configured with the write-capable credentials
Required IAM Policy
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": [
"wellarchitected:CreateWorkload",
"wellarchitected:UpdateWorkload",
"wellarchitected:GetWorkload",
"wellarchitected:ListWorkloads",
"wellarchitected:AssociateLenses",
"wellarchitected:ListLensReviews",
"wellarchitected:ListAnswers",
"wellarchitected:UpdateAnswer",
"wellarchitected:GetAnswer",
"wellarchitected:CreateMilestone",
"wellarchitected:GetLensReview",
"wellarchitected:GetLensReviewReport",
"wellarchitected:TagResource"
],
"Resource": "*"
}]
}Sync Flow
Step 1: Create or Find Workload
# List existing workloads
aws wellarchitected list-workloads --query 'WorkloadSummaries[].{Id:WorkloadId,Name:WorkloadName}' --output table
# Create new workload
aws wellarchitected create-workload \
--workload-name "{workload_name}" \
--description "WA Review - {date}" \
--environment PRODUCTION \
--aws-regions "{region}" \
--review-owner "{owner_email}" \
--lenses wellarchitected \
--query 'WorkloadId' --output textStep 2: Associate Lenses
aws wellarchitected associate-lenses \
--workload-id {workload_id} \
--lens-aliases wellarchitectedStep 3: Populate Answers
For each pillar, list questions and update answers based on assessment findings:
# List questions for a pillar
aws wellarchitected list-answers \
--workload-id {workload_id} \
--lens-alias wellarchitected \
--pillar-id security \
--query 'AnswerSummaries[].{QuestionId:QuestionId,QuestionTitle:QuestionTitle}' \
--output table
# Update an answer
aws wellarchitected update-answer \
--workload-id {workload_id} \
--lens-alias wellarchitected \
--question-id {question_id} \
--selected-choices {choice_id_1} {choice_id_2} \
--notes "Assessment finding: {finding_summary}" \
--is-applicableStep 4: Create Milestone
aws wellarchitected create-milestone \
--workload-id {workload_id} \
--milestone-name "AI-WA Review {date}" \
--query 'MilestoneNumber' --output textStep 5: Generate WA Tool Report
aws wellarchitected get-lens-review \
--workload-id {workload_id} \
--lens-alias wellarchitected \
--output json
aws wellarchitected get-lens-review-report \
--workload-id {workload_id} \
--lens-alias wellarchitected \
--query 'LensReviewReport.Base64String' --output text | base64 -d > wa-tool-report.pdfPillar ID Mapping
| Pillar | WA Tool Pillar ID |
|---|---|
| Security | security |
| Operational Excellence | operationalExcellence |
| Reliability | reliability |
| Performance Efficiency | performance |
| Cost Optimization | costOptimization |
| Sustainability | sustainability |
Error Handling
| Error | Action |
|---|---|
| ConflictException (workload exists) | Offer to update existing workload |
| ValidationException (invalid choice) | Log and skip that question |
| ThrottlingException (429) | Exponential backoff |
| AccessDeniedException | Missing WA Tool permissions — guide IAM setup |
---
AWS WA Tool API 工程细节(必读避坑)
以下 7 个细节是 service-screener-v2 的 frameworks/helper/WATools.py 踩过的坑,AWS 官方文档中 读不到。运行 sync 流程前逐项核对。1. 幂等创建模式:list-by-prefix 而非 get-by-id
创建 workload 之前必须先 list 所有 workload 按名称前缀过滤,避免重复创建。
# 错误:直接创建 → 可能产生同名 workload、后续查询混乱
# 正确:先 list 检查是否已存在
existing=$(aws wellarchitected list-workloads \
--workload-name-prefix "{workload_name}" \
--query "WorkloadSummaries[?WorkloadName=='{workload_name}'].WorkloadId" \
--output text)
if [ -n "$existing" ]; then
echo "Workload exists: $existing, reuse"
workload_id="$existing"
else
workload_id=$(aws wellarchitected create-workload ... --query 'WorkloadId' --output text)
fi2. Milestone 命名 × ConflictException 3 次重试
Milestone name 在 workload 内全局唯一,同名会冲突。必须加时间戳 + attempt 后缀 + 3 次重试。
for attempt in 1 2 3; do
ts=$(date +%Y%m%d%H%M%S)
milestone_name="AI-WA-${ts}-${attempt}"
result=$(aws wellarchitected create-milestone \
--workload-id "$workload_id" \
--milestone-name "$milestone_name" \
--query 'MilestoneNumber' --output text 2>&1)
if [[ "$result" != *ConflictException* ]]; then
echo "$result"; break
fi
sleep 1
done参考:SS-{YYYYMMDDHHmmss}-{attempt} 是 service-screener 的原生命名。
3. Notes 必须截断到 2000 字符
update_answer 的 --notes API 上限是 2048,但多字节字符会超。留 buffer 截到 2000。
notes=$(echo "$finding_summary" | head -c 2000)
aws wellarchitected update-answer ... --notes "$notes"如果 notes 被截,末尾加一行 ... [truncated, full report at: <link>]。
4. selectedChoices 必须 dedupe + 过滤 None
# 错误:--selected-choices 传了重复 ID 或空字符串 → ValidationException
# 正确:先 dedupe + 过滤空
choices=$(echo "$raw_choices" | tr ' ' '\n' | grep -v '^$' | sort -u | tr '\n' ' ')
aws wellarchitected update-answer ... --selected-choices $choices5. workload 创建后 ≈ 3s 最终一致性窗口
刚创建的 workload 立刻调 list-answers 会 ResourceNotFoundException。加 3 次 × 3s 重试。
for attempt in 1 2 3; do
result=$(aws wellarchitected list-answers \
--workload-id "$workload_id" \
--lens-alias wellarchitected \
--pillar-id security 2>&1)
if [[ "$result" != *ResourceNotFoundException* ]]; then
echo "$result"; break
fi
sleep 3
done6. 权限降级标志位:碑不崩溃
Agent 流程遇到 AccessDeniedException 不应 crash 全部同步,而是设个 HASPERMISSION=false 标志位,跳过后续写操作,只输出本地报告 + 提示客户手工导入 WA Tool。
HASPERMISSION=true
result=$(aws wellarchitected list-workloads 2>&1) || true
if [[ "$result" == *AccessDenied* ]]; then
HASPERMISSION=false
echo "⚠️ WA Tool 写权限缺失,后续 sync 步骤跳过。本地报告仍会生成。"
fi7. list_answers 不要传 MilestoneNumber
service-screener 代码中有一行被注释掉的 list_answers(MilestoneNumber=...) —— 实际用 milestone-attached answers 查询 API 行为不稳。不要加 MilestoneNumber 参数,始终查当前 state。
---
调用顺序 Checklist
[✓] 预检查:region / reportName / new-milestone-flag 各一个必填
[✓] preflight 调 list-workloads,判定 HASPERMISSION
[✓] HASPERMISSION=false → 跳过后续,只输出本地 .md 报告
[✓] HASPERMISSION=true → list-by-prefix 检查同名 workload
[✓] 不存在则 create-workload,存在则复用
[✓] sleep 3 + retry list-answers(最终一致性)
[✓] 按 pillar 递归,update-answer 逐问题写入 (notes 截 2000、choices dedupe)
[✓] 所有 update 完成 → create-milestone × ConflictException 3 次重试
[✓] 最后 get-lens-review-report 拉 PDF---
反向同步(不支持)
WATools.py 只做单向推(本地报告 → WA Tool)。不从 WA Tool 拉回人工修订的答题。如需双向:
- 在本地报告里标记
ManualOverride: true的 finding - sync 时跳过这些字段,避免覆盖人工决策
- 本 skill 未实现,记载为 known limitation
Workflow Overview
4-Phase Automated Assessment Flow
flowchart TD
A[User: Start WA Review] --> B{Phase 1: Bootstrap}
B -->|Credentials Valid| C[Phase 2: Discover]
B -->|Invalid/Write Perms| X[HALT — Fix Credentials]
C --> C1[1. Security ★]
C1 --> C2[2. Ops Excellence]
C2 --> C3[3. Reliability]
C3 --> C4[4. Performance]
C4 --> C5[5. Cost Optimization]
C5 --> C6[6. Sustainability]
C6 --> D[Phase 3: Analysis]
D --> D1[Risk Consolidation]
D1 --> D2[HRI/MRI Classification]
D2 --> D3[Priority Matrix]
D3 --> D4[Improvement Roadmap]
D4 --> E[Phase 4: Report]
E --> E1[Markdown Report]
E --> E2[HTML Report]
E --> E3[Executive Summary]
E1 --> F{Sync to WA Tool?}
F -->|Yes| G[WA Tool API Sync]
F -->|No| H[Done ✅]
G --> HPhase Details
Phase 1: Bootstrap (~2 minutes)
- Human interaction: YES (credential confirmation + scope selection)
- Inputs: AWS credentials, target account/region
- Outputs: Validated environment config
- Can fail: Yes — invalid credentials or write permissions detected
Phase 2: Discover (~15-30 minutes)
- Human interaction: NO (fully automated)
- Inputs: Environment config from Phase 1
- Outputs: Per-pillar findings with severity ratings
- Order: Security ALWAYS first (Security-First principle)
- Parallelism: Sequential (one pillar at a time to manage API rate limits)
Phase 3: Analysis (~5 minutes)
- Human interaction: NO
- Inputs: All pillar findings
- Outputs: Risk portfolio, priority matrix, improvement roadmap
Phase 4: Report (~2 minutes)
- Human interaction: NO (optional WA Tool sync prompt)
- Inputs: Analysis results
- Outputs: Markdown report, HTML report, executive summary
Security-First Principle
Security is ALWAYS assessed first because: 1. Security vulnerabilities can invalidate all other improvements 2. Security services (GuardDuty, CloudTrail) provide visibility for other pillars 3. Compliance requirements often mandate security baselines 4. Security incidents are exponentially more expensive than prevention
Error Handling
| Error | Action |
|---|---|
| API throttling (429) | Exponential backoff (AWS CLI handles this) |
| Permission denied | Log as UNABLE_TO_ASSESS, not a finding |
| Service unavailable | Skip with region note |
| Timeout | Retry once, then skip |
| Credential expired | Prompt re-authentication |
Assessment Depth
| Scope | Pillars | Estimated Time | Checks |
|---|---|---|---|
| Quick Scan | Security only | ~5 min | ~25 |
| Focused | Security + 1-2 pillars | ~10-15 min | ~50-75 |
| Standard | All 6 pillars | ~20-30 min | ~150 |
| Deep Dive | All 6 + cross-pillar | ~30-45 min | ~200+ |
#!/usr/bin/env python3
"""
Generate HTML report from WA Review Markdown assessment.
Usage: python3 generate-html-report.py wafr-reports/wafr-assessment-YYYY-MM-DD.md
"""
import sys
import re
import json
from pathlib import Path
from datetime import datetime
HTML_TEMPLATE = """<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AWS Well-Architected Review — {date}</title>
<style>
* {{ margin: 0; padding: 0; box-sizing: border-box; }}
body {{ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: #f5f7fa; color: #1a1a2e; line-height: 1.6; }}
.container {{ max-width: 1200px; margin: 0 auto; padding: 20px; }}
header {{ background: linear-gradient(135deg, #232f3e 0%, #37475a 100%); color: white; padding: 40px; border-radius: 12px; margin-bottom: 30px; }}
header h1 {{ font-size: 2em; margin-bottom: 10px; }}
header .meta {{ display: flex; gap: 20px; flex-wrap: wrap; font-size: 0.9em; opacity: 0.9; }}
.score-card {{ display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 16px; margin-bottom: 30px; }}
.pillar-card {{ background: white; border-radius: 10px; padding: 20px; box-shadow: 0 2px 8px rgba(0,0,0,0.08); text-align: center; }}
.pillar-card h3 {{ font-size: 0.9em; color: #666; margin-bottom: 8px; }}
.pillar-card .score {{ font-size: 2.5em; font-weight: 700; }}
.pillar-card .stars {{ font-size: 1.2em; color: #ff9900; }}
.score-5 .score {{ color: #0d9e3f; }}
.score-4 .score {{ color: #3b82f6; }}
.score-3 .score {{ color: #f59e0b; }}
.score-2 .score {{ color: #ef4444; }}
.score-1 .score {{ color: #991b1b; }}
.section {{ background: white; border-radius: 10px; padding: 24px; margin-bottom: 20px; box-shadow: 0 2px 8px rgba(0,0,0,0.08); }}
.section h2 {{ font-size: 1.3em; margin-bottom: 16px; border-bottom: 2px solid #ff9900; padding-bottom: 8px; }}
table {{ width: 100%; border-collapse: collapse; margin-top: 12px; }}
th, td {{ padding: 10px 12px; text-align: left; border-bottom: 1px solid #eee; font-size: 0.9em; }}
th {{ background: #f8f9fa; font-weight: 600; }}
.severity-critical {{ background: #fee2e2; color: #991b1b; padding: 2px 8px; border-radius: 4px; font-weight: 600; }}
.severity-high {{ background: #fef3c7; color: #92400e; padding: 2px 8px; border-radius: 4px; font-weight: 600; }}
.severity-medium {{ background: #e0e7ff; color: #3730a3; padding: 2px 8px; border-radius: 4px; }}
.severity-low {{ background: #f0fdf4; color: #166534; padding: 2px 8px; border-radius: 4px; }}
.risk-badge {{ display: inline-block; padding: 4px 12px; border-radius: 20px; font-weight: 600; font-size: 0.85em; }}
.hri {{ background: #ef4444; color: white; }}
.mri {{ background: #f59e0b; color: white; }}
.lri {{ background: #3b82f6; color: white; }}
footer {{ text-align: center; padding: 20px; color: #666; font-size: 0.85em; }}
</style>
</head>
<body>
<div class="container">
<header>
<h1>🏗️ AWS Well-Architected Review</h1>
<div class="meta">
<span>📅 {date}</span>
<span>🔑 Account: {account}</span>
<span>🌍 Region: {region}</span>
<span>📊 Framework: General WA (6 Pillars)</span>
</div>
</header>
<div class="score-card">
{pillar_cards}
</div>
<div class="section">
<h2>📋 Risk Summary</h2>
<p>
<span class="risk-badge hri">HRI: {hri_count}</span>
<span class="risk-badge mri">MRI: {mri_count}</span>
<span class="risk-badge lri">LRI: {lri_count}</span>
</p>
</div>
<div class="section">
<h2>🔍 Top Findings</h2>
<table>
<thead><tr><th>#</th><th>Finding</th><th>Pillar</th><th>Severity</th></tr></thead>
<tbody>{findings_rows}</tbody>
</table>
</div>
<div class="section">
<h2>📄 Full Report</h2>
<div>{markdown_body}</div>
</div>
<footer>
Generated by AWS Well-Architected Review Skill — {timestamp}
</footer>
</div>
</body>
</html>"""
def parse_markdown(md_path: str) -> dict:
"""Parse the markdown assessment into structured data."""
text = Path(md_path).read_text()
data = {
'date': datetime.now().strftime('%Y-%m-%d'),
'account': 'Unknown',
'region': 'Unknown',
'pillars': {},
'findings': [],
'hri_count': 0, 'mri_count': 0, 'lri_count': 0,
}
# Extract metadata
for line in text.split('\n'):
if 'Account ID' in line and '|' in line:
data['account'] = line.split('|')[-2].strip()
if 'Region' in line and '|' in line and 'Pillar' not in line:
data['region'] = line.split('|')[-2].strip()
if 'Assessment Date' in line and '|' in line:
data['date'] = line.split('|')[-2].strip()
# Extract pillar scores from scorecard table
pillar_names = ['Security', 'Ops Excellence', 'Reliability', 'Performance', 'Cost Optimization', 'Sustainability']
pillar_icons = ['🔒', '⚙️', '🔄', '⚡', '💰', '🌱']
for i, name in enumerate(pillar_names):
score_match = re.search(rf'{re.escape(name)}.*?(\d)/5', text)
score = int(score_match.group(1)) if score_match else 3
data['pillars'][name] = {'score': score, 'icon': pillar_icons[i]}
# Count risk levels
data['hri_count'] = text.lower().count('critical') + text.lower().count('hri')
data['mri_count'] = text.lower().count('medium')
data['lri_count'] = text.lower().count('low')
return data
def generate_html(data: dict, md_text: str) -> str:
"""Generate HTML from parsed data."""
# Pillar cards
cards = []
for name, info in data['pillars'].items():
stars = '★' * info['score'] + '☆' * (5 - info['score'])
cards.append(f'''
<div class="pillar-card score-{info['score']}">
<h3>{info['icon']} {name}</h3>
<div class="score">{info['score']}/5</div>
<div class="stars">{stars}</div>
</div>''')
# Simple markdown to HTML (basic)
md_html = md_text.replace('\n', '<br>\n')
md_html = re.sub(r'```(\w*)\n(.*?)```', r'<pre><code>\2</code></pre>', md_html, flags=re.DOTALL)
md_html = re.sub(r'\*\*(.*?)\*\*', r'<strong>\1</strong>', md_html)
md_html = re.sub(r'#{1,3}\s+(.*?)(<br>)', r'<h3>\1</h3>', md_html)
return HTML_TEMPLATE.format(
date=data['date'],
account=data['account'],
region=data['region'],
pillar_cards='\n'.join(cards),
hri_count=data['hri_count'],
mri_count=data['mri_count'],
lri_count=data['lri_count'],
findings_rows='<tr><td colspan="4">See full report below</td></tr>',
markdown_body=md_html,
timestamp=datetime.now().isoformat(),
)
def main():
if len(sys.argv) < 2:
print("Usage: python3 generate-html-report.py <markdown-file>")
sys.exit(1)
md_path = sys.argv[1]
if not Path(md_path).exists():
print(f"Error: {md_path} not found")
sys.exit(1)
md_text = Path(md_path).read_text()
data = parse_markdown(md_path)
html = generate_html(data, md_text)
out_path = md_path.replace('.md', '.html')
Path(out_path).write_text(html)
print(f"HTML report generated: {out_path}")
if __name__ == '__main__':
main()
AWS Well-Architected Framework Review — Automated Assessment
Role
You are a senior AWS Solutions Architect conducting an automated Well-Architected Framework review. You leverage AWS APIs (read-only) to programmatically assess infrastructure against all six WAF pillars, classify risks, and generate a structured Markdown report with a prioritized improvement roadmap and remediation commands.
You bring two perspectives to every finding:
1. AWS Principal SA — judges adherence to the Well-Architected Framework, points out service selection issues and known pitfalls. 2. Customer Principal Architect — judges feasibility of remediation, migration cost, operational burden, and team capability fit.
Surface both viewpoints in your report; never give one without the other.
Security Constraint
All operations are READ-ONLY during assessment. OnlyDescribe*/Get*/List*API calls are permitted.
>
Before any pillar scan, validate the active credential against credential-boundary.md. If the credential carries write permissions (e.g.AdministratorAccess,PowerUserAccess), HALT and request a read-only role.
>
The optional WA Tool sync flow (wa-tool-sync.md) is the only time write permissions may be used, and it requires a separate, explicitly named credential.
---
Workflow Overview
This skill runs in Autopilot Mode by default — minimal human interaction after Phase 1.
Phase 1: Bootstrap (~2 min) → Credential validation + scope confirmation
Phase 2: Assess (~15-30 min) → 6-pillar programmatic scan in Security-First order
Phase 3: Analyze (~5 min) → Risk classification + cross-pillar correlation
Phase 4: Report (~2 min) → Structured Markdown report with 3-phase roadmapFor detailed flow, read workflow-overview.md.
---
Phase 1: Environment Bootstrap
This is the only phase requiring human interaction.
1. Verify AWS CLI: Run aws --version. If missing, guide installation.
2. Verify Credentials: Run aws sts get-caller-identity.
- Record Account ID, Region, Role/User ARN
- If no credentials → guide setup or switch to questionnaire-only mode
3. Permission Boundary Check (MANDATORY, non-skippable):
- Load credential-boundary.md
- Validate the credential is read-only (
ReadOnlyAccess/ViewOnlyAccess/SecurityAudit, or a custom policy with onlyDescribe*/Get*/List*actions) - If write permissions detected → HALT and request compliant credentials
4. Apply DON'T-FETCH guardrails — Before any large-output API call, follow the context-budget rules in environment-bootstrap.md. Avoid cloudtrail lookup-events, unbounded s3api list-objects-v2, full IAM authorization dumps, etc. — they will exhaust the context window with no analytical value.
5. Scope Confirmation: Ask user to confirm:
- Target AWS Account ID and Region(s)
- Target VPC(s) or "all"
- Pillar scope (default: all 6; allow narrowing, e.g. "security only")
- Report format preference (Markdown by default; HTML optional via
scripts/generate-html-report.py)
6. Display environment summary and proceed:
[BOOTSTRAP] Environment Ready:
• AWS CLI: v2.x.x ✅
• Credentials: arn:aws:iam::XXXX:role/ReadOnlyRole ✅
• Permission Boundary: ReadOnly ✅
• Region: ap-northeast-1
• Scope: All VPCs
• Framework: General WA (6 pillars, Security-First)
• Mode: Autopilot---
Phase 2: Pillar Assessment (Automated)
Execute pillar checks in Security-First order. For each pillar, on-demand load the corresponding check file from references/programmatic-checks/. Do not preload all six — keep the active context narrow.
| Order | Pillar | Check File | Key Domains |
|---|---|---|---|
| 1 | Security (mandatory, always first) | security-checks.md | GuardDuty, Security Hub, IAM, encryption, network exposure, KMS rotation |
| 2 | Operational Excellence | ops-excellence-checks.md | AWS Config, CloudWatch alarms, SSM patching, CloudFormation health, Trusted Advisor |
| 3 | Reliability | reliability-checks.md | Multi-AZ, Backup plans, ASG topology, ELB health checks, Route53 failover, EKS nodegroups |
| 4 | Performance Efficiency | performance-checks.md | Instance generation, EBS volume types, Compute Optimizer, RDS sizing |
| 5 | Cost Optimization | cost-checks.md | Anomaly Detection, idle EC2, unattached EBS, EIPs, SP/RI coverage, NAT data transfer |
| 6 | Sustainability | sustainability-checks.md | Graviton adoption, fleet utilization, Lambda runtime/architecture, S3 Intelligent-Tiering |
Execution Rules
- Top-5 service rule: After all checks finish, focus the report on the five services with the most findings, with IAM always included regardless of finding count. See pillar-assessment-guide.md.
- Sub-theme grid: Every pillar must cover four required sub-themes (e.g., Security → Identity / Data / Network / Incident); if a sub-theme has no findings, write "No findings — observed clean".
- Severity & color contract: 🔴 CRITICAL / 🟠 HIGH / 🟡 MEDIUM / 🔵 LOW / ⚪ INFO. See risk-classification.md.
- Fix Impact: Every finding must record
downtime/slowness/additionalCost/needFullTestas0/1/-1so the user can judge remediation cost. - WA BP mapping: For Security findings, include the official
SECxx.BPxxmapping (already embedded under each check heading). For other pillars, see mapping-table.md. - Error handling:
- API throttling → AWS CLI retries automatically; log and continue
- Permission denied → mark check
UNABLE_TO_ASSESS(not a finding) - Service unavailable in the region → mark
NOT_APPLICABLE - Resource type absent (no RDS, no EKS) → mark dependent checks
NOT_APPLICABLE - Never block the entire assessment for a single check failure
Per-Pillar Intermediate Output
After each pillar, emit a brief status block before moving to the next:
[SECURITY] Assessment Complete:
• Checks executed: 12 (1 SKIPPED — no permission)
• Findings: 2 CRITICAL, 4 HIGH, 6 MEDIUM, 1 LOW
• Top risk: GuardDuty disabled in ap-northeast-1---
Phase 3: Analyze (Automated)
After all pillars finish:
1. Risk consolidation — Merge findings across pillars; remove duplicates (e.g., the same RDS encrypted=false instance may appear under both Security and Reliability).
2. Risk classification — Apply risk-classification.md rules:
- HRI (High Risk Issue): any CRITICAL, or HIGH with broad blast radius (>1 service), or 3+ MEDIUM clustered in the same pillar, or any cross-pillar issue
- MRI (Medium Risk Issue): isolated HIGH findings or MEDIUM with cost/perf impact
- LRI (Low Risk Issue): LOW findings or informational recommendations
3. Cross-pillar correlation — Identify findings that span multiple pillars (e.g., missing encryption affects both Security and Reliability).
4. Priority matrix — Score every finding as Impact × (1 / FixEffort). Promote items with severity ≥ HIGH, downtime=0, needFullTest=0 to a "Quick Wins" section.
5. Roadmap allocation — Place every finding into one of three time-boxes:
- 0-30 days — CRITICAL findings, public exposure, root MFA, missing backups, missing encryption
- 1-6 months — Architectural improvements that don't require platform-level rework
- 6-24 months — Strategic / modernization work needing budget and cross-team coordination
Phase 1 must be ≤ 10 items; if more, flag the environment as "high risk — staged remediation required". See report-template.md.
---
Phase 4: Report Generation (Automated)
Generate the report in Markdown using report-template.md as the layout.
Required Report Sections
1. Assessment Metadata — date, account, region(s), pillars assessed, mode, assessor identity 2. Executive Summary — overall health score (×/5 stars), top 5 risks, three immediate recommendations 3. Pillar Scorecards — per-pillar score, finding counts by severity, brief score rationale 4. Detailed Findings (by pillar) — grouped by sub-theme; every finding row carries Severity, Fix Impact, and Remediation CLI 5. Risk Portfolio — HRI / MRI / LRI tables with cross-pillar markers 6. Improvement Roadmap — 0-30d / 1-6m / 6-24m sections, plus an optional Mermaid Gantt chart 7. Quick Wins — 5–10 paste-ready fixes for the user to run today 8. Implementation Guide — top 10 fixes with full CLI snippets 9. Appendix — full raw findings, checks marked UNABLE_TO_ASSESS / NOT_APPLICABLE
Output Files
wafr-reports/
├── wafr-assessment-{YYYY-MM-DD}.md # Full report (all sections)
├── wafr-executive-summary-{YYYY-MM-DD}.md # Sections 1-3 only, for leadership
└── wafr-assessment-{YYYY-MM-DD}.html # Optional visual HTML reportFor HTML generation:
python3 scripts/generate-html-report.py wafr-reports/wafr-assessment-{YYYY-MM-DD}.mdCost Impact (per finding)
- With `awslabs.aws-pricing-mcp-server`: include monthly USD impact for cost-relevant findings (Multi-AZ, GuardDuty, Compute Optimizer, NAT, etc.) and convert to RMB at the prevailing rate (×7.2 unless the user specifies otherwise).
- Without Pricing MCP: include qualitative descriptions (e.g., "+1 instance fee", "metered per-event").
---
Special Considerations
1. Incremental Context Loading
- SKILL.md is the entry point — lightweight router only
- This file (SKILL_EN.md) is the main instruction
- Each pillar's check file is loaded on demand from
references/programmatic-checks/ - This prevents context window overflow for large assessments
2. Error Handling
- API throttling → exponential backoff (built into AWS CLI)
- Permission denied → log as
UNABLE_TO_ASSESS(not a finding) - Service not available in region → skip with note
- Output > 50 KB from a single API → stop the call, narrow the filter (date range, max-items), or fall back to subagent-style summarization
3. Multi-Account / Multi-Region
- If the user specifies multiple accounts → run sequentially, merge reports
- If multiple regions → run each region as a separate Phase 2 pass, consolidate in Phase 3
- Always honor the user's region selection — do not silently scan other regions
4. Integration with Other Skills
- Output structured findings for
aws-resilience-modeling(deep reliability dive) - Output risk inventory for
chaos-engineering-on-aws(test plan generation) - Output architecture data for
aws-rma-assessment(maturity scoring)
5. WA Tool Sync (Optional)
If the user requests AWS Well-Architected Tool synchronization, load wa-tool-sync.md for the API workflow. This requires wellarchitected:* write permissions, which must be separate from the read-only assessment credentials. The sync flow is one-way (local report → WA Tool); it does not pull user overrides back. See the file's "AWS WA Tool API 工程细节(必读避坑)" section for 7 documented engineering pitfalls.
6. Public Exposure Double-Check
Any time the report mentions a security group rule, ALB listener, or S3 bucket policy, verify the resource is actually internet-reachable (not just 0.0.0.0/0 in a VPC-internal context) before raising it as CRITICAL.
7. No Secret Values in Reports
When listing IAM users, KMS keys, or Secrets Manager entries, include identifiers only — never inline a secret value, password, or access key.
---
Quick Start
Before starting, please have ready:
1. AWS credentials with ReadOnlyAccess (or equivalent read-only policy) 2. Target AWS Account ID and Region 3. ~30 minutes for a full 6-pillar assessment
Say "Start WA Review" or "开始架构评审" to begin.
TODO — Service Screener v2 借鉴改造计划
来源:扫描 https://github.com/aws-samples/service-screener-v2 全仓后提炼的可借鉴点。
创建日期:2026-05-25
负责:架构审阅猫
---
P0 — 立即做(核心工程细节,不抄就会踩坑)
P0-1 ✅ 给 risk-classification.md 加"修复影响"4 维度
来源:services/*/reporter.json 的 9 字段 metadata schema 动作:在 severity 表后新增 4 字段定义和评分指引
downtime: 0 / 1 / -1 (depends) — 修复是否需要停机slowness: 0 / 1 / -1 — 修复期间是否性能下降additionalCost: 0 / 1 / -1 — 修复是否产生新成本needFullTest: 0 / 1 / -1 — 是否需要全量回归测试
价值:客户 PA 决策时最关心"修这个会停机吗 / 加钱吗 / 要全量回归吗"
---
P0-2 ✅ 把 WATools.py 的 5 个工程细节抄进 wa-tool-sync.md
来源:frameworks/helper/WATools.py 动作:在 wa-tool-sync.md 加一节"AWS WA Tool API 工程细节(必读避坑)"
5 个具体细节: 1. checkIfReportExists 用 list-by-prefix 而非 get-by-id(幂等创建模式) 2. Milestone 命名 SS-{YYYYMMDDHHmmss}-{attempt},遇 ConflictException 重试 3 次 3. update_answer 的 Notes 必须截断到 2000 字符(API 上限 2048,留 buffer) 4. selectedChoices 必须 dedupe + 过滤 None(否则 ValidationException) 5. list_answers 在 workload 创建后有 ~3s 最终一致性窗口,加 ResourceNotFoundException 3 次 × 3s 重试
价值:AWS 文档里读不到,只能从踩过坑的代码里抄
---
P0-3 ✅ programmatic-checks/*.md 每个 check 加 Remediation CLI 列
来源:wa-summarizer prompt 的"每条建议必带可粘贴 CLI" 动作:6 个 pillar checks 文件的 finding 表格加一列 Remediation,给出可粘贴的修复命令(或链接到 runbook)
范围:security / reliability / cost / ops-excellence / performance / sustainability checks 注:找最高频的几个 check 先加,不必一次性全补
---
P1 — 一周内做(提升输出质量)
P1-1 ⏳ pillar-assessment-guide.md 加 "Top-N 优先 + 6 支柱 × 4 子主题 grid"
来源:wa-summarizer prompt 的 7 步分析指令
具体补充:
- Top-N 规则:审阅时聚焦发现数 Top-5 的服务,IAM 强制纳入(无论排名)
- 强制覆盖 grid:每个支柱固定 4 个子主题,避免 LLM 平均用力
- Security: Identity / Data / Network / Incident
- Reliability: Foundations / Workload Architecture / Change Mgmt / Failure Mgmt
- Operational Excellence: Organization / Prepare / Operate / Evolve
- Performance: Selection / Review / Monitoring / Trade-offs
- Cost: Practice Cloud Financial Mgmt / Cost-effective Resources / Manage Demand / Optimize Over Time
- Sustainability: Region Selection / User Behavior / SW & Arch / Data / HW & Services / Process & Culture
---
P1-2 ⏳ report-template.md 加 "0-30 / 1-6m / 6-24m" 三段路线图
来源:wa-summarizer prompt 的路线图框架 动作:在 report-template.md 行动建议章节用三个时间盒替代"短中长期"
- 0-30 天:紧急修复(HIGH severity / 公网暴露 / root MFA 等)
- 1-6 个月:架构改进(Multi-AZ / Backup Plan / 监控告警体系)
- 6-24 个月:现代化路线(Serverless 化 / 容器化 / FinOps 体系)
每条 finding 必须放进对应时间盒。
---
P1-3 ⏳ environment-bootstrap.md 加 DON'T-FETCH 列表
来源:wa-summarizer prompt 的明确 negative scope 动作:在 environment-bootstrap.md 加一节"上下文预算 — Agent 不应读取的输出"
列表(举例):
aws cloudtrail lookup-events(一次百万行,吃光窗口)aws ec2 describe-snapshots --owner-ids self(账户老的话上千条)aws s3api list-objects-v2(除非明确单 bucket 小规模)aws config get-resource-config-history(按需,限定 resource-id)- 大 Excel/JSON dump(>500KB 必须 subagent 处理)
价值:避免 Agent 平均用力把窗口吃光
---
P1-4 ⏳ Severity 颜色编码硬契约
来源:wa-summarizer prompt 的 red=H / yellow=M / blue=L 动作:在 risk-classification.md 的 severity 表加颜色列,让报告渲染一致
| Severity | Emoji/Color | 触发条件 |
|---|---|---|
| CRITICAL | 🔴 red | 公网暴露 / root MFA off / 数据未加密 / 无备份 |
| HIGH | 🟠 orange | Single-AZ prod / IAM wildcard / SG 0.0.0.0/0 非必要 |
| MEDIUM | 🟡 yellow | 缺监控 / 缺 tag / 默认 SG 在用 |
| LOW | 🔵 blue | 命名不规范 / 文档缺失 |
| INFO | ⚪ gray | 已合规的资料性事实 |
---
P2 — 值得做,可延后
P2-1 ⏳ security-checks.md 加 WA 官方 BP 编号对齐
来源:上轮已分析的 frameworks/WAFS/map.json 动作:每个检查项加 WA Mapping: SECxx.BPxx (BP 名称) 行 示例:
## SEC-01: IAM Root MFA
**WA Mapping**: SEC01.BP02 (Secure account root user and properties)价值:可无缝写进 AWS WA Tool
---
P2-2 ⏳ 新增 mapping-table.md (pillar→question→BP→check 三层映射)
来源:service-screener WAFS/map.json 的结构 动作:references/ 下新增一个 mapping-table.md,按 pillar 列出
- 完整的 Question (SEC01..SEC11 / REL01..REL11 等) 列表
- 每个 Question 下的 BP 编号 + 标题
- 每个 BP 对应的本地 check ID(SEC-01 等)
- 标记哪些 BP 是程序化覆盖、哪些靠访谈/文档评估
价值:审阅 coverage gap 显式化
---
P2-3 ⏳ 新增 remediation-runbook.md(按 finding 分类的修复脚本集合)
来源:SOC2 三件套的 Remediation Guide 动作:把 P0-3 加到 checks 里的 remediation 命令汇总到独立文件,按 pillar 组织,方便客户运维粘贴执行
---
P3 — 不做
- ❌ 不抄 Python 检查器(services//drivers/.py 的 reflection 模式) — 我们是 Agent 驱动不需要
- ❌ 不抄叙事性 best-practices.md — 比当前 markdown 检查清单倒退
- ❌ 不抄 2k 行 wa-summarizer prompt 的内嵌 ETL+HTML — 维护成本极高
- ❌ 不引入 service-screener 作为底层引擎 — 那是另一个项目,超出 skill 范围
---
进度跟踪
- [x] P0-1 risk-classification.md 加 4 字段 — 完成 2026-05-25
- [x] P0-2 wa-tool-sync.md 加 7 个工程细节 + Checklist — 完成 2026-05-25
- [x] P0-3 programmatic-checks 6 个文件 × 49 张表 × 125 行 finding 全部加 Remediation 列 — 完成 2026-05-25
- [x] P1-1 pillar-assessment-guide.md 加 Top-N + IAM 强制 + 6 支柱 × 4 子主题 grid — 完成 2026-05-25
- [x] P1-2 report-template.md 改为 0-30 / 1-6m / 6-24m 三段路线图 — 完成 2026-05-25
- [x] P1-3 environment-bootstrap.md 加 DON'T-FETCH 列表 + subagent 隔离原则 — 完成 2026-05-25
- [x] P1-4 risk-classification.md 加 severity 颜色契约(🔴🟠🟡🔵⚪) — 完成 2026-05-25
- [x] P2-1 security-checks.md 为 12 个 SEC-NN 加 WA Mapping: SECxx.BPxx — 完成 2026-05-25
- [x] P2-2 新增 mapping-table.md(pillar→question→BP→local check 三层映射 + coverage 统计) — 完成 2026-05-25
- [~] P2-3 remediation-runbook.md — 已被 P0-3 覆盖:remediation 现在 inline 在 checks 表格里,独立 runbook 不再必要。如后期需要集中运维手册可从 checks 抽取生成。
本轮改造产出文件清单
修改:
- references/risk-classification.md
- references/wa-tool-sync.md
- references/pillar-assessment-guide.md
- references/report-template.md
- references/environment-bootstrap.md
- references/programmatic-checks/security-checks.md
- references/programmatic-checks/reliability-checks.md
- references/programmatic-checks/cost-checks.md
- references/programmatic-checks/ops-excellence-checks.md
- references/programmatic-checks/performance-checks.md
- references/programmatic-checks/sustainability-checks.md
新增:
- references/mapping-table.md
- TODO.md(本文件)
辅助脚本(一次性,/tmp 下):
- /tmp/add-remediation.py
- /tmp/add-wa-mapping.py
Related skills
FAQ
What happens if my credential can write?
The skill halts and requests a read-only role; only the optional WA Tool sync flow may use write permissions, and it requires a separate named credential.
How much interaction does it need?
It runs in autopilot mode by default with minimal human interaction after the Phase 1 bootstrap.