A collection of useful AWS CLI commands and snippets I’ve gathered over time. These cover everything from S3 and Glacier operations to ECS, Lightsail, CloudFront, and Athena queries.
S3 and Glacier Link to heading
Iterate through an S3 Glacier vault and delete contents Link to heading
This multi-step process retrieves an inventory of a Glacier vault and then deletes all archives before removing the vault itself.
# To get each archive out of the vault:
aws --region us-east-1 glacier initiate-job \
--vault-name arq_14396D48-D24A-4A8F-8EF7-B55F66B2BF68_78E9B43F-FF42-4594-9FE8-E877F458197E \
--account-id 655943246657 \
--job-parameters '{"Type": "inventory-retrieval"}'
# This command checks on the status of the job:
aws --region us-east-1 glacier describe-job \
--vault-name arq_14396D48-D24A-4A8F-8EF7-B55F66B2BF68_78E9B43F-FF42-4594-9FE8-E877F458197E \
--account-id 655943246657 \
--job-id ppoQZmzIwiHzCgBWLy6L3nrnr6BMHeVxJ6U6_Z6kMdCnXyfgTXvG5k4TFoFz8zkPY-FdquZi_Lg6RKzRzxsyFnLGlNRh
# Once that's done I save the job output to a file:
aws --region us-east-1 glacier get-job-output \
--vault-name arq_14396D48-D24A-4A8F-8EF7-B55F66B2BF68_78E9B43F-FF42-4594-9FE8-E877F458197E \
--account-id 655943246657 \
--job-id ppoQZmzIwiHzCgBWLy6L3nrnr6BMHeVxJ6U6_Z6kMdCnXyfgTXvG5k4TFoFz8zkPY-FdquZi_Lg6RKzRzxsyFnLGlNRh \
1.json
# I then iterate through that file, deleting all of the archives:
for x in $(cat 1.json | jq ".ArchiveList[].ArchiveId"); do
echo "Deleting ${x}"
aws --region us-east-1 glacier delete-archive \
--vault-name arq_14396D48-D24A-4A8F-8EF7-B55F66B2BF68_78E9B43F-FF42-4594-9FE8-E877F458197E \
--account-id 655943246657 \
--archive-id ${x}
done
# To delete the vaults:
aws glacier --region us-east-1 delete-vault \
--vault-name arq_14396D48-D24A-4A8F-8EF7-B55F66B2BF68_78E9B43F-FF42-4594-9FE8-E877F458197E \
--account-id 655943246657
Enable intelligent tiering on all S3 buckets Link to heading
for x in $(aws s3 ls | awk '{ print $3 }'); do
echo ${x}
aws s3api put-bucket-intelligent-tiering-configuration \
--cli-input-json "{\"Bucket\":\"${x}\",\"Id\":\"${x}\",\"IntelligentTieringConfiguration\":{\"Id\":\"${x}\",\"Status\":\"Enabled\",\"Tierings\":[{\"Days\":365,\"AccessTier\":\"DEEP_ARCHIVE_ACCESS\"}]}}"
done
Change storage class of all objects in a bucket Link to heading
for x in $(aws s3 ls | grep 'dmp-00' | egrep -v '00014|00015' | awk '{ print $3 }'); do
echo ${x}
aws s3 cp s3://${x}/ s3://${x}/ --recursive --storage-class INTELLIGENT_TIERING
done
S3 bucket policy for federated / SSO role Link to heading
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:role/aws-reserved/sso.amazonaws.com/AWSReservedSSO_AcctMigrationDeveloper_asfasfafsafasf"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::ergon-test-chroma-datastage/*"
}
]
}
Find largest objects in an S3 bucket Link to heading
aws s3api list-objects-v2 --bucket BUCKET_NAME --query 'sort_by(Contents, &Size)[-10:].{Key:Key,Size:Size}' --output table
Sync S3 buckets across regions Link to heading
aws s3 sync s3://source-bucket s3://destination-bucket --source-region us-east-1 --region us-west-2
Enable versioning on an S3 bucket Link to heading
aws s3api put-bucket-versioning --bucket BUCKET_NAME --versioning-configuration Status=Enabled
List all S3 buckets with their creation dates Link to heading
aws s3api list-buckets --query 'Buckets[].{Name:Name,Created:CreationDate}' --output table
Lightsail Link to heading
List, modify, and put firewall rules for Lightsail instances Link to heading
aws lightsail get-instance-port-states --instance-name INSTANCE_NAME --output json | grep -v "state" > firewall.json
aws lightsail put-instance-public-ports --instance-name INSTANCE_NAME --cli-input-json file://firewall.json
ECS Link to heading
Get latest Amazon Linux ECS optimized AMI Link to heading
aws ssm get-parameters --names /aws/service/ecs/optimized-ami/amazon-linux-2/recommended
List all ECS clusters Link to heading
aws ecs list-clusters --output table
List all services in an ECS cluster Link to heading
aws ecs list-services --cluster my-cluster --output table
Update ECS service to force new deployment Link to heading
aws ecs update-service --cluster my-cluster --service my-service --force-new-deployment
Stop a running ECS task Link to heading
aws ecs stop-task --cluster my-cluster --task TASK_ARN --reason "Manual stop"
Get logs from ECS container using task ID Link to heading
TASK_ARN=$(aws ecs list-tasks --cluster my-cluster --service my-service --desired-status RUNNING --query 'taskArns[0]' --output text)
aws ecs describe-tasks --cluster my-cluster --tasks $TASK_ARN --query 'tasks[0].containers[0].name' --output text
IAM and Security Link to heading
List all IAM users Link to heading
aws iam list-users --query 'Users[*].[UserName,CreateDate]' --output table
Find IAM users without MFA enabled Link to heading
aws iam get-credential-report
aws iam generate-credential-report
sleep 5
aws iam get-credential-report --query 'Content' --output text | base64 -d | awk -F, '$4 == "false" {print $1}'
List all IAM access keys older than 90 days Link to heading
aws iam list-users --query 'Users[].UserName' --output text | while read user; do
aws iam list-access-keys --user-name $user --query "AccessKeyMetadata[?CreateDate<='$(date -d '90 days ago' -Iseconds)'].[UserName,AccessKeyId,CreateDate]" --output text
done
Assume a role and export credentials Link to heading
CREDS=$(aws sts assume-role --role-arn arn:aws:iam::123456789012:role/MyRole --role-session-name my-session)
export AWS_ACCESS_KEY_ID=$(echo $CREDS | jq -r '.Credentials.AccessKeyId')
export AWS_SECRET_ACCESS_KEY=$(echo $CREDS | jq -r '.Credentials.SecretAccessKey')
export AWS_SESSION_TOKEN=$(echo $CREDS | jq -r '.Credentials.SessionToken')
Minimum requirements for Session Manager Link to heading
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"ssm:GetConnectionStatus",
"ssm:StartSession"
],
"Resource": "arn:aws:ec2:::instance/*"
}
]
}
Root login notifications Link to heading
Terraform code for setting up CloudWatch event rule to monitor root account logins:
resource "aws_cloudwatch_event_rule" "root-login-event" {
count = var.enable_events_root_login ? 1 : 0
name = "root-account-login"
description = "Root account login"
event_pattern = <<EOF
{
"detail-type": [
"AWS Console Sign In via CloudTrail"
],
"detail": {
"userIdentity": {
"type": [
"Root"
]
}
}
}
EOF
}
CloudFront Link to heading
Find the distribution / account that has your CNAME Link to heading
Useful for resolving CNAMEAlreadyExists
errors. See AWS documentation for more details.
aws --profile santa_dev cloudfront list-conflicting-aliases \
--distribution-id EMZM3HV48HKBK \
--alias dev.muh-website.co \
--no-cli-pager
Example output:
{
"ConflictingAliasesList": {
"MaxItems": 100,
"Quantity": 1,
"Items": [
{
"Alias": "dev.muh-website.co",
"DistributionId": "*******9I2761G",
"AccountId": "******673587"
}
]
}
}
EC2 Link to heading
Install atop on Amazon Linux Link to heading
amazon-linux-extras install -y epel
yum -y install atop
sed -i 's/^LOGINTERVAL=600.*/LOGINTERVAL=60/' /etc/sysconfig/atop
systemctl enable atop.service
systemctl restart atop.service
List all EC2 instances with name, instance ID, type, and state Link to heading
aws ec2 describe-instances --query 'Reservations[*].Instances[*].[Tags[?Key==`Name`].Value|[0],InstanceId,InstanceType,State.Name]' --output table
Stop all running EC2 instances with a specific tag Link to heading
aws ec2 describe-instances --filters "Name=tag:Environment,Values=dev" "Name=instance-state-name,Values=running" --query 'Reservations[].Instances[].InstanceId' --output text | xargs -n 1 aws ec2 stop-instances --instance-ids
Find unattached EBS volumes Link to heading
aws ec2 describe-volumes --filters Name=status,Values=available --query 'Volumes[*].{ID:VolumeId,Size:Size,Type:VolumeType,Created:CreateTime}' --output table
Get instance metadata from within an EC2 instance Link to heading
# Get instance ID
curl -s http://169.254.169.254/latest/meta-data/instance-id
# Get availability zone
curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone
# Get public IP
curl -s http://169.254.169.254/latest/meta-data/public-ipv4
# Get IAM role
curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/
Create an AMI from a running instance Link to heading
aws ec2 create-image --instance-id i-1234567890abcdef0 --name "My-AMI-$(date +%Y%m%d-%H%M%S)" --description "Automated backup"
RDS Link to heading
List all RDS instances with status Link to heading
aws rds describe-db-instances --query 'DBInstances[*].[DBInstanceIdentifier,DBInstanceClass,Engine,DBInstanceStatus]' --output table
Create a manual snapshot of an RDS instance Link to heading
aws rds create-db-snapshot --db-instance-identifier mydb --db-snapshot-identifier mydb-snapshot-$(date +%Y%m%d-%H%M%S)
Find RDS instances without encryption Link to heading
aws rds describe-db-instances --query 'DBInstances[?StorageEncrypted==`false`].[DBInstanceIdentifier,Engine,DBInstanceClass]' --output table
List all RDS snapshots older than 30 days Link to heading
aws rds describe-db-snapshots --query "DBSnapshots[?SnapshotCreateTime<='$(date -d '30 days ago' -Iseconds)'].[DBSnapshotIdentifier,SnapshotCreateTime]" --output table
Lambda Link to heading
List all Lambda functions with runtime and memory Link to heading
aws lambda list-functions --query 'Functions[*].[FunctionName,Runtime,MemorySize,LastModified]' --output table
Invoke a Lambda function Link to heading
aws lambda invoke --function-name my-function --payload '{"key":"value"}' response.json
cat response.json
Update Lambda function code from a zip file Link to heading
aws lambda update-function-code --function-name my-function --zip-file fileb://function.zip
Get Lambda function logs (recent 10) Link to heading
aws logs tail /aws/lambda/FUNCTION_NAME --follow
CloudWatch Logs Link to heading
Tail CloudWatch logs in real-time Link to heading
aws logs tail /aws/lambda/my-function --follow --format short
Search CloudWatch logs for a specific pattern Link to heading
aws logs filter-log-events --log-group-name /aws/lambda/my-function --filter-pattern "ERROR" --start-time $(date -d '1 hour ago' +%s)000
Delete old log streams Link to heading
aws logs describe-log-streams --log-group-name /aws/lambda/my-function --order-by LastEventTime --descending --max-items 100 | jq -r '.logStreams[] | select(.lastEventTimestamp < (now - 2592000) * 1000) | .logStreamName' | xargs -I {} aws logs delete-log-stream --log-group-name /aws/lambda/my-function --log-stream-name {}
Export logs to S3 Link to heading
aws logs create-export-task --log-group-name /aws/lambda/my-function --from $(date -d '7 days ago' +%s)000 --to $(date +%s)000 --destination my-logs-bucket --destination-prefix lambda-logs/
Route 53 Link to heading
List all hosted zones Link to heading
aws route53 list-hosted-zones --query 'HostedZones[*].[Name,Id,ResourceRecordSetCount]' --output table
List all records in a hosted zone Link to heading
aws route53 list-resource-record-sets --hosted-zone-id Z1234567890ABC --output table
Create a simple A record Link to heading
aws route53 change-resource-record-sets --hosted-zone-id Z1234567890ABC --change-batch '{
"Changes": [{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "example.com",
"Type": "A",
"TTL": 300,
"ResourceRecords": [{"Value": "192.0.2.1"}]
}
}]
}'
VPC Link to heading
List all VPCs with their CIDR blocks Link to heading
aws ec2 describe-vpcs --query 'Vpcs[*].[VpcId,CidrBlock,Tags[?Key==`Name`].Value|[0]]' --output table
Find unused security groups Link to heading
aws ec2 describe-security-groups --query 'SecurityGroups[?IpPermissions==`[]` && IpPermissionsEgress==`[]`].[GroupId,GroupName]' --output table
List all subnets with available IP counts Link to heading
aws ec2 describe-subnets --query 'Subnets[*].[SubnetId,CidrBlock,AvailableIpAddressCount,AvailabilityZone]' --output table
Show all internet gateways not attached to a VPC Link to heading
aws ec2 describe-internet-gateways --query 'InternetGateways[?Attachments==`[]`].[InternetGatewayId]' --output table
Cost and Billing Link to heading
Get current month’s AWS costs by service Link to heading
aws ce get-cost-and-usage --time-period Start=$(date +%Y-%m-01),End=$(date +%Y-%m-%d) --granularity MONTHLY --metrics BlendedCost --group-by Type=DIMENSION,Key=SERVICE --output table
Find most expensive resources in the last 30 days Link to heading
aws ce get-cost-and-usage --time-period Start=$(date -d '30 days ago' +%Y-%m-%d),End=$(date +%Y-%m-%d) --granularity MONTHLY --metrics UnblendedCost --group-by Type=DIMENSION,Key=RESOURCE_ID --output json | jq '.ResultsByTime[].Groups | sort_by(.Metrics.UnblendedCost.Amount | tonumber) | reverse | .[0:10]'
SNS Link to heading
List all SNS topics Link to heading
aws sns list-topics --query 'Topics[*].TopicArn' --output table
Publish a message to an SNS topic Link to heading
aws sns publish --topic-arn arn:aws:sns:us-east-1:123456789012:my-topic --message "Hello from AWS CLI" --subject "Test Message"
List subscriptions for a topic Link to heading
aws sns list-subscriptions-by-topic --topic-arn arn:aws:sns:us-east-1:123456789012:my-topic --output table
SQS Link to heading
List all SQS queues Link to heading
aws sqs list-queues --output table
Send a message to an SQS queue Link to heading
aws sqs send-message --queue-url https://sqs.us-east-1.amazonaws.com/123456789012/my-queue --message-body "Test message from CLI"
Receive and delete messages from SQS queue Link to heading
# Receive messages
aws sqs receive-message --queue-url https://sqs.us-east-1.amazonaws.com/123456789012/my-queue --max-number-of-messages 10
# Delete a message
aws sqs delete-message --queue-url https://sqs.us-east-1.amazonaws.com/123456789012/my-queue --receipt-handle "MESSAGE_RECEIPT_HANDLE"
Purge all messages from a queue Link to heading
aws sqs purge-queue --queue-url https://sqs.us-east-1.amazonaws.com/123456789012/my-queue
Get queue attributes (message count, etc.) Link to heading
aws sqs get-queue-attributes --queue-url https://sqs.us-east-1.amazonaws.com/123456789012/my-queue --attribute-names All
DynamoDB Link to heading
List all DynamoDB tables Link to heading
aws dynamodb list-tables --output table
Describe a DynamoDB table Link to heading
aws dynamodb describe-table --table-name my-table --query 'Table.[TableName,TableStatus,ItemCount,TableSizeBytes]' --output table
Scan a DynamoDB table (get all items) Link to heading
aws dynamodb scan --table-name my-table --output json
Query DynamoDB table with a key condition Link to heading
aws dynamodb query --table-name my-table --key-condition-expression "id = :id" --expression-attribute-values '{":id":{"S":"12345"}}' --output json
Put an item into DynamoDB Link to heading
aws dynamodb put-item --table-name my-table --item '{"id":{"S":"12345"},"name":{"S":"John Doe"},"age":{"N":"30"}}'
Delete an item from DynamoDB Link to heading
aws dynamodb delete-item --table-name my-table --key '{"id":{"S":"12345"}}'
Create a backup of a DynamoDB table Link to heading
aws dynamodb create-backup --table-name my-table --backup-name my-table-backup-$(date +%Y%m%d)
Athena Link to heading
Create an Athena table of a TSV file in S3 Link to heading
This example works with gzipped files and skips the header row:
CREATE EXTERNAL TABLE IF NOT EXISTS `imdb-name`.`name_dir` (
`nconst` string,
`primaryName` string,
`birthYear` int,
`deathYear` int,
`primaryProfession` string,
`knownForTitles` string
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe'
WITH SERDEPROPERTIES ('field.delim' = '\t')
STORED AS INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION 's3://imdb-example-dataset/name/'
TBLPROPERTIES (
"skip.header.line.count"="1"
);
Join tables and run a select Link to heading
SELECT
tc.tconst,
tc.originalTitle,
rd.averageRating AS rating,
rd.numVotes AS numberOfVotes
FROM
title_dir AS tc
LEFT JOIN
ratings_dir AS rd
ON
tc.tconst = rd.tconst
WHERE
tc.titleType = 'movie' AND rd.numVotes > 10000
ORDER BY
rd.averageRating DESC,
rd.numVotes DESC
LIMIT 10;