AWS Cheatsheet
S3
Use this AWS reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
Bucket Operations
aws s3 mb s3://my-bucket # make bucket aws s3 mb s3://my-bucket --region eu-west-1 # in specific region aws s3 rb s3://my-bucket # remove empty bucket aws s3 rb s3://my-bucket --force # remove + delete all objects aws s3 ls # list all buckets aws s3 ls s3://my-bucket # list bucket root aws s3 ls s3://my-bucket/prefix/ --recursive # list recursively aws s3 ls s3://my-bucket --recursive --human-readable --summarize
Object Copy / Move / Delete
| Command | What it does |
|---|---|
aws s3 cp file.txt s3://bucket/key | Upload local file |
aws s3 cp s3://bucket/key file.txt | Download object |
aws s3 cp s3://src/key s3://dst/key | Server-side copy |
aws s3 mv file.txt s3://bucket/key | Upload + delete local |
aws s3 mv s3://bucket/old s3://bucket/new | Rename object |
aws s3 rm s3://bucket/key | Delete object |
aws s3 rm s3://bucket/prefix/ --recursive | Delete all under prefix |
# Upload with metadata + storage class aws s3 cp file.txt s3://bucket/file.txt \ --storage-class INTELLIGENT_TIERING \ --metadata '{"project":"web"}' # Sync directory (only changed/new files) aws s3 sync ./dist s3://bucket/dist/ aws s3 sync s3://bucket/dist/ ./dist # download sync aws s3 sync ./dist s3://bucket/ --delete # mirror (remove extra) aws s3 sync ./dist s3://bucket/ --exclude "*.log" --include "*.html"
Presigned URLs
# Generate download URL valid for 1 hour (default 3600s) aws s3 presign s3://bucket/secret-file.pdf # Custom expiry (max 7 days for v4) aws s3 presign s3://bucket/file.pdf --expires-in 86400
The CLI can only presign GET — there is no s3api generate-presigned-url command. Presigned PUT (upload) URLs require an SDK:
# Presigned PUT with boto3 import boto3 url = boto3.client("s3").generate_presigned_url( "put_object", Params={"Bucket": "my-bucket", "Key": "uploads/file.zip"}, ExpiresIn=3600, ) # then: curl -X PUT --upload-file file.zip "$url"
Bucket Policy & ACL
# Apply bucket policy from file aws s3api put-bucket-policy --bucket my-bucket --policy file://policy.json # Get current policy aws s3api get-bucket-policy --bucket my-bucket # Delete bucket policy aws s3api delete-bucket-policy --bucket my-bucket
Legacy — ACLs: new buckets default to
BucketOwnerEnforced(ACLs disabled) since April 2023, soaws s3api put-object-acl --acl public-readerrors unless you first change the bucket's Object Ownership setting. Use bucket policies instead.
Example public-read bucket policy (policy.json)
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket/*"
}]
}Static Website Hosting
aws s3 website s3://my-bucket \
--index-document index.html \
--error-document error.html
# Endpoint: http://my-bucket.s3-website-<region>.amazonaws.comVersioning
aws s3api put-bucket-versioning \ --bucket my-bucket \ --versioning-configuration Status=Enabled aws s3api get-bucket-versioning --bucket my-bucket # List versions of an object aws s3api list-object-versions --bucket my-bucket --prefix my-file.txt # Restore specific version aws s3api get-object \ --bucket my-bucket --key file.txt \ --version-id abc123 restored.txt
Lifecycle Rules
aws s3api put-bucket-lifecycle-configuration \ --bucket my-bucket \ --lifecycle-configuration file://lifecycle.json
lifecycle.json — move to IA after 30d, Glacier after 90d, delete after 365d:
{
"Rules": [{
"ID": "archive-rule",
"Status": "Enabled",
"Filter": { "Prefix": "logs/" },
"Transitions": [
{ "Days": 30, "StorageClass": "STANDARD_IA" },
{ "Days": 90, "StorageClass": "GLACIER" }
],
"Expiration": { "Days": 365 }
}]
}Storage Classes
| Class | Use Case | Min Duration |
|---|---|---|
STANDARD | Frequent access | — |
INTELLIGENT_TIERING | Unknown/changing access | — |
STANDARD_IA | Infrequent access, rapid retrieval | 30 days |
ONE_ZONE_IA | Infrequent, single-AZ | 30 days |
GLACIER_IR | Archive, instant retrieval | 90 days |
GLACIER | Archive, minutes-to-hours retrieval | 90 days |
GLACIER_DEEP_ARCHIVE | Long-term archive, 12h retrieval | 180 days |
Encryption
# Server-side encryption with S3-managed keys (SSE-S3) aws s3 cp file.txt s3://bucket/ --sse AES256 # SSE-KMS (AWS managed key) aws s3 cp file.txt s3://bucket/ --sse aws:kms # SSE-KMS with specific key aws s3 cp file.txt s3://bucket/ \ --sse aws:kms \ --sse-kms-key-id arn:aws:kms:us-east-1:123:key/abc-123 # Enforce encryption on bucket (via policy) aws s3api put-bucket-encryption \ --bucket my-bucket \ --server-side-encryption-configuration '{ "Rules":[{"ApplyServerSideEncryptionByDefault":{"SSEAlgorithm":"AES256"}}] }'
Block Public Access (recommended default)
aws s3api put-public-access-block \
--bucket my-bucket \
--public-access-block-configuration \
"BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"CORS Configuration
aws s3api put-bucket-cors --bucket my-bucket --cors-configuration file://cors.json
cors.json:
{
"CORSRules": [{
"AllowedOrigins": ["https://myapp.com"],
"AllowedMethods": ["GET", "PUT"],
"AllowedHeaders": ["*"],
"MaxAgeSeconds": 3000
}]
}Replication
# Enable versioning on both source and destination first, then: aws s3api put-bucket-replication \ --bucket source-bucket \ --replication-configuration file://replication.json