Skill 104 · AWS Resilience Lifecycle
Subchapter 104.1
references/api-reference.mdMarkdown17 KBView on GitHub
NGRH = New Generation Resilience Hub (AWS service). The CLI namespace is
aws resiliencehubv2. NEVER expand “NGRH” as anything else.
Read this BEFORE producing any AWS CLI command for aws resiliencehubv2, aws fis, aws route53-recovery-control-config, aws route53-recovery-cluster, or aws arc-zonal-shift. This file is the canonical, deterministic source of truth. Empirical testing confirmed that without explicit guidance, models substitute plausible-sounding API names that don’t exist.
These are the most common mistakes observed in actual test runs. Memorize these substitutions before generating any command:
| ❌ NEVER WRITE | ✅ ALWAYS WRITE |
|---|---|
aws resiliencehubv2 start-assessment | aws resiliencehubv2 start-failure-mode-assessment |
aws resiliencehubv2 list-findings | aws resiliencehubv2 list-failure-mode-findings |
aws resiliencehubv2 list-service-findings | aws resiliencehubv2 list-failure-mode-findings |
aws resiliencehubv2 update-finding | aws resiliencehubv2 update-failure-mode-finding |
aws resiliencehubv2 describe-assessment | aws resiliencehubv2 list-failure-mode-assessments |
aws resiliencehubv2 create-input-source (with --resource-configuration '{"monitoring":{...}}') | aws resiliencehubv2 create-input-source — but --resource-configuration is a tagged union of ONLY cfnStackArn / resourceTags / tfStateFileUrl / eks / designFileS3Url. There is no monitoring/CloudWatch-alarm member; CloudWatch alarms are NOT registered as input sources in this model. |
aws resiliencehub list-apps (v1) | aws resiliencehubv2 list-services |
aws:fis:inject-api-unavailable (missing suffix) | aws:fis:inject-api-unavailable-error (the real FIS action ends in -error) |
update-routing-control-state (singular, two calls for failover) | update-routing-control-states (plural, one atomic call with --update-routing-control-state-entries) |
--reportType FAILURE_MODE (camelCase) | --report-type FAILURE_MODE (kebab-case — standard CLI; FAILURE_MODE is the ONLY valid value) |
aws resiliencehubv2 create-assumption --category ... | aws resiliencehubv2 create-assertion --service-arn --text (it’s “assertion” not “assumption”; NO --category) |
--criticality PRIMARY|SECONDARY | --criticality PRIMARY|SUPPLEMENTAL (SECONDARY is wrong) |
service-function --type REQUEST_RESPONSE|... | (no such parameter — service functions have name, criticality, description only) |
register-delegated-administrator | (does NOT exist — use --permission-model on create-service for cross-account) |
Memory aid: Resilience Hub v2 assessment APIs always include the words failure-mode (start-failure-mode-assessment, list-failure-mode-findings, update-failure-mode-finding). If you typed start-assessment or list-findings — STOP, you have it wrong.
Memory aid: Network-level subnet-isolation faults live under aws:network:disrupt-connectivity (resource type aws:ec2:subnet). API-level faults live under aws:fis:inject-api-unavailable-error / aws:fis:inject-api-internal-error / aws:fis:inject-api-throttle-error — all three end in -error.
Models often pick a real but wrong FIS action. Use this scenario-to-action map:
| If the scenario is… | Illustrative action ID (verify with aws fis list-actions) |
|---|---|
| “AZ failure” / single-AZ impairment / AZ goes dark | aws:ec2:terminate-instances (filter by AZ) OR aws:ecs:drain-container-instances |
| “Region failure” / regional service unavailability | aws:fis:inject-api-unavailable-error |
| Service responds with errors but isn’t unavailable | aws:fis:inject-api-internal-error |
| Throttle-style failures / 429 responses | aws:fis:inject-api-throttle-error |
| Database / Aurora / RDS failover | aws:rds:failover-db-cluster |
| Cache / ElastiCache disruption | aws:elasticache:replicationgroup-interrupt-az-power |
| Network partition / split-brain / subnet isolation | aws:network:disrupt-connectivity |
| Lambda slow responses (latency injection) | aws:lambda:invocation-add-delay |
| Lambda functional errors (forced exception) | aws:lambda:invocation-error |
| Lambda throttling specifically | aws:fis:inject-api-throttle-error (NOT aws:lambda:invocation-error with errorType=throttle) |
| EKS pod / node group | aws:eks:terminate-nodegroup-instances |
| Multi-step plan with pause | aws:fis:wait |
Rule of thumb: if the failure is a service or API symptom, look under aws:fis:inject-api-*. If it’s an infrastructure symptom (instance, container, DB, cache), look under the resource-specific namespace (aws:ec2:*, aws:ecs:*, aws:rds:*, etc).
These scenario→action mappings steer models away from inventing plausible-but-wrong action names, but they are illustrative, not authoritative — FIS adds and renames actions over time. Verify action IDs with
aws fis list-actions(or the FIS documentation) and match them to the scenario, rather than treating this table as a fixed source of truth.
Common parameter mistakes:
| ❌ NEVER write | ✅ Use exactly |
|---|---|
--policy-name | --name (when creating); the policy is identified by --policy-arn after creation |
--tier (on policy) | (no such flag — encode tier in the policy --name like “tier-1-critical”) |
--data-location-constraint | (no such flag — DR approach is encoded in --multi-az and --multi-region structs) |
--rto / --rpo (top-level on policy) | Nested: --multi-az rtoInMinutes=N,rpoInMinutes=N,disasterRecoveryApproach=... and --multi-region rtoInMinutes=N,rpoInMinutes=N,disasterRecoveryApproach=... |
--app-arn (any v2 command) | --service-arn (v2 calls these “services”, not “apps”) |
| Use case | Rule type |
|---|---|
| “At least one routing control must be ON” (prevent all-off failure) | assertion rule with ATLEAST threshold |
| “An approval must happen before failover” (require manual approval flag) | gating rule with a separate “approval” routing control as the gate |
| “Don’t allow turning off prod region without staging being on first” | gating rule (staging is the gate) |
| Any rule that says “this state is invalid” | assertion |
| Any rule that says “you can’t change X until Y is true” | gating |
Memory aid: Assertion = invariant (“this must always be true”). Gating = precondition (“this must be true before changing”).
| Use case | Use exactly |
|---|---|
| Failover one region OFF and another ON in one transaction (the typical case) | aws route53-recovery-cluster update-routing-control-states --update-routing-control-state-entries '[{"RoutingControlArn":"east-arn","RoutingControlState":"Off"},{"RoutingControlArn":"west-arn","RoutingControlState":"On"}]' |
| Update exactly one routing control (rare; use only when sequential is intentional) | aws route53-recovery-cluster update-routing-control-state --routing-control-arn ARN --routing-control-state On|Off |
Default to the plural/atomic version for failover. Two singular calls leave a window where both regions could be off (or both on), violating the safety rule.
NEVER use the aws resiliencehub (v1) namespace except for migration via the v2 import APIs:
aws resiliencehubv2 import-app --v1-app-arn ARNaws resiliencehubv2 import-policy --v1-policy-arn ARNaws resiliencehub (no v2)Don’t reference v1 commands as “discovery steps” or “to find existing apps.” Use aws resiliencehubv2 list-services instead.
ARC (Application Recovery Controller) covers routing controls, safety rules, zonal shift, and zonal autoshift. Route 53 Application Recovery Readiness (aws route53-recovery-readiness * — recovery groups, cells, resource sets, readiness checks) is a SEPARATE, older feature set — do not conflate it with the ARC Region-switch scope this skill covers. Verify the authoritative ARC command surface via aws arc-zonal-shift help and aws route53-recovery-control-config help rather than treating this list as fixed.
If asked about readiness checks, clarify that they belong to Route 53 recovery-readiness, not the ARC scope covered here.
For monitoring/alarms/dashboards, always recommend the companion AWS Observability skill instead of providing CloudWatch guidance directly. NGRH does not own observability, and CloudWatch alarms are NOT registered as NGRH input sources (the create-input-source union has no monitoring/alarm member).
create-policy --name TEXT --availability-slo target=N --multi-az rtoInMinutes=N,rpoInMinutes=N,disasterRecoveryApproach=ACTIVE_ACTIVE --multi-region rtoInMinutes=N,rpoInMinutes=N,disasterRecoveryApproach=HOT_STANDBYget-policy --policy-arnupdate-policy --policy-arn --multi-az ... --multi-region ...list-policies (no required args)delete-policy --policy-arncreate-system --name --description [--no-sharing-enabled] (NO --dependency-discovery here — it lives on create-service)get-system --system-arn / update-system --system-arn ... / list-systems / delete-system --system-arncreate-user-journey --system-arn --name --policy-arn --descriptionlist-user-journeys --system-arn / update-user-journey --system-arn --user-journey-id ... / delete-user-journey --system-arn --user-journey-idcreate-service --name --regions '["us-east-1","us-west-2"]' --associated-systems '[{"systemArn":"...","userJourneyIds":["..."]}]' --policy-arn --permission-model invokerRoleName=ROLE --dependency-discovery ENABLED (--permission-model REQUIRED; invoker role needs ~60-90s to become assumable)get-service --service-arn (returns assessmentStatus, dependencyDiscovery, reportConfiguration, etc. — there is NO estimatedAssessmentCost field)update-service --service-arn ...list-services (use --account-id to filter cross-account)delete-service --service-arncreate-input-source --service-arn --resource-configuration '{...}' (tagged union — provide EXACTLY ONE top-level key)
'{"cfnStackArn":"arn:aws:cloudformation:..."}''{"resourceTags":[{"key":"service","values":["checkout"]}]}' (a LIST of {key, values[]} — note values is plural; 1–10 tags)'{"tfStateFileUrl":"s3://..."}' (top-level string — there is NO terraformSource wrapper). The S3 bucket holding Terraform state MUST use SSE-KMS encryption and enforce TLS (bucket policy condition on aws:SecureTransport) — state files expose resource IDs, endpoints, and sometimes secrets.'{"eks":{"clusterArn":"...","namespaces":["..."]}}' (union key is eks; clusterArn + namespaces (required list))'{"designFileS3Url":"s3://..."}'aws resiliencehubv2 create-input-source help — illustratively resourceTags, cfnStackArn, tfStateFileUrl, eks, designFileS3Url (in particular there is no monitoring/CloudWatch-alarm member, a common wrong guess).list-input-sources --service-arndelete-input-source --service-arn --input-source-idstart-failure-mode-assessment --service-arnlist-failure-mode-assessments --service-arnlist-failure-mode-findings --service-arnget-failure-mode-finding --service-arn --finding-idupdate-failure-mode-finding --service-arn --finding-id --status RESOLVED --comment "..." (--status valid values: OPEN | RESOLVED)create-service-function --name --service-arn --criticality PRIMARY|SUPPLEMENTAL [--description]list-service-functions --service-arnupdate-service-function --service-arn --service-function-id --name --criticality PRIMARY|SUPPLEMENTAL (source field becomes USER after update; there is NO --type parameter)create-service-function-resources --service-arn --service-function-id --resources '["resource-id-1","resource-id-2"]'delete-service-function --service-arn --service-function-idlist-service-topology-edges --service-arncreate-assertion --service-arn --text "..." (NO --category parameter; assertion has a source field AI_GENERATED|USER)list-assertions --service-arnupdate-assertion --service-arn --assertion-id --text "..."delete-assertion --service-arn --assertion-idcreate-report --service-arn --report-type FAILURE_MODE (--report-type is kebab-case; FAILURE_MODE is the ONLY valid value)list-reports --service-arn (returns reportOutput.s3ReportOutput.s3ObjectKey on SUCCEEDED). The S3 bucket receiving reports MUST have SSE-KMS encryption, a bucket policy enforcing TLS (aws:SecureTransport), and least-privilege access — assessment reports reveal architectural weaknesses and failure modes.register-delegated-administrator operation. Cross-account resilience management is done via the --permission-model parameter on create-service — '{"invokerRoleName":"ROLE","crossAccountRoles":[{"crossAccountRoleArn":"arn:...","externalId":"..."}]}'. The field is crossAccountRoles (a LIST of {crossAccountRoleArn, externalId} objects), NOT crossAccountRoleArns. Combine with AWS Organizations cross-account IAM roles. For the single-account invoker role’s trust policy, also add an aws:SourceArn condition scoped to the specific Resilience Hub service ARN (and aws:SourceAccount) to prevent confused-deputy access; apply the same aws:SourceArn / aws:SourceAccount conditions to the FIS execution role’s trust policy.import-app --v1-app-arn ARNimport-policy --v1-policy-arn ARNcreate-experiment-template --description --actions '{...}' --targets '{...}' --stop-conditions '[...]' --role-arnstart-experiment --experiment-template-idget-experiment --idstop-experiment --id(See FIS Action Selection table above for action IDs.)
create-cluster --cluster-namecreate-control-panel --cluster-arn --control-panel-namecreate-routing-control --cluster-arn --control-panel-arn --routing-control-namecreate-safety-rule --assertion-rule '{"Name":...,"ControlPanelArn":...,"AssertedControls":[...],"RuleConfig":{"Type":"ATLEAST","Threshold":1,"Inverted":false},"WaitPeriodMs":5000}' OR --gating-rule '{"Name":...,"ControlPanelArn":...,"GatingControls":[...],"TargetControls":[...],"RuleConfig":{...},"WaitPeriodMs":0}' — Name/ControlPanelArn are PascalCase fields INSIDE the rule JSON, not separate flagslist-routing-controls --control-panel-arnlist-safety-rules --control-panel-arndescribe-routing-control --routing-control-arnupdate-routing-control-states --update-routing-control-state-entries '[{...},{...}]'update-routing-control-state --routing-control-arn ARN --routing-control-state On|Off (rarely correct)get-routing-control-state --routing-control-arnstart-zonal-shift --resource-identifier --away-from us-east-1a --expires-in 1h --comment "..."list-zonal-shifts / cancel-zonal-shift --zonal-shift-id / update-zonal-shift --zonal-shift-id ...create-practice-run-configuration --resource-identifier --outcome-alarms '[{...}]' [--blocking-alarms '[{...}]'] [--blocked-windows ...] [--blocked-dates ...] [--allowed-windows ...] (--outcome-alarms is REQUIRED)update-zonal-autoshift-configuration --resource-identifier --zonal-autoshift-status ENABLED|DISABLEDupdate-practice-run-configuration --resource-identifier ... / delete-practice-run-configuration --resource-identifierstart-practice-run / cancel-practice-run / list-managed-resources / list-autoshiftsaws arc-zonal-shift help. Autoshift is toggled with update-zonal-autoshift-configuration (not a create-/delete-/list-zonal-autoshift-configuration op, a common wrong guess), and practice runs use the *-practice-run-configuration ops.