'504 Error for Cloudfront.net distribution and Route53 Domain

I'm trying to setup a static S3 website to be reachable via my custom domain, but when I've tested my cloudfront URL I'm getting 504 Error and in the logs, I see the following:

<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>ZFD3NVWGP7DE08W1</RequestId>
<HostId>o2iGHpwIdQjHQ51nG6HwoFtCx5QE9l0rZytYatSMF3zOVjKpHg00ph2vSAiUYJog5ZVsnxr5C18=</HostId>
</Error>

Here is my bucket policy:

{
    "Version": "2012-10-17",
    "Id": "MyPolicy",
    "Statement": [
        {
            "Sid": "PublicReadForGetBucketObjects",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::xyz-cloud-website/*"
        }
    ]
}

I've checked my S3 bucket settings as explained in the AWS documentation but as far as I can tell, all of the following is true:

  • My objects are publicly accessible
  • My objects are not KMS-encrypted
  • My account owns both the bucket and the objects

I built this via an IaC SAM CLI deployment with the following template:

Resources:
  MyWebsite:
    Type: AWS::S3::Bucket
    Properties:
      AccessControl: PublicRead
      WebsiteConfiguration:
        IndexDocument: index.html
      BucketName: xyz-cloud-website

  MyRoute53Record:
    Type: "AWS::Route53::RecordSetGroup"
    Properties:
      HostedZoneId: 00000000000000000 
      RecordSets:
        - Name: xyz-website.com
          Type: A
          AliasTarget:
            HostedZoneId: Z2FDTNDATAQYW2
            DNSName: !GetAtt MyDistribution.DomainName

  MyDistribution:
    Type: "AWS::CloudFront::Distribution"
    Properties:
      DistributionConfig:
        ViewerCertificate:
          AcmCertificateArn: !Ref MyCertificate
          SslSupportMethod: sni-only
        Aliases:
          - xyz-website.com
        DefaultCacheBehavior:
          ViewerProtocolPolicy: allow-all
          TargetOriginId: xyz-cloud-website.s3-website-us-east-1.amazonaws.com
          DefaultTTL: 0
          MinTTL: 0
          MaxTTL: 0
          ForwardedValues:
            QueryString: "false"
        Origins:
          - DomainName: xyz-cloud-website.s3-website-us-east-1.amazonaws.com
            Id: xyz-cloud-website.s3-website-us-east-1.amazonaws.com
            CustomOriginConfig:
              OriginProtocolPolicy: match-viewer
        Enabled: "true"
        DefaultRootObject: index.html

When I access my static s3 bucket via xyz-cloud-website.s3-website-us-east-1.amazonaws.com, I have no issues. It's only when I try to use my xyz123.cloudfront.net URL or the custom domain that I get the 504.

My Cloudfront Domain, Alt, and Origin all look correct... any ideas on why this would be throwing a 504 error when I try to use Cloudfront? Trying to avoid throwing money at AWS for help on a personal project.

*Note I've obviously masked my URLs in these examples. The correct ones are in my template and are appearing in the AWS Console.



Solution 1:[1]

I figured this one out. CloudFront wants a slightly different input for the Origin as a result of more recent updates that makes the old method of demarking static S3 bucket websites a bit different now.

So instead of:

        Origins:
          - DomainName: xyz-cloud-website.s3-website-us-east-1.amazonaws.com
            Id: xyz-cloud-website.s3-website-us-east-1.amazonaws.com
            CustomOriginConfig:
              OriginProtocolPolicy: match-viewer

It should be something more like:

        Origins:
          - DomainName: xyz-cloud-website.s3.us-east-1.amazonaws.com
            Id: xyz-cloud-website.s3.us-east-1.amazonaws.com
            CustomOriginConfig:
              OriginProtocolPolicy: match-viewer # OR HTTPS-only if appropriate, as it was in my case

This now has my CloudFront AND Custom Domain displaying as intended. This can also be achieved via the console.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ian