AWS CLI Cheatsheet

Quick reference for the most commonly used AWS CLI commands across EC2, S3, IAM, EKS, RDS, CloudWatch, and more.

Tip: Install or update the AWS CLI: pip install --upgrade awscli or use the official installer. Verify with aws --version.

Configure & Auth

aws configure
aws configure --profile prod
aws configure list
aws configure list-profiles
aws sts get-caller-identity
aws sts assume-role \
  --role-arn arn:aws:iam::123:role/MyRole \
  --role-session-name session1
export AWS_PROFILE=prod

EC2

aws ec2 describe-instances \
  --query 'Reservations[*].Instances[*].[InstanceId,State.Name,PrivateIpAddress]' \
  --output table
aws ec2 start-instances --instance-ids i-1234567890abcdef0
aws ec2 stop-instances --instance-ids i-1234567890abcdef0
aws ec2 describe-instance-types \
  --filters "Name=vcpu-info.default-vcpus,Values=4"
aws ec2 describe-security-groups --group-ids sg-12345678
aws ec2 create-snapshot \
  --volume-id vol-12345 --description "backup"

S3

aws s3 ls s3://my-bucket/
aws s3 cp file.txt s3://my-bucket/path/
aws s3 cp s3://my-bucket/file.txt ./
aws s3 sync ./local-dir s3://my-bucket/remote-dir/
aws s3 rm s3://my-bucket/file.txt
aws s3 rb s3://my-bucket --force
aws s3api put-bucket-versioning \
  --bucket my-bucket \
  --versioning-configuration Status=Enabled
aws s3api get-bucket-policy --bucket my-bucket

IAM

aws iam list-users --output table
aws iam get-user --user-name myuser
aws iam list-attached-user-policies --user-name myuser
aws iam list-roles
aws iam get-role --role-name MyRole
aws iam list-role-policies --role-name MyRole
aws iam create-role \
  --role-name MyRole \
  --assume-role-policy-document file://trust.json
aws iam attach-role-policy \
  --role-name MyRole \
  --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess

EKS

aws eks list-clusters
aws eks describe-cluster --name my-cluster
aws eks update-kubeconfig \
  --name my-cluster --region us-east-1
aws eks list-nodegroups --cluster-name my-cluster
aws eks update-nodegroup-version \
  --cluster-name my-cluster \
  --nodegroup-name ng-1 \
  --release-version 1.28.5-20240101

RDS

aws rds describe-db-instances \
  --query 'DBInstances[*].[DBInstanceIdentifier,DBInstanceStatus,Endpoint.Address]' \
  --output table
aws rds create-db-snapshot \
  --db-instance-identifier mydb \
  --db-snapshot-identifier mydb-snap-$(date +%Y%m%d)
aws rds restore-db-instance-from-db-snapshot \
  --db-instance-identifier mydb-restored \
  --db-snapshot-identifier mydb-snap
aws rds modify-db-instance \
  --db-instance-identifier mydb \
  --db-instance-class db.t3.large \
  --apply-immediately

CloudWatch

aws cloudwatch describe-alarms --state-value ALARM
aws cloudwatch get-metric-statistics \
  --namespace AWS/EC2 \
  --metric-name CPUUtilization \
  --dimensions Name=InstanceId,Value=i-123 \
  --start-time 2024-01-01T00:00:00Z \
  --end-time 2024-01-01T01:00:00Z \
  --period 300 --statistics Average
aws logs describe-log-groups
aws logs tail /aws/lambda/my-function --follow
aws logs filter-log-events \
  --log-group-name /aws/eks/my-cluster/cluster \
  --filter-pattern "ERROR"

Secrets Manager & SSM

aws secretsmanager list-secrets
aws secretsmanager get-secret-value \
  --secret-id my-secret
aws secretsmanager create-secret \
  --name prod/db/password \
  --secret-string "mypassword"
aws ssm get-parameter \
  --name /prod/db/password --with-decryption
aws ssm put-parameter \
  --name /prod/db/password \
  --value "newpass" \
  --type SecureString --overwrite
aws ssm start-session \
  --target i-1234567890abcdef0

Route53

aws route53 list-hosted-zones
aws route53 list-resource-record-sets \
  --hosted-zone-id Z1234567890
aws route53 change-resource-record-sets \
  --hosted-zone-id Z1234 \
  --change-batch file://changes.json

Cost & Billing

aws ce get-cost-and-usage \
  --time-period Start=2024-01-01,End=2024-02-01 \
  --granularity MONTHLY \
  --metrics BlendedCost \
  --output table
aws ce get-rightsizing-recommendation \
  --service EC2
aws budgets describe-budgets \
  --account-id 123456789012

Useful Flags

--output table|json|text|yaml
--query 'key.path'          # JMESPath filter
--region us-east-1
--profile myprofile
--no-cli-pager              # disable pager
--dry-run                   # EC2 operations
--no-verify-ssl             # skip SSL (corp proxy)

Configure & Authentication

Credentials Setup

# Interactive setup — prompts for Access Key, Secret, Region, Output format
aws configure

# Named profile
aws configure --profile prod

# View current configuration
aws configure list
aws configure list-profiles

# Environment variables (override config file)
export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
export AWS_DEFAULT_REGION=us-east-1
export AWS_PROFILE=prod

Identity & Assume Role

# Who am I?
aws sts get-caller-identity

# Assume a role and export temporary credentials
CREDS=$(aws sts assume-role \
  --role-arn arn:aws:iam::123456789012:role/MyRole \
  --role-session-name my-session \
  --query 'Credentials' --output json)

export AWS_ACCESS_KEY_ID=$(echo $CREDS | jq -r '.AccessKeyId')
export AWS_SECRET_ACCESS_KEY=$(echo $CREDS | jq -r '.SecretAccessKey')
export AWS_SESSION_TOKEN=$(echo $CREDS | jq -r '.SessionToken')

EC2

Instances

# List all instances with key fields
aws ec2 describe-instances \
  --query 'Reservations[*].Instances[*].[InstanceId,State.Name,InstanceType,PrivateIpAddress,PublicIpAddress,Tags[?Key==`Name`].Value|[0]]' \
  --output table

# Filter by state
aws ec2 describe-instances \
  --filters "Name=instance-state-name,Values=running" \
  --query 'Reservations[*].Instances[*].[InstanceId,InstanceType,PrivateIpAddress]' \
  --output table

# Start / Stop / Terminate
aws ec2 start-instances --instance-ids i-1234567890abcdef0
aws ec2 stop-instances --instance-ids i-1234567890abcdef0
aws ec2 terminate-instances --instance-ids i-1234567890abcdef0

# Reboot
aws ec2 reboot-instances --instance-ids i-1234567890abcdef0

Security Groups & Key Pairs

# List security groups
aws ec2 describe-security-groups --output table
aws ec2 describe-security-groups --group-ids sg-12345678

# Create security group
aws ec2 create-security-group \
  --group-name my-sg \
  --description "My security group" \
  --vpc-id vpc-12345678

# Add inbound rule
aws ec2 authorize-security-group-ingress \
  --group-id sg-12345678 \
  --protocol tcp --port 443 \
  --cidr 10.0.0.0/8

# Key pairs
aws ec2 describe-key-pairs
aws ec2 create-key-pair --key-name my-key --query 'KeyMaterial' --output text > my-key.pem
chmod 400 my-key.pem

Snapshots & AMIs

# Create snapshot
aws ec2 create-snapshot \
  --volume-id vol-12345678 \
  --description "Pre-upgrade backup $(date +%Y%m%d)"

# List snapshots owned by me
aws ec2 describe-snapshots --owner-ids self --output table

# Create AMI from instance
aws ec2 create-image \
  --instance-id i-1234567890abcdef0 \
  --name "my-ami-$(date +%Y%m%d)" \
  --no-reboot

# List AMIs owned by me
aws ec2 describe-images --owners self --output table

S3

Basic Operations

# List buckets / objects
aws s3 ls
aws s3 ls s3://my-bucket/
aws s3 ls s3://my-bucket/prefix/ --recursive --human-readable --summarize

# Copy
aws s3 cp file.txt s3://my-bucket/path/
aws s3 cp s3://my-bucket/file.txt ./
aws s3 cp s3://source-bucket/ s3://dest-bucket/ --recursive

# Sync (efficient incremental copy)
aws s3 sync ./local-dir s3://my-bucket/remote-dir/
aws s3 sync s3://my-bucket/remote-dir/ ./local-dir
aws s3 sync ./local-dir s3://my-bucket/ --exclude "*.tmp" --exclude ".git/*"
aws s3 sync ./local-dir s3://my-bucket/ --delete   # mirror (removes extra files)

# Delete
aws s3 rm s3://my-bucket/file.txt
aws s3 rm s3://my-bucket/prefix/ --recursive
aws s3 rb s3://my-bucket --force   # remove bucket (must be empty first without --force)

Bucket Configuration

# Enable versioning
aws s3api put-bucket-versioning \
  --bucket my-bucket \
  --versioning-configuration Status=Enabled

# Get bucket policy
aws s3api get-bucket-policy --bucket my-bucket

# Put bucket policy
aws s3api put-bucket-policy \
  --bucket my-bucket \
  --policy file://policy.json

# Block public access
aws s3api put-public-access-block \
  --bucket my-bucket \
  --public-access-block-configuration \
    "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"

# Server-side encryption
aws s3api put-bucket-encryption \
  --bucket my-bucket \
  --server-side-encryption-configuration \
    '{"Rules":[{"ApplyServerSideEncryptionByDefault":{"SSEAlgorithm":"aws:kms"}}]}'

IAM

# Users
aws iam list-users --output table
aws iam get-user --user-name myuser
aws iam list-attached-user-policies --user-name myuser
aws iam create-user --user-name myuser
aws iam delete-user --user-name myuser

# Roles
aws iam list-roles --output table
aws iam get-role --role-name MyRole
aws iam list-role-policies --role-name MyRole
aws iam list-attached-role-policies --role-name MyRole
aws iam create-role \
  --role-name MyRole \
  --assume-role-policy-document file://trust-policy.json
aws iam attach-role-policy \
  --role-name MyRole \
  --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
aws iam delete-role --role-name MyRole

# Policies
aws iam list-policies --scope Local --output table
aws iam get-policy --policy-arn arn:aws:iam::123:policy/MyPolicy
aws iam create-policy \
  --policy-name MyPolicy \
  --policy-document file://policy.json
aws iam delete-policy --policy-arn arn:aws:iam::123:policy/MyPolicy

EKS

# Clusters
aws eks list-clusters
aws eks describe-cluster --name my-cluster
aws eks update-kubeconfig --name my-cluster --region us-east-1
aws eks update-kubeconfig \
  --name my-cluster --region us-east-1 \
  --alias my-cluster-alias   # friendly context name

# Node groups
aws eks list-nodegroups --cluster-name my-cluster
aws eks describe-nodegroup \
  --cluster-name my-cluster \
  --nodegroup-name ng-1
aws eks update-nodegroup-version \
  --cluster-name my-cluster \
  --nodegroup-name ng-1 \
  --release-version 1.28.5-20240101

# Add-ons
aws eks list-addons --cluster-name my-cluster
aws eks describe-addon \
  --cluster-name my-cluster \
  --addon-name coredns
aws eks update-addon \
  --cluster-name my-cluster \
  --addon-name coredns \
  --addon-version v1.11.1-eksbuild.4

RDS

# List instances
aws rds describe-db-instances \
  --query 'DBInstances[*].[DBInstanceIdentifier,DBInstanceStatus,DBInstanceClass,Endpoint.Address,Endpoint.Port]' \
  --output table

# Snapshots
aws rds create-db-snapshot \
  --db-instance-identifier mydb \
  --db-snapshot-identifier mydb-snap-$(date +%Y%m%d)
aws rds describe-db-snapshots \
  --db-instance-identifier mydb \
  --output table
aws rds restore-db-instance-from-db-snapshot \
  --db-instance-identifier mydb-restored \
  --db-snapshot-identifier mydb-snap-20240101

# Modify instance
aws rds modify-db-instance \
  --db-instance-identifier mydb \
  --db-instance-class db.t3.large \
  --apply-immediately

# Parameter groups
aws rds describe-db-parameter-groups
aws rds modify-db-parameter-group \
  --db-parameter-group-name myparams \
  --parameters "ParameterName=max_connections,ParameterValue=200,ApplyMethod=pending-reboot"

CloudWatch & Logs

# Alarms
aws cloudwatch describe-alarms --state-value ALARM
aws cloudwatch describe-alarms --state-value OK
aws cloudwatch set-alarm-state \
  --alarm-name my-alarm \
  --state-value OK \
  --state-reason "Manual reset"

# Metrics
aws cloudwatch get-metric-statistics \
  --namespace AWS/EC2 \
  --metric-name CPUUtilization \
  --dimensions Name=InstanceId,Value=i-1234567890abcdef0 \
  --start-time 2024-01-01T00:00:00Z \
  --end-time 2024-01-01T01:00:00Z \
  --period 300 \
  --statistics Average Maximum

# Log groups & streams
aws logs describe-log-groups
aws logs describe-log-streams \
  --log-group-name /aws/eks/my-cluster/cluster

# Tail logs (real-time)
aws logs tail /aws/lambda/my-function --follow
aws logs tail /aws/eks/my-cluster/cluster --since 1h

# Filter log events
aws logs filter-log-events \
  --log-group-name /aws/eks/my-cluster/cluster \
  --filter-pattern "ERROR" \
  --start-time $(date -d '1 hour ago' +%s000)

# Insights query
aws logs start-query \
  --log-group-name /aws/lambda/my-function \
  --start-time $(date -d '1 hour ago' +%s) \
  --end-time $(date +%s) \
  --query-string 'fields @timestamp, @message | filter @message like /ERROR/ | sort @timestamp desc | limit 20'

Secrets Manager & SSM

# Secrets Manager
aws secretsmanager list-secrets
aws secretsmanager get-secret-value --secret-id my-secret
aws secretsmanager get-secret-value \
  --secret-id my-secret \
  --query SecretString --output text
aws secretsmanager create-secret \
  --name prod/db/password \
  --secret-string "mypassword"
aws secretsmanager update-secret \
  --secret-id prod/db/password \
  --secret-string "newpassword"
aws secretsmanager rotate-secret --secret-id prod/db/password
aws secretsmanager delete-secret \
  --secret-id prod/db/password \
  --recovery-window-in-days 7

# SSM Parameter Store
aws ssm get-parameter \
  --name /prod/db/password --with-decryption
aws ssm get-parameters-by-path \
  --path /prod/ --recursive --with-decryption
aws ssm put-parameter \
  --name /prod/db/password \
  --value "newpass" \
  --type SecureString --overwrite
aws ssm delete-parameter --name /prod/db/password

# SSM Session Manager (no SSH needed)
aws ssm start-session --target i-1234567890abcdef0
aws ssm start-session \
  --target i-1234567890abcdef0 \
  --document-name AWS-StartPortForwardingSession \
  --parameters '{"portNumber":["3306"],"localPortNumber":["3306"]}'

Route53

# List hosted zones
aws route53 list-hosted-zones
aws route53 list-hosted-zones-by-name \
  --dns-name example.com

# List records in a zone
aws route53 list-resource-record-sets \
  --hosted-zone-id Z1234567890ABCDEF

# Upsert DNS record (change-batch file)
aws route53 change-resource-record-sets \
  --hosted-zone-id Z1234567890ABCDEF \
  --change-batch file://changes.json

# Example changes.json
# {
#   "Changes": [{
#     "Action": "UPSERT",
#     "ResourceRecordSet": {
#       "Name": "api.example.com",
#       "Type": "A",
#       "TTL": 300,
#       "ResourceRecords": [{"Value": "1.2.3.4"}]
#     }
#   }]
# }

# Health checks
aws route53 list-health-checks
aws route53 get-health-check-status \
  --health-check-id abc123

Cost & Billing

# Monthly cost summary
aws ce get-cost-and-usage \
  --time-period Start=2024-01-01,End=2024-02-01 \
  --granularity MONTHLY \
  --metrics BlendedCost UnblendedCost \
  --output table

# Cost by service
aws ce get-cost-and-usage \
  --time-period Start=2024-01-01,End=2024-02-01 \
  --granularity MONTHLY \
  --metrics BlendedCost \
  --group-by Type=DIMENSION,Key=SERVICE \
  --output table

# Rightsizing recommendations
aws ce get-rightsizing-recommendation --service EC2

# Budgets
aws budgets describe-budgets --account-id 123456789012
aws budgets describe-budget-performance-history \
  --account-id 123456789012 \
  --budget-name my-budget
Cost Tip: Use --dry-run on EC2 operations to verify permissions without incurring charges. Always tag resources with --tag-specifications for accurate cost allocation.
Pro Tips:
  • Use --output json | jq for powerful ad-hoc filtering
  • Set AWS_PAGER="" to disable the pager globally
  • Use aws configure set cli_follow_urlparam false to prevent URL parameter auto-expansion
  • Use --no-cli-pager for scripts to avoid interactive prompts

Back to Documents  |  gcloud Cheatsheet