I recently worked on implementing CloudFront for s3 bucket files. Most of the tutorials were doing that using console management(UI) but we at Blue Sky Analytics prefer “code as infrastructure”. So I had to do this using CloudFormation. With the help of a few StackOverflow links and tutorials, I was able to write CloudFormation Template.
So What exactly CloudFront and CloudFromation are?
These definitions will help you out.
CloudFront: Amazon CloudFront is a fast content delivery network (CDN) service that securely delivers data, videos, applications, and APIs to customers globally with low latency, high transfer speeds, all within a developer-friendly environment.
CloudFromation: On AWS, the CloudFormation service provides Infrastructure as Code capabilities. CloudFormation uses templates, configuration files defined in JSON or YAML syntax, that are human readable and can be easily edited, which you can use to define the resources you want to set up. CloudFormation reads a template and generates a stack, a set of resources ready to use on AWS.
We are gonna use a private bucket, a public bucket can also be used but we don't use it to avoid direct access to bucket and leakage.
CloudFront can access private bucket data using OAI(Origin Access Identity). An OAI is like a virtual user through which CloudFront can access private bucket. After creating OAI and using it in CloudFront, we need to update bucket policy, So that CloudFront with an OAI can access it.
Resources we are going to build using CloudFormation:
AWSTemplateFormatVersion: "2010-09-09"
Resources:
First, we need to define AWS template version and a "Resources" attribute to start writing resource templates. AWS template version defines the capabilities of a template.
Bucker resource template
Bucket:
Type: AWS::S3::Bucket
Properties:
AccessControl: Private
BucketName: private-bucket
Tags:
- Key: description
Value: "Private files"
"Bucket" is the name of resource template. We can use it any suitable name here. "Type" defines the type of resource, after this, we can define properties of resource. Each resource will have its own properties.
OAI resource template
CloudFrontOriginIdentity:
Type: AWS::CloudFront::CloudFrontOriginAccessIdentity
Properties:
CloudFrontOriginAccessIdentityConfig:
Comment: 'origin identity'
Template resource to update bucket policy.
BucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: private-bucket
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
AWS: !Sub 'arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity ${CloudFrontOriginIdentity}'
Action: 's3:GetObject'
Resource: arn:aws:s3:::private-bucket/*
Two of the most important fields, here are AWS field under principle and Resource fields.
Recently created OAI can be used directly by using its template resource name like this "${CloudFrontOriginIdentity}"
Now the final CloudFront Distribution resource template.
One property you need to be careful here is "Origins", that basically defines your bucket origin and "DomainName" will be like this "${bucket name}.s3.${region}.amazonaws.com".
publicDistribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Origins:
- DomainName: private-bucket.s3.us-east-2.amazonaws.com
Id: S3-private-bucket
S3OriginConfig:
OriginAccessIdentity: !Sub 'origin-access-identity/cloudfront/${CloudFrontOriginIdentity}'
Enabled: 'true'
Comment: Some comment
DefaultCacheBehavior:
AllowedMethods:
- GET
- HEAD
TargetOriginId: S3-private-bucket
ForwardedValues:
QueryString: 'false'
Cookies:
Forward: none
ViewerProtocolPolicy: redirect-to-https
ViewerCertificate:
CloudFrontDefaultCertificate: 'true'
After completing CloudFromation template, you can use sam command to deploy and check status of its CloudFromation stack.
Sam command :
sam deploy --template-file [sample-template] --stack-name [Stack name] --s3-bucket sam-test-bucket --capabilities CAPABILITY_IAM
Few links to learn more:
Thanks for reading 💓️