AWS CLI Like a Pro — 30 Commands That Replace Console Clicking
Every time you click through the AWS console to check an instance's status, you waste 30 seconds. Do that 20 times a day and you've lost 2.5 hours per week. The CLI is faster, scriptable, and gives you a history of exactly what you did. Here are 30 commands that will change how you work with AWS.
Setup and Configuration
Before anything else, configure your CLI properly:
# Configure a named profile
aws configure --profile production
# AWS Access Key ID: AKIA...
# AWS Secret Access Key: ****
# Default region: us-east-1
# Default output format: json
# Set default profile for the session
export AWS_PROFILE=production
export AWS_DEFAULT_REGION=us-east-1
# Verify your identity
aws sts get-caller-identity
Pro tip: Use named profiles for different accounts/environments. Never hardcode credentials in scripts.
Output Formats
The CLI supports three output formats. Use the right one for the job:
| Format | Flag | Best For |
|---|---|---|
| JSON | --output json | Scripts, piping to jq, complete data |
| Table | --output table | Human-readable terminal output |
| Text | --output text | Simple values, shell variable assignment |
EC2 Commands (1-8)
# 1. List all running instances with name and IP
aws ec2 describe-instances \
--filters "Name=instance-state-name,Values=running" \
--query 'Reservations[*].Instances[*].[Tags[?Key==`Name`].Value|[0],InstanceId,InstanceType,PrivateIpAddress,PublicIpAddress]' \
--output table
# 2. Start/stop an instance
aws ec2 start-instances --instance-ids i-0abc123def456
aws ec2 stop-instances --instance-ids i-0abc123def456
# 3. Get instance status checks
aws ec2 describe-instance-status \
--instance-ids i-0abc123def456 \
--query 'InstanceStatuses[0].[InstanceStatus.Status,SystemStatus.Status]' \
--output text
# 4. Find the latest Amazon Linux 2023 AMI
aws ec2 describe-images \
--owners amazon \
--filters "Name=name,Values=al2023-ami-2023*-x86_64" \
--query 'sort_by(Images, &CreationDate)[-1].[ImageId,Name]' \
--output text
# 5. List all security groups and their rules
aws ec2 describe-security-groups \
--query 'SecurityGroups[*].[GroupName,GroupId,Description]' \
--output table
# 6. Find instances without a specific tag
aws ec2 describe-instances \
--query 'Reservations[*].Instances[?!Tags[?Key==`Environment`]].[InstanceId,Tags[?Key==`Name`].Value|[0]]' \
--output table
# 7. Create a snapshot of an EBS volume
aws ec2 create-snapshot \
--volume-id vol-0abc123def456 \
--description "Pre-deployment backup $(date +%Y-%m-%d)" \
--tag-specifications 'ResourceType=snapshot,Tags=[{Key=Name,Value=pre-deploy-backup}]'
# 8. Get console output for debugging
aws ec2 get-console-output \
--instance-id i-0abc123def456 \
--output text
S3 Commands (9-14)
# 9. Sync a local directory to S3 (deploy a website)
aws s3 sync ./dist s3://my-website-bucket \
--delete \
--exclude ".git/*" \
--cache-control "max-age=31536000"
# 10. Find large files in a bucket
aws s3api list-objects-v2 \
--bucket my-app-bucket \
--query 'sort_by(Contents, &Size)[-5:].[Key,Size]' \
--output table
# 11. Get total bucket size
aws s3api list-objects-v2 \
--bucket my-app-bucket \
--query 'sum(Contents[].Size)' \
--output text
# 12. Copy between buckets with storage class
aws s3 cp s3://source-bucket/data/ s3://archive-bucket/data/ \
--recursive \
--storage-class GLACIER
# 13. Generate a pre-signed URL
aws s3 presign s3://my-bucket/report.pdf --expires-in 3600
# 14. Delete all versions in a versioned bucket (dangerous!)
aws s3api list-object-versions \
--bucket my-bucket \
--query '{Objects: Versions[].{Key:Key,VersionId:VersionId}}' \
--output json | aws s3api delete-objects --bucket my-bucket --delete file:///dev/stdin
IAM Commands (15-19)
# 15. List all users and their last login
aws iam generate-credential-report > /dev/null
aws iam get-credential-report \
--query 'Content' \
--output text | base64 --decode | cut -d',' -f1,5,11,16
# 16. Find users with old access keys (> 90 days)
aws iam list-users \
--query 'Users[*].UserName' \
--output text | tr '\t' '\n' | while read user; do
aws iam list-access-keys --user-name "$user" \
--query "AccessKeyMetadata[?CreateDate<='$(date -u -d '90 days ago' +%Y-%m-%d)'].[UserName,AccessKeyId,CreateDate,Status]" \
--output text
done
# 17. List all policies attached to a role
aws iam list-attached-role-policies \
--role-name my-app-role \
--query 'AttachedPolicies[*].[PolicyName,PolicyArn]' \
--output table
# 18. Simulate a policy (test without applying)
aws iam simulate-principal-policy \
--policy-source-arn arn:aws:iam::123456789012:user/deploy-bot \
--action-names s3:GetObject s3:PutObject \
--resource-arns arn:aws:s3:::production-bucket/* \
--query 'EvaluationResults[*].[EvalActionName,EvalDecision]' \
--output table
# 19. Get account authorization details (full IAM audit)
aws iam get-account-authorization-details \
--filter User Role Group LocalManagedPolicy \
--output json > iam-audit-$(date +%Y%m%d).json
CloudWatch Commands (20-23)
# 20. Get CPU utilization for an instance
aws cloudwatch get-metric-statistics \
--namespace AWS/EC2 \
--metric-name CPUUtilization \
--dimensions Name=InstanceId,Value=i-0abc123def456 \
--start-time $(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%S) \
--end-time $(date -u +%Y-%m-%dT%H:%M:%S) \
--period 300 \
--statistics Average Maximum \
--output table
# 21. Tail CloudWatch logs in real-time
aws logs tail /aws/lambda/my-function --follow --since 30m
# 22. Search logs for errors
aws logs filter-log-events \
--log-group-name /aws/lambda/my-function \
--filter-pattern "ERROR" \
--start-time $(date -u -d '24 hours ago' +%s)000 \
--query 'events[*].[timestamp,message]' \
--output text
# 23. Set a billing alarm
aws cloudwatch put-metric-alarm \
--alarm-name billing-alarm-100 \
--alarm-description "Alert when AWS bill exceeds $100" \
--namespace AWS/Billing \
--metric-name EstimatedCharges \
--dimensions Name=Currency,Value=USD \
--statistic Maximum \
--period 21600 \
--threshold 100 \
--comparison-operator GreaterThanThreshold \
--evaluation-periods 1 \
--alarm-actions arn:aws:sns:us-east-1:123456789012:billing-alerts
Lambda Commands (24-27)
# 24. Invoke a Lambda function
aws lambda invoke \
--function-name my-function \
--payload '{"key": "value"}' \
--cli-binary-format raw-in-base64-out \
response.json && cat response.json
# 25. View recent invocation errors
aws lambda get-function \
--function-name my-function \
--query 'Configuration.[FunctionName,Runtime,MemorySize,Timeout,LastModified]' \
--output table
# 26. Update function code from a zip file
aws lambda update-function-code \
--function-name my-function \
--zip-file fileb://function.zip
# 27. List all functions with runtime info
aws lambda list-functions \
--query 'Functions[*].[FunctionName,Runtime,MemorySize,CodeSize]' \
--output table
RDS and Misc Commands (28-30)
# 28. List all RDS instances with status
aws rds describe-db-instances \
--query 'DBInstances[*].[DBInstanceIdentifier,Engine,DBInstanceClass,DBInstanceStatus,Endpoint.Address]' \
--output table
# 29. Get your current AWS bill (month-to-date)
aws ce get-cost-and-usage \
--time-period Start=$(date +%Y-%m-01),End=$(date +%Y-%m-%d) \
--granularity MONTHLY \
--metrics BlendedCost \
--query 'ResultsByTime[0].Total.BlendedCost.[Amount,Unit]' \
--output text
# 30. Describe all resources in a CloudFormation stack
aws cloudformation describe-stack-resources \
--stack-name my-app-stack \
--query 'StackResources[*].[ResourceType,LogicalResourceId,ResourceStatus]' \
--output table
The Power of --query (JMESPath)
The --query parameter uses JMESPath expressions to filter and transform output. Here are patterns you'll use constantly:
# Select specific fields
--query 'Items[*].[Field1, Field2]'
# Filter with conditions
--query 'Items[?Status==`active`]'
# Sort results
--query 'sort_by(Items, &CreatedDate)'
# Get first/last element
--query 'sort_by(Items, &Date)[-1]'
# Flatten nested arrays
--query 'Reservations[*].Instances[*].InstanceId[]'
What's Next?
Now that you can drive AWS from the command line, it's time to tackle databases. Next up: RDS vs Aurora vs DynamoDB — how to pick the right AWS database for your workload without overengineering it.
This is Part 6 of our AWS series. Print this cheat sheet and keep it next to your terminal. You'll use these commands every day.
