My project has a simple static website as the root (literally a single index.html file) and and Angular app that should be displayed with the user clicks on a navigation link. I have configured CloudFront + S3 using OAC as described in this AWS blog post.
It works perfectly fine for the root website. For example when the user navigates to mydomain.com the basic static website displays as expected. The problem I am having is when the user attempts to navigate to mydomain.com/myApp I get a 403 Access Denied.
On the S3 side I have individual buckets for the root app and the Angular app.
The file structure for the Angular app in S3 is MyBucket/myApp/Angular build files
.
The bucket policy in place is the default policy that AWS provides when you assign the OAC from CloudFront, shown below:
{
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "AllowCloudFrontServicePrincipal",
"Effect": "Allow",
"Principal": {
"Service": "cloudfront.amazonaws.com"
},
"Action": "s3:GetObject",
"Resource": [
"arn:aws:s3:::<my-bucket>/*",
"arn:aws:s3::: <my-bucket>/myApp/*" <--Added as attempt to solve 403
],
"Condition": {
"StringEquals": {
"AWS:SourceArn": "arn:aws:cloudfront::<numbers>:distribution/<id>"
}
}
}
]
}
On the CloudFront side I have a single distribution with the default origin pointing to the S3 bucket with the basic static website (index.html file) and an additional origin pointing to the S3 bucket with the Angular app.
In addition, I have configured a Behaviors pattern with a Path Pattern = myApp/*
with the origin= S3 bucket with Angular app and "viewer Protocol Policy=HTTP & HTTPS
. All other configuration in the Behavior pattern were left at default.
On the Angular side I have configured the app to use a base href="/myApp/"
I’ve tried so many different AWS configurations like setting an origin path = /myApp
in CloudFront, setting Viewer Protocol Policy= redirect HTTP to HTTPS
. I’ve tried flattening the directory structure in S3 to remove the myApp
dir and have all the Angular build files at the root. I’ve been hitting dead ends all over and haven’t been able to find a solution on StackOverflow or broader internet. I may just be asking the wrong questions, but I’m really stuck here. Any solutions or insight are greatly appreciated!
2
Answers
"arn:aws:s3:::<my-bucket>/*"
is enough."arn:aws:s3:::<my-bucket>/myApp/*"
is a subset of the first.You have a different issue here. To solve the issue you can use 1. or 2. from the below:
redirect
requests to index.htmlCouldFront literally requires
path/to/something
object to be present at S3 for urls like https://host/path/to/something.So you can use something similar to ‘react-snap’ for Angular to generate static HTML for all required paths and upload the correct structure to s3.
Mind that for object
s3://bucket/path/index.html
the https://host/path will not work with CloudFront. CloudFront needs to haves3://bucket/path
wherepath
has content ofindex.html
You mention that you have two different buckets: one for the root app and another for the Angular app, but it seems that the resource policy shown in the code snippet is attached only to the root app bucket. You need to attach a similar policy to the Angular app bucket.