S3
04 / 08

Advanced Features & CLI

S3 Advanced Features

Versioning, lifecycle policies, event notifications, and replication are the production-grade S3 features that enable data protection, cost management, and event-driven architectures.

Versioning & Lifecycle Policies

# Versioning — keeps all versions of every object
# Once enabled, cannot be fully disabled (only suspended)
# Deleted objects get a "delete marker", not actually removed
# Previous versions can be restored by removing the delete marker

# Enable versioning
aws s3api put-bucket-versioning \
  --bucket my-app-uploads \
  --versioning-configuration Status=Enabled

# List versions of an object
aws s3api list-object-versions \
  --bucket my-app-uploads \
  --prefix "user/123/avatar.jpg"

# Restore a specific version
aws s3api copy-object \
  --bucket my-app-uploads \
  --copy-source "my-app-uploads/user/123/avatar.jpg?versionId=abc123" \
  --key "user/123/avatar.jpg"

# Lifecycle policy — automate storage transitions and expiration
aws s3api put-bucket-lifecycle-configuration \
  --bucket my-app-uploads \
  --lifecycle-configuration '{
    "Rules": [
      {
        "ID": "move-old-to-ia",
        "Status": "Enabled",
        "Filter": {"Prefix": "uploads/"},
        "Transitions": [
          {"Days": 30, "StorageClass": "STANDARD_IA"},
          {"Days": 90, "StorageClass": "GLACIER_IR"},
          {"Days": 365, "StorageClass": "DEEP_ARCHIVE"}
        ],
        "Expiration": {"Days": 2555}
      },
      {
        "ID": "delete-incomplete-multipart",
        "Status": "Enabled",
        "Filter": {},
        "AbortIncompleteMultipartUpload": {"DaysAfterInitiation": 7}
      },
      {
        "ID": "expire-old-versions",
        "Status": "Enabled",
        "Filter": {},
        "NoncurrentVersionExpiration": {"NoncurrentDays": 90}
      }
    ]
  }'

Event Notifications & S3 Select

# S3 Event Notifications — trigger on object create/delete/restore
# Destinations: Lambda, SQS, SNS, EventBridge (EventBridge supports more event types)

# Configure event notification (send to SQS on any object creation)
aws s3api put-bucket-notification-configuration \
  --bucket my-uploads-bucket \
  --notification-configuration '{
    "QueueConfigurations": [
      {
        "Id": "NewUploadNotification",
        "QueueArn": "arn:aws:sqs:us-east-1:123:upload-processing-queue",
        "Events": ["s3:ObjectCreated:*"],
        "Filter": {
          "Key": {
            "FilterRules": [
              {"Name": "prefix", "Value": "uploads/"},
              {"Name": "suffix", "Value": ".jpg"}
            ]
          }
        }
      }
    ]
  }'
# NOTE: SQS queue policy must allow s3.amazonaws.com to send messages

# Enable EventBridge integration (more flexible — pattern matching, multiple targets)
aws s3api put-bucket-notification-configuration \
  --bucket my-uploads-bucket \
  --notification-configuration '{"EventBridgeConfiguration": {}}'

# S3 Select — query structured data in-place (CSV, JSON, Parquet)
# Reduces data transfer by up to 80% compared to downloading whole object
aws s3api select-object-content \
  --bucket my-data-bucket \
  --key data/users.csv \
  --expression "SELECT s.name, s.email FROM S3Object s WHERE s.country = 'US'" \
  --expression-type SQL \
  --input-serialization '{"CSV": {"FileHeaderInfo": "USE", "FieldDelimiter": ","}}' \
  --output-serialization '{"CSV": {}}' \
  /dev/stdout

# S3 Multipart Upload — required for objects > 5 GB, recommended for > 100 MB
# Enables parallelism and retry of failed parts
aws s3api create-multipart-upload \
  --bucket my-bucket --key large-file.zip
# Upload parts (minimum 5 MB each except last)
# Complete multipart upload
aws s3api complete-multipart-upload \
  --bucket my-bucket --key large-file.zip \
  --upload-id abc123 \
  --multipart-upload file://parts.json

# aws s3 cp and sync handle multipart automatically for large files
# Control multipart threshold and chunk size
aws configure set default.s3.multipart_threshold 64MB
aws configure set default.s3.multipart_chunksize 16MB

Replication & Object Lock

# Replication — copies objects to another bucket (asynchronously)
# CRR (Cross-Region Replication): source and destination in different regions
# SRR (Same-Region Replication): same region (e.g. copy prod to dev account)
# Requires: versioning on BOTH source and destination buckets

# Create replication configuration
aws s3api put-bucket-replication \
  --bucket my-source-bucket \
  --replication-configuration '{
    "Role": "arn:aws:iam::123:role/s3-replication-role",
    "Rules": [
      {
        "ID": "replicate-uploads",
        "Status": "Enabled",
        "Filter": {"Prefix": "uploads/"},
        "Destination": {
          "Bucket": "arn:aws:s3:::my-dr-bucket-us-west-2",
          "StorageClass": "STANDARD_IA",
          "ReplicationTime": {
            "Status": "Enabled",
            "Time": {"Minutes": 15}
          },
          "Metrics": {"Status": "Enabled", "EventThreshold": {"Minutes": 15}}
        },
        "DeleteMarkerReplication": {"Status": "Enabled"}
      }
    ]
  }'
# ReplicationTime (RTC): guarantees 99.99% of objects replicated within 15 min (costs extra)

# Object Lock — WORM (Write Once Read Many) protection
# Prevent deletion or overwrite for a fixed retention period
# Use for: regulatory compliance, ransomware protection
# Must be enabled at bucket creation time
aws s3api create-bucket \
  --bucket my-compliant-bucket \
  --region us-east-1
aws s3api put-object-lock-configuration \
  --bucket my-compliant-bucket \
  --object-lock-configuration '{
    "ObjectLockEnabled": "Enabled",
    "Rule": {
      "DefaultRetention": {
        "Mode": "COMPLIANCE",
        "Days": 2555
      }
    }
  }'
# COMPLIANCE mode: cannot be deleted or shortened even by root user
# GOVERNANCE mode: can be overridden by users with s3:BypassGovernanceRetention permission

# S3 Batch Operations — apply an operation to billions of objects
# Operations: copy, PUT tags, invoke Lambda, restore from Glacier, replicate
aws s3control create-job \
  --account-id 123456789012 \
  --operation '{"S3PutObjectTagging": {"TagSet": [{"Key": "processed", "Value": "true"}]}}' \
  --manifest '{"Spec": {"Format": "S3BatchOperations_CSV_20180820"}, "Location": {"ObjectArn": "arn:aws:s3:::my-bucket/manifest.csv", "ETag": "abc"}}' \
  --report '{"Bucket": "arn:aws:s3:::my-reports", "ReportScope": "AllTasks", "Enabled": true}' \
  --role-arn arn:aws:iam::123:role/batch-ops-role \
  --priority 10 \
  --confirmation-required

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free