requests to www.mydomain.com/blabla... will be redirected to the same mydomain but without the www
This is done by creating an empty bucket in S3 named www.example.com
, configuring it to redirect all requests to a different hostname (example.com
) and pointing DNS at it.
If you want it to support https request redirection on the www side, you create a second CloudFront distribution for the www hostname, pointing to the web site endpoint for the bucket, and point DNS to CloudFront.
requests to mydomain.com/anything/including/path/like/this will give the s3 (/cloudfront) index.html
Configure the example.com
bucket (the one with your content, not the empty one discussed above) for static web site hosting, and set the index document name to index.html
in the bucket's static web site hosting configuration options. As discussed in the S3 documentation, when the S3 web site hosting feature is enabled for the bucket, the named index page from the appropriate place in the bucket will automatically be returned by S3 wherever possible, according to these rules:
If the the path requested is /foo/bar/
(with trailing slash) then S3 looks for an object with the key foo/bar/index.html
and returns it, leaving the browser's address bar unchanged.
If the path requested is /foo/bar
(no trailing slash) and foo/bar/index.html
exists, then S3 returns a redirect to /foo/bar/
, which results in the behavior described above, after the trailing /
appears in the browser's address bar. (This is redirection to add the trailing slash is standard web server behavior; otherwise relative links in the index page will pointing to the wrong directory).
Instead of selecting the bucket from the drop-down list in CloudFront, you need to type in the web site endpoint hostname for the bucket, when setting up the CloudFront origin. Otherwise the web site features like index documents won't be enabled:
Important
Do not select the name of your bucket from the list, such as example.com.s3.amazonaws.com
http://docs.aws.amazon.com/gettingstarted/latest/swh/getting-started-create-cfdist.html
Next issue:
requests to mydomain.com/path/or/not/path/file_that_ends_with_any_extesnion_like.js will serve that file from the s3 (/cloudfront) if it's too hard I can also set up my website so all that assests will be in the assets folder so requests to mydomain.com/assets/path/blabla.bla will serve the static file from the s3 (/cloudfront)
You can configure CloudFront to choose which "origin" (back-end system) a request will be sent to, using cache behaviors, each of which matches a path pattern. It sounds like, in this case, you'd want your default cache behavior to point to the bucket, which will send all requests there, if not matching another cache behavior.
and last but not least requests to mydomain.com/api/... will redirect to the ec2 instance which holds my REST API node.js server
Presumably you don't really mean "redirect" but instead you mean "forward" or "proxy" (same thing) requests to the EC2 instance.
Declare the EC2 instance as another origin in the CloudFront distribution for your site. Create a new cache behavior matching path pattern /api/*
that uses this origin, and CloudFront will send these requests to your EC2 instance.
Be sure your code on EC2 returns appropriate Cache-Control:
headers on API responses so that CloudFront will cache them for an appropriate amount of time, or not at all if you return Cache-Control: no-cache
.
Note that on cache behavior path patterns, a missing leading slash is implicit, so api/*
is equivalent to /api/*
.
Note also that CloudFront has a setting called "origin path", an attribute of the origin, which sometimes people get confused with "path pattern," which is an attribute of cache behaviors. Leave "origin path" blank, because it is not related to the paths you want to send to a particular origin.
There are three, maybe four possibilities:
you have in fact configured this domain as an Alternate Domain Name in CloudFront -- in this AWS account or in another account and you've forgotten about it, or
someone else has accidentally or deliberately configured this domain on a CloudFront distribution, or
you already configured this in API Gateway, but in a different AWS Region, or
this is a bug in the integration between API Gateway and CloudFront.
To troubleshoot:
Go to CloudFront and create a new distribution.
Try to set this hostname as an alternate domain name.
If that works, then this seems like a bug in the API Gateway/CloudFront integration. Delete the hostname from Alternate Domain Names for that new distribution, wait a few minutes for the distribution to go back to Deployed
status, then try again in API Gateway. (Later, delete the distribution -- it isn't needed).
But, I'm going to assume that the above will not work. You should get an error from CloudFront, CNAMEAlreadyExists
. (It's not really a CNAME but that's what they unfortunately called it.)
So, follow the official process to prove ownership and control of your domain name and associate it with the new CloudFront distribution.
This process should release that hostname from whatever CloudFront distribution is claiming it.
Once that completes, remove this hostname from the Alternate Domain Names setting of the new distribution, save changes, wait for it to return to the Deployed
state, and go back to API Gateway and try again. (Later, delete the unused distribution.)
The issue here is that -- just like the S3 bucket namespace -- the CloudFront front-end Host:
header namespace is global. A hostname can't be associated with more than one CloudFront distribution, including the "stealth" distributions that API Gateway uses. The error implies that the one you're trying to use, for some reason, already is.
This should be unrelated to a wildcard you may have from ACM.
Best Answer
I run multiple web apps exactly with your proposed design, and I extracted gofaas, an educational Go and Lambda app, to share the techniques.
You need two separate domains, e.g.
www.gofaas.net
for S3 + CloudFront andapi.gofaas.net
for API Gateway + Lambda.Then you can let your static site interact with the API with an API Gateway CORS configuration and some JavaScript:
Here are some guides for setting all this up:
Static Websites with S3, CloudFront and ACM
API Security with Lambda, API Gateway, CORS and JWT