I have a CloudFront distribution that I am trying to use to serve a React application on S3. Following the AWS documentation, I have the current S3 policy:
S3 bucket policy
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowCloudFrontServicePrincipalReadOnly",
"Effect": "Allow",
"Principal": {
"Service": "cloudfront.amazonaws.com"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-s3-bucket/*",
"Condition": {
"StringEquals": {
"AWS:SourceArn": "arn:aws:cloudfront::x:distribution/x" // sanitized with x (copied from cloudfront UI panel)
}
}
}
]
}
CloudFront distribution origin
My Cloudfront distribution has the following:
origin name | domain | path | type | shield region | access |
---|
myS3Origin | my-s3-bucket.s3.us-east-1.amazonaws.com | | S3 | | ABC |
Origin Access Control (OAC)
resource "aws_cloudfront_origin_access_control" "default" {
name = "DefaultAccessControl"
origin_access_control_origin_type = "s3"
signing_behavior = "always"
signing_protocol = "sigv4"
}
Per the terraform documentation, I am using that in the cloudfront distribution resource:
resource "aws_cloudfront_distribution" "s3_distribution" {
origin {
domain_name = aws_s3_bucket.deployment_bucket.bucket_regional_domain_name
origin_access_control_id = aws_cloudfront_origin_access_control.default.id
origin_id = "myS3Origin"
Encryption
I am using the standard Server-side encryption with Amazon S3 managed keys (SSE-S3).
Result
When I navigate to my Distribution domain name
at x.cloudfront.net
, I see the following XML:
<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>QNQMMS43DTSYZNS3</RequestId>
<HostId>8t3bGWPGKd/u2bWlEKkqy1BJulDigA/ewXnwLrA2A4iC+R4A7DyZE+VxeBIK+aiLICHGOA3OV5g=</HostId>
</Error>
Attempts to troubleshoot
- Delete the bucket policy completely
- Replace with another similar policy
Ideas
I noticed that the distributions origin access "ID" does not match the "ID" at the end of its ARN. Maybe that's normal? Also, is the origin access intended to be listed somewhere in S3? Maybe in the bucket policy?
I'm not sure if OAC is the issue, but the documentation listed by ElectricSpice seems to suggest it is set up correctly.
In the S3 bucket Access control list (ACL), I see a table. The only accessor with any list/write/read is Bucket owner (your AWS account)
. All of the others have no permissions.
Possibly the way I added my React build assets to S3
I'm brand new to front-end, so I may have screwed up the way I added the assets to S3. When I run npm run build
, there is a /dist
folder with the following structure:
$ ls -alh ./dist
vite.svg
index.html
assets/
In the documentation from AWS for a React app in S3 it states:
Choose Add folder, and then choose the static directory. Important: Don’t choose the contents; choose the directory.
I take this as explicitly stating I need to add the dist/
directory.
I went into S3 manually (through the console) and added this dist/
dir. So if I navigate to the bucket cik-front-end
, I see an object dist/
.
Now if I change my request to https://d3me6d4ypmjduw.cloudfront.net/dist/index.html
, I see a new error:
<Error>
<Code>AccessDenied</Code>
<Message>
User: arn:aws:sts::856369053181:assumed-role/OriginAccessControlRole/OriginAccessSession is not authorized to perform: kms:Decrypt on the resource associated with this ciphertext because the resource does not exist in this Region, no resource-based policies allow access, or a resource-based policy explicitly denies access
</Message>
<RequestId>VQK7FCNQ0M6BEVQB</RequestId>
<HostId>
QtFINcK8nLKBD9P+gEvXxZJOUyugRoqjwvVShJvNd1YDoR9Dx95gs4nveVzhzk1p3/DZp/fP4U8=
</HostId>
</Error>
Solved
Ok so it looks like the AWS documentation is just incorrect.
Choose Add folder, and then choose the static directory. Important: Don’t choose the contents; choose the directory.
This is untrue. I deleted the contents of that bucket, and re-added them as a flattened upload (everything inside the dist/
directory. The app now serves the React SPA.
@max I'm not sure how to directly reply to your response. However suggestion #1 was already a hit. My ID distribution origin access and the ARN listed in both my distribution arn and bucket policy do not match:
ABC
arn:aws:cloudfront::339712767340:distribution/DEF
"AWS:SourceArn": "arn:aws:cloudfront::339712767340:distribution/DEF"
Is that identifier supposed to match?
My terraform has:
I'm not sure why this is creating a bucket policy arn that does not match.