Search code examples
amazon-web-servicesamazon-ec2amazon-cloudfrontamazon-route53

AWS CloudFront distributions under same domain as web server


Currently I have my webserver at mydomain.com and two CDNs at static.mydomain.com and media.mydomain.com.

Would it be possible to have all under mydomain.com? e.g.

mydomain.com - webserver

mydomain.com/static - static CDN

mydomain.com/media - media CDN


Solution

  • This configuration should be possible using a combination of Route 53's alias feature, S3 redirects and CloudFront behaviors.

    1 Configuring a CloudFront distribution with multiple origins and path matching behaviors

    It looks like you have three different content origins, the 'webserver' content, the 'static' content, and the 'media' content. CloudFront should be able to serve the content for each of these origins behind the same domain name. To set this up you'll need to configure three different origins within your CloudFront distribution. Here's a guide to creating a CloudFront distribution, and I've provided an overview below: http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/CreatingDownloadDistributions.html

    • Setup the 'webserver' as the origin when you create the distribution
    • Once the distribution is created, navigate to the distribution settings and click into the origin tab
    • Add two more origins, one for static and one for media
    • Click on the behaviors tab
    • Create a new behavior with a path pattern of /static/* and select the 'static' content origin you just created. Repeat the steps to create a second behavior for the /media/* path and point this behavior to the 'media' content origin. Anything that doesn't match these two patch patterns will fall back to the default behavior and will serve content from your 'webserver' origin.

    2 Configure CloudFront to work with your domain name

    When you create a CloudFront distribution you are issued a distribution name under the 'cloudfront.net' domain. In order for CloudFront to work in conjunction with your own domain name, you'll need to configure a CNAME that points 'www.mydomain.com' domain to the CloudFront distribution DNS name. Then you'll need to configure your CloudFront distribution to respond when it sees requests for the www.mydomain.com domain.

    Docs: http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/CNAMEs.html

    • Edit your CloudFront distribution, and navigate to the 'General' tab of distribution details. Click the edit button and add 'www.mydomain.com' to the list of Alternative Names
    • Within your 'mydomain.com' hosted zone in Route 53, create a new RRSet as a CNAME type, set the name to www.mydomain.com, and configure the value to be the 'Domain Name' assigned to the CloudFront distribution you've already created. You can find the distribution 'Domain Name' in the General tab of distribution details.

    At this point, when you browse to www.mydomain.com, you'll be routed to the nearest CloudFront edge location, and the content returned will come from one of three different content origins based on the path of the request. But you'd also like 'mydomain.com' to behave the same way. You can achieve this by creating a www-lyzer with Route 53 Aliases and S3 redirects.

    3 Creating a www-a-lizer at the zone apex of 'mydomain.com' with Route 53 alias and S3 redirects

    This blog post provides a pretty good walk through of Route 53 Alias and S3 redirects, for this example we'll need to make a couple of adjustments called out in the steps below:

    http://aws.typepad.com/aws/2012/12/root-domain-website-hosting-for-amazon-s3.html

    • Create a new S3 bucket called 'mydomain.com' using the S3 console
    • Configure the 'mydomain.com' bucket to redirect all requests to 'www.mydomain.com'. Note because we need to redirect to something other than an S3 bucket, we'll have to use redirection rules instead of the 'Redirect all requests' option. So within your bucket properties, click the 'Enable website hosting' radio button. Expand 'Edit Redirection Rules' and add the following rules configuration:
    <RoutingRules>
        <RoutingRule>
            <Redirect>
                <HostName>www.mydomain.com</HostName>
            </Redirect>
        </RoutingRule>
    </RoutingRules>
    
    • Using the Route 53 console, open your 'mydomain.com' hosted zone and create a new RRSet as follows:

    Name: 'mydomain.com'

    Type: 'A'

    Alias: 'Yes'

    • In the value field, you should see the bucket you just created. Choose the 'mydomain.com' bucket.

    Response to the comment:

    The goal of the third step is to ensure that requests to 'mydomain.com' are directed through the CloudFront distribution. Ideally, we'd be able to use CNAMEs as outlined in step 2, however CNAMEs can't be used at the zone apex. For the time being this means we have to jump through some hoops.

    It is possible to use expanded redirection rules within S3 to redirect to different origins based on path matching. That would mean all of your user's requests would hit S3 before redirecting to the CDN or directly to your origin. That would add a bit more latency to each request. To get the best performance from the CDN, you'll want your users to connect as directly as possible (ideally with no redirects). The solution proposed above counts on the fact that redirection happens only one time (when the user request 'mydomain.com'), and all subsequent user requests go directly to 'www.mydomain.com'.

    As for POST and authentication via CloudFront. CloudFront will pass back cookies and query strings to the origin, if its configured to do so. If your auth system can leverage either of these methods for token passing, you should be able to pass your auth requests through CloudFront. At this time, CloudFront does not passthrough POST requests to the origin. If you're using client-side script to POST, then you could POST around CloudFront using a different DNS name. e.g. 'post.www.mydomain.com'.