aws-wtf

from opsyhq/opsy

AI DevOps Agent that won't take down your production

12 stars0 forksUpdated Jan 24, 2026
npx skills add https://github.com/opsyhq/opsy --skill aws-wtf

SKILL.md

AWS WTF Skill for Opsy

Explains every charge on your AWS bill — what it is, why you're paying, and what resource caused it.

⚠️ Mandatory Output

You MUST automatically generate and save a CSV file at the end of every analysis. Do not wait for the user to ask. The analysis is incomplete until the CSV exists.

Step 1: Cost Explorer (Two Queries Required)

Run BOTH queries to detect credit coverage:

# Query 1: Normal (shows $0 if credits cover costs)
aws ce get-cost-and-usage \
  --time-period Start=$(date -v-30d +%Y-%m-%d),End=$(date +%Y-%m-%d) \
  --granularity MONTHLY \
  --metrics "UnblendedCost" "UsageQuantity" \
  --group-by Type=DIMENSION,Key=SERVICE

# Query 2: Exclude credits (shows ACTUAL usage cost)
aws ce get-cost-and-usage \
  --time-period Start=$(date -v-30d +%Y-%m-%d),End=$(date +%Y-%m-%d) \
  --granularity MONTHLY \
  --metrics "UnblendedCost" "UsageQuantity" \
  --group-by Type=DIMENSION,Key=SERVICE \
  --filter '{"Not": {"Dimensions": {"Key": "RECORD_TYPE", "Values": ["Credit", "Refund"]}}}'

Interpretation:

  • Query 1 = $0, Query 2 = $X → Credits covering $X actual usage
  • Query 1 = Query 2 = $0 → Real free tier
  • Query 1 = Query 2 = $X → Normal billing

If credits detected, warn user: "Your bill shows $0 but actual usage is $X/month. When credits run out, you WILL be charged."

Step 2: Identify ALL Regions

aws ce get-cost-and-usage \
  --time-period Start=$(date -v-30d +%Y-%m-%d),End=$(date +%Y-%m-%d) \
  --granularity MONTHLY \
  --metrics "UnblendedCost" \
  --group-by Type=DIMENSION,Key=REGION \
  --filter '{"Not": {"Dimensions": {"Key": "RECORD_TYPE", "Values": ["Credit", "Refund"]}}}'

You MUST enumerate resources in EVERY region showing charges > $0.01.

Step 3: Enumerate ALL Resources

For each region with charges, query ALL applicable services using --region $REGION:

  • aws ec2 describe-instances
  • aws ec2 describe-volumes
  • aws ec2 describe-snapshots --owner-ids self
  • aws ec2 describe-addresses
  • aws ec2 describe-nat-gateways
  • aws rds describe-db-instances
  • aws elbv2 describe-load-balancers
  • aws ecs list-clustersdescribe-clusterslist-serviceslist-tasks
  • aws eks list-clustersdescribe-cluster
  • aws lambda list-functions
  • aws s3api list-buckets (global) → get-bucket-location per bucket
  • aws ecr describe-repositories
  • aws secretsmanager list-secrets
  • aws logs describe-log-groups
  • aws kms list-keys
  • aws route53 list-hosted-zones (global)

ARN Construction

For resources without ARN in response, construct: arn:aws:{service}:{region}:{account}:{resource-type}/{id}

Examples:

  • EC2: arn:aws:ec2:us-east-1:123456789012:instance/i-abc123
  • EBS: arn:aws:ec2:us-east-1:123456789012:volume/vol-abc123
  • S3: arn:aws:s3:::bucket-name

⚠️ CRITICAL: Every Charge Must Have Identification

Every row in the CSV MUST have a resource identifier (ARN + resource_id) UNLESS it is truly untraceable.

What CAN Be Traced (MUST have ARN)

ANY charge from these services MUST be traced to a specific resource:

ServiceHas ARNExample
EC2✅ AlwaysInstance, Volume, Snapshot, EIP, NAT Gateway
S3✅ AlwaysBucket
RDS✅ AlwaysInstance
ECS/EKS✅ AlwaysCluster, Service, Task
Lambda✅ AlwaysFunction
ALB/NLB✅ AlwaysLoad Balancer
CloudWatch Logs✅ AlwaysLog Group
Secrets Manager✅ AlwaysSecret
KMS✅ AlwaysKey
ECR✅ AlwaysRepository
Route 53✅ AlwaysHosted Zone

If Cost Explorer shows charges for these but you can't find the resource → it was deleted mid-period. Put ARN as DELETED - {service} and note in description.

What CANNOT Be Traced (N/A allowed)

Only these charges are truly untraceable to a single resource:

Charge TypeWhy Untraceable
Data Transfer OutAggregated from multiple sources
Data Transfer Inter-RegionNo single source
Data Transfer Inter-AZNo single source
Support PlanAccount-level
TaxAccount-level
CloudWatch Custom Metrics (aggregated)No single dimension

For these only: use arn: N/A - Service-level charge or N/A - Account-level charge

Verification Rule

Before marking ANY charge as N/A, ask: "Is there a specific AWS resource that caused this?"

  • If YES → find it, get its ARN
  • If NO (only data transfer, support, tax) → N/A is acceptable

Elastic IP Verification

Check AssociationId before calling an IP "unattached":

  • AssociationId present → attached (even if InstanceId is empty)
  • NetworkInterfaceOwnerId = "amazon-..." → service-managed (ALB, RDS, NAT)

Public IPv4 Charges

AWS charges $0.005/hr ($3.60/mo) per public IPv4. Find all sources:

  • EC2 public IPs, Elastic IPs, internet-facing ALBs, NAT Gateways

CSV Output (Mandatory)

Filename: aws-wtf-{account-id}-{date}.csv

account_id,resourc

...
Read full content

Repository Stats

Stars12
Forks0