AWS CLI v2 Cheatsheet: S3, EC2, IAM, Lambda and JMESPath
By DevShelfHub
Profiles, SSO, S3, EC2, IAM, Lambda, CloudFormation, ECS, logs, --query JMESPath — the AWS CLI v2 commands used daily in cloud automation and CI/CD pipelines. Covers named profiles, assume-role chaining, and the output formats needed for scripting.
121 items
◷ 9 min
Profiles
S3
IAM
Start hereQuick start · 6 you’ll reach for daily
Who am Iaws sts get-caller-identity
Switch profileexport AWS_PROFILE=prod
SSO refreshaws sso login --profile prod
Sync to S3aws s3 sync ./dist s3://bucket
Tail logsaws logs tail /aws/lambda/x --follow
Slice JSON--query 'X[?Y==`z`].Id'
Target versions · paceVersions
Targets:aws-cli ≥ 2.15SSO sessionsIMDSv2
v1 is end-of-life — aws --version must start with
aws-cli/2.. v2 ships its own Python, supports SSO,
auto-paginates by default, and prefers --profile over
--region-style flag soup. Region resolution order:
--region → AWS_REGION →
profile’s region → EC2/ECS metadata.
Long-lived access keys are a smell. Use SSO for humans, IAM roles for workloads (EC2 instance
profile, ECS task role, Lambda execution role). Static keys belong only in ~/.aws/credentials
for tools that don’t speak SSO yet.
--output · --query · --filterOutput & queries
--output json
Default. Pipe into jq.
--output yaml
Human-readable; round-trips with CloudFormation.
--output text
Tab-separated. Easy to cut/awk.
--output table
ASCII grid. Eyeball-friendly, scripting-hostile.
--query 'Reservations[].Instances[].InstanceId'
JMESPath. Project + filter client-side.
--filters Name=tag:Env,Values=prod
Server-side filter (only certain APIs).
--no-cli-pager
Print straight to stdout instead of less.
--no-paginate
Skip auto-pagination. Caps at one API page.
--max-items 100 --page-size 50
Cap total items and per-call page.
--starting-token TOKEN
Resume from a NextToken.
bash
# --query is client-side JMESPath, but skips the noise.
# one field
aws ec2 describe-instances \
--query 'Reservations[].Instances[].InstanceId'
# table of {Id, State, Type, Name-tag}
aws ec2 describe-instances \
--query 'Reservations[].Instances[].{Id:InstanceId, State:State.Name, Type:InstanceType, Name:Tags[?Key==`Name`]|[0].Value}' \
--output table
# filter by tag, then project
aws ec2 describe-instances \
--filters 'Name=tag:Env,Values=prod' \
--query 'Reservations[].Instances[?State.Name==`running`].InstanceId' \
--output text
# bucket names only
aws s3api list-buckets --query 'Buckets[].Name' --output text
cp · sync · presignS3
aws s3 ls
List buckets in current account.
aws s3 ls s3://bucket/path/ --recursive --human-readable --summarize
sync · invalidate · tailEnd-to-end · Ship a static site
Upload a built site to S3 with sane cache headers, invalidate CloudFront so the change is visible
instantly, then tail the edge function’s logs to confirm it’s healthy. Wire this into CI and
you have a single-command deploy.
bash
# end-to-end: ship a static site to S3 + invalidate CloudFront
BUCKET=my-site-prod
DIST_ID=E1ABCDXYZ12345
REGION=us-east-1
# 1) sync the build (delete removed files, set cache headers)
aws s3 sync ./dist "s3://$BUCKET" \
--delete \
--cache-control "public, max-age=31536000, immutable" \
--exclude "index.html"
# 2) re-upload index.html with a short TTL so updates roll out fast
aws s3 cp ./dist/index.html "s3://$BUCKET/index.html" \
--cache-control "public, max-age=60"
# 3) bust CloudFront edge cache
aws cloudfront create-invalidation \
--distribution-id "$DIST_ID" \
--paths "/*"
# 4) tail Lambda@Edge logs (optional)
aws logs tail "/aws/lambda/us-east-1.my-edge-fn" --since 5m --follow
Best practiceGood to know
Anchor every debug session with sts get-caller-identity.
If the answer surprises you, every command after this point is hitting the wrong account or
role. Faster than chasing a confusing 403.
Prefer --query over piping to jq for shell composition.--output text with a JMESPath projection produces clean tab/newline-separated
values that xargs and while read handle natively.
SSM Session Manager beats SSH for ad-hoc access.
No keypair, no bastion, no inbound port 22 — just aws ssm start-session and
IAM authorizes the shell. Sessions are logged to CloudTrail.
Common trapsWatch out for
v2 expects payloads as base64.aws lambda invoke --payload '{…}' errors with Invalid base64. Either
pass --cli-binary-format raw-in-base64-out or set
cli_binary_format = raw-in-base64-out in your profile.
Region defaults are sticky in subtle ways.
A profile’s region wins over AWS_REGION only if you pass
--profile. EC2 metadata wins when no profile is set. Always pass
--region explicitly in CI to remove ambiguity.
aws s3 sync --delete is one keystroke from data loss.
Reversing src/dst (or pointing at the wrong bucket) deletes everything not present locally. Dry-run with
--dryrun the first time on a new path.
AWS CLI v2 is the official command-line tool for managing AWS services. It ships as a self-contained binary with no Python runtime dependency, adds native SSO support, automatic pagination, and a built-in pager. Install it from the official AWS installer — not pip — to get the full v2 feature set.
How do I configure named profiles in the AWS CLI?
Run `aws configure --profile <name>` and enter your access key, secret key, default region, and output format. Reference the profile per command with `--profile <name>`, or export `AWS_PROFILE=<name>` to use it for the entire shell session without repeating the flag.
How does the AWS CLI --query flag work?
The `--query` flag accepts a JMESPath expression that filters or reshapes the JSON response before output. For example, `--query 'Reservations[].Instances[].InstanceId'` returns a flat list of EC2 instance IDs from the verbose `describe-instances` response.
How do I use AWS SSO with the AWS CLI?
Run `aws configure sso` to register your SSO start URL and region. The wizard creates a named profile automatically. Authenticate each session with `aws sso login --profile <name>`, which opens a browser for the SSO portal. Tokens are cached locally and expire per your IdP policy.
What is the difference between AWS CLI v1 and v2?
AWS CLI v2 ships as a standalone binary with no Python dependency, adds native SSO and credential-process support, outputs pagination hints automatically, and breaks a small number of v1 behaviours (such as how binary parameters are passed). AWS recommends v2 for all new work; v1 is in maintenance mode only.
How do I use the AWS CLI in CI/CD pipelines without hardcoded credentials?
In GitHub Actions, use the aws-actions/configure-aws-credentials action with OIDC federation — no secrets needed. The action exchanges a GitHub-issued OIDC token for temporary AWS credentials via sts:AssumeRoleWithWebIdentity. For EC2 and ECS, attach an IAM instance role or task role; the CLI automatically picks up credentials from the metadata service.