Aws
AwsIntermediate

How to Host a Static Website on AWS S3 (Step-by-Step Guide)

Admin
6 min read
AWSS3Static WebsiteCloudFrontHosting

TL;DR

Learn how to host your static website on Amazon S3, configure permissions, and set up custom domains with CloudFront.

How to Host a Static Website on AWS S3

``mermaid

graph LR

Users((Users)) --> CF[CloudFront]

CF --> S3[S3 Bucket]

S3 --> Index[index.html]

S3 --> Error[error.html]

S3 --> Assets[Static Assets]

subgraph Security

WAF[AWS WAF] --> CF

ACM[ACM Certificate] --> CF

end

subgraph DNS

Route53[Route 53] --> CF

end

`

$1

  • Setting up an S3 bucket for static website hosting
  • Configuring bucket permissions and policies
  • Enabling HTTPS with CloudFront
  • Setting up custom domains with Route 53
  • Implementing security best practices
  • Optimizing performance and costs
  • Troubleshooting common issues
  • $1

    $1

    Requirement Purpose Notes
    AWS Account Service access Free tier eligible
    AWS CLI Command-line management Version 2.x recommended
    Domain Name Custom URL (optional) Can use Route 53 or external registrar

    $1

    File Type Required Best Practice
    HTML files Yes Minified for production
    CSS/JavaScript Optional Bundled and minified
    Images Optional Optimized and compressed

    $1

    $1

    `bash

    Create S3 bucket

    aws s3api create-bucket \

    --bucket your-website-bucket \

    --region us-east-1

    Enable website hosting

    aws s3api put-bucket-website \

    --bucket your-website-bucket \

    --website-configuration file://website-config.json

    `

    $1

    `json

    {

    "IndexDocument": {

    "Suffix": "index.html"

    },

    "ErrorDocument": {

    "Key": "error.html"

    }

    }

    `

    $1

    `json

    {

    "Version": "2012-10-17",

    "Statement": [

    {

    "Sid": "PublicReadGetObject",

    "Effect": "Allow",

    "Principal": "*",

    "Action": [

    "s3:GetObject"

    ],

    "Resource": "arn:aws:s3:::your-website-bucket/*"

    }

    ]

    }

    `

    $1

    `json

    {

    "CORSRules": [

    {

    "AllowedOrigins": ["*"],

    "AllowedMethods": ["GET"],

    "MaxAgeSeconds": 3000,

    "AllowedHeaders": ["Authorization", "Content-Length"]

    }

    ]

    }

    `

    $1

    $1

    `plaintext

    your-website/

    ├── index.html

    ├── error.html

    ├── assets/

    │ ├── css/

    │ │ └── styles.css

    │ ├── js/

    │ │ └── main.js

    │ └── images/

    │ └── logo.png

    ├── blog/

    │ └── index.html

    └── about/

    └── index.html

    `

    $1

    `bash

    Upload all files with proper content types

    aws s3 sync . s3://your-website-bucket \

    --exclude "*.DS_Store" \

    --exclude "node_modules/*" \

    --include "*.html" \

    --include "*.css" \

    --include "*.js" \

    --include "*.jpg" \

    --include "*.png" \

    --cache-control "max-age=86400"

    `

    $1

    File Type Content-Type Cache Control
    .html text/html no-cache
    .css text/css max-age=604800
    .js application/javascript max-age=604800
    images image/[type] max-age=31536000

    $1

    $1

    Setting Value Explanation
    Origin Domain bucket-name.s3-website-region.amazonaws.com S3 website endpoint
    Origin Path / Root path
    Viewer Protocol Policy Redirect HTTP to HTTPS Force HTTPS
    Allowed HTTP Methods GET, HEAD Static content only
    Cache Policy CachingOptimized Best for static sites
    Price Class Use All Edge Locations Global distribution

    $1

    Function Type Purpose Example
    Viewer Request URL rewriting Add index.html
    Origin Request Header modification Add security headers
    Origin Response Response modification Add CORS headers

    $1

    $1

    `bash

    Request certificate

    aws acm request-certificate \

    --domain-name example.com \

    --validation-method DNS \

    --subject-alternative-names www.example.com

    `

    $1

    Record Type Name Value TTL
    A (Alias) example.com CloudFront distribution Automatic
    CNAME www CloudFront domain 300 seconds
    AAAA (Alias) example.com CloudFront distribution Automatic

    $1

    $1

    `json

    {

    "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",

    "Content-Security-Policy": "default-src 'self'",

    "X-Content-Type-Options": "nosniff",

    "X-Frame-Options": "DENY",

    "X-XSS-Protection": "1; mode=block",

    "Referrer-Policy": "strict-origin-when-cross-origin"

    }

    `

    $1

    `json

    {

    "ErrorDocument": {

    "Key": "error.html"

    },

    "RoutingRules": [

    {

    "Condition": {

    "HttpErrorCodeReturnedEquals": "404"

    },

    "Redirect": {

    "HostName": "example.com",

    "ReplaceKeyWith": "404.html"

    }

    }

    ]

    }

    ``

    $1

    $1

    Path Pattern TTL Settings Compression
    /*.html 0 seconds Yes
    /assets/images/* 1 year No
    /assets/css/* 1 week Yes
    /assets/js/* 1 week Yes

    $1

    Format Use Case Optimization Tool
    WebP Modern browsers cwebp
    JPEG Photos jpegoptim
    PNG Icons/logos pngquant

    $1

    $1

    Metric Description Threshold
    Requests Total requests Monitor trends
    BytesDownloaded Data transfer Cost control
    4xxErrorRate Client errors Less than 1%
    5xxErrorRate Server errors Less than 0.1%

    $1

    $1

    1. Storage Optimization

    - Enable lifecycle policies

    - Remove unused files

    - Use appropriate storage class

    2. CloudFront Optimization

    - Choose appropriate price class

    - Optimize cache hit ratio

    - Monitor data transfer

    3. Request Optimization

    - Bundle and minify assets

    - Use appropriate cache settings

    - Implement lazy loading

    $1

    Component Usage Estimated Cost
    S3 Storage 1 GB $0.023
    Data Transfer 100 GB $8.50
    Requests 1M $0.40

    $1

    $1

    1. Weekly

    - Monitor error rates

    - Check access logs

    - Review security findings

    2. Monthly

    - Update content

    - Review metrics

    - Cost analysis

    3. Quarterly

    - Security assessment

    - Performance optimization

    - Infrastructure review

    $1

    $1

    Issue Possible Cause Solution
    403 Forbidden Bucket policy Verify permissions
    HTTPS not working SSL certificate Check ACM setup
    Slow loading Cache settings Optimize CloudFront
    404 errors Missing files Check file paths

    $1

    Hosting a static website on AWS S3 with CloudFront provides a scalable, secure, and cost-effective solution. By following this comprehensive guide and implementing the best practices, you can create a high-performance website with global reach.

    $1

    1. [AWS S3 Documentation](https://docs.aws.amazon.com/AmazonS3/latest/userguide/WebsiteHosting.html)

    2. [CloudFront Developer Guide](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Introduction.html)

    3. [AWS Pricing Calculator](https://calculator.aws)

    4. [AWS Well-Architected Framework](https://aws.amazon.com/architecture/well-architected/)

    5. [Static Website Security Guide](https://aws.amazon.com/blogs/networking-and-content-delivery/)

    Why This Matters

    Understanding the business and technical context helps you make informed decisions rather than blindly following patterns.

    Trade-offs to Consider

    Every architectural decision involves trade-offs. Consider your specific requirements, team expertise, and scale when evaluating options.

    When NOT to Use This

    Knowing when a solution doesn't apply is as valuable as knowing when it does. Consider alternatives for your specific situation.

    Decision Framework

    Use this framework to evaluate whether this approach is right for your use case based on your specific constraints and requirements.