aws-samples / aws-cdk-examples

Example projects using the AWS CDK
Apache License 2.0
4.96k stars 2.1k forks source link

Public static site fails to deploy due to missing public access block configuration #919

Open matt-fff opened 9 months ago

matt-fff commented 9 months ago

Describe the bug

If you try to deploy a public S3 bucket with the CDK or cloudformation in general, AWS will give you this useless error:

API: s3:PutBucketPolicy Access Denied 

The only way around it is to explicitly specify the bucket's block public access configuration to allow it.

The python public static site example does not set this configuration.

This is very time consuming to figure out, since the AWS docs helpfully don't mention this secret behavior in any relevant place.

Expected Behavior

The site should deploy.

Current Behavior

The deployment fails with access denied for s3:PutBucketPolicy, regardless of the permissions of the user or role.

The error message isn't helpful at all in diagnosing the issue.

Reproduction Steps

Try to deploy the public static site example.

You may need to work around the other static site issues that are still open here.

Possible Solution

Add the block_public_access keyword argument to the creation of the public site bucket. e.g.

self.bucket = s3.Bucket(
    self,
    "site_bucket",
    bucket_name=self._site_domain_name,
    website_index_document="index.html",
    website_error_document="404.html",
    removal_policy=RemovalPolicy.DESTROY,
    auto_delete_objects=True,
    block_public_access=s3.BlockPublicAccess(
        block_public_acls=False,
        block_public_policy=False,
        ignore_public_acls=False,
        restrict_public_buckets=False,
    ),
)

Additional Information/Context

No response

CDK CLI Version

2.96.0 (build e6322aa)

Framework Version

No response

Node.js Version

v18.17.1

OS

Linux 6.4.4-arch1-1

Language

Python

Language Version

3.11.3

rushali-aws commented 3 months ago

@matt-fff , I checked and could confirm the above error . Then I went ahead and observed the failed PutBucketPolicy Api Call.

Generally this error message occurs due to the following reasons:

I tested the below code :

bucket = s3.Bucket(self, "site_bucket_test",
    website_index_document="index.html",
    website_error_document="404.html",
    removal_policy= RemovalPolicy.DESTROY,
    auto_delete_objects=True,
    public_read_access=True,
)

Moving ahead, I checked the bucket policy which CDK is trying to put on this public bucket :

 "PolicyDocument": {
     "Statement": [
      {
       "Action": "s3:GetObject",
       "Effect": "Allow",
       "Principal": {
        "AWS": "*"
       },
       "Resource": {
        "Fn::Join": [
         "",
         [
          {
           "Fn::GetAtt": [
            "sitebuckettest3767A6F6",
            "Arn"
           ]
          },
          "/*"
         ]
        ]
       }
      }

You are witnessing this error because it is using the "Principal": “*” .

Please note that, if you use “*” in the “Principal” field, then it means that you are willing to allow everyone (anonymous access ) across the world to have given access to your objects and as you have Block Public Access Settings turned ON for the bucket and AWS account, that is the reason you are unable to edit the bucket policy. Please note that the bucket policy will not grant public access when S3 Block Public Access is enabled.

Now, in order to troubleshoot this error and if you want to allow everyone/anonymous to have access to your objects in the bucket. So in this case, for granting public access to objects, you need to follow 2 steps given below :

  1. Removing block public access at Account Level [+] https://docs.aws.amazon.com/AmazonS3/latest/userguide/configuring-block-public-access-account.html
  2. Removing block public access at Bucket Level [+] https://docs.aws.amazon.com/AmazonS3/latest/userguide/configuring-block-public-access-bucket.html

For disabling block public access at Bucket Level in cloudformation/CDK we need to specifiy 'PublicAccessBlockConfiguration' property as mentioned below in your S3 bucket resource . Since we haven’t specified this property in our bucket it is enabled by default.

 block_public_access=s3.BlockPublicAccess(
        block_public_acls=False,
        block_public_policy=False,
        ignore_public_acls=False,
        restrict_public_buckets=False,
    )

However I do agree that it should be mentioned somewhere in the documentation that this property is set as true by default unless we disable it explicitly.