Create AWS Cloudfront Distribution using Terraform

In this post, we’ll create the AWS Cloudfront Distribution using Terraform and for this, we need the latest version of Terraform.

Terraform v0.6.15
  • Complete Cloudfront Terraform Plan as gist
  • Complete Variables as gist

Before using the terraform, we need to export AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY as environment variables:

export AWS_ACCESS_KEY_ID="xxxxxxxxxxxxxxxx"
export AWS_SECRET_ACCESS_KEY="yyyyyyyyyyyyyyyyyyyy"

The first step is to create an S3 bucket that will act as the ‘origin‘ in cloudfront distribution, this will be the place where all of your static files and assets will live. Here’s the code to do this:

// Setup your S3 Bucket
resource "aws_s3_bucket" "cdn_bucket" {
bucket = "${var.bucket_name}"
acl = "public-read"
policy = <<POLICY
"Principal": "*",
view raw hosted with ❤ by GitHub

Next we need to setup the CloudFront distribution that will use the S3 bucket as origin that we have just created in the above step.

// Setup the CloudFront Distribution
resource "aws_cloudfront_distribution" "cloudfront_distribution" {
origin {
domain_name = "${var.bucket_name}"
origin_id = "S3-${var.bucket_name}"
s3_origin_config {}
enabled = true
price_class = "${var.price_class}"
default_cache_behavior {
allowed_methods = [ "DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT" ]
cached_methods = [ "GET", "HEAD" ]
target_origin_id = "S3-${var.bucket_name}"
forwarded_values {
query_string = true
cookies {
forward = "none"
viewer_protocol_policy = "allow-all"
min_ttl = 0
default_ttl = 3600
max_ttl = 86400
retain_on_delete = "${var.retain_on_delete}"
viewer_certificate {
cloudfront_default_certificate = true
restrictions {
geo_restriction {
restriction_type = "none"

Let’s examine some of the important parameters:

domain_name: points to the origin which is S3 bucket endpoint.
origin_id: A unique identifier for this origin configuration, which is the name of the S3 bucket plus “S3” keyword
s3_origin_config: Extra S3 origin options, we leave this blank
enabled: Enable our CloudFront distribution
price_class: Price varies depending on the edge location from which CloudFront serves the requests.
retain_on_delete: Decide whether delete or disable the cloudfront distribution upon terraform destory command
allowed_methods: Which HTTP requests we permit the distribution to serve
cached_methods: Which HTTP requests we let this behaviour apply to
target_origin_id: we use the same as “origin_id
forwarded_values: Entities that will be passed from the edge to our origin.
viewer_protocol_policy: Which HTTP protocol policy to enforce. For example: allow-all, https-only, or redirect-to-https.
min_ttl: Minimum time (seconds) for objects to live in the distribution cache
max_ttl: Maximum time (seconds) that objects can live in the distribution cache
default_ttl: The default time (seconds) for the objects to live in the distribution cache

Last step is to add the Route53 records to reference the CloudFront distribution that we have created above.

//Add Root Route53 Records
resource "aws_route53_record" "main_record" {
zone_id = "${var.hosted_zone_id}"
name = "${var.route53_record_name}.${var.domain_name}"
type = "A"
alias {
name = "${aws_cloudfront_distribution.cloudfront_distribution.domain_name}"
zone_id = "${var.alias_zone_id}"
evaluate_target_health = false

Few critical pieces you should know about:

zone_id: ID for the domain hosted zone
domain_name: Name of the domain where record(s) need to create
route53_record_name: Name of the record that you want to create for CDN
alias_zone_id: Fixed hardcoded constant zone_id that is used for all CloudFront distributions

Required variables:

Modify the variables as per your requirements.

variable aws_region {
default = "us-east-1"
variable bucket_name {
description = "name of the bucket that will use as origin for CDN"
default = "tendo-cdn-bucket"
variable retain_on_delete {
description = "Instruct CloudFront to simply disable the distribution instead of delete"
default = false
variable price_class {
description = "Price classes provide you an option to lower the prices you pay to deliver content out of Amazon CloudFront"
default = "PriceClass_All"
variable hosted_zone_id {
description = "ID for the domain hosted zone"
variable domain_name {
description = "Name of the domain where record(s) need to create"
default = ""
variable route53_record_name {
description = "Name of the record that you want to create for CDN"
default = "tend-cdn"
variable alias_zone_id {
description = "Fixed hardcoded constant zone_id that is used for all CloudFront distributions"
default = "Z2FDTNDATAQYW2"

To Generate and show an execution plan (dry run):

terraform plan

To Builds or makes actual changes in infrastructure:

terraform apply

After successful completion of terraform plan(wait for 15 to 20 minutes), login to the AWS Web Console and verify the resources:




Enjoy :-)

Hope this will help you!

Please Remember me in your prayers!


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: