AWS CLI cheat sheet — 80+ commands for EC2 / S3 / IAM / Lambda / RDS / EKS / CloudFormation with real examples.
Runs locally
CategoryDeveloper & DevOps
Best forFormatting, validating, shrinking, or inspecting code-adjacent text.
144 commands
Config & STS (11)
aws configure
Interactive prompt to write AKID, secret, default region, and output format to ~/.aws/credentials and ~/.aws/config.
⚠ Common pitfall: Writes to the [default] profile. On a multi-account org use `aws configure --profile <name>` so you do not overwrite an existing key.
Examples
aws configure
aws configure --profile prod
aws configure list
aws configure sso
Set up an IAM Identity Center (SSO) profile — opens the browser to authenticate, then caches a short-lived token.
⚠ Common pitfall: Tokens expire (default 8h). When they do, every command 401s — run `aws sso login --profile <name>` again, no need to re-configure.
Examples
aws configure sso
aws sso login --profile prod-admin
aws sso logout
aws sts get-caller-identity
Print the AWS account, user/role ARN, and user ID for the current credentials. The "who am I" of AWS.
⚠ Common pitfall: Always run this BEFORE any destructive command. The two-second check has saved a thousand careers from deleting the wrong stack.
Examples
aws sts get-caller-identity
aws sts get-caller-identity --profile prod
aws sts get-caller-identity --output text --query Arn
aws sts assume-role
Assume an IAM role and return temporary credentials (access key, secret, session token) for that role.
⚠ Common pitfall: The returned creds expire (default 1h). Export all THREE — most failures are forgetting AWS_SESSION_TOKEN. Better: set source_profile + role_arn in ~/.aws/config so the CLI auto-assumes.
aws sts assume-role-with-web-identity --role-arn ... --web-identity-token $TOKEN --role-session-name ci
aws configure list-profiles
List every profile defined in ~/.aws/credentials and ~/.aws/config.
Examples
aws configure list-profiles
AWS_PROFILE=prod aws sts get-caller-identity
aws --version
Print the CLI version. Required to tell v1 from v2 — they have different defaults for pager, output, and binary payload encoding.
⚠ Common pitfall: v1 is in end-of-life. Most ops issues stem from running v1 with v2 docs. Upgrade with `pip install --upgrade awscli` (v1) or the installer (v2).
Examples
aws --version
which aws
aws configure get
Read a single config value (region, output, aws_access_key_id…) for a profile without opening the file.
Examples
aws configure get region --profile prod
aws configure get output
aws configure get aws_access_key_id --profile dev
aws configure set
Write a single config value into ~/.aws/config or ~/.aws/credentials non-interactively. Handy in setup scripts.
⚠ Common pitfall: Setting a credential key (`aws_secret_access_key`) puts the plaintext secret in ~/.aws/credentials. Prefer SSO or `assume-role` over long-lived keys.
Examples
aws configure set region ap-northeast-1 --profile prod
aws configure set output json --profile prod
aws configure set cli_pager "" --profile prod
aws sts get-session-token
Get temporary credentials for your OWN identity, typically to satisfy an MFA requirement before a sensitive call.
⚠ Common pitfall: This does NOT switch roles — it just wraps your current identity (optionally with MFA). To change permissions use `assume-role` instead.
Refresh the short-lived SSO token for a profile by re-authenticating in the browser. No re-configure needed.
⚠ Common pitfall: After the token expires every command 401s. `aws sso login` is the fix, not `aws configure sso`. Add `--no-browser` for headless boxes.
Examples
aws sso login --profile prod-admin
aws sso login --no-browser --profile ci
EC2 (22)
aws ec2 describe-instances
List EC2 instances in the current region with full state: ID, type, IP, security groups, tags, launch time.
⚠ Common pitfall: Default table output truncates wide columns. For scripting use `--output text --query` to extract specific fields. Without `--filters` you get every instance ever.
Stop running EC2 instances. EBS volumes and Elastic IPs are preserved, you stop paying for compute.
⚠ Common pitfall: You still pay for the EBS volume while stopped. To stop all billing terminate instead — but terminating deletes the volume by default.
Permanently destroy EC2 instances. The instance ID is unrecoverable, and EBS root volumes are deleted by default.
⚠ Common pitfall: Cannot be undone. Enable termination protection (`modify-instance-attribute --disable-api-termination`) on production hosts so a typo cannot nuke them.
Launch a new EC2 instance from an AMI. Specify image, type, key pair, subnet, and security group.
⚠ Common pitfall: Forgetting `--security-group-ids` lands the instance in the default SG, which usually blocks all inbound. Forgetting `--key-name` means no SSH key — you cannot log in.
Add an inbound rule to a security group — open a port to a CIDR or another SG.
⚠ Common pitfall: Opening 0.0.0.0/0 to SSH (22) or RDP (3389) shows up in your security audit within hours. Scope to your office CIDR, or use SSM Session Manager and skip SSH entirely.
Search for AMIs by owner, name pattern, or architecture. The "find an AMI ID" workhorse.
⚠ Common pitfall: Without `--owners` you scan the entire AMI marketplace and the call hangs. Use `--owners amazon` or `--owners 099720109477` (Canonical) to scope.
Reboot running EC2 instances in place. Keeps the same instance ID, private IP, and EBS volumes.
⚠ Common pitfall: A reboot is NOT a stop/start — it stays on the same host, so it will not clear an underlying-hardware problem. For that, stop then start.
Take a point-in-time snapshot of an EBS volume. Snapshots are incremental and stored in S3 under the hood.
⚠ Common pitfall: For a consistent multi-volume snapshot of a running instance use `create-snapshots` (plural) with `--instance-specification`, not one volume at a time.
List availability zones (and local/wavelength zones) in a region, with their state and zone IDs.
⚠ Common pitfall: Zone NAMES (us-east-1a) are randomized per account — `us-east-1a` in your account is not the same hardware as in another. Use zone IDs (use1-az1) to truly pin.
Add or overwrite tags on one or more EC2 resources (instances, volumes, snapshots, AMIs…).
⚠ Common pitfall: Tags drive cost allocation and IAM conditions. A typo in a `Key` silently creates a brand-new tag instead of updating — your cost report then splits.
Change an instance attribute while stopped — instance type, EBS optimization, user-data, or termination protection.
⚠ Common pitfall: Changing `--instance-type` requires the instance be STOPPED first, and the new type must be available in the same AZ. Otherwise you get IncorrectInstanceState.
List S3 buckets, or the contents of a bucket / prefix. The s3 equivalent of `ls`.
⚠ Common pitfall: Paginates silently — first 1000 keys only by default. Use `--recursive` to walk subprefixes, and `--page-size` / `--max-items` to control.
Examples
aws s3 ls
aws s3 ls s3://my-bucket/
aws s3 ls s3://my-bucket/logs/ --recursive --human-readable --summarize
aws s3 cp
Copy a file to/from/between S3. The basic upload/download primitive.
⚠ Common pitfall: Single-object only by default. Use `--recursive` for a folder, or switch to `aws s3 sync` which is incremental and faster on re-runs.
Rsync-style sync: copy only files that differ (by size and modified time). Use --delete to mirror deletions.
⚠ Common pitfall: Forgetting the source subfolder (`aws s3 sync . s3://b/ --delete`) silently nukes everything in the bucket on first run. Always dry-run with `--dryrun` first.
Move an object — equivalent to cp followed by rm at the source.
⚠ Common pitfall: If the network drops mid-transfer the source is gone but the destination is empty. For irreplaceable data prefer `cp` then verify, then `rm`.
Delete an S3 object (or a whole prefix with --recursive).
⚠ Common pitfall: On versioned buckets `rm` only adds a delete marker — the data is still there and you still pay for it. Use `aws s3api delete-object` with `--version-id` to truly purge.
Make bucket — create a new S3 bucket. Name must be globally unique across all of AWS.
⚠ Common pitfall: Bucket names are global. Pick a project-prefixed name (`lilei-2026-logs`) not a generic one (`logs`) which is taken. Outside us-east-1 you must pass `--region`.
Configure a bucket for static website hosting (index document, error document).
⚠ Common pitfall: The website endpoint is HTTP only and uses path-style URLs. For HTTPS + custom domain put CloudFront in front, or use the newer S3 + OAC pattern.
Set bucket-level Block Public Access. Belt-and-suspenders defense against accidental world-readable buckets.
⚠ Common pitfall: Account-level setting overrides bucket-level. Set both: `s3control put-public-access-block --account-id <id>` and the per-bucket one.
Attach a JSON bucket policy that controls who can read/write the bucket.
⚠ Common pitfall: A policy allowing `Principal: "*"` with `s3:GetObject` makes the bucket world-readable. Combine with Block Public Access settings or every audit fires.
Fetch only an object’s metadata (size, content-type, ETag, storage class, last-modified) without downloading the body.
⚠ Common pitfall: On a missing key it returns exit code 254 with an empty error — scripts must check `$?`, not just parse stdout, to tell "missing" from "error".
Server-side copy within S3 — change storage class, metadata, or encryption without pulling bytes to your machine.
⚠ Common pitfall: Metadata only updates if you pass `--metadata-directive REPLACE`. With the default COPY directive your new `--content-type` is silently ignored.
aws s3api copy-object --bucket b --key f --copy-source b/f --metadata-directive REPLACE --content-type application/json
aws s3api put-bucket-versioning
Turn on (or suspend) object versioning for a bucket so overwrites and deletes keep prior versions.
⚠ Common pitfall: Versioning can be Suspended but never fully turned Off once enabled. Old versions keep billing — pair with a lifecycle rule to expire noncurrent versions.
Attach lifecycle rules to a bucket — transition objects to cheaper storage classes or expire them after N days.
⚠ Common pitfall: Each call REPLACES the entire rule set, not appends. Always read the existing config first, edit the JSON, then put the whole thing back.
Set default server-side encryption (SSE-S3 / SSE-KMS) so every new object is encrypted at rest automatically.
⚠ Common pitfall: SSE-KMS adds a KMS API call per object — at high request rates you can hit the KMS throttle limit. Enable S3 Bucket Keys to cut KMS calls dramatically.
Kick off a restore of an object archived in Glacier / Glacier Deep Archive back to a temporarily retrievable copy.
⚠ Common pitfall: Restore is asynchronous and slow — Standard tier is minutes-to-hours, Deep Archive can take up to 12 hours. Poll `head-object` for the `Restore` header.
aws iam list-users --query "Users[].UserName" --output text
aws iam create-user
Create a new IAM user. No login or programmatic access by default — you add those separately.
⚠ Common pitfall: Modern practice is to skip IAM users entirely and federate through Identity Center (SSO). IAM users with long-lived access keys are a recurring breach source.
Examples
aws iam create-user --user-name lilei
aws iam create-login-profile --user-name lilei --password Temp-2026! --password-reset-required
aws iam attach-user-policy
Attach a managed policy (AWS or customer) to an IAM user.
⚠ Common pitfall: Attaching AdministratorAccess is the lazy answer. Prefer specific managed policies (PowerUserAccess, ReadOnlyAccess) and least privilege.
Examples
aws iam attach-user-policy --user-name lilei --policy-arn arn:aws:iam::aws:policy/ReadOnlyAccess
aws iam list-attached-user-policies --user-name lilei
aws iam create-access-key
Generate a new access key (AKID + secret) for an IAM user. Returned ONCE — save the secret now or it is gone.
⚠ Common pitfall: Never commit AKID/secret to git, even in a private repo. Rotate every 90 days, delete the old one. If leaked, `aws iam delete-access-key` immediately then investigate.
Examples
aws iam create-access-key --user-name lilei
aws iam delete-access-key --user-name lilei --access-key-id AKIA...
aws iam list-roles
List all IAM roles in the account.
Examples
aws iam list-roles --query "Roles[].RoleName" --output text
aws iam list-roles --path-prefix /aws-service-role/
aws iam create-role
Create an IAM role with a trust policy (the document that defines WHO can assume it).
⚠ Common pitfall: The trust policy is mandatory and the most common source of "AccessDenied" — wrong principal ARN, missing condition. Get the JSON exact.
Examples
aws iam create-role --role-name MyAppRole --assume-role-policy-document file://trust.json
aws iam attach-role-policy --role-name MyAppRole --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
aws iam simulate-principal-policy
Test whether a user/role would be allowed to perform an action against a resource — without actually trying. The IAM debugger.
Examples
aws iam simulate-principal-policy --policy-source-arn arn:aws:iam::123456789012:user/lilei --action-names s3:GetObject --resource-arns arn:aws:s3:::my-bucket/key
aws iam get-account-summary
High-level account totals — number of users, roles, MFA devices, password policy status.
Examples
aws iam get-account-summary
aws iam get-account-authorization-details
Dump the entire IAM model — every user, group, role, policy, and attachment — in one JSON blob. The audit firehose.
⚠ Common pitfall: The output is huge on real accounts. Pipe to a file and analyze with jq offline rather than scrolling the terminal.
Examples
aws iam get-account-authorization-details > iam-dump.json
aws iam get-account-authorization-details --filter Role
aws iam list-access-keys
List the access keys (IDs, status, creation date) for an IAM user. Shows nothing secret, just metadata.
⚠ Common pitfall: A user can have at most TWO keys — that two-key limit exists precisely so you can rotate: create the new one, deploy, then delete the old.
Examples
aws iam list-access-keys --user-name lilei
aws iam update-access-key --user-name lilei --access-key-id AKIA... --status Inactive
aws iam get-access-key-last-used
Show when and where an access key was last used (date, region, service). The "is this key dead?" check.
⚠ Common pitfall: A key never used in 90+ days is a prime candidate to delete. Combine with a credential report to sweep the whole account.
Examples
aws iam get-access-key-last-used --access-key-id AKIAIOSFODNN7EXAMPLE
aws iam generate-credential-report
Generate (then `get-credential-report`) a CSV of every user’s key age, MFA status, and last-used data. Audit gold.
⚠ Common pitfall: Generate is async — call `generate` first, wait for COMPLETE, then `get-credential-report` to read the base64 CSV. Reports cache for 4 hours.
Examples
aws iam generate-credential-report
aws iam get-credential-report --query Content --output text | base64 --decode
aws iam create-policy
Create a customer-managed policy from a JSON document so you can attach the same permissions to many principals.
⚠ Common pitfall: Each policy is capped at 5 versions — `create-policy-version` past that fails. Delete an old version, or set `--set-as-default` consciously.
Examples
aws iam create-policy --policy-name S3ReadMyBucket --policy-document file://policy.json
aws iam create-policy-version --policy-arn arn:aws:iam::123:policy/S3ReadMyBucket --policy-document file://v2.json --set-as-default
aws iam list-attached-role-policies
List the managed policies attached to a role. Pair with `list-role-policies` for inline policies.
⚠ Common pitfall: Managed and inline policies are separate worlds. A "missing permission" you cannot find is often hiding in an inline policy, not the attached managed ones.
Examples
aws iam list-attached-role-policies --role-name MyAppRole
aws iam list-role-policies --role-name MyAppRole
aws iam create-service-linked-role
Create the special IAM role a particular AWS service needs to act on your behalf (e.g. ECS, ELB, Auto Scaling).
⚠ Common pitfall: Most services auto-create theirs on first use. You only run this manually when a CloudFormation or Terraform deploy fails with "service-linked role does not exist yet".
Examples
aws iam create-service-linked-role --aws-service-name elasticloadbalancing.amazonaws.com
Lambda (12)
aws lambda list-functions
List all Lambda functions in the region with runtime, memory, and last-modified time.
Examples
aws lambda list-functions
aws lambda list-functions --query "Functions[?Runtime=='nodejs20.x'].FunctionName" --output text
aws lambda invoke
Synchronously invoke a Lambda function with a JSON payload and write the response to a local file.
⚠ Common pitfall: On v2 CLI you MUST pass `--cli-binary-format raw-in-base64-out` or `--payload` is base64-encoded silently and your function gets garbage.
Change Lambda configuration in place — memory, timeout, env vars, handler, layers.
⚠ Common pitfall: Setting `--environment "Variables={...}"` REPLACES all env vars, not merges. Always `get-function-configuration` first and add to the existing set.
Grant another AWS service or account permission to invoke your function — e.g. let API Gateway or S3 trigger it.
⚠ Common pitfall: Each statement needs a unique `--statement-id`. Re-running with the same SID throws ResourceConflictException — `remove-permission` first or use a fresh SID.
Wire a stream/queue source (SQS, Kinesis, DynamoDB Streams, Kafka) to poll-trigger your function.
⚠ Common pitfall: For SQS, set `--batch-size` and `--maximum-batching-window-in-seconds` together. Too large a batch with a short function timeout silently drops throughput.
Get everything about a function: configuration plus a presigned URL to download the deployed code package.
⚠ Common pitfall: The Code.Location URL is presigned and expires in ~10 minutes — download right away, do not stash it for later.
Examples
aws lambda get-function --function-name my-fn
aws lambda get-function --function-name my-fn --query Code.Location --output text
aws lambda put-function-concurrency
Reserve (or cap) concurrent executions for a function so it cannot starve — or overwhelm — the rest of the account.
⚠ Common pitfall: Reserving concurrency for one function REMOVES it from the account-wide unreserved pool. Over-reserve and other functions start throttling.
Pre-warm a fixed number of execution environments for an alias/version to eliminate cold starts on latency-critical paths.
⚠ Common pitfall: Provisioned concurrency bills even when idle, and only attaches to a VERSION or ALIAS, never $LATEST. Forgetting that is the usual "why is it still cold" cause.
Fetch raw metric data points for a namespace/metric/dimension over a time window with a chosen aggregation.
⚠ Common pitfall: Use UTC for `--start-time` and `--end-time`. ISO-8601 only — passing a Unix timestamp silently errors. Period must be a multiple of 60s.
Tail a CloudWatch Logs group like `tail -f`, with optional regex filter and --follow for live streams.
⚠ Common pitfall: Tailing is throttled to ~10 log streams concurrently. For very busy groups use `--log-stream-name-prefix` or switch to Logs Insights.
Discover which metrics actually exist for a namespace/dimension before you try to graph or alarm on them.
⚠ Common pitfall: list-metrics only shows metrics that have reported data in the last ~2 weeks. A brand-new resource may not appear yet even though it is configured.
The modern, batched metric query — pull many metrics with math expressions in one call. Replaces get-metric-statistics at scale.
⚠ Common pitfall: Uses a JSON `--metric-data-queries` structure, not flat flags. Each query needs a unique `Id` matching `^[a-z][a-zA-Z0-9_]*$` — uppercase-first Ids are rejected.
Manually force an alarm into ALARM/OK/INSUFFICIENT_DATA — great for testing that your SNS/paging wiring actually fires.
⚠ Common pitfall: The forced state is temporary — the next real evaluation overwrites it. Use it to test the notification path, not as a permanent override.
Take a manual snapshot of an RDS instance. Manual snapshots persist until you delete them.
⚠ Common pitfall: Snapshots are not portable across accounts by default — must `share-db-snapshot` first. And storage cost applies forever; clean up old ones.
⚠ Common pitfall: Without `--apply-immediately` changes wait for the maintenance window. Common surprise — "I changed the password and it did not take effect".
List Aurora / Multi-AZ DB clusters with their writer and reader endpoints, engine version, and status.
⚠ Common pitfall: Aurora has SEPARATE cluster and reader endpoints. Pointing all traffic at the cluster (writer) endpoint wastes your read replicas entirely.
Trigger a controlled failover in an Aurora cluster, optionally promoting a specific reader to writer.
⚠ Common pitfall: Failover drops all existing DB connections — there is a brief outage. Run it in a maintenance window unless you are actively testing resilience.
Update an EKS addon version (VPC CNI, CoreDNS, kube-proxy, EBS CSI). Specify --resolve-conflicts to handle field ownership.
⚠ Common pitfall: Without `--resolve-conflicts OVERWRITE` (or PRESERVE) the update aborts if you previously kubectl-edited the addon. Pick one consciously.
Roll a managed node group to a newer AMI / Kubernetes version, draining and replacing nodes gracefully.
⚠ Common pitfall: Without PodDisruptionBudgets your workloads can all evict at once mid-roll. Set PDBs before upgrading, or `--force` will honor nothing.
High-level deploy that creates the stack if missing or updates it if present. Computes the changeset for you.
⚠ Common pitfall: Without `--capabilities CAPABILITY_NAMED_IAM` any template that creates IAM resources fails with "Requires capabilities" — most stacks need this.
Stream the event log for a stack. The "why did my deploy fail" view.
⚠ Common pitfall: Events are reverse-chronological. The FIRST failure is the root cause and is buried at the bottom — scroll all the way down or pipe through `tac`.
Delete a CloudFormation stack and all the resources it created.
⚠ Common pitfall: Buckets with objects, log groups with retention=Never, RDS without skip-snapshot — these can stall the delete. Check `describe-stack-events` for which resource is wedged.
Detect whether live resources have drifted from what the stack template declares — someone clicked in the console again.
⚠ Common pitfall: Drift detection is async: `detect-stack-drift` returns an id, then poll `describe-stack-drift-detection-status` and `describe-stack-resource-drifts`.
Abort an in-progress stack UPDATE and roll back to the last known-good state.
⚠ Common pitfall: Only works while status is UPDATE_IN_PROGRESS. If it has already moved to UPDATE_ROLLBACK_FAILED you must `continue-update-rollback` instead.
Create, update, or delete DNS records via a JSON change batch. The only way to script DNS changes.
⚠ Common pitfall: A DELETE must match the existing record EXACTLY — same value, same TTL. Mismatch and you get InvalidChangeBatch. Always list-resource-record-sets first to copy the exact JSON.
Ask Route 53 what answer it WOULD return for a name/type from a given resolver IP — without changing your real DNS.
⚠ Common pitfall: This queries the authoritative zone directly, bypassing all resolver and TTL caching. It is the truth, but not what an end user with a cached record sees.
Examples
aws route53 test-dns-answer --hosted-zone-id Z1234567890ABC --record-name www.example.com --record-type A
aws route53domains list-domains
List domain names registered through Route 53 Domains, with expiry dates and auto-renew status.
⚠ Common pitfall: Route 53 Domains is a global service — the API only answers in us-east-1. Add `--region us-east-1` or it fails to connect.
Without `--profile <name>` (or AWS_PROFILE env var), the CLI uses `[default]`. On multi-account orgs this is almost always the wrong account. Set AWS_PROFILE in your shell, or alias commands per project.
⚠ Common pitfall: A typo like `--profile=prod` (with =) sometimes works, sometimes does not depending on CLI version. Stick to `--profile prod` (space-separated).
Examples
export AWS_PROFILE=prod
aws s3 ls --profile dev
alias awsp="aws --profile prod"
--region default empty
If neither `--region`, AWS_REGION, AWS_DEFAULT_REGION, nor profile region is set, you get "You must specify a region" or a confusing "Could not connect" error.
⚠ Common pitfall: Different services live in different regions. Setting a default in `~/.aws/config` per profile is the most maintainable.
Examples
aws configure set region us-east-1 --profile prod
export AWS_REGION=ap-northeast-1
aws s3 ls --region eu-west-1
pagination truncates output
AWS APIs paginate. The CLI auto-paginates by default but if AWS_PAGER is set to "" or you pass --no-paginate you only see page 1. `aws s3 ls` paginates at 1000 keys.
json is for piping into jq. text is tab-separated and ideal for shell loops (`for i in $(aws ... --output text)`). table is for humans and truncates wide columns. Set the default in `~/.aws/config`.
Examples
aws ec2 describe-instances --output text --query "Reservations[].Instances[].InstanceId"
aws s3api list-buckets --query "Buckets[?starts_with(Name, 'logs-')].Name" --output text
--dry-run is EC2-only
Many people assume every AWS service supports `--dry-run`. It does NOT — only most EC2 mutate operations do. Returns DryRunOperation on success. For other services, simulate via `iam simulate-principal-policy` or `cloudformation deploy --no-execute-changeset`.
aws cloudformation deploy --template-file t.yaml --stack-name s --no-execute-changeset
S3 eventual consistency
Since 2020 S3 reads-after-writes are strongly consistent globally. The OLD eventual-consistency trap (PUT then LIST does not see the new key) is gone. But cross-region replication, CloudFront caches, and versioning are still eventually consistent.
Examples
aws s3 cp file s3://b/key && aws s3 ls s3://b/key
aws s3api put-object --bucket b --key k --body file
AKID leaked to git
If an access key ends up in git history, GitHub bots scan and abuse it within minutes — bitcoin miners spin up across every region. Immediately `iam delete-access-key`, audit CloudTrail for the past 24h, rotate every secret in the same account.
⚠ Common pitfall: Rewriting git history does NOT help — the key is already cached and scraped. Delete the key first, history cleanup is cosmetic.
Examples
aws iam delete-access-key --user-name lilei --access-key-id AKIA...
IAM, Route 53, CloudFront, WAF (global), and Organizations are global but their CLI endpoint is us-east-1. Commands that "cannot connect" or return empty in another region almost always need `--region us-east-1`.
On bulk calls AWS returns ThrottlingException / RequestLimitExceeded. The CLI retries with backoff, but loops calling it per-item will still get rate-limited. Raise `--cli-read-timeout`, set `AWS_MAX_ATTEMPTS`, or use server-side batch APIs.
aws configure set retry_mode adaptive --profile prod
fileb:// vs file:// for binaries
Use `file://` for text (JSON policies, templates) and `fileb://` for BINARY (a Lambda zip, an image). Passing a zip with `file://` corrupts it because the CLI treats it as UTF-8 text.
aws iam create-policy --policy-name P --policy-document file://policy.json
AWS_PAGER opens less and hangs
CLI v2 pipes long output through your pager (less) by default. In scripts and CI this looks like the command "hangs" waiting for a keypress. Set `AWS_PAGER=""` globally or per command.
Examples
export AWS_PAGER=""
AWS_PAGER="" aws ec2 describe-instances
aws configure set cli_pager "" --profile prod
clock skew breaks signatures
AWS rejects requests whose signature timestamp is more than ~5 minutes off server time with "Signature expired" or "InvalidSignatureException". If every command suddenly fails auth, check your system clock / NTP first.
Examples
date -u
sudo chronyc makestep
endpoint-url for LocalStack / VPC endpoints
Point the CLI at a non-default endpoint with `--endpoint-url` — for LocalStack testing, an S3-compatible store, or a private VPC endpoint. Without it you hit the real public AWS endpoint and may bill or fail.
Examples
aws --endpoint-url http://localhost:4566 s3 ls
aws --endpoint-url https://bucket.vpce-xxx.s3.us-east-1.vpce.amazonaws.com s3 cp f s3://b/f
What this tool does
Searchable AWS CLI cheat sheet covering the 80+ commands cloud
engineers, SREs, and DevOps actually run on a real AWS account —
not the marketing-page list. Eleven service groups: config
(configure, sso login, sts get-caller-identity, sts assume-role),
EC2 (describe-instances, run-instances, start/stop/terminate,
describe-security-groups, authorize-security-group-ingress, key
pairs), S3 (ls, cp, sync, mv, rm, mb, rb, presign, website, plus
the s3api low-level escape hatch), IAM (list-users, create-user,
attach-policy, list-roles, create-role, simulate-principal-policy),
Lambda (list-functions, invoke, update-function-code,
get-function-configuration, publish-version, create-alias),
CloudWatch (get-metric-statistics, put-metric-alarm,
describe-alarms, logs tail, logs filter-log-events), RDS
(describe-db-instances, create-db-snapshot,
restore-db-instance-from-db-snapshot, modify-db-instance), EKS
(update-kubeconfig, describe-cluster, list-nodegroups,
describe-nodegroup, update-addon), CloudFormation (deploy,
describe-stacks, describe-stack-events, delete-stack, package),
Route53 (list-hosted-zones, change-resource-record-sets,
list-resource-record-sets), and a pitfall section fixing the
eight things that actually waste your afternoon: --profile vs
default, --region default empty, pagination cutting output to
1000, --output json/table/text, --query JMESPath vs jq, --dry-run
on EC2 only, S3 eventual consistency, and AKID leaked to git.
Every entry has full syntax, bilingual EN/ZH description, the
real-world trap, and 1-3 copy-ready examples with realistic
ARNs and instance IDs. Search across command + description +
pitfall + example — type "AKID" and the leak entry surfaces.
Pure client-side, no AWS account connected. Pair with our
kubectl, Docker, nginx, and curl cheat sheets.
Tool details
Input
Text
The page exposes text boxes, numeric controls, file pickers, or structured inputs depending on the tool.
Output
Live result + Copy + Preview
The result area focuses on usable output, with copy, download, or preview actions when supported.
Privacy
Browser-side processing
The main tool logic does not call an external API, so inputs normally stay in the current tab.
Save / share
Shareable URL state
Key settings are encoded in the URL so another person can reopen the same setup.
Performance budget
Initial JS <= 30 KB
No WASM budget is declared, keeping the tool quick to open on mobile.
Best fit
Developer & DevOps · Developer
Category and role tags drive related tools, internal links, and quick fit checks.
How to use
1
1. Input
Paste or drop your content into the tool panel.
2
2. Process
Click the button. All processing is local in your browser.
3
3. Copy / Download
Copy the result or download to disk in one click.
How AWS CLI Cheatsheet fits into your work
Use it in the small gaps between coding, reviewing, debugging, and shipping.
Developer jobs
Formatting, validating, shrinking, or inspecting code-adjacent text.
Preparing snippets for documentation, tickets, commits, or handoff.
Checking a small payload quickly without switching tools.
Developer checks
Run irreversible transforms like minify or obfuscate on a copy.
Keep secrets out of pasted snippets unless the tool explicitly stays local.
Use your normal tests or linter before shipping transformed code.
Good next steps
These links move the current task into a more complete workflow.
Deploy a static site to S3 + CloudFront without nuking the bucket
You ship a Next.js export to s3://acme-www and need the right sync
line. The sheet hands you `aws s3 sync ./out s3://acme-www --delete`
plus the CloudFront invalidation `aws cloudfront create-invalidation
--distribution-id E2QWXYZ --paths "/*"`. The pinned-source warning
saves you from the `sync . --delete` that wipes the whole bucket on a
forgotten subfolder.
Find which account you are actually in before a destructive run
On a 9-account org you are about to run `terminate-instances` and the
shell prompt does not say which profile is live. You grab `aws sts
get-caller-identity --profile prod` from the config group, read the
Account 4179... and Arn, confirm it is prod not staging, then run with
the same `--profile prod`. Thirty seconds that stops a wrong-account
delete.
Tail a Lambda's logs while reproducing a 502 in staging
A checkout Lambda throws intermittently. You copy `aws logs tail
/aws/lambda/checkout-fn --follow --since 5m --profile staging`, replay
the failing cart, and watch the stack trace stream live. The sheet
also gives `aws lambda invoke --function-name checkout-fn --payload
file://event.json out.json` so you can fire a deterministic test event
instead of clicking the UI.
Snapshot an RDS instance before a risky schema migration
Before an ALTER TABLE on a 40GB Postgres prod DB, you want a rollback
point. You copy `aws rds create-db-snapshot --db-instance-identifier
acme-prod --db-snapshot-identifier acme-prod-pre-migrate-2026-05-30`,
wait for available, then run the migration. If it goes wrong, the
restore line is one search away. No console clicking under pressure.
Common pitfalls
Forgetting `--profile` on a multi-account org silently hits the default profile. Pin it on every write, e.g. `aws ec2 terminate-instances --instance-ids i-0abc --profile prod`.
Treating `--query` like jq. It is JMESPath, so `.Reservations[0]` becomes `Reservations[0]` and pipe is `|`, not `| jq`. Test on a read before scripting it.
Running `aws s3 sync . s3://bucket --delete` from the wrong directory wipes the bucket. Pin the source to a real subfolder and add `--dryrun` on the first run.
Privacy
This cheat sheet is a single static page. Search runs entirely in your browser against an in-memory command array. It never prompts for credentials, loads no AWS SDK, and makes zero API calls. Your search terms stay local and never enter the URL, so nothing is shared when you copy the page link.
FAQ
Related tools
Hand-picked utilities that pair well with this one.