CloudFront multi site based on paths / routes - amazon-web-services

Existing App
I have a website hosted on S3 and CloudFront. APIs are hosted on ECS and are served by CloudFront via /api/* Behaviour. To handle the manual entered routes I've configured Error Pages 404 and 403 to route to /index.html on Default Behaviour.
URL -> CF -> S3 (default origin)
URL/api/** -> CF -> LB -> ECS+Fargate
Requirement
What I'm trying to do is host Admin site under a new path /admin pointing to new S3 bucket (origin 3).
URL/admin -> CF -> S3 (Origin 3)
Problem
All the traffic at /admin path is falling under Error pages and is getting routed to Default origin.
Things I've checked:
There are no conflicting paths
Cleared Cache
S3 configs are exactly same on Default Origin Bucket and Origin 3 Bucket

I figured out the solution when I removed the Error pages config. After removing this config, I was getting Access Denied error. This is the error when really the access is not there OR when the object doesn't exists. So it seems that CloudFront was unable to access files on S3 bucket.
The solution was that /admin/ path require admin folder in s3 as well for both paths to map on each other. When I moved my files in 2nd S3 bucket in correct folder everything started working.
This is a great way to host 2 sites which can share the Cookies and FrontEnd context with each other as both are under the same domain. And you don't need to manage CORS as well for this.

Related

AWS Cloudfront rewrites CSS and JS references in index.html to index_files/style.css instead of css/style.css

I have the following setup:
S3 bucket where Website hosting is enabled, "block all access" default feature is disabled. In the bucket I have an index.html file a css and a js folder with some files. I referencing them in the HTML code like <link rel="stylesheet" href="index_files/style.css"> and <script src="js/somejsfile.js"></script>. I haven't made any of the objects public directly. The bucket name is mydomain.com (I also have a www.mydomain.com and s0ubqconfigured as website enabled resdirecting everything to mydomain.com bucket)
I have a single certificate with all the cname included (naked, www, sub1). Certificate is validated using Route53
I have created a Cloudfront distribution.
Origin Domain Name points to mydomain.com.s3.amazonaws.com
Origin Path was left empty
Restrict Bucket Access: yes
Created new Identity
Allowed Cloudfront to Update bucket policy (I verified later that the policy indeed was modified)
Alternate Domain Names: listed all 3 domains
Custom SSL certificate --> used the previously created cert
default root object: index.html
redirect HTTP to HTTPS
everything else is default
Route 53 alias for the cloudformation dns entry.
The problem:
The site seems completely broken both on mydomain.com and the cloudformation url. After checking the page source in Firefox it turnes out that somehow all the CSS and JS reference got overwritten like href="index_files/some-css-file.css" and src="index_files/some-js-file.js". I have no clue where this index_files comes from. I have double checked on S3, downloaded my index.html and the code does not have this index_files nonsense.
I used Firefox Web Developer tool to overwrite temporarly index_files to css and js and the sites load as it should be...
What am I missing? And where this index_files stuff comes from? My google-fu fails me on this one.
Edit/Update:
I used the AWS Console to configure everything so no terraform or cloudformation or even aws cli is involved. (this was supposed to be a fast PoC)
The content in S3 was copied there using S3 sync. Original content comes from a website which I httrack-ed (basically downloaded all the static content of the site)
BTW today I have checked the site again and it is working. No clue why. My modifications:
I have added new origins to the distribution using same settings but with the www and the sub1 S3 buckets as soruce (so now the distributiuon has 3 origin). I don't know why would this fix it, since those S3 buckets are empty and I was always testing the site using the naked mydomain.com.
I have added a CORS rule to the bucket to allow "*" and all GET methods. But since all the files in the same naked domain s3 bucket I don't know why whould this fix the issue.
So the usual meme:
my stuff is not working... Why?
my stiff is working... But why?

Multiple websites in the same S3 bucket

I am trying to host multiple websites with similar subdomains in the same S3 bucket under different folders with a cloudfront distribution that redirects to each folder.
Suppose my bucket is example.com and I want to host my angular website at sub1.example.com and another one at sub2.example.com. I have created folders for each of them in the bucket named sub1 and sub2. I have also created cloudfront distributions with the origin name points to the S3 bucket and added the origin path to the corresponding folder.
After doing this, if I try to go to sub1.example.com it works fine. But if I try sub1.example.com/home I get a 404 page with Code: NoSuchKey. I think this is because S3 is trying to look for sub1/home in the bucket rather than serving the angular file in the sub1 folder.
Is this something that can corrected? I need to do this with a single S3 bucket.
I've managed to fix the issue by following these instructions. I was able to fix the issue after adding Default Root Object when creating the cloudfront distribution and adding custom error responses in the cloudfront distribution that redirects 404 and 403 error codes to index.html.

Serve single page app under specific path with AWS

At the moment I have mydomain.com pointing to a Django EC2 instance with ABL in front of it and CF in front of the ABL.
Now I have the requirement of serving a React single page app under an specific path mydomain.com/my-specific-path (of course everything under HTTPS)
I tried everything I could to host my SPA in an S3 bucket and use CF to redirect the calls to that S3. But it was impossible to serve the app over HTTPS that way (because of S3 hosting and subfolders).
I am thinking now about setting a reverse proxy in front of my Django app. But I don't know if that is the best solution, and I don't know the best way to do it.
Could you please give me some insights about how to serve a SPA under a specific path?
Thank you in advance.
You need to:
1) Add your ALB as an origin to your CloudFront distribution
2) Add your S3 bucket website URL as an origin to your CloudFront distribution
Note: Adding S3 as an origin from the dropdown box that auto populates here will not work for hosting a website out of S3. This feature is for hosting static files only.
2a) Optionally lock your S3 bucket down to CloudFront using a condition in the bucket policy that checks for header value that only CloudFront and your S3 bucket knows
3) Set the default root object in your CloudFront distribution to be index.html
4) Upload your react app to a sub-folder in your S3 bucket, not in the root. This sub-folder must match the path you set on your React app origin in CloudFront
5) Set a default behaviour in your CloudFront distribution that points to your ALB
6) Set a behaviour in your CloudFront distribution that points my-specific-path/* to your S3 bucket origin
7) Terminate SSL on your CloudFront distribution using AWS Certificate Manager
This setup should give you SSL on both your Django app and your React app being hosted in S3.
I've got this running, screen shots below:

AWS S3 sending download.txt file

I'm setting up an S3 bucket behind CloudFront that is meant to serve static assets. My problem is doing a / on any directory with no file name will have the browser download a download.txt with 0 bytes. I have my S3 bucket setup for Static Website Hosting and is pubic, so I'm able to access my assets.
https://s3-bucket.domain.com/path/to/file.jpg -> get asset, working
https://s3-bucket.domain.com/path/to/file-bad-name -> Error status 403, working. Renders error.html from S3.
https://s3-bucket.domain.com/path/to/ -> sends download.txt, not working
How do I configure #3 to not send a download.txt and render an error page instead?
There are few things happening there.
You need to map it to new origin if you want to point the path to an S3 object.
Your pattern is not having priority in CloudFront.
If you fix one of the above or both, then it should work as expected.
I have my S3 bucket setup for Static Website Hosting and is pubic
...but you selected the bucket from the dropdown list when defining the origin... yes?
You need to configure the origin domain name to use the web site hosting endpoint for the bucket.
When you configure your CloudFront distribution, for the origin, enter the Amazon S3 static website hosting endpoint for your bucket. This value appears in the Amazon S3 console, on the Properties page under Static Website Hosting. For example: http://bucket-name.s3-website-us-west-2.amazonaws.com
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/DownloadDistS3AndCustomOrigins.html#concept_S3Origin_website
If you don't do this, and you created folders in the bucket using the S3 console, then what you are currently observing is the expected behavior, a side effect of the way the console creates those imaginary folders.

S3 website hosting - Too Many Redirects

I have a React app served from an S3 bucket which is set up for static website hosting, behind a Cloudfront distribution, with a custom domain (https://dev.meal-plannr.com) managed by Route 53.
When I go to my custom domain or the Cloudfront URL I get a "Too many redirections" (Safari) or "dev.meal-plannr.com redirected you too many times." (Chrome). Going to the S3 bucket URL loads the website fine. Interestingly I only get the error in Chrome if I have the dev tools displayed - without that the website loads correctly on all URLs.
Here is the configuration for each of the services mentioned above.
S3
Cloudfront
Origin configuration:
General:
Behaviours:
Error Pages:
Route 53
Up until around 30 minutes ago my S3 bucket was set up to redirect to https://dev.meal-plannr.com but I've since removed this. Have I misconfigured something?
I had the same issue after setting up a redirect for my S3 bucket. After clearing my Cloudfront Cache, everything was back to normal.