Deployment of an S3 Bucket and Bucket Policy using CloudFormation
Below is the link to the YouTube tutorial. (Deployment of S3 Bucket and Bucket Policy using CloudFormation | CloudFormation Series | DevOps)
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.
Using the aws configure
command, input your new IAM user's credentials.
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.
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 bucketName
making 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-stack
your 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!