API Gateway + S3 Integration proxy - Handle key not found - amazon-s3

Currently I have an API Gateway integrated with S3 bucket with {proxy} resource.
When a key that doesn't exist is passed it returns "Specified key doesn't exist".
Is there a way to configure the resource/method so it returns a default key (e.g. a 404.html) when the informed one doesn't exist?
I tried adding the 404.html to the Error document in the S3 bucket (it's configured for static website hosting)

Related

CloudFront or S3 ACL: This XML file does not appear to have... AccessDenied / Failed to contact the origin

I'm using custom domain and CloudFront for S3 static hosting site to serve https.
It's working fine when I open the pages through the app's internal buttons or link,
but if I input direct URL in the address bar, or click the browser refresh button, it shows
This XML file does not appear to have any style information associated with it. The document tree is shown below.... Access Denied error screen.
I searched related answers and tried to /index.html in the CloudFront general setting as Default Root Object but it didn't work. (Before this try, it was index.html)
When I updated it as /index.html, even the domain itself didn't work.
I have another S3 static hosting site without CloudFront and certificate just for testing.
This site is working fine even I input direct url or click the refresh button.
Above two S3 bucket have same settings (root object is index.html and error document is also index.html)
After this, I changed CloudFront Origin Domain Name from REST endpoint to website endpoint referred to this docs (https://aws.amazon.com/premiumsupport/knowledge-center/s3-website-cloudfront-error-403/)
But now getting this error when I refresh the screen.
All the object in S3 is owned to bucket owner and has public access.
This app is made by React and using react-router-dom.
Could you give me any hint or advice?
Thanks.
Solved...
My S3 bucket region requires . instead of - when I use website endpoint for cloudfront.
And FYI..
In my case, there are some little difference with the document and some tutorial. My CloudFront distribution doesn't need to use default root object, and individual objects in S3 has no public access but the bucket has it.
There are some specific endpoints to be used for website hosting buckets, which are listed in the Amazon Simple Storage Service endpoints and quotas document. For example, when hosting in eu-west-1, cloudfront will prepopulate the dropdown with example.s3.eu-west-1.amazonaws.com, but if you look into the bucket settings, Static website hosting section, it will show you the correct url example.s3-website-eu-west-1.amazonaws.com
Carefully read the table! The url scheme is not fully consistent, eg. s3-website.us-east-2.amazonaws.com but s3-website-us-east-1.amazonaws.com - just to make your day a bit more joyful.
So I had the exact same issue and was able to resolve it after taking the s3 bucket endpoint located in the properties of the s3 bucket and then pasting it into the cloudfront origins section into the origin domain. I removed the beginning of the endpoint for example: "http://website.com.s3-website.us-east-2.amazonaws.com" you would just remove the "http://" and then post the rest into the cloudfront origin domain and click save. That should solve the problem!
I tried all kinds of different options such as making sure every object was public as well in the s3 bucket. Make sure your s3 bucket is also publicly available.
Certain regions do have different endpoints for your s3 buckets. Here is a link that shows more of that: https://aws.amazon.com/premiumsupport/knowledge-center/s3-rest-api-cloudfront-error-403/

How to integrate API Gateway with S3 AWS Service using greedy path proxy resource

I have files in an S3 bucket that I am serving using AWS API Gateway
I have a resource GET /{file} that maps to mybucket:/{file}
ie http://myapigateway.com/test1.txt correctly returns mybucket:/test1.txt
Now I want to serve files with directory paths:
http://myapigateway.com/dirA/test2.txt should return the file mybucket:/dirA/test2.txt
I can not get this to work. The problem is that when I set the new API Gateway resource to use greedy path matches as a "proxy resource":
GET /{proxy+}
I no longer have the option to integrate with s3 (see image below)
I tried to pass the method.request.querystring.proxy var instead of method.request.path.proxy to prevent the slashes from being stripped but that didn't help.
If I can't integrate with s3 directly, is there any way I can work-around with a lambda function?
screen-shot: no option to integrate with AWS Service

How to host website in S3 and CloudFront?

I am trying to host my Angular website using CloudFront, S3, and Amazon EC2
instances. I am creating a bucket for e.g. bucket_name and creating 3 folders in it naming:-
1. example
2. login
3. logout
And my URL is:-
1. abc.com/example/
2. abc.com/example/login
3. abc.com/example/logout
But when I host my website I am able to access abc.com/example/ but the issue I am facing is that when I tried to access login and logout URL I am getting an error "404 not found". Because it is trying to locate index.html in the example folder of the S3 bucket like in this way example/login/index.html and EC2 instance is for API calls.
To host your site on S3 bucket and aws CloudFront you must include your parent file index.html in S3 bucket and after this you need to configure static website hosting under properties of S3 bucket. Set these fields as use this bucket to host website then enter index document index.html this file must be in S3 bucket, and save this.
Next step you can edit public access of this bucket, if you want this site accessible outside world then turn off block public access under Permissions tab of S3 bucket.
Later, to host this using CloudFront you need to create CloudFront distribution, and set Origin Domain name = Your S3 bucket name and Default Root Object to your parent index.html file (which is stored in s3 bucket) and save this CloudFront distribution, now check the Domain name URL on browser, it should work fine.
After completing this you can setup your EC2 instance for back-end API calls as per your needs.
Try to keep pages like login.html and logout.html. That should work.

AWS S3 Static hosing: Routing rules doesn't work with cloudfront

I am using AWS S3 static web hosting for my VueJs SPA app. I have setup routing rules in S3 and it works perfectly fine when I access it using S3 static hosting url. But, I also have configured CloudFront to use it with my custom domain. Since single page apps need to be routed via index.html, I have setup custom error page in cloudfront to redirect 404 errors to index.html. So now routing rules I have setup in S3 no longer works.
What is the best way to get S3 routing rules to work along with CloudFront custom error page setup for SPA?
I think I am a bit late but here goes anyway,
Apparently you can't do that if you are using S3 REST_API endpoints (example-bucket.s3.amazonaws.com) as your origin for your CloudFront distribution, you have to use the S3 website url provided by S3 as the origin (example-bucket.s3-website-[region].amazonaws.com). Also, objects must be public you can't lock your bucket to the distribution by origin policy.
So,
Objects must be public.
S3 bucket website option must be turned on.
Distribution origin has to come from the S3 website url, not the rest api endpoint.
EDIT:
I was mistaking, actually, you can do it with the REST_API endpoint too, you only have to create a Custom Error Response inside your CloudFront distribution, probably only for the 404 and 403 error codes, set the "Customize Error Response" option to "yes", Response Page Path to "/index.html" and HTTP Response Code to "200". You can find that option inside your distribution and the error pages tab if you are using the console.

CloudFront - Editing Origin - Restrict Bucket Access

I have a situation which I am unable to understand easily why and I am not able to find any documentation either.
I have done the following:
Created a S3 bucket
Given public access to it
Enabled it for static website hosting
Created a CloudFront distribution to it
Enabled HTTPS at cloudfront
Now I am trying to restrict the access of S3 bucket only to CloudFront.
I tried the steps presented at
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html
Unfortunately, when I tried to edit the origin I don't see all the options in the UI especially Restrict Bucket Access is missing.
I only see options to edit Origin Domain Name, Origin Path, Origin Id (grayedout), Origin Custom Headers - No option to enter OAI or setting Restrict Bucket Access etc.
Is it because of enabling HTTPS?
S3 masters, please help!
Origin access identities are only applicable when using the S3 REST endpoint (e.g. example-bucket.s3.amazonaws.com) for the bucket -- not when you are using the website hosting endpoint (e.g. example-bucket.s3-website.us-east-2.amazonaws.com), because website hosting endpoints do not support authenticated requests -- they are only for public content... but OAI is an authentication mechanism.
When using the website endpoint, CloudFront does not treat the origin as an S3 Origin -- it is treated as a Custom Origin, and these options are not available, because if they were available, they wouldn't work anyway (for the reason mentioned above).
For those who have since changed some S3 settings to not be public and intend it to be only retrievable via Cloudfront, it is now there but hidden. You just have to cut copy the value from Origin Domain Name in origin tab and then re-paste it in again (if its the name bucket) and the UI will now render with the Restrict Access input options.