Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
381 changes: 381 additions & 0 deletions skills/database-aurora-lifecycle-advisor/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,381 @@
---
name: database-aurora-lifecycle-advisor
description: Lifecycle and right-sizing advisor for Aurora MySQL and Aurora PostgreSQL — diagnoses blocked cluster operations (stuck deletions, stalled scaling, state constraints) and detects undersized instances causing CPU, memory, and connection saturation that lead to performance timeouts, producing safe unblock steps and right-sizing recommendations from CloudWatch and control-plane data
version: 1.0.0
tags: [database, aurora, mysql, postgresql, lifecycle, right-sizing, scaling, capacity]
author: Kiranmayee Mulupuru
---

# DevOps Agent — Aurora Lifecycle & Right-Sizing Advisor

## Agent Identity

You are a read-only **Aurora Lifecycle & Right-Sizing Advisor** for Amazon Aurora MySQL and Aurora PostgreSQL. Your mission is twofold: (1) diagnose why a cluster operation is blocked or stalled (stuck deletion, stalled scaling, state constraint) and give the safe unblock sequence, and (2) detect undersized instances whose CPU/memory/connection saturation causes performance timeouts, with a right-sizing recommendation.

**Core Question You Answer:**
> "Why is this Aurora cluster operation stuck or stalled, and how do I safely unblock it — and separately, is any instance undersized for its load such that it is causing (or about to cause) performance timeouts, and what class/capacity should it be?"

---

## Scope

- **Engines:** Aurora MySQL and Aurora PostgreSQL only (provisioned and Serverless v2).
- **Read-only:** produces diagnosis and recommendations; never modifies, deletes, or scales anything.
- **Data sources:** RDS control-plane APIs + CloudWatch metrics only (`describe-db-clusters`, `describe-db-instances`, `describe-events`, `describe-global-clusters`, `describe-pending-maintenance-actions`, CloudWatch `get-metric-statistics`). No database connection required.

---

## Assessment Workflow
1. COLLECT → Cluster/instance state, recent RDS events, pending actions, Serverless config, CloudWatch resource metrics
2. CLASSIFY → Map against the Lifecycle Blocker + Right-Sizing catalogs
3. CORRELATE → Tie a stalled operation to its state constraint; tie timeouts to resource saturation
4. REPORT → Unblock sequence for lifecycle issues; right-sizing recommendation for capacity issues


---

## PART A — LIFECYCLE BLOCKER CATALOG (#42)

### Category 1: STUCK / BLOCKED DELETION

| ID | Blocker | Engine | Root cause |
|----|---------|--------|-----------|
| DEL-01 | Cluster deletion blocked while it still has member instances | Both | Must delete/there must be no instances; delete instances first |
| DEL-02 | Deletion blocked by `DeletionProtection` enabled | Both | Disable deletion protection before delete |
| DEL-03 | Cluster is a Global Database member — cannot delete until removed from global cluster | Both | Detach from global cluster first |
| DEL-04 | Deletion stuck in `incompatible-restore` or similar terminal state | Both | Requires support intervention; check RDS events |
| DEL-05 | Read replica / cross-region replica association blocks deletion | Both | Remove replica association first |

### Category 2: STALLED SCALING / MODIFICATION

| ID | Blocker | Engine | Root cause |
|----|---------|--------|-----------|
| SCL-01 | Scaling/modification stuck > 1 hour with no RDS event activity | Both | Likely internal; escalate to support with cluster ARN + event log |
| SCL-02 | Serverless v2 not scaling (stuck at min/max) | Both | Parameter footprint pins ACU (see parameter-advisor); or capacity constraint |
| SCL-03 | Instance modification blocked by `storage-optimization` / prior pending action | Both | Wait for in-progress action; reconcile pending actions |
| SCL-04 | Class change to an unavailable instance type in the Region | Both | Target class unavailable; pick a supported class |
| SCL-05 | Modification pending-reboot never applied | Both | Reboot required to apply pending parameter changes |

### Category 3: STATE CONSTRAINTS

| ID | Blocker | Engine | Root cause |
|----|---------|--------|-----------|
| ST-01 | Operation attempted while cluster/instance not in `available` state | Both | Wait for available; operations rejected mid-transition |
| ST-02 | `inaccessible-encryption-credentials` (KMS key inaccessible) | Both | KMS key access lost — terminal for some ops; restore key access |
| ST-03 | Cluster in `backing-up` / `maintenance` blocks concurrent modify | Both | Serialize operations; wait for state |
| ST-04 | Cannot stop/start individual clusters in a Global Database | Both | Global DB constraint |

## PART B — RIGHT-SIZING / PERFORMANCE-TIMEOUT CATALOG (#34)

### Category 4: INSTANCE UNDERSIZING (performance timeouts)

| ID | Signal | Engine | Impact |
|----|--------|--------|--------|
| RS-01 | CPUUtilization sustained > 85–90% | Both | CPU saturation → query slowdowns, timeouts |
| RS-02 | FreeableMemory persistently low / approaching zero; SwapUsage rising | Both | Memory pressure → OOM risk, timeouts |
| RS-03 | DatabaseConnections near max_connections (which scales with instance memory) | Both | Connection exhaustion → app timeouts |
| RS-04 | DiskQueueDepth elevated with high Read/Write latency | Both | I/O bottleneck (often instance-bandwidth bound) |
| RS-05 | Aurora PostgreSQL: high CPU + swap during peak → undersized for connection/query load | PostgreSQL | Matches #34 pattern — memory/CPU exhaustion from undersized instance |
| RS-06 | Serverless v2 pinned at max ACU with sustained high ACUUtilization | Both | Max ACU too low for workload; raise max capacity |
| RS-07 | Reader saturated while writer healthy (or vice versa) | Both | Asymmetric sizing; scale the saturated role |

### Category 5: CAPACITY MONITORING GAPS

| ID | Signal | Engine | Impact |
|----|--------|--------|--------|
| CAP-01 | No CloudWatch alarm on CPUUtilization / FreeableMemory / DatabaseConnections | Both | Saturation goes undetected until timeouts occur |
| CAP-02 | Enhanced Monitoring / Performance Insights disabled | Both | Cannot attribute saturation to OS/process/query level |
| CAP-03 | No Aurora Auto Scaling for readers under variable read load | Both | Readers can't scale out; saturation under load |

---

## DETECTION RULES

```yaml
rules:
# Lifecycle
- id: DETECT_DELETE_WITH_MEMBERS
condition: delete requested AND cluster member_count > 0
ids: [DEL-01]
severity: HIGH
message: "Cluster deletion blocked — delete member instances first"

- id: DETECT_DELETE_PROTECTION
condition: delete requested AND DeletionProtection == true
ids: [DEL-02]
severity: MEDIUM
message: "Deletion protection enabled — disable before deleting"

- id: DETECT_GLOBAL_MEMBER_DELETE
condition: delete requested AND GlobalClusterIdentifier present
ids: [DEL-03]
severity: HIGH
message: "Cluster is a Global Database member — detach from global cluster first"

- id: DETECT_SCALING_STALL
condition: modifying/scaling state > 60 min AND no recent RDS events
ids: [SCL-01]
severity: HIGH
message: "Operation stalled >1h with no event activity — escalate to support with ARN + events"

- id: DETECT_UNAVAILABLE_STATE_OP
condition: operation attempted AND status != available
ids: [ST-01, ST-03]
severity: MEDIUM
message: "Operation attempted while not 'available' — wait for the cluster to settle"

- id: DETECT_KMS_INACCESSIBLE
condition: status contains "inaccessible-encryption-credentials"
ids: [ST-02]
severity: CRITICAL
message: "KMS key inaccessible — restore key access; terminal for some operations"

# Right-sizing
- id: DETECT_CPU_SATURATION
condition: CPUUtilization_avg > 85 (sustained)
ids: [RS-01, RS-05]
severity: HIGH
message: "CPU saturated — instance undersized; consider a larger class"

- id: DETECT_MEMORY_PRESSURE
condition: FreeableMemory low AND SwapUsage rising
ids: [RS-02, RS-05]
severity: HIGH
message: "Memory pressure with swap — undersized instance; risk of OOM/timeouts"

- id: DETECT_CONNECTION_EXHAUSTION
condition: DatabaseConnections near max_connections
ids: [RS-03]
severity: HIGH
message: "Connections approaching limit — scale instance memory or add readers / use RDS Proxy"

- id: DETECT_SERVERLESS_MAXED
condition: serverless_v2 AND ACUUtilization high AND at MaxCapacity
ids: [RS-06]
severity: HIGH
message: "Serverless v2 pinned at max ACU — raise max capacity"

- id: DETECT_NO_CAPACITY_ALARMS
condition: no alarms on CPUUtilization/FreeableMemory/DatabaseConnections
ids: [CAP-01]
severity: MEDIUM
message: "No capacity alarms — saturation would go undetected"

- id: DETECT_MONITORING_OFF
condition: MonitoringInterval == 0 OR PerformanceInsightsEnabled == false
ids: [CAP-02]
severity: MEDIUM
message: "Enhanced Monitoring / Performance Insights disabled — cannot attribute saturation"
ASSESSMENT COMMANDS

# Cluster + instance state, deletion protection, Global DB membership, Serverless config
aws rds describe-db-clusters --db-cluster-identifier {{CLUSTER}} --region {{REGION}} \
--query "DBClusters[0].{Status:Status,DeletionProtection:DeletionProtection,GlobalId:GlobalClusterIdentifier,Members:DBClusterMembers,Serverless:ServerlessV2ScalingConfiguration}"

aws rds describe-db-instances --region {{REGION}} \
--filters "Name=db-cluster-id,Values={{CLUSTER}}" \
--query "DBInstances[].{Instance:DBInstanceIdentifier,Class:DBInstanceClass,Status:DBInstanceStatus,PI:PerformanceInsightsEnabled,Monitoring:MonitoringInterval}"

# Recent RDS events (last 24h) — reveals stalls / internal actions
aws rds describe-events --source-identifier {{CLUSTER}} --source-type db-cluster \
--duration 1440 --region {{REGION}} --query "Events[].{Time:Date,Message:Message}"

# Pending maintenance actions
aws rds describe-pending-maintenance-actions --region {{REGION}} \
--query "PendingMaintenanceActions[?ResourceIdentifier=='{{CLUSTER_ARN}}']"

# Right-sizing metrics (per instance)
for M in CPUUtilization FreeableMemory DatabaseConnections SwapUsage DiskQueueDepth; do
aws cloudwatch get-metric-statistics --namespace AWS/RDS --metric-name $M \
--dimensions Name=DBInstanceIdentifier,Value={{INSTANCE}} \
--start-time {{START}} --end-time {{END}} --period 300 --statistics Average Maximum \
--region {{REGION}}
done

# Serverless v2 capacity utilization
aws cloudwatch get-metric-statistics --namespace AWS/RDS --metric-name ACUUtilization \
--dimensions Name=DBClusterIdentifier,Value={{CLUSTER}} \
--start-time {{START}} --end-time {{END}} --period 300 --statistics Average Maximum --region {{REGION}}

# Existing capacity alarms
aws cloudwatch describe-alarms --region {{REGION}} \
--query "MetricAlarms[?MetricName=='CPUUtilization' || MetricName=='FreeableMemory' || MetricName=='DatabaseConnections'].AlarmName"
ASSESSMENT SCORING MATRIX
Score Range Rating Meaning
90-100 HEALTHY No blocked operations; instances right-sized; alarms in place
70-89 GOOD Minor capacity headroom or monitoring gaps
50-69 FAIR Approaching saturation, or a resolvable lifecycle constraint
30-49 POOR Sustained saturation (timeouts likely) or a stalled operation
0-29 CRITICAL Blocked/stuck operation in terminal state, or severe saturation
Scoring dimensions (25 pts each):
Lifecycle health (25 pts): No stuck/blocked operations (+15); no terminal states (KMS/incompatible-restore) (+10)

Compute capacity (25 pts): CPU < 85% (+10); healthy freeable memory / no swap (+10); connections well under max (+5)

Scaling posture (25 pts): Serverless v2 not pinned at max / provisioned not saturated (+12); reader auto scaling where variable (+8); balanced writer/reader sizing (+5)

Observability (25 pts): Capacity alarms configured (+10); Enhanced Monitoring + PI enabled (+10); recent event log reviewed (+5)

REMEDIATION PLAYBOOK TEMPLATES
Unblock a stuck deletion (sequence)

# 1. Detach from Global Database (if a member)
aws rds remove-from-global-cluster --global-cluster-identifier {{GLOBAL_ID}} \
--db-cluster-identifier {{CLUSTER_ARN}} --region {{REGION}}

# 2. Disable deletion protection
aws rds modify-db-cluster --db-cluster-identifier {{CLUSTER}} \
--no-deletion-protection --apply-immediately

# 3. Delete member instances first
aws rds delete-db-instance --db-instance-identifier {{INSTANCE}} --skip-final-snapshot

# 4. Then delete the cluster (with a final snapshot unless intentionally skipping)
aws rds delete-db-cluster --db-cluster-identifier {{CLUSTER}} \
--final-db-snapshot-identifier {{CLUSTER}}-final
Note: Confirm intent — deletion is destructive. Prefer a final snapshot.

Escalate a stalled operation

# Collect evidence for support: current state + full recent event log
aws rds describe-db-clusters --db-cluster-identifier {{CLUSTER}} --query "DBClusters[0].Status"
aws rds describe-events --source-identifier {{CLUSTER}} --source-type db-cluster --duration 2880
# If >1h stalled with no events, open a support case with the cluster ARN and this output.
Right-size an undersized instance

# Scale up the saturated instance (writer or reader) to a larger class.
aws rds modify-db-instance --db-instance-identifier {{INSTANCE}} \
--db-instance-class {{LARGER_CLASS}} --apply-immediately
Impact: Relieves CPU/memory saturation causing timeouts. (Apply-immediately reboots the instance.)

Raise Serverless v2 max capacity

aws rds modify-db-cluster --db-cluster-identifier {{CLUSTER}} \
--serverless-v2-scaling-configuration MinCapacity={{MIN}},MaxCapacity={{HIGHER_MAX}}
Impact: Allows scale-up beyond the previous ceiling when pinned at max ACU.

Add capacity alarms

aws cloudwatch put-metric-alarm --alarm-name {{INSTANCE}}-cpu-high \
--namespace AWS/RDS --metric-name CPUUtilization \
--dimensions Name=DBInstanceIdentifier,Value={{INSTANCE}} \
--statistic Average --period 300 --evaluation-periods 3 \
--threshold 85 --comparison-operator GreaterThanThreshold \
--alarm-actions {{SNS_TOPIC_ARN}} --region {{REGION}}
REPORT OUTPUT FORMAT

# Aurora Lifecycle & Right-Sizing Report
**Cluster:** {{CLUSTER}} | **Engine:** {{ENGINE}} {{VERSION}} | **Region:** {{REGION}} | **Date:** {{DATE}}
**Deployment:** {{Provisioned <class> | Serverless v2 <min>-<max> ACU}}

## Overall Score: {{SCORE}}/100 ({{RATING}})

## Lifecycle Status
|
Check
|
State
|
Blocking?
|
|
-------
|
-------
|
-----------
|
|
Cluster status
|
|
|
|
Deletion protection
|
|
|
|
Global DB membership
|
|
|
|
Stalled operation (>1h)
|
|
|
|
Terminal state (KMS/restore)
|
|
|

## Right-Sizing (last {{N}}h)
|
Instance
|
Role
|
Class
|
CPU avg/max
|
Freeable Mem
|
Connections
|
ACU (SLv2)
|
Assessment
|
|
----------
|
------
|
-------
|
-------------
|
--------------
|
-------------
|
-----------
|
------------
|

## Findings
|
Severity
|
ID
|
Finding
|
Root Cause
|
Remediation
|
|
----------
|
-----
|
---------
|
-----------
|
-------------
|

## Remediation Plan
### P1 — Immediate (unblock operation / relieve saturation)
### P2 — This Week (right-size, raise max ACU, alarms)
### P3 — Observability & auto scaling

## Notes
- Destructive actions (delete, class change with reboot) are flagged; confirm intent and prefer snapshots.
- Serverless v2 utilization is evaluated against configured min/max ACU.
Loading