blogs-image

Deploying a Static Website on AWS S3 with CloudFront: A Complete Guide

Purpose

Hosting static websites on Amazon S3 and serving them via CloudFront offers a scalable, cost-effective, and highly performant solution. This guide walks you through deploying a static site, securing it, and optimizing delivery globally.

Prerequisites

  • An AWS account with permissions for S3, CloudFront, and IAM
  • A static website (HTML, CSS, JS, images, etc.) ready for deployment
  • Basic knowledge of AWS Console and CLI
  • (Optional) A custom domain and access to its DNS settings

Step-by-Step Deployment Guide

1. Create and Configure Your S3 Bucket

  1. Log in to the AWS S3 Console.
  2. Click Create bucket. Name it exactly as your domain (e.g., example.com).
  3. Uncheck Block all public access (required for static website hosting). Confirm the warning.
  4. Complete bucket creation.
  5. Upload your static website files to the bucket.

2. Enable Static Website Hosting

  1. In your S3 bucket, go to the Properties tab.
  2. Scroll to Static website hosting and click Edit.
  3. Select Enable and specify your index document (e.g., index.html).
  4. (Optional) Set an error document (e.g., error.html).
  5. Save changes and note the Bucket website endpoint.

3. Set Bucket Policy for Public Read Access

  1. Go to the Permissions tab of your bucket.
  2. Click Bucket Policy and add the following policy (replace YOUR_BUCKET_NAME):
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "PublicReadGetObject",
          "Effect": "Allow",
          "Principal": "*",
          "Action": "s3:GetObject",
          "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME/*"
        }
      ]
    }
  3. Save the policy.

4. Create a CloudFront Distribution

  1. Go to the CloudFront Console and click Create Distribution.
  2. For Origin domain, select your S3 bucket’s website endpoint (not the S3 REST endpoint).
  3. Set Viewer Protocol Policy to Redirect HTTP to HTTPS for security.
  4. Under Default Root Object, enter index.html.
  5. (Optional) Add your custom domain under Alternate domain name (CNAME) and attach an ACM SSL certificate.
  6. Click Create Distribution and wait for deployment (typically a few minutes).

5. (Optional) Point Your Domain to CloudFront

  1. In your DNS provider, create a CNAME record pointing your domain (e.g., www.example.com) to the CloudFront distribution domain name (e.g., d1234abcd.cloudfront.net).
  2. Allow DNS propagation (can take up to 24 hours).

Usage Examples

  • 1. Deploy via AWS CLI:
    aws s3 sync ./website s3://YOUR_BUCKET_NAME --delete
  • 2. Invalidate CloudFront Cache after Update:
    aws cloudfront create-invalidation --distribution-id DISTRIBUTION_ID --paths '/*'
  • 3. Integrate with GitHub Actions for CI/CD:
    - name: Deploy to S3
      run: aws s3 sync ./build s3://YOUR_BUCKET_NAME --delete
    - name: Invalidate CloudFront
      run: aws cloudfront create-invalidation --distribution-id ${{ secrets.CLOUDFRONT_ID }} --paths '/*'
  • 4. REST API Example to List Bucket Contents:
    curl https://YOUR_BUCKET_NAME.s3.amazonaws.com?list-type=2
  • 5. Use with Single Page Applications (SPA):

Security Best Practices

  • Restrict S3 bucket access to CloudFront only using Origin Access Control (OAC) or Origin Access Identity (OAI).
  • Enable HTTPS on CloudFront for secure content delivery.
  • Regularly review and update your S3 bucket policies.
  • Enable logging for both S3 and CloudFront to monitor access.
  • Use versioning in S3 to protect against accidental deletions or overwrites.

Feature Comparison: S3 Website Endpoint vs CloudFront

Feature S3 Website Endpoint CloudFront Distribution
HTTPS Support No (only HTTP) Yes (with free SSL/TLS)
Global CDN No Yes
Custom Domain Support Limited Full (with SSL)
Caching No Yes (configurable)
Access Control Basic (public/private) Advanced (signed URLs, OAI/OAC)

FAQs

Costs depend on storage, requests, and data transfer. S3 charges for storage and requests; CloudFront charges for data transfer and requests. For most small sites, costs are a few dollars per month. See S3 Pricing and CloudFront Pricing.

Yes. Use CloudFront with an ACM SSL certificate and add your domain as an Alternate Domain Name (CNAME) in the distribution settings.

Use Origin Access Control (OAC) or Origin Access Identity (OAI) to allow only CloudFront to access your S3 bucket. Update your bucket policy accordingly.

Set the S3 error document to index.html. In CloudFront, configure a custom error response to redirect 404 errors to /index.html with a 200 status code.

Upload new files to S3 (using the AWS Console or CLI), then create a CloudFront invalidation to refresh the CDN cache.

Conclusion

Deploying a static website using AWS S3 and CloudFront is a robust, scalable, and secure approach for modern web hosting. By following the steps and best practices above, you ensure your site is fast, reliable, and protected. For more details, refer to the AWS S3 Website Hosting Documentation and CloudFront Developer Guide.