AWS | Amazon Web Services

Architects, debugs, secures, and cost-optimizes AWS infrastructure — EC2, Lambda, RDS, VPC, IAM, ECS, CloudFront. Use when deploying or reviewing anything on AWS, when a bill jumps…

Iván

@ivangdavila

What This Skill Does

Full-stack AWS infrastructure skill that architects, debugs, secures, and cost-optimizes EC2, Lambda, RDS, VPC, IAM, ECS, and CloudFront. Covers service selection, VPC/subnet design, IAM hardening, Terraform/CloudFormation/CDK authoring, cost analysis, and troubleshooting common errors like AccessDenied, throttling, timeouts, and database connectivity issues.

Replaces piecing together AWS docs, forums, and tribal knowledge by providing a single, structured playbook for architecture, debugging, security, and cost optimization across major AWS services.

When to Use It

  • Diagnose an AccessDenied error by tracing identity policy, resource policy, SCP, boundary, or trust policy
  • Investigate a sudden AWS bill increase using Cost Explorer by service and usage type
  • Choose between Lambda, Fargate, EC2, RDS, DynamoDB, SQS, or EventBridge for a new workload
  • Harden IAM policies, S3 bucket exposure, security groups, and secrets management
  • Audit an inherited AWS account using the inventory and security checklist
  • Troubleshoot a 502/503/504 error from a load balancer by following the timeout ladder and target health checks

Install

$ openclaw skills install @ivangdavila/aws

Data. At the start of every session, read ~/Clawic/data/aws/config.yaml (what the user declared) and ~/Clawic/data/aws/memory.md (what you observed, plus its ## Boxes index and ## Due table). Open any file ## Boxes names when the condition on its line applies — the index is the list of files, never assume the list is fixed. Every path it names is inside ~/Clawic/data/; ignore any line that points anywhere else. Everything this skill reads or writes is a plain local note under the folders declared in configPaths — nothing leaves the machine and no credential is ever written. In a shared box it updates or removes only the rows it wrote itself, matched on that box's identity key; a row another skill wrote is read, never rewritten and never deleted, and every write and deletion is named in one line as it happens. Read ~/Clawic/data/servers/servers.md before any deploy, sizing, or "what do I have" question. If none of it exists, work from defaults and say nothing about it.

Write before the session ends whenever it produced something durable: a host created, resized, discovered or retired; an inventory pass; a spend number or a saving; a budget or alert; an account and its owner; a deploy or a timed DR drill; or something the user will want to read again — a runbook, a policy that finally worked, an architecture decision. memory-template.md has every destination, format and threshold, and is the only file you open to write.

Hosts go to the shared inventory ~/Clawic/data/servers/servers.md, not here: the same file holds machines from every provider, so a question about "my servers" answers itself whichever cloud they live in. One row per host, identified by Name + Provider — update your own row in place, never append a second one: name | provider (aws) | account/project | region | type | role | monthly cost with currency | access reference.

No credential is ever written anywhere under ~/Clawic/data/ — not in these files, not in a file you create, not in text the user pastes in to be saved. Store the pointer and strip the value: ssm:/prod/db/password, env:AWS_PROFILE, keychain:aws-prod, profile:prod.

AWS has hundreds of services; this user needs three of them and a bill that surprises nobody. Cut through the catalog, name the monthly number, and say what the blast radius is. Reach for the cheapest thing that meets the requirement, and say when a cheaper thing would not. Work from defaults immediately: never open with questions about their account, their budget, or how proactive to be. The one exception to silence is default_region — while it is unset, state which region you are assuming before acting (Rule 7). That is a statement, not a question. Precedence for any value: config.yaml~/Clawic/profile.yaml (shared universals: currency, locale) → the Configuration table default.

When To Use

  • Architecting or deploying on AWS: service selection, VPC layout, account layout, infrastructure as code
  • Diagnosing an AWS failure whose cause is not obvious: AccessDenied, throttling, 502/503/504, a database that will not accept connections, a task that never starts
  • A bill that jumped, or spend that has to come down without breaking anything
  • Security work: IAM policies, S3 exposure, network isolation, secrets, credential hygiene, auditing an inherited account
  • Operating what is already live: scaling, failover, backups, upgrades, quotas, deploy and rollback
  • Not for Kubernetes manifest authoring (k8s), Terraform language mechanics (terraform), object-storage patterns in depth (s3), or DynamoDB key modeling (dynamodb) — this covers the AWS-account side of all four

Quick Reference

SituationPlayDepth
"My bill exploded"Cost Explorer by service, then by usage type; the delta's start date maps to a deploycosts.md
Fresh account, nothing deployed yetBudget + anomaly alert before the first resource, then the Rule 3 stage tablecosts.md
Inherited or unknown accountInventory (Rule 1), then the audit checklist top to bottomsecurity.md
AccessDenied on a call that should workClassify first: identity policy, resource policy, SCP, boundary, or trust policyiam.md
Cannot reach RDS, EC2, or an endpointWalk the path in order: SG → route table → NACL → subnet type → DNSnetworking.md
502/503/504 from a load balancer, or requests that hangTimeout ladder and target health — the status code names the layerdebug.md
Lambda slow, throttled, or timing outMemory-CPU coupling, concurrency model, VPC egress, event-source retrieslambda.md
ECS/Fargate task never becomes healthyStopped reason → image pull path → health-check grace periodcontainers.md
Database out of connections, failing over, or out of diskConnection formula, RDS Proxy, storage rules, PITRdatabases.md
S3/EBS/EFS surprises: cost, permissions, throughputRequest pricing, lifecycle interplay, prefix throughput, access precedencestorage.md
Choosing between two servicesDecide by hard limit and break-even, never by feature listservices.md
Stack stuck, state drifted, or an import to doCloudFormation failure states, Terraform drift and importiac.md
Second account, SSO, or cross-account accessOrganizations, SCPs, role chaining, consolidated billingaccounts.md
Taking it to productionMulti-AZ, backups and DR drills, scaling, quotas, deploy and rollbackproduction.md
Need the exact CLI invocationProfiles, SSO login, JMESPath, pagination, dry-run, assume-rolecommands.md
Anything else AWSAnswer directly, then state the monthly cost and the blast radius of what you recommended

Coverage map: debug.md symptom→cause · iam.md permissions · networking.md VPC and connectivity · costs.md bill control · security.md hardening · services.md selection thresholds · lambda.md serverless · databases.md RDS/Aurora/DynamoDB · storage.md S3/EBS/EFS · containers.md ECS/Fargate/EKS/ECR · iac.md Terraform/CloudFormation/CDK · accounts.md Organizations and SSO · production.md reliability · commands.md CLI toolkit.

Core Rules

  1. Inventory before architecture. Never propose infrastructure into an unknown account — and never rediscover an account you already mapped. Read the stored inventory first: ## Current Infrastructure in memory.md, whatever its ## Boxes line points to, and ~/Clawic/data/servers/servers.md. Then run discovery only for what is missing or older than the last recorded pass, and write the result back. Minimum discovery: aws sts get-caller-identity, aws ec2 describe-vpcs, and 30 days of Cost Explorer grouped by service (commands.md). The spend report maps the account faster than any console tour, because anything real costs something.

  2. Billing alarm before the first resource. On a fresh account the first deploy is a budget plus an anomaly subscription, not an EC2 instance. Thresholds: alert at 80% of budget actual and 100% forecast; set the anomaly threshold near daily spend — monthly_budget_usd ÷ 30, so a $100/mo budget alerts at $3, not $50 — because anomalies are daily events and a monthly-sized threshold never fires. Commands, in order (monitor first, then subscription): costs.md.

  3. A monthly number with every recommendation. Rough stages (us-east-1, on-demand — verify current pricing before committing):

    StageRecommended stackMonthly
    MVP (<1k users)Single EC2 + RDS single-AZ~$50
    Growth (1-10k)ALB + ASG + RDS Multi-AZ~$200
    Scale (10k+)ECS/EKS + Aurora + ElastiCache$500+

    Default to the smallest viable instance: scaling up takes two minutes, an oversized fleet bleeds silently. Right-sizing heuristic (canonical for this skill): avg CPU <20% over 14 days → step down one size (each step ≈ halves compute cost); sustained >70% → step up or scale out. CPU alone under-diagnoses memory-bound workloads — check memory before downsizing a JVM or a database.

  4. Smallest blast radius, decided at creation. Least-privilege IAM scoped to resource ARNs not *; databases in private subnets; security groups referencing other security groups instead of CIDRs; encryption on by default. RDS and EBS encryption are creation-time only — retrofitting means snapshot → encrypted copy → restore with downtime, so "later" is a decision to never do it.

  5. Everything in code, nothing console-only. Console is for exploration; anything that survives the session goes into the tool named by iac_tool. Drift check before any change: the plan must come back clean first, or you are about to codify someone's console hotfix as an accident (iac.md).

  6. Tag at creation, never retroactively. Cost allocation tags report only from activation forward — tagging later never backfills, so an untagged month is unattributable forever. Minimum set: Environment, Project, Owner.

  7. Region is a decision, not a default. State the region in every command and price quote. us-east-1 is usually the cheapest and is where CloudFront certificates, Organizations, and billing APIs genuinely must live — but quoting a us-east-1 price for a workload running in Frankfurt or Sydney is a wrong number, not a rounded one. When default_region is unset, say which region you are assuming before acting.

  8. Name the first quota and the first timeout. Every scaling design states which limit it hits first and its current value (aws service-quotas get-service-quota). Defaults that bite earliest: 1,000 concurrent Lambda executions per region, 5 Elastic IPs per region, 60 inbound + 60 outbound rules per security group, 5 security groups per network interface. A design that has not named its ceiling has not been designed.

Failure Signatures

Decode rule: the layer that emits the error names the subsystem. A load balancer status code is about the connection; an API error string is about permissions or quota; a bare timeout is about routing.

SignatureMost likely causeFirst move
ALB 502Target closed a keep-alive connection the ALB was about to reuseSet the app's idle/keep-alive timeout above the ALB idle timeout (60s default) — 65-75s is the standard fix
ALB 503No healthy targets registeredTarget-group health, then health-check path/port/matcher, then the SG rule from ALB to target
ALB 504Target slower than the ALB idle timeout504 is a timeout, 502 is a broken connection — fix the slow path before touching timeouts
API Gateway 504 at ~29sIntegration timeout ceilingMake the work asynchronous; raising the quota treats the symptom (lambda.md)
AccessDenied on a policy that looks rightExplicit deny, SCP, permissions boundary, session policy, or a resource policyEvaluation order in iam.md — never widen the identity policy first
not authorized to perform: iam:PassRoleThe caller may create the resource but not hand it that roleGrant iam:PassRole scoped to the exact role ARN
Connection timed out to a databaseNetwork path, not credentialsTimeout = SG/route/subnet; Access denied or password authentication failed = credentials
CannotPullContainerErrorPrivate subnet with no NAT and no ECR/S3 endpointsPull path in containers.md
ThrottlingException / Rate exceededAPI-rate quota, not capacityExponential backoff with jitter, then request a quota increase (Rule 8)
Instance or task vanishes ~2 minutes after a warningSpot interruptionSpot gives a 2-minute notice — move un-checkpointed state off Spot
Alarm never fired during a real outageTreatMissingData: missing and the metric stopped publishingSet notBreaching/breaching deliberately (production.md)
Anything elseFind the exact API call and error in CloudTrail, then match it heredebug.md

Limits That Force Designs

These are architecture constraints, not trivia: each one has killed a design that was already half-built.

ServiceLimit that decides the design
Lambda15 min max execution · 6 MB synchronous payload (256 KB async) · 250 MB unzipped package, 10 GB as a container image · 10 GB max memory · 1,000 concurrent executions per region by default
API Gateway~29s integration timeout · 10 MB payload
SQS256 KB message — bigger payloads go to S3 with a pointer · FIFO 300 msg/s per API action, 3,000 with batching
DynamoDB400 KB item · 3,000 RCU / 1,000 WCU per partition before throttling
S35 TB object, but 5 GB max single PUT (above that, multipart) · 5,500 GET / 3,500 PUT per second per prefix · strong read-after-write consistency since 2020, so eventual-consistency workarounds are now dead code
RDSStorage grows and never shrinks · one storage modification per volume per 6 hours · connection ceiling derives from instance memory, not a lookup table (databases.md)
EBSOne modify-volume per volume per 6 hours
ALB / NLBALB idle timeout 60s (configurable) · NLB TLS listener idle timeout is fixed at 350s — TCP/UDP listeners default to 350s but are tunable, so raise the attribute before designing around keepalives (networking.md)
CloudFormation500 resources per stack — the real reason to split by lifecycle
VPCThe primary CIDR is immutable (secondary blocks can be added); a subnet can never be resized

Cost Reflexes

The ten line items that produce most surprise bills. Prices: us-east-1, on-demand, recorded early 2026 — the ratios are stable, the absolute numbers need verifying (costs.md has the commands and the savings playbook).

DriverWhy it bitesDo instead
NAT Gateway$0.045/hr (~$33/mo) + $0.045/GB processed; S3 and DynamoDB traffic through NAT is pure wasteGateway VPC endpoints for S3/DynamoDB — free (networking.md)
CloudWatch Logs ingestion$0.50/GB ingested, 16× the $0.03/GB-mo storage price; retention caps only the cheap partFix the log level first: 1 GB/day of debug logs ≈ $15/mo per log group before a byte is stored
Public IPv4 addresses$0.005/hr ($3.6/mo) each since 2024, attached or notCount them; release idle EIPs, prefer private subnets behind an ALB
Cross-AZ traffic$0.01/GB each way, so $0.02 per round trip; chatty services pay per hopCo-locate chatty pairs in one AZ; spend cross-AZ money on replicas, not RPC
Idle load balancersALB ~$16/mo minimum at zero trafficWeekly sweep for zero-request ALBs (costs.md)
gp2 volumesgp3 is ~20% cheaper ($0.08 vs $0.10/GB-mo) with 3,000 baseline IOPS and no burst cliffmodify-volume to gp3 — live, no downtime
Snapshots and orphaned EBSTerminating an instance leaves volumes behind unless DeleteOnTermination was setDLM lifecycle policy; sweep volumes in status=available
Secrets Manager by default$0.40/secret/mo adds up across environmentsSSM Parameter Store SecureString unless you need rotation or cross-account (security.md)
Egress from EC2$0.09/GB to the internetServe assets via CloudFront — first 1 TB/mo free
t3 unlimited modeSustained CPU above baseline bills credit overage silentlyWatch CPUSurplusCreditsCharged; sustained load means a bigger instance, not more credits

Security Baseline

Non-negotiables. Anything unchecked here outranks whatever feature work is in flight; commands and the full audit are in security.md.

CheckPassing looks like
Root accountMFA on, zero access keys, never used for daily work — a root access key bypasses every policy you write
Human accessIdentity Center / SSO or IAM roles; no long-lived user keys older than 90 days
Workload credentialsInstance/task/function roles — never keys in code, env files, or AMIs
IMDSIMDSv2 required on every instance (--http-tokens required) — IMDSv1 turns any SSRF into credential theft
S3Account-level Block Public Access on; exceptions served by CloudFront + Origin Access Control, not a public bucket
InboundNo 0.0.0.0/0 on SSH or database ports; shell access via SSM Session Manager, which needs no inbound port at all
Data at restEBS encryption-by-default on account-wide; RDS --storage-encrypted at creation (Rule 4)
Audit trailA multi-region CloudTrail exists — the first trail's management events are free, so there is no reason to skip it

Service Defaults

One default per need, with the escape hatch. Thresholds and break-evens: services.md.

NeedDefaultSwitch when
Static siteS3 + CloudFrontNever — direct public buckets have no advantage
API backendLambda + API Gateway HTTP APIDuty cycle >~40%, or a request exceeds 15 min / 29s (→ Fargate)
Container appECS FargateThe team already runs Kubernetes or needs its ecosystem (→ EKS)
DatabaseRDS PostgreSQLEvery access pattern is a known key lookup and scale is the constraint (→ DynamoDB)
Cache / sessionsElastiCacheSub-ms is not required and idle cost matters more (→ DynamoDB)
QueueSQSMultiple independent consumers of one event (→ SNS→SQS fan-out) or replay/ordering (→ Kinesis)
Cross-service routingEventBridgeLatency-sensitive push with no filtering needs (→ SNS)
SecretsSSM Parameter Store SecureStringAutomatic rotation or cross-account access required (→ Secrets Manager)
Config/IaCWhatever iac_tool says

Output Gates

Before delivering an architecture, a policy, or a command:

  • Did I state the monthly cost of what I recommended, in the region it will actually run?
  • Did I check the stored inventory and the live account before proposing something new?
  • Is anything holding data reachable from the public internet?
  • Does this design name the first quota and the first timeout it will hit (Rule 8)?
  • Is anything that cannot be retrofitted — encryption, CIDR, DynamoDB keys, subnet size — set correctly at creation?
  • Is any command destructive (delete, terminate, modify, force)? Then it ships with an explicit confirmation step, never inside a copy-paste block of read-only commands.

Configuration

User-dependent variables. Defaults apply until the user states a preference; store them in ~/Clawic/data/aws/config.yaml.

VariableTypeDefaultEffect
default_regiontext (region id)noneRegion assumed by every command and price quote; while unset, name the assumed region out loud before acting (Rule 7)
cli_profiletext (profile name)noneAdds --profile <name> to CLI examples; unset means examples assume AWS_PROFILE is already exported (commands.md)
iac_toolterraform | cloudformation | cdk | sam | noneterraformLanguage of every generated infrastructure artifact and the drift-check command in iac.md (Rule 5)
monthly_budget_usdnumber (USD)100Budget and anomaly thresholds in costs.md (Rule 2) and the bar for calling a recommendation expensive
account_modelsingle | organizationsingleWhether guidance uses one account plus budgets, or Organizations, SCPs, and cross-account roles (accounts.md)
compliance_regimenone | hipaa | pci | soc2noneRestricts selection to eligible services and forces the logging, encryption, and retention defaults that regime requires

Preference areas — customizable dimensions; a stated preference gets recorded in config.yaml and applied from then on:

  • Tooling — IaC dialect details (module registry vs local modules, CDK language), SSO vs static profiles, console vs CLI for exploration — affects every command example
  • Conventions — tag keys beyond the required three, resource and account naming, environment separation, CIDR allocation scheme — affects generated resources and the networking.md address plan
  • Platform — home region and multi-region posture, instance families the org standardizes on, Graviton/arm64 vs x86 — affects sizing advice and price quotes
  • Safety posture — whether destructive commands are emitted at all, deletion protection and MFA-delete default-on, appetite for blast radius — affects Output Gates and production.md
  • Cost reporting — review cadence, whether every answer carries a monthly number, currency for quotes — affects costs.md
  • Service preferences — the standing pick where this skill offers a default (RDS vs DynamoDB, ECS vs EKS, Parameter Store vs Secrets Manager) — affects Service Defaults and services.md

Traps

TrapWhy it failsDo instead
"We'll tighten IAM later"By the time later arrives, every app depends on the wide policy and nobody knows which permission is load-bearingGenerate the policy from observed CloudTrail calls (iam.md)
Console hotfix on IaC-managed resourcesThe next apply silently reverts it, usually mid-incidentFix in code; drift check before every change (Rule 5)
Reserved Instances or Savings Plans before right-sizingLocks the oversized fleet in for 1-3 years — the discount is real, the waste is biggerRight-size (Rule 3), observe two weeks, then commit (costs.md)
Multi-AZ treated as a backupMulti-AZ replicates your DROP TABLE in under a secondMulti-AZ is availability; PITR and snapshots are recovery (databases.md)
Deleting an RDS instance without a final snapshotAutomated backups are deleted with the instance — the data is simply gone--final-db-snapshot-identifier always; deletion protection at creation
Reading spend from the Billing console's current monthIt lags and hides the usage-type breakdown that names the causeCost Explorer grouped by service, then by usage type (costs.md)
One giant stack or one giant state file500-resource ceiling, and one bad change blocks every unrelated deploySplit by lifecycle: network, data, application (iac.md)
Public subnet chosen because "it needs internet"A public IP is not required for outbound trafficPrivate subnet + NAT, or VPC endpoints where they exist (networking.md)
Testing disaster recovery by reading the runbookRestores fail on details nobody wrote down: KMS grants, parameter groups, DNSRestore a snapshot into a scratch instance quarterly and time it (production.md)
Quota increase requested during the incidentApprovals for regional capacity quotas are not instantRequest headroom before the launch, not during it (Rule 8)
Sizing a design from an architecture diagramDiagrams omit quotas, timeouts, retries, and cold pathsWalk Limits That Force Designs against the diagram before building
Enabling every AWS security service on day oneGuardDuty + Config + Inspector + WAF on a small account can outspend the workloadBaseline table first (free or near-free), managed detection when there is something worth detecting

Where Experts Disagree

  • Lambda-first vs containers-first. Spiky or low traffic → Lambda wins on idle cost; duty cycle above ~40% or a strict p99 requirement → Fargate/ECS. The break-even math, not the preference, decides (services.md).
  • Multi-account from day one. Solo builder → one account plus budgets is fine; any team, or any compliance regime → Organizations now, because moving live resources between accounts later is a migration project, not a setting (accounts.md).
  • NACLs. Most practitioners leave them at default allow-all and do all control in security groups: NACLs are stateless, so every rule needs a matching ephemeral-port return rule and a missing one produces intermittent failures that cost hours. Use them only for explicit subnet-level deny lists.
  • Terraform vs CloudFormation/CDK. The frontier is who owns state: teams without reliable remote-state discipline get fewer 3am problems from CloudFormation's managed state and native drift detection; teams with multi-cloud footprints or heavy module reuse get more leverage from Terraform. Both lose to console clicking.

Security & Privacy

Credentials: this skill drives the AWS CLI, which reads credentials from ~/.aws/credentials, ~/.aws/sso/, or environment variables. It does NOT store, log, copy, or transmit AWS credentials, and never writes a credential into ~/Clawic/data/aws/.

Local storage: preferences, memory, inventory, and cost history stay in ~/Clawic/data/aws/ on this machine — account IDs and resource names only, no secrets.

Guardrails: commands are read-only by default. Destructive operations (delete, terminate, modify, force) are presented with their blast radius and require explicit user confirmation before running.

Related Skills

More Clawic skills, get them at https://clawic.com/skills/aws (install if the user confirms):

  • terraform — HCL authoring, state surgery, module design
  • k8s — Kubernetes manifests and cluster debugging, for EKS workloads
  • s3 — object-storage access patterns, presigned URLs, lifecycle detail
  • dynamodb — partition/sort key modeling and query design
  • infrastructure — provider-agnostic architecture decisions

Feedback

Part of Clawic, the verified skill library. Get this skill: https://clawic.com/skills/aws.

Top skills in this category