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 | jqfor powerful ad-hoc filtering - Set
AWS_PAGER=""to disable the pager globally - Use
aws configure set cli_follow_urlparam falseto prevent URL parameter auto-expansion - Use
--no-cli-pagerfor scripts to avoid interactive prompts