Deployment of an S3 Bucket and Bucket Policy using CloudFormation

Uzair Mansoor
5 min readJan 22, 2023

--

Below is the link to the YouTube tutorial. (Deployment of S3 Bucket and Bucket Policy using CloudFormation | CloudFormation Series | DevOps)

https://youtu.be/1Kftd1ER4JI

In this walkthrough, we’ll be deploying an S3 bucket and Bucket Policy in Amazon Web Services (AWS) using CloudFormation. This is a pretty straightforward walkthrough but you will change a bit of information in your .yml files.

Prerequisites

AWS account

IDE (Pycharm/ Visual Studio/ Cloud9 for example)

Step 1:

Create a new IAM user with full S3 access. I’m going to grant my IAM user Administrator Access and S3 Full access. I’m giving Administrative Access to my IAM user because I’ll use this same IAM user in my next tutorials. But, this isn’t a good practice while you’re working in the production environment.

Granting Permissions to an IAM User

Using the aws configure command, input your new IAM user's credentials.

Login IAM User through CLI

Step 2:

Head over to GitHub and fork this repository. Once you’ve done that, git clone the repo in your CLI.

Clone the GitHub Repo

Clone the GitHub repo.

cd into your repository.

Head over to your s3-app.yml file, as we are going to understand what resources are creating.

AWS::S3::Bucket: This part creates an S3 Bucket. The Deletion Policy is set to Delete , which means that the bucket will be deleted when the stack will delete. WebsiteConfiguration will enable Static Web Hosting on an S3 bucket. VersioningConfiguration will enable the versioning on an S3 bucket.

AWS::S3::BucketPolicy: This part defines an S3 Bucket Policy. Here, we’re setting s3:x-amz-server-side-encryption it to “true”. Now, all the objects must be encrypted while uploading to this S3 Bucket. All the unencrypted objects would be denied.

AWSTemplateFormatVersion : "2010-09-09"
Description: "CloudFormation Template for deploying S3 Bucket"

Parameters:
project:
Type: String
Description: Project Name
app:
Type: String
Description: Application Name
env:
Type: String
AllowedValues:
- prod
- dev
- qa
- uat
Description: Environment Name
bucketName:
Type: String
Description: Bucket Name
versioningStatus:
Type: String
Description: Enables multiple versions of all objects in this bucket
AllowedValues:
- Enabled
- Suspended
indexDocument:
Type: String
Description: The name of the index document for the website
errorDocument:
Type: String
Description: The name of the error document for the website

Resources:
s3Bucket:
Type: 'AWS::S3::Bucket'
DeletionPolicy: Delete
Properties:
BucketName: !Sub ${project}-${app}-${env}-${bucketName}-${AWS::Region}-${AWS::AccountId}
WebsiteConfiguration:
IndexDocument: !Ref indexDocument
ErrorDocument: !Ref errorDocument
VersioningConfiguration:
Status: !Ref versioningStatus
Tags:
- Key: name
Value: !Sub "${project}-${app}-${env}-s3Bucket"
- Key: project
Value: !Ref project
- Key: app
Value: !Ref app
- Key: env
Value: !Ref env
bucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref s3Bucket
PolicyDocument:
Version: '2012-10-17'
Id: ObjectPolicy
Statement:
- Sid: DenyUnEncryptedObjectUploads
Effect: Deny
Principal:
AWS: !Sub ${AWS::AccountId}
Action: s3:PutObject
Resource: !Sub arn:aws:s3:::${s3Bucket}/*
Condition:
'Null':
s3:x-amz-server-side-encryption: true

Outputs:
s3Bucket:
Description: S3 Bucket Name
Value: !Ref s3Bucket
Export:
Name: !Sub "${project}-${app}-${env}-s3Bucket"

Head over to your s3-app-main.yml file, as we are going to make a few updates.

The first thing you’ll want to do is change the s3ArtifactPath parameter value. In this case, I’ve used the URL of my S3 Bucket, where I’m uploading the s3-app.yml file. Next, you’re going to change the name of your S3 bucket bucketNamemaking sure it is globally unique.

AWSTemplateFormatVersion : "2010-09-09"
Description: "Driver Template for deploying S3 Bucket"

Parameters:
project:
Type: String
Description: Project Name
Default: devops-poc
app:
Type: String
Description: Application Name
Default: app
env:
Type: String
AllowedValues:
- prod
- dev
- qa
- uat
Description: Environment Name
Default: dev
s3ArtifactPath:
Type: String
Description: "Artifact Bucket Path"
Default: "https://devops-training-poc-app-dev-us-east-1-007756798683.s3.amazonaws.com/code/cfn/services"

Resources:
s3Bucket:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: !Sub "${s3ArtifactPath}/s3/s3-app.yml"
Parameters:
project: !Ref project
app: !Ref app
env: !Ref env
bucketName: artifacts
versioningStatus: Enabled
indexDocument: index.html
errorDocument: error.html

Outputs:
s3Bucket:
Description: S3 Bucket Stack
Value: !Ref s3Bucket
Export:
Name: !Sub "${project}-${app}-${env}-s3BucketStack"

Step 3:

Now that we’ve set up our configuration code, let’s sync the files to an Artifact S3 Bucket.

Upload objects to S3 Bucket: aws s3 sync . s3://iacartifacts-devops-youtube-tutorials-us-east-1–355986150263/code/cfn/services/s3/

Create Cfn template: aws cloudformation create-stack — stack-name uzair-poc-dev-tutorialstask1-us-east-1 — template-body file://s3-app-main.yml

The CloudFormation console will look like this.

The S3 Bucket is deployed by the CloudFormation template.

This is the Bucket Policy deployed by the CloudFormation template.

Delete Cfn template: aws cloudformation delete-stack — stack-name uzair-poc-dev-tutorialstask1-us-east-1

Don’t forget to delete-stackyour resources so you don't incur any additional AWS charges outside of the free tier.

Great job on making it to the end of this walkthrough 👏🏾🤠! Congratulations!

--

--

Uzair Mansoor
Uzair Mansoor

Written by Uzair Mansoor

I'm Uzair Mansoor. I've more than four-year experience in the DevOps domain. I'm 2xAWS certified and Azure Administrator Certified.

No responses yet