S3 Operations Reference

Core S3 Commands

# List buckets aws s3 ls # List objects with size and date aws s3 ls s3://my-bucket/ --human-readable --summarize # Copy local to S3 aws s3 cp ./report.pdf s3://my-bucket/reports/report.pdf aws s3 cp s3://src-bucket/file.txt s3://dst-bucket/file.txt # bucket to bucket # Sync directory (only changed files) aws s3 sync ./dist s3://my-bucket/web --delete --exact-timestamps # Make / remove bucket aws s3 mb s3://my-new-bucket --region ap-southeast-1 aws s3 rb s3://my-empty-bucket # Move (copy + delete) aws s3 mv s3://my-bucket/old.txt s3://my-bucket/new.txt

Lifecycle Rules

# lifecycle.json { "Rules": [ { "ID": "MoveToIA", "Status": "Enabled", "Filter": {"Prefix": "logs/"}, "Transitions": [ {"Days": 30, "StorageClass": "STANDARD_IA"}, {"Days": 90, "StorageClass": "GLACIER"} ], "Expiration": {"Days": 365} }, { "ID": "CleanupIncomplete", "Status": "Enabled", "Filter": {}, "AbortIncompleteMultipartUpload": {"DaysAfterInitiation": 7} } ] } # Apply lifecycle configuration aws s3api put-bucket-lifecycle-configuration \ --bucket my-bucket \ --lifecycle-configuration file://lifecycle.json

Presigned URLs

# Generate presigned GET URL (expires in 1 hour) aws s3 presign s3://my-bucket/private/doc.pdf --expires-in 3600 # Generate presigned PUT URL via SDK (CLI only supports GET) # Python boto3 example: # import boto3 # s3 = boto3.client('s3') # url = s3.generate_presigned_url( # 'put_object', # Params={'Bucket': 'my-bucket', 'Key': 'upload/file.txt'}, # ExpiresIn=3600 # ) # Use presigned URL with curl curl -o downloaded.pdf "https://my-bucket.s3.amazonaws.com/private/doc.pdf?X-Amz-..."

Bucket Policies

# Public read policy (static website hosting) { "Version": "2012-10-17", "Statement": [{ "Sid": "PublicReadGetObject", "Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::my-website-bucket/*" }] } # Restrict to specific VPC endpoint { "Statement": [{ "Effect": "Deny", "Principal": "*", "Action": "s3:*", "Resource": ["arn:aws:s3:::my-bucket", "arn:aws:s3:::my-bucket/*"], "Condition": { "StringNotEquals": {"aws:sourceVpce": "vpce-1a2b3c4d"} } }] } # Apply bucket policy aws s3api put-bucket-policy --bucket my-bucket --policy file://policy.json

CORS Configuration

# cors.json { "CORSRules": [ { "AllowedHeaders": ["Authorization", "Content-Type"], "AllowedMethods": ["GET", "PUT", "POST"], "AllowedOrigins": ["https://example.com", "https://app.example.com"], "ExposeHeaders": ["ETag"], "MaxAgeSeconds": 3600 } ] } # Apply CORS configuration aws s3api put-bucket-cors \ --bucket my-bucket \ --cors-configuration file://cors.json # Get current CORS config aws s3api get-bucket-cors --bucket my-bucket

Storage Classes

ClassUse CaseRetrieval
STANDARDFrequently accessed dataImmediate
STANDARD_IAInfrequently accessed, rapid retrieval neededImmediate
ONEZONE_IANon-critical, reproducible dataImmediate
INTELLIGENT_TIERINGUnknown/changing access patternsImmediate
GLACIER_IRArchive with milliseconds retrievalMilliseconds
GLACIERLong-term archiveMinutes to hours
DEEP_ARCHIVERegulatory archiveUp to 12 hours