How to Create S3 Bucket Policy using CloudFormation

bucket policy using cloudformation

How to Create S3 Bucket Policy using CloudFormation

Dear Reader, In one of my previous posts, I shared with you “How to Create an S3 Bucket using CloudFormation”.

In this post, I will help you create an S3 bucket policy using CloudFormation. You will also see how the created policy is attached to the S3 bucket.

You can also check out my post on: How to Create S3 Bucket Policy using Terraform

Don’t want to miss any posts from us? join us on our Facebook group, and follow us on Facebook, Twitter, LinkedIn, and Instagram. You can also subscribe to our newsletter below to not miss any updates from us.

Background:

S3 Bucket policies are important for managing access permission to the S3 bucket and objects within it.

In other words, they can help you set up public access for all users, limited access for an IAM user/role for your account or even cross-account access permissions.

Therefore, let’s start with understanding the bucket policy itself.

You Might be interested in :

s3 bucket policy using CloudFomation

What is an S3 Bucket Policy?

An S3 bucket policy is basically a resource-based IAM policy which specifies which ‘principles’ (users) are allowed to access an S3 bucket and objects within it.

  • You can add a bucket policy to an S3 bucket to permit other IAM users or accounts to be able to access the bucket and objects in it.

Please note that an S3 bucket at a time can only have a single bucket policy.

So, please make sure to add all your required permission in a single bucket policy and attach the policy to a bucket you want to control access to.

Suggested Read: Understand IAM PassRole to Secure Your AWS Infrastructure

An example bucket policy to allow read-only access to everyone

In the below snippet, I am defining a bucket policy on my bucket cloudkatha-bucket. If you look closely at the actions list, two permissions are present.

  • s3:GetObject: To get/read objects in the bucket
  • s3:ListBucket: To list objects in the bucket
{ 
  "Statement": [
    {
      "Sid": "AllowEveryoneReadOnlyAccess",
      "Effect": "Allow",
      "Principal": "*",
      "Action": [ "s3:GetObject", "s3:ListBucket" ],
      "Resource": ["arn:aws:s3:::cloudkatha-bucket",
                   "arn:aws:s3:::cloudkatha-bucket/*"]
    }
  ]
}

The above policy says that Principle ‘*’ , means everyone can do actions list bucket and get an object on the resource bucket cloudkatha-bucket and all objects in this bucket.

Permissions Required

When you create a bucket policy using CloudFormation, CloudFormation under the hood calls PutBucketPolicy API.

So, the calling identity(user/role) must have s3:PutBucketPolicy permission on the bucket otherwise Amazon S3 returns a 403 Access Denied error.

{ 
  "Statement": [
    {
      "Sid": "PutBucketPolicyPermission",
      "Effect": "Allow",
      "Principal": "*",
      "Action": [ "s3:PutBucketPolicy" ],
      "Resource": ["arn:aws:s3:::cloudkatha-bucket"]
    }
  ]
}

Let’s get back on track and start creating a bucket policy using CloudFormation

Steps to create an S3 Bucket Policy using CloudFormation?

Let’s see the step-by-step instruction to create a bucket policy.

  1. Provide proper permission
  2. Prepare a template
  3. Create a Stack using the saved template

Step1: Provide proper permission

If you are not an admin user, you should have s3:PutBucketPolicy permission for your user/role. As always you will also need cloudformation:* as well to be able to do CloudFormation operations.

Step2: Prepare a template

You can use YAML or JSON for your template. Below is a template for YAML. If you want it in JSON, Please check JSON Section.

Alternatively, you can check my post on How to Convert a CloudFormation Template From JSON to YAML and Vice Versa

Copy the below snippet and put it into an editor. You can change the value of the BucketName parameter and also edit the policy as per your requirement.

Template Example to Create S3 Bucket Policy using CloudFormation in YAML

AWSTemplateFormatVersion: '2010-09-09'
Description: Template to create s3 bucket and policy

Parameters:

  BucketName:
    Type: String
    Description: Bucket Name
    Default: cloudkatha-bucket

Resources:

  MyS3Bucket:
    Type: 'AWS::S3::Bucket'
    Description: Bucket on which we will attach and test bucket policy
    Properties:
      BucketName: !Ref BucketName
          
  MyS3BucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref MyS3Bucket
      PolicyDocument:
        Statement:
          -
            Action:
              - s3:*
            Effect: Allow
            Resource:
              - !Sub arn:aws:s3:::${MyS3Bucket}
              - !Sub arn:aws:s3:::${MyS3Bucket}/*
            Principal:
              AWS:
                - '*'

Once done, save it as bucketpolicy.yml

Step3: Create a Stack using the saved template

  • Login to AWS Management Console, navigate to CloudFormation and click on Create stack
  • Click on “Upload a template file”, upload bucketpolicy.yml and click Next
  • Enter the stack name and click on Next. In the configuration, keep everything as default and click on Next.
  • In the events tab of the stack, you can view the status.
  • Once the stack is successfully created, head to your S3 bucket and you will see your bucket policy in the permissions tab.

Template Example to Create S3 Bucket Policy using CloudFormation in JSON

{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "Template to create s3 bucket and policy",
    "Parameters": {
        "BucketName": {
            "Type": "String",
            "Description": "Bucket Name",
            "Default": "cloudkatha-bucket"
        }
    },
    "Resources": {
        "MyS3Bucket": {
            "Type": "AWS::S3::Bucket",
            "Description": "Bucket on which we will attach and test bucket policy",
            "Properties": {
                "BucketName": {
                    "Ref": "BucketName"
                }
            }
        },
        "MyS3BucketPolicy": {
            "Type": "AWS::S3::BucketPolicy",
            "Properties": {
                "Bucket": {
                    "Ref": "MyS3Bucket"
                },
                "PolicyDocument": {
                    "Statement": [
                        {
                            "Action": [
                                "s3:*"
                            ],
                            "Effect": "Allow",
                            "Resource": [
                                {
                                    "Fn::Sub": "arn:aws:s3:::${MyS3Bucket}"
                                },
                                {
                                    "Fn::Sub": "arn:aws:s3:::${MyS3Bucket}/*"
                                }
                            ],
                            "Principal": {
                                "AWS": [
                                    "*"
                                ]
                            }
                        }
                    ]
                }
            }
        }
    }
}

Where was the connection between bucket and policy?

  MyS3BucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref MyS3Bucket

If you see the template above, the Bucket property of AWS::S3::BucketPolicy is used to specify which bucket the policy needs to be applied upon.

You can also check out my post on: How to Deploy a CloudFormation Template using AWS CLI

Conclusion:

To sum up, In this post –

  • I explained the S3 bucket policy with an example.
  • After that, I shared a template in YAML and JSON to create an S3 bucket policy using CloudFormation.
  • Then I shared the steps to create a stack
  • Lastly, I showed how the policy was attached to a bucket

Please feel free to add a comment in case of any doubt.

Enjoyed the content?

Subscribe to our newsletter below to get awesome AWS learning materials delivered straight to your inbox.

Don’t forget to motivate me by-

Suggested Read:

Leave a Reply

Your email address will not be published. Required fields are marked *