The Cheapest, Most Resilient Static Website: Private S3 Bucket + CloudFront OAI

Ned
Ned Cloud Engineer
· Updated · 3 min read
The Cheapest, Most Resilient Static Website: Private S3 Bucket + CloudFront OAI

The Problem

You are migrating a marketing website from on-premises to AWS. It is entirely static, updated infrequently, and needs to be the most cost-effective and resilient origin possible for a CloudFront distribution.

The Solution

Create a private S3 bucket as the CloudFront origin. Use a CloudFront Origin Access Identity (OAI) in the bucket policy so only CloudFront can read the objects.

How It Works

Architecture

1
2
3
User → CloudFront (edge caching) → S3 (private, OAI-only)
                                     ↑
                                     └─ Bucket policy allows OAI, denies everyone else

Step 1: Create the OAI

1
2
3
aws cloudfront create-cloud-front-origin-access-identity \
  --cloud-front-origin-access-identity-config \
  CallerReference=marketing-site-oai,Comment="OAI for marketing site"

Save the returned OAI ID — you’ll need it for the bucket policy.

Step 2: Attach the Bucket Policy

1
2
3
4
5
6
7
8
9
10
11
12
{
  "Version": "2012-10-17",
  "Statement": [{
    "Sid": "AllowOAIReadOnly",
    "Effect": "Allow",
    "Principal": {
      "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E1XXXXXXXXXXXX"
    },
    "Action": "s3:GetObject",
    "Resource": "arn:aws:s3:::marketing-content/*"
  }]
}

Also enable S3 Block Public Access — this is a private bucket.

Step 3: Upload Content With the CLI

1
2
aws s3 sync ./website s3://marketing-content/ \
  --cache-control "public, max-age=86400"

The AWS CLI handles authentication automatically. No SFTP server, no separate transfer service, no cost.

Why This Beats Every Other Option

Approach Monthly Cost (typical) Resilience Ops Burden
S3 + CloudFront + OAI ~$1-10 11 nines durability, global edge Zero
Lightsail instance ~$5-40 Single instance Patching, monitoring
EC2 + ALB + Auto Scaling ~$40+ Multi-AZ Full server management
Public S3 + Transfer Family ~$25+ hourly High Manage SFTP config

OAI vs OAC — Choose OAC for New Distributions

Origin Access Control (OAC) is the newer replacement for OAI. Use OAC when:

  • Your bucket is encrypted with a customer-managed KMS key
  • You want SigV4 signing (stronger security)
  • You want support for all AWS Regions (OAI has limits in some newer Regions)

OAI still works and is simpler for basic setups.

Why Not the Alternatives?

Lightsail virtual server — Requires 24/7 server rental for infrequent updates. Higher cost and single point of failure.

Auto Scaling Group + ALB — Way over-engineered for static content. Massive cost overhead.

Public S3 + AWS Transfer for SFTP — Making the bucket public is a security downgrade — users can bypass CloudFront. Transfer Family also has hourly costs for infrequent uploads.

Key Takeaways

  • Private S3 + CloudFront + OAI is the cheapest, most resilient static hosting on AWS
  • Keep the origin bucket private — public buckets let users bypass CloudFront and CDN benefits
  • Use the AWS CLI or aws s3 sync for uploads — no SFTP server needed
  • For new distributions, prefer OAC over OAI, especially with SSE-KMS
  • Enable S3 Block Public Access on any bucket serving as a CloudFront origin
Rating:
Share
Previous S3 Interface VPC Endpoint: Private Access With Fine-Grained IAM Role Restriction Next Public But Immutable: S3 Object Lock for Untouchable Publicly-Readable Files