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
- Log in to the AWS S3 Console.
- Click Create bucket. Name it exactly as your domain (e.g.,
example.com
). - Uncheck Block all public access (required for static website hosting). Confirm the warning.
- Complete bucket creation.
- Upload your static website files to the bucket.
2. Enable Static Website Hosting
- In your S3 bucket, go to the Properties tab.
- Scroll to Static website hosting and click Edit.
- Select Enable and specify your
index document
(e.g.,index.html
). - (Optional) Set an
error document
(e.g.,error.html
). - Save changes and note the Bucket website endpoint.
3. Set Bucket Policy for Public Read Access
Warning: Granting public read access exposes your files to the internet. Only do this for static, non-sensitive content.
- Go to the Permissions tab of your bucket.
- 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/*" } ] }
- Save the policy.
4. Create a CloudFront Distribution
- Go to the CloudFront Console and click Create Distribution.
- For Origin domain, select your S3 bucket’s website endpoint (not the S3 REST endpoint).
- Set Viewer Protocol Policy to Redirect HTTP to HTTPS for security.
- Under Default Root Object, enter
index.html
. - (Optional) Add your custom domain under Alternate domain name (CNAME) and attach an ACM SSL certificate.
- Click Create Distribution and wait for deployment (typically a few minutes).
5. (Optional) Point Your Domain to CloudFront
- 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
). - 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):
Set the
error document
in S3 toindex.html
to handle client-side routing.
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.