I'm uploading a website to S3 which I configured to be accessed via a cloudfront distribution. When I access the distribution URL through in the browser I get:
<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>TKHNQGGSSHY3ZH6T</RequestId>
<HostId>zXD7uBIpJUGHaUl8m5/9xtm2cnvX/Kok6rYp0oz6RFbqJeLreohaOWHx4jHJ/F675UGxo1SfEYs=
</HostId>
</Error>
This is my sam cloudformation tempalte snippet, I'm guessing there's some issue with the StockMonitorFeBucketPolicy.
##################### FRONTEND
StockMonitorFeBucket:
Type: 'AWS::S3::Bucket'
DeletionPolicy: Delete
Properties:
BucketName: osotnikov-stock-monitor-front-end-resources-s3-bucket
AccessControl: Private
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
StockMonitorFeBucketDistributionOriginAccessIdentity:
Type: 'AWS::CloudFront::CloudFrontOriginAccessIdentity'
Properties:
CloudFrontOriginAccessIdentityConfig:
Comment: This is the origin access identity (simply user).
StockMonitorFeBucketDistribution:
Type: 'AWS::CloudFront::Distribution'
DependsOn:
- StockMonitorFeBucket
- StockMonitorFeBucketDistributionOriginAccessIdentity
Properties:
DistributionConfig:
Origins:
- DomainName: !GetAtt
- StockMonitorFeBucket
- DomainName
Id: StockMonitorFeBucketCloudFrontOrigin
S3OriginConfig:
OriginAccessIdentity: !Sub >-
origin-access-identity/cloudfront/${StockMonitorFeBucketDistributionOriginAccessIdentity}
Enabled: 'true'
DefaultCacheBehavior:
TargetOriginId: StockMonitorFeBucketCloudFrontOrigin
ForwardedValues:
QueryString: 'false'
ViewerProtocolPolicy: allow-all
StockMonitorFeBucketPolicy:
Type: 'AWS::S3::BucketPolicy'
DependsOn:
- StockMonitorFeBucket
- StockMonitorFeBucketDistributionOriginAccessIdentity
- StockMonitorFeBucketDistribution
Properties:
Bucket: !Ref StockMonitorFeBucket
PolicyDocument:
Statement:
- Sid: cloudFrontReadAccess
Effect: Allow
Principal:
CanonicalUser: !GetAtt
- StockMonitorFeBucketDistributionOriginAccessIdentity
- S3CanonicalUserId
Action: 's3:GetObject'
Resource: >-
arn:aws:s3:::osotnikov-stock-monitor-front-end-resources-s3-bucket/*
This is the bucket policy that it added after deployment:
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "cloudFrontReadAccess",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E1V8NTQPK5FD7P"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::osotnikov-stock-monitor-front-end-resources-s3-bucket/*"
}
]
}
Alternatively I try:
Properties:
Bucket: !Ref StockMonitorFeBucket
PolicyDocument:
Statement:
- Sid: cloudFrontReadAccess
Effect: Allow
Principal:
AWS: !Join
- ' '
- - 'arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity'
- - !GetAtt [ StockMonitorFeBucketDistributionOriginAccessIdentity, S3CanonicalUserId ]
Action: 's3:GetObject'
Resource: >-
arn:aws:s3:::osotnikov-stock-monitor-front-end-resources-s3-bucket/*
But then I get:
a string delimiter and (2) a list of strings to be joined or a function that returns a list of strings (such as Fn::GetAZs) to be joined.
I tried to change the principal to
Principal: AWS: !Join [' ', ['arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity', !GetAtt [StockMonitorFeBucketDistributionOriginAccessIdentity, S3CanonicalUserId]]]
But I get Invalid principal in policy error
CodePudding user response:
There is nothing wrong with your template (I deployed it). It works as expected. The only way to get AccessDenied
in your case is due to lack of DefaultRootObject as index.html
defined. Thus you have to explicitly add index.html
to your cloudfront url, e.g.:
http://21342sfssgdf.cloudfront.net/index.html
CodePudding user response:
I just changed the Principal to
CanonicalUser: !GetAtt StockMonitorFeBucketDistributionOriginAccessIdentity.S3CanonicalUserId
and it worked ... maybe it's because I'm using sam idk