Cloud CLI15 min
AWS CLI — Comprehensive Reference Cheat Sheet
Cross-service AWS CLI reference — auth, EC2, S3, IAM, CloudFormation, Lambda, RDS, ECS, and scripting patterns every AWS admin needs.
Setup & Auth
# Install AWS CLI v2
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip && sudo ./aws/install
# Configure credentials
aws configure
# Prompts for: Access Key ID, Secret Access Key, Default region, Output format
# Named profiles
aws configure --profile prod
aws configure --profile dev
# Use a profile
aws ec2 describe-instances --profile prod
export AWS_PROFILE=prod # set for entire session
# Environment variable auth (overrides config)
export AWS_ACCESS_KEY_ID=AKIA...
export AWS_SECRET_ACCESS_KEY=...
export AWS_DEFAULT_REGION=us-east-1
# Current identity
aws sts get-caller-identity
# List profiles
aws configure list-profiles
cat ~/.aws/credentials
EC2
# Describe instances
aws ec2 describe-instances
aws ec2 describe-instances --query "Reservations[*].Instances[*].[InstanceId,State.Name,PublicIpAddress,Tags[?Key=='Name'].Value|[0]]" --output table
aws ec2 describe-instances --filters "Name=instance-state-name,Values=running" --output table
aws ec2 describe-instances --filters "Name=tag:Env,Values=production"
# Start / stop / terminate
aws ec2 start-instances --instance-ids i-0123456789abcdef0
aws ec2 stop-instances --instance-ids i-0123456789abcdef0
aws ec2 terminate-instances --instance-ids i-0123456789abcdef0
aws ec2 reboot-instances --instance-ids i-0123456789abcdef0
# Run new instance
aws ec2 run-instances \
--image-id ami-0abcdef1234567890 \
--instance-type t3.micro \
--key-name my-key \
--security-group-ids sg-12345678 \
--subnet-id subnet-12345678 \
--count 1 \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=myVM},{Key=Env,Value=prod}]'
# Key pairs
aws ec2 create-key-pair --key-name my-key --query KeyMaterial --output text > my-key.pem
chmod 400 my-key.pem
aws ec2 describe-key-pairs
# Security groups
aws ec2 describe-security-groups --output table
aws ec2 authorize-security-group-ingress --group-id sg-12345 --protocol tcp --port 80 --cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress --group-id sg-12345 --protocol tcp --port 22 --cidr 10.0.0.0/8
aws ec2 revoke-security-group-ingress --group-id sg-12345 --protocol tcp --port 80 --cidr 0.0.0.0/0
# AMIs
aws ec2 describe-images --owners amazon \
--filters "Name=name,Values=amzn2-ami-hvm-2*" "Name=state,Values=available" \
--query "Images | sort_by(@, &CreationDate)[-1].ImageId" -o text
# Volumes / snapshots
aws ec2 describe-volumes --output table
aws ec2 create-snapshot --volume-id vol-0123456789 --description "backup"
aws ec2 describe-snapshots --owner-ids self --output table
S3
# Bucket operations
aws s3 mb s3://my-unique-bucket-name
aws s3 rb s3://my-unique-bucket-name --force # force delete non-empty
aws s3 ls # list all buckets
aws s3 ls s3://my-bucket/ # list bucket contents
aws s3 ls s3://my-bucket/prefix/ --recursive
# Copy / sync
aws s3 cp file.txt s3://my-bucket/path/file.txt
aws s3 cp s3://my-bucket/file.txt ./local.txt
aws s3 cp s3://bucket1/file.txt s3://bucket2/file.txt # server-side copy
aws s3 sync ./local-dir/ s3://my-bucket/prefix/
aws s3 sync s3://my-bucket/prefix/ ./local-dir/ --delete # mirror (delete extras)
# Move / delete
aws s3 mv file.txt s3://my-bucket/
aws s3 rm s3://my-bucket/file.txt
aws s3 rm s3://my-bucket/prefix/ --recursive # delete "folder"
# Presigned URL (1 hour)
aws s3 presign s3://my-bucket/file.txt --expires-in 3600
# S3 API (more control)
aws s3api put-bucket-versioning --bucket my-bucket \
--versioning-configuration Status=Enabled
aws s3api put-public-access-block --bucket my-bucket \
--public-access-block-configuration "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"
aws s3api get-bucket-policy --bucket my-bucket
aws s3api list-object-versions --bucket my-bucket
IAM
# Users
aws iam list-users --output table
aws iam create-user --user-name alice
aws iam delete-user --user-name alice
aws iam get-user --user-name alice
# Access keys
aws iam create-access-key --user-name alice
aws iam list-access-keys --user-name alice
aws iam delete-access-key --user-name alice --access-key-id AKIA...
# Groups
aws iam create-group --group-name Developers
aws iam add-user-to-group --group-name Developers --user-name alice
aws iam remove-user-from-group --group-name Developers --user-name alice
aws iam list-groups-for-user --user-name alice
# Policies
aws iam list-policies --scope AWS --output table
aws iam attach-user-policy --user-name alice \
--policy-arn arn:aws:iam::aws:policy/ReadOnlyAccess
aws iam attach-group-policy --group-name Developers \
--policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
aws iam list-attached-user-policies --user-name alice
# Roles
aws iam list-roles --output table
aws iam get-role --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/AmazonEC2ReadOnlyAccess
CloudFormation
# Deploy / create stack
aws cloudformation deploy \
--template-file template.yaml \
--stack-name my-stack \
--parameter-overrides Env=prod InstanceType=t3.micro \
--capabilities CAPABILITY_IAM
# Create stack (direct)
aws cloudformation create-stack \
--stack-name my-stack \
--template-body file://template.yaml \
--capabilities CAPABILITY_NAMED_IAM
# Update stack
aws cloudformation update-stack \
--stack-name my-stack \
--template-body file://updated-template.yaml
# Change set (preview changes)
aws cloudformation create-change-set \
--stack-name my-stack \
--change-set-name my-changes \
--template-body file://updated-template.yaml
aws cloudformation describe-change-set --stack-name my-stack --change-set-name my-changes
aws cloudformation execute-change-set --stack-name my-stack --change-set-name my-changes
# Status / outputs
aws cloudformation describe-stacks --stack-name my-stack
aws cloudformation describe-stack-events --stack-name my-stack
aws cloudformation describe-stacks --stack-name my-stack \
--query "Stacks[0].Outputs" --output table
# Validate template
aws cloudformation validate-template --template-body file://template.yaml
# Delete stack
aws cloudformation delete-stack --stack-name my-stack
Lambda
# List functions
aws lambda list-functions --output table
# Invoke function
aws lambda invoke \
--function-name my-function \
--payload '{"key":"value"}' \
--cli-binary-format raw-in-base64-out \
response.json
cat response.json
# Deploy code (ZIP)
zip function.zip lambda_function.py
aws lambda update-function-code \
--function-name my-function \
--zip-file fileb://function.zip
# Get function config / logs
aws lambda get-function-configuration --function-name my-function
aws lambda get-function --function-name my-function
RDS
aws rds describe-db-instances --output table
aws rds start-db-instance --db-instance-identifier my-db
aws rds stop-db-instance --db-instance-identifier my-db
aws rds create-db-snapshot --db-instance-identifier my-db --db-snapshot-identifier my-snap
aws rds delete-db-snapshot --db-snapshot-identifier my-snap
Scripting Patterns
# Get running instance IDs
aws ec2 describe-instances \
--filters "Name=instance-state-name,Values=running" \
--query "Reservations[*].Instances[*].InstanceId" \
--output text
# Count instances by state
aws ec2 describe-instances \
--query "Reservations[*].Instances[*].State.Name" \
--output text | tr '\t' '\n' | sort | uniq -c
# Stop all instances in a region
aws ec2 stop-instances --instance-ids \
$(aws ec2 describe-instances --query "Reservations[*].Instances[*].InstanceId" --output text)
# Find large S3 buckets
aws s3 ls | awk '{print $3}' | while read bucket; do
size=$(aws s3 ls s3://$bucket --recursive --summarize | grep "Total Size" | awk '{print $3}')
echo "$bucket: $size bytes"
done
# Export all IAM users to CSV
aws iam list-users --query "Users[].[UserName,CreateDate,PasswordLastUsed]" --output text | tr '\t' ','
Output & Queries
# Output formats
aws ec2 describe-instances --output json # default, full
aws ec2 describe-instances --output table # human-friendly
aws ec2 describe-instances --output text # tab-separated
# JMESPath filters
--query "Reservations[*].Instances[*].InstanceId" # all IDs
--query "Reservations[0].Instances[0].PublicIpAddress" # first IP
--query "sort_by(Images, &CreationDate)[-1].ImageId" # latest AMI
--query "length(Reservations)" # count
