How do I 301 redirect a single page on my Cloudfront/ S3 hosted web page? - amazon-web-services

I use an AWS Cloudfront + S3 solution to host my website.
I redirect all naked domain and vanilla HTTP requests to the prefix https://www.example.com.
The following S3 Cloudfront Architecture cartoon captures my approach:
In addition to the existing logic, I would like to also redirect a single page, namely:
https://www.example.com/category/coins/
to
https://www.example.com/cat/coins.html
I tried to do this via the S3 buckets redirect rules and received a 301 redirect to the bucket address, and not the cloudfront endpoint.
e.g.
http://www.example.com.s3-website-us-east-1.amazonaws.com/cat/coins.html
How can I correctly redirect this particular page?

AWS provides documentation on how to redirect with CloudFront and that are Viewer Request Functions.
S3 also has documentation on how to do redirects based on different hosts
Configure Host name in S3 (S3 -> Properties -> Static website hosting -> Host name). This may rewrite the domain part (I'm not 100% sure)
Advanced redirection rules allow to replace paths with different keys which should definitely work. There is an example on the page that fits the question

Related

HTTP redirects in the AWS world, anything better than S3+CloudFront?

I'm moving my domain names from CloudFlare's DNS to AWS Route53 and in some cases I'm using CloudFlare's redirects for project that are dead so that their domains go to a page in another domain, so https://projectx.com goes to https://example.com/projectx-is-no-more.
I want to replicate this in AWS and what I found so far is this:
Set up an S3 bucket with the redirect to the desired URL, https://example.com/projectx-is-no-more
Set up CloudFront for the domain, projectx.com
Generate the TLS cert for projectx.com and add it to CloudFront so it can serve both https and http.
Set up Route53 to resolve the domain name to CloudFront.
I set it up, it's working, I'm even using CDK so I'm not doing it manually. But I'm wondering if there's a way of setting up these redirects that requires less moving pieces. It sounds like such a redirect would be a common enough problem that maybe Route53 or CloudFront would have a shortcut. Are there any?
Update: using only S3 doesn't work because S3 cannot serve https://projectx.com. S3 has no method by which it can respond to HTTPS request for arbitrary domains, there's no way of adding a TLS certificate (and keys) for another domain.
I checked for information and see only three possible solutions:
Set up CloudFront + S3 *
Set up Application Load Balancer
Set up API Gateway + Lambda (mock integration may be used instead of Lambda, that should reduce service cost)
Use GitHub pages with custom domain
※ S3 support only HTTP traffic so we need to add CloudFront for HTTPS:
Amazon S3 does not support HTTPS access to the website. If you want to use HTTPS, you can use Amazon CloudFront to serve a static website hosted on Amazon S3.
In my opinion the ②nd way is super easy to set up but running 24/7 ALB is little bit expensive. In other way Lambda and API Gateway price depending on requests count. CloudFront seems to be cheaper than ALB too.
So the better solution is depending on how many requests you have
The ④th solution is depends on GitHub platform (wider than AWS only scope), but it is absolutely free and support custom domain and Let's Encrypt certificates out of the box.
You just need to create repository with static index.html file that will do redirects
You can do it without including CloudFront.
What you need to do is create S3 bucket projectx.com. In Properties go to Static website hosting. Enable static website hosting and choose Redirect as a hosting type (add the redirection URL).
You will still need to set up Route53, but you will now add alias to this projectx.com bucket, instead of going to CloudFront

How to use Amazon S3 to do domain forwarding while preserving URL paths?

My goal is to redirect a naked domain [example.org][1] to [www.example.org][2] while preserving the URL paths exactly.
e.g., a GET request to http://example.org/foobar/file.html results in a 302 to http://www.example.org/foobar/file.html
I do not want to setup or configure any servers to do this.
Currently the plan is to use Amazon's S3 static hosting redirect service (as suggested in this answer).
However, I cannot figure out how (or if its possible?) to configure the Amazon S3 bucket to perform the redirect while preserving the path.
There are two options on the Static Website Hosting configuration screen, "Use this bucket to host a web site" and "Redirect requests."
Choose "Redirect requests." You're prompted only for the target hostname and port. This option automatically preserves the path.
The documentation doesn't seem to mention that fact, but that's what happens when you choose that option. You only need the more complicated routing rules if you want to modify the path, or only redirect certain paths.

Supporting HTTPS URL redirection with a single CloudFront distribution

I have a domain formulagrid.com.
I am using AWS S3 to host it as a static website. My problem was that I wanted to redirect the www subdomain to the bare domain like so:
https://www.formulagrid.com -> https://formulagrid.com
http://www.formulagrid.com -> https://formulagrid.com
Amazon provides URL redirecting from S3 bucket to S3 bucket if both are setup for static website hosting.
So what I had to do was set up two buckets:
formulagrid.com - actual website
www.formulagrid.com - exists solely to redirect to the actual website
This works perfectly fine if you're operating only over HTTP, but S3 has absolutely no support for HTTPS.
The way that one can use HTTPS to connect to an S3 static website is by setting up a CloudFront distribution in front of an S3 bucket. CloudFront, however, while it does provide HTTPS, mainly exists to function as a CDN.
Initially, I had a single CloudFront distribution setup in front of the S3 bucket holding the actual site. Everything seemed operational: the site was distributed over the CDN, it had HTTPS, and HTTP redirected to HTTPS.
There was one exception.
https://www.formulagrid.com was a completely broken page
After trying to find the source of the error for a while, I realized it's because it wasn't going through the CDN, and trying to access S3 over HTTPS doesn't work.
Finally, what I ended up having to do was provision another distribution to sit in front of the www S3 bucket so it was accessible over HTTPS. This is where my concerns come in because, like I mentioned earlier, CloudFront's main purpose is to be a CDN.
It doesn't make any sense to me to have a CDN sit in front of a url that just redirects to another. Also it brings up the question of whether I would be double charged for every request that hits the www subdomain because it'd hit the other CloudFront distribution after being redirected.
This is frustrating because I'm trying to do a "serverless" architecture using Lambda, and having to provision an EC2 instance just to do url rewriting isn't something I want to do unless it's my last resort.
The solution would be trivial if Amazon offered any form of URL rewriting or if CloudFront itself did redirecting, but neither of these exist as far as I know (let me know if they do).
I'm new to AWS so I'm hoping someone with more experience can point me in the right direction.
You're thinking too narrowly -- there's nothing wrong with this setup.
The solution would be trivial if Amazon offered any form of URL rewriting
They do -- the empty bucket.
S3 has absolutely no support for HTTPS.
Not for web site hosted buckets, no... but CloudFront does.
CloudFront is not just a CDN. It's also an SSL offloader, Host: header rewriter, path prepender, geolocator, georestrictor, secure content gateway, http to https redirector, error page customizer, root page substituter, web application firewall, origin header injector, dynamic content gzipper, path-based multi-origin http request router, viewer platform identifier, DDoS mitigator, zone apex alias target... so don't get too hung up on "CDN" or on the fact that you're stacking one service in front of another -- CloudFront was designed, in large part, to complement S3. They each specialize in certain facets of storage and delivery.
So, you did it right... most of it, anyway... Create a bucket, configure it for web site hosting, set it to redirect all requests to another site (the non-www) and put a CloudFront distribution in front of it -- using the web site endpoint URL for with bucket in CloudFront, not the one from the drop-down list -- configured with high TTLs so that CloudFront will send a minimal number of requests to S3 then put your (free!) SSL certificate from Amazon Certificate Manager. HTTPS alternate domain routing: solved. No servers, no troubleshooting, and cheap. The only charges are the usage -- there is no background recurring charge as there would be with servers.
Extra credit: configure the redirecting CloudFront distribution for the cheapest rate tier. Redirects from more expensive locations will either be routed to a cheaper edge location or -- at CloudFront's option -- may be served out of a higher cost location but billed at the lower rate.
Note that most of the time, CloudFront should serve the redirects from S3 from it's cache... and when you configure a bucket to redirect all requests to another hostname, the redirect is a 301 permanent redirect -- which browsers are supposed to cache, themselves.

How do you use Amazon Route 53 to redirect a subdomain to a specific page?

I would like to redirect my subdomain "subdomain.example.com" to a specific page on my site "example.com/specific-page" using Amazon Route 53. Is this possible?
I saw this answer and tried it (Set up DNS based URL forwarding in Amazon Route53) but that appears to only allow you to redirect to root domains, not specific pages on that domain.
Is this possible with Route 53?
Set up Route53 to point to the subdomain. The rest should be handled by your webserver.
For Apache, you can use .htaccess.
For NGINX, I'd set up the server and location blocks accordingly.
I don't believe that this is possible.
You could set up a DNS wildcard, so that *.example.com was mapped to a specific server, and then that server could use something like mod_rewrite to redirect from somename.example.com to example.com/somename.
This is actually fairly simple.
Follow the instructions outlined in the original example, except do not follow step #3.
Instead of following step #3 do this:
In the S3 Properties for subdomain.example.com select Static Website Hosting.
Select the radio button for Redirect all requests to another host name.
In the textbox, enter example.com/specific-page.
Click Save.
Proceed with the rest of the steps as outlined in the original example.
Your bucket should look like this:
You could solve this problem by creating an S3 bucket, enabling the bucket for static web hosting. On the static web hosting tab in the bucket, you can configure a redirect rule, set that redirect rule to https and set the redirect host to the desired address e.g.example.com/blabla
Then go over to Route53, configure a A record for the hosted zone, enable Alias, and point the A record to the S3 bucket endpoint.

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
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'.
Short answer: no.
Long answer: though it is possible, it is extremely inefficient. You could setup a proxy server (e.g. in Nginx) or setup HAProxy for custom path rules, but it would double your bandwidth costs (CDN -> proxy -> client, instead of CDN -> client). Moreover, it would not make sense, since there are basically no benefits left for using a CDN in the first place.
This is based on the assumption that mydomain.com does provide dynamic content. If it does not, you could just as well host the entire domain (mydomain.com) on S3.