Efficient Multi-Site Hosting with AWS: One S3 Bucket, Multiple Websites

Streamline Your Web Infrastructure with Amazon S3 and CloudFront Functions

·

3 min read

As web developers and cloud architects, we often face the challenge of efficiently hosting multiple websites while maintaining security. In this blog post, we'll explore an elegant solution using Amazon S3 and CloudFront to host multiple websites from a single private S3 bucket. We'll walk through the process of setting up two subdomains, each serving content from different folders within the same bucket.

The Challenge

Imagine you need to host two separate websites: Site1 and Site2. You want to serve them under different subdomains (site1.example.com and site2.example.com) while keeping your S3 bucket private for enhanced security.

The Solution: Amazon S3 + CloudFront Functions

We'll leverage the power of Amazon S3 for storage and Amazon CloudFront for content delivery. Here's an overview of our architecture:

  1. A private Amazon S3 bucket containing two folders: "site1" and "site2".

  2. An Amazon CloudFront distribution to serve content and handle subdomain routing.

  3. A custom CloudFront function to modify request URIs based on the subdomain.

Let's dive into the implementation details.

Step 1: Set Up Your S3 Bucket

Create a private S3 bucket with two folders:

  • site1/

  • site2/

Upload your website files to their respective folders.

Step 2: Create a CloudFront Distribution

  1. Create a new CloudFront distribution

  2. Set the origin to your private S3 bucket

  3. Configure the default cache behavior:

    • Set "Viewer Protocol Policy" to "Redirect HTTP to HTTPS"

    • Set "Allowed HTTP Methods" to "GET, HEAD" (add others if needed)

Step 3: Implement a CloudFront Function

Create a new CloudFront function with the following code:

function handler(event) {
    var request = event.request;
    var headers = request.headers;
    var host = headers.host.value;
    var uri = request.uri;

    if (host.startsWith("site2.")) {
        if (uri === "/") {
            request.uri = "/site2/index.html";
        } else {
            request.uri = "/site2" + uri;
        }
    } else if (host.startsWith("site1.")) {
        if (uri === "/") {
            request.uri = "/site1/index.html";
        } else {
            request.uri = "/site1" + uri;
        }
    }

    return request;
}

Step 4: Associate the Function with Your Distribution

In your CloudFront distribution's settings:

  1. Go to the "Behaviors" tab

  2. Edit the default cache behavior

  3. In the "Function Associations" section, add a new association:

    • Set "Event Type" to "Viewer Request"

    • Select the CloudFront function you created in Step 3

Step 5: Configure DNS

Update your DNS records to point the subdomains to your CloudFront distribution's domain name:

The Result

With this setup, your websites will be served as follows:

Your S3 bucket remains private, with access controlled through the CloudFront distribution. The CloudFront function handles subdomain routing, ensuring that the appropriate content is served based on the requested subdomain.

Additional Considerations

  1. S3 Bucket Policy: Update your S3 bucket policy to grant necessary permissions to the CloudFront Origin Access Identity (OAI).

  2. HTTPS: Ensure you have valid SSL certificates for your subdomains, which can be easily managed through AWS Certificate Manager.

  3. Caching: Fine-tune CloudFront caching settings to optimize performance and reduce S3 requests.

Conclusion

This solution provides an efficient and secure way to host multiple websites from a single private S3 bucket using Amazon CloudFront. It offers several benefits:

  • Secure: Keep your S3 bucket private while serving content publicly

  • Scalable: Easily add more subdomains by updating the CloudFront function

  • Performant: Leverage CloudFront's global CDN for fast content delivery

By following this guide, you can streamline your web hosting infrastructure, enhance security, and improve the overall management of your multiple website projects.

Happy coding!

Did you find this article valuable?

Support Yash Bhuva by becoming a sponsor. Any amount is appreciated!