Home > Net >  Cloudformation template - S3 bucket website with cloudfront distribution - distribution can't a
Cloudformation template - S3 bucket website with cloudfront distribution - distribution can't a

Time:01-25

I'm just trying to get a static site on a S3 bucket and have it being accessible only trough a CloudFront distribution, but something is missing and I cannot figure out what.

Currently my stack have

  • an S3 bucket for site hosting
  • a cloudfront distribution for serving the site
  • a bucket policy to let only the distribution accessing the bucket
  • a default cache policy for the distribution

When trying to access the website directly from the bucket website url I get a 403 (forbidden, access denied) and that's ok.
When trying to access it from the distribution domain I get a generic error page with the message Failed to contact the origin.
When trying to access it from my registered domain I get a 403 error page with the message The request could not be satisfied. followed by generics tips on how to fix it (login later, contact website owner, check documentation, etc)

Since I'm using CloudFormation template from my cli every resource is in the same region, and everything else too looks right to me, but obviously something is wrong.

CloudFormation template

Resources:

  BucketPolicy:
    Type: 'AWS::S3::BucketPolicy'
    DependsOn:
      - AppBucket
      - CloudFrontDistribution
    Properties:
      Bucket: !Ref AppBucket
      PolicyDocument:
        Id: MyPolicy
        Version: '2012-10-17'
        Statement:
          - Sid: PolicyForCloudFrontPrivateContent
            Action: s3:GetObject
            Effect: Allow
            Principal:
              Service: cloudfront.amazonaws.com
            Condition:
              StringLike:
                aws:Referer: !Sub 'https://*.${CloudFrontDistribution}.cloudfront.net/*'
            Resource: !Sub arn:aws:s3:::${AppBucket}/*

  CloudFrontDistribution:
    Type: AWS::CloudFront::Distribution
    DependsOn:
      - AppBucket
      - DefaultCachePolicy
    Properties:
      DistributionConfig:
        Enabled: true
        Origins:
          - Id: AppBucket
            DomainName: !GetAtt AppBucket.DomainName
            OriginPath: /*
            S3OriginConfig: {}
        DefaultCacheBehavior:
          ViewerProtocolPolicy: redirect-to-https
          TargetOriginId: AppBucket
          CachePolicyId: !Ref DefaultCachePolicy

  AppBucket:
    Type: 'AWS::S3::Bucket'
    Properties:
      BucketName: 'test-spa-stack-bucket-app'
      PublicAccessBlockConfiguration:
        BlockPublicAcls : false
        BlockPublicPolicy : false
        IgnorePublicAcls : false
        RestrictPublicBuckets : false
      VersioningConfiguration:
        Status: Enabled
      BucketEncryption:
        ServerSideEncryptionConfiguration:
        - ServerSideEncryptionByDefault:
            SSEAlgorithm: 'AES256'
      WebsiteConfiguration:
        IndexDocument: index.html
              
  DefaultCachePolicy:
    Type: AWS::CloudFront::CachePolicy
    Properties: 
      CachePolicyConfig: 
        Name: test-cache-policy
        DefaultTTL: 10
        MaxTTL: 10
        MinTTL: 1
        ParametersInCacheKeyAndForwardedToOrigin: 
            CookiesConfig: 
              CookieBehavior: none
            EnableAcceptEncodingBrotli: true
            EnableAcceptEncodingGzip: true
            HeadersConfig: 
              HeaderBehavior: none
            QueryStringsConfig: 
              QueryStringBehavior: none

CodePudding user response:

Your bucket policy seems wrong.

You need to allow Origin access control of your CloudFront distribution to access the S3 bucket.

{
    "Version": "2012-10-17",
    "Statement": {
        "Sid": "AllowCloudFrontServicePrincipalReadOnly",
        "Effect": "Allow",
        "Principal": {
            "Service": "cloudfront.amazonaws.com"
        },
        "Action": "s3:GetObject",
        "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*",
        "Condition": {
            "StringEquals": {
                "AWS:SourceArn": "arn:aws:cloudfront::111122223333:distribution/EDFDVBD6EXAMPLE"
            }
        }
    }
}

You also need to provide the same origin access control id in your CloudFront distribution definition:

  CloudFrontDistribution:
    Type: AWS::CloudFront::Distribution
    DependsOn:
      - AppBucket
      - DefaultCachePolicy
    Properties:
      DistributionConfig:
        Enabled: true
        Origins:
          - Id: AppBucket
            DomainName: !GetAtt AppBucket.DomainName
            OriginPath: /*
            OriginAccessControlId: "EDFDVBD6EXAMPLE" <- PROVIDE ID HERE
        DefaultCacheBehavior:
          ViewerProtocolPolicy: redirect-to-https
          TargetOriginId: AppBucket
          CachePolicyId: !Ref DefaultCachePolicy

See Restricting access to an Amazon S3 origin

  • Related