Docs
/
AWS Cloud
Chapter 4

04 — S3 & Storage

What is S3?

Simple Storage Service — unlimited object storage. Store files (objects) in buckets.

Bucket: my-app-uploads (globally unique name)
  └── users/
      └── avatar-123.jpg    (object, up to 5 TB)
      └── avatar-456.png
  └── documents/
      └── report.pdf

Core Operations

# Buckets
aws s3 mb s3://my-unique-bucket              # Create bucket
aws s3 ls                                     # List buckets
aws s3 rb s3://my-bucket --force              # Delete bucket + contents

# Objects
aws s3 cp file.txt s3://my-bucket/           # Upload
aws s3 cp s3://my-bucket/file.txt ./         # Download
aws s3 sync ./dist s3://my-bucket/           # Sync directory
aws s3 rm s3://my-bucket/file.txt            # Delete
aws s3 ls s3://my-bucket/ --recursive        # List objects

SDK (Node.js)

import { S3Client, PutObjectCommand, GetObjectCommand } from '@aws-sdk/client-s3';
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';

const s3 = new S3Client({ region: 'us-east-1' });

// Upload
await s3.send(new PutObjectCommand({
  Bucket: 'my-bucket',
  Key: 'uploads/photo.jpg',
  Body: fileBuffer,
  ContentType: 'image/jpeg',
}));

// Pre-signed URL (temporary access without making object public)
const url = await getSignedUrl(s3, new GetObjectCommand({
  Bucket: 'my-bucket',
  Key: 'uploads/photo.jpg',
}), { expiresIn: 3600 }); // 1 hour

Storage Classes

ClassAvailabilityMin DurationUse Case
Standard99.99%Frequently accessed data
Standard-IA99.9%30 daysInfrequent access, rapid retrieval
One Zone-IA99.5%30 daysRe-creatable infrequent data
Glacier Instant99.9%90 daysArchive with instant access
Glacier Flexible99.99%90 daysArchive (minutes to hours retrieval)
Glacier Deep99.99%180 daysLong-term archive (12-48 hr retrieval)
Intelligent-Tiering99.9%Unknown/changing access patterns

Lifecycle Policies

Automatically transition or expire objects.

{
  "Rules": [
    {
      "ID": "ArchiveOldLogs",
      "Status": "Enabled",
      "Filter": { "Prefix": "logs/" },
      "Transitions": [
        { "Days": 30, "StorageClass": "STANDARD_IA" },
        { "Days": 90, "StorageClass": "GLACIER" }
      ],
      "Expiration": { "Days": 365 }
    }
  ]
}
Day 0-30:   Standard (frequent access)
Day 30-90:  Standard-IA (cheaper, infrequent)
Day 90-365: Glacier (archive)
Day 365+:   Deleted

Versioning

Keep multiple versions of objects. Protects against accidental deletion.

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

# List versions
aws s3api list-object-versions --bucket my-bucket --prefix file.txt

# Delete creates a "delete marker" — old versions still exist
# Restore by deleting the delete marker

Bucket Policies & Access Control

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PublicRead",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::my-website-bucket/*"
    }
  ]
}

Block Public Access (default: ON)

# Always keep this ON unless hosting a public website
aws s3api put-public-access-block \
  --bucket my-bucket \
  --public-access-block-configuration \
    BlockPublicAcls=true,IgnorePublicAcls=true,\
    BlockPublicPolicy=true,RestrictPublicBuckets=true

Static Website Hosting

aws s3 website s3://my-website \
  --index-document index.html \
  --error-document error.html

# Upload React/Angular build
aws s3 sync ./dist s3://my-website --delete

# Access at: http://my-website.s3-website-us-east-1.amazonaws.com
# Use CloudFront in front for HTTPS + caching

Server-Side Encryption

TypeKey Management
SSE-S3AWS manages keys (default, automatic)
SSE-KMSAWS KMS manages keys (audit trail, key rotation)
SSE-CYou provide keys with each request
# Enable default encryption (SSE-S3)
aws s3api put-bucket-encryption \
  --bucket my-bucket \
  --server-side-encryption-configuration \
    '{"Rules":[{"ApplyServerSideEncryptionByDefault":{"SSEAlgorithm":"AES256"}}]}'

Key Takeaways

  • S3 = unlimited object storage with 99.999999999% (11 9's) durability
  • Use pre-signed URLs for temporary secure access (uploads/downloads)
  • Use lifecycle policies to auto-transition to cheaper storage classes
  • Enable versioning for critical buckets (protects against accidental deletion)
  • Block public access by default — only open for static website hosting
  • Use SSE-KMS for sensitive data (audit trail + key rotation)
  • S3 + CloudFront = fast, cheap static website hosting