I want to put a Cloudfront CDN in front of a S3 website bucket for a static website, and restrict read access of the bucket to the Cloudfront distribution. Pretty common, and documented by AWS and other sources. But for some reason I can’t get it to work.
And I’m not the first one to stumble upon this. (1, 2, 3). I’ve tried the solutions posted there, but again, no luck.
My setup, as a Cloudformation template, looks as follows:
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
s3BucketName:
Type: String
domainName:
Type: String
certificateArn:
Type: String
bucketAuthHeader:
Type: String
Resources:
cloudfrontDistribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Enabled: true
PriceClass: PriceClass_100
Origins:
- Id: !Sub "ID-${s3BucketName}"
DomainName: !Sub "${s3BucketName}.s3-website.eu-central-1.amazonaws.com"
CustomOriginConfig:
OriginProtocolPolicy : http-only
OriginCustomHeaders:
- HeaderName: User-Agent
HeaderValue: !Ref bucketAuthHeader
DefaultCacheBehavior:
AllowedMethods:
- GET
- HEAD
- OPTIONS
CachedMethods:
- GET
- HEAD
- OPTIONS
DefaultTTL: 600
ForwardedValues:
QueryString: false
TargetOriginId: !Sub "ID-${s3BucketName}"
ViewerProtocolPolicy: redirect-to-https
s3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Ref s3BucketName
AccessControl: Private
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
WebsiteConfiguration:
IndexDocument: index.html
ErrorDocument: _errors/404/index.html
DeletionPolicy: Delete
s3BucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref s3BucketName
PolicyDocument:
Version: 2012-10-17
Id: "Cloudfront Bucket Access"
Statement:
- Sid: "Cloudfront Bucket Access via Referer"
Effect: Allow
Principal: "*"
Action: "s3:GetObject"
Resource: !Sub "arn:aws:s3:::${s3BucketName}/*"
Condition:
StringEquals:
aws:UserAgent:
- !Ref bucketAuthHeader
However, when applying this, I cannot access files via Cloudfront, I always get a 403. I also tried tweaking values in PublicAccessBlockConfiguration
and AccessControl
and tried uploading bucket content with aws s3 sync … --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers
.
But I always end up with either public S3 content, or content being unavailable via Cloudfront as well.
Does anybody have an idea what else I could try?