iToverDose/Software· 6 MAY 2026 · 16:03

Secure CloudFront CDN with Terraform in 5 Practical Steps

Learn how to deploy a CloudFront CDN with HTTPS using Terraform, replacing manual configurations with fully automated infrastructure-as-code. Follow a step-by-step guide to integrate CloudFront, Route53, and ACM for a faster, more secure web presence.

DEV Community4 min read0 Comments

CloudFront CDNs don’t just speed up your website—they make it more secure and globally accessible. When paired with Terraform, you can provision a fully automated CDN that serves HTTPS traffic from AWS edge locations. This guide breaks down the process into five straightforward steps, from setting up the origin server to enforcing HTTPS across your domain.

Why Use CloudFront with Terraform?

Traditional CDN setups often require manual console work, DNS juggling, and SSL certificate provisioning. Terraform turns this into a repeatable, version-controlled process. By defining your CloudFront distribution, Route53 records, and SSL certificates as code, you ensure consistency across deployments and eliminate configuration drift. The result is a faster, more resilient web application that scales automatically with your traffic.

Key benefits include:

  • Global edge caching reduces latency by serving content from the nearest AWS location.
  • Automatic HTTPS enforcement secures user data without manual certificate management.
  • Infrastructure as Code (IaC) enables team collaboration and version tracking.

Step 1: Define Your Origin Server

Your CloudFront distribution needs an origin—a server or service that hosts your content. In this example, we use an EC2 instance as the origin, accessible via a Route53 DNS record. Start by declaring the Route53 zone and record in your Terraform module:

# modules/dns/main.tf
resource "aws_route53_zone" "main" {
  name = "your-domain.com"
}

resource "aws_route53_record" "origin" {
  zone_id = var.main_zone_id
  name    = var.origin_domain
  type    = "A"
  ttl     = 300
  records = [var.origin_ip]
}

Next, define the required variables in variables.tf:

# modules/dns/variables.tf
variable "main_zone_id" {
  type = string
}

variable "origin_domain" {
  type = string
}

variable "origin_ip" {
  type = string
}

In your root main.tf, reference the EC2 instance’s public IP as the origin:

module "dns" {
  source       = "./modules/dns"
  origin_domain = "origin.your-domain.com"
  main_zone_id  = aws_route53_zone.main.zone_id
  origin_ip     = module.ec2.public_ip
}

Finally, expose the origin’s FQDN as an output for reuse in CloudFront:

# modules/dns/outputs.tf
output "origin_fqdn" {
  value       = aws_route53_record.origin.fqdn
  description = "Fully qualified domain name of the origin server"
}

Step 2: Configure the CloudFront Distribution

With the origin in place, define the CloudFront distribution to cache and serve your content. Start with the basic configuration in a new module:

# modules/cloudfront/main.tf
resource "aws_cloudfront_distribution" "cdn" {
  enabled             = true
  default_root_object = "index.html"

  origin {
    domain_name = var.origin_fqdn
    origin_id   = var.origin_fqdn

    custom_origin_config {
      http_port            = 80
      https_port           = 443
      origin_protocol_policy = "http-only"
      origin_ssl_protocols = ["TLSv1.2"]
    }
  }

  default_cache_behavior {
    allowed_methods  = ["GET", "HEAD"]
    cached_methods   = ["GET", "HEAD"]
    target_origin_id = var.origin_fqdn

    forwarded_values {
      query_string = false
      cookies {
        forward = "none"
      }
    }

    viewer_protocol_policy = "redirect-to-https"
    min_ttl                = 0
    default_ttl            = 3600
    max_ttl                = 86400
  }

  price_class = "PriceClass_100"
  viewer_certificate {
    cloudfront_default_certificate = true
  }

  restrictions {
    geo_restriction {
      restriction_type = "none"
    }
  }
}

Add the required variable and output:

# modules/cloudfront/variables.tf
variable "origin_fqdn" {
  type = string
}
# modules/cloudfront/outputs.tf
output "distribution_domain" {
  value = aws_cloudfront_distribution.cdn.domain_name
}

In main.tf, pass the origin FQDN to the CloudFront module:

module "cloudfront" {
  source      = "./modules/cloudfront"
  origin_fqdn = module.dns.origin_fqdn
}

Step 3: Update Security Groups and Apply Changes

Ensure your EC2 instance’s security group allows inbound HTTP traffic from any source:

# modules/security_group/main.tf
resource "aws_security_group" "web_server" {
  name   = "web-server-sg"
  vpc_id = var.vpc_id

  ingress {
    cidr_blocks = ["0.0.0.0/0"]
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
  }

  egress {
    cidr_blocks = ["0.0.0.0/0"]
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
  }
}

Apply the changes with:

terraform init
terraform apply

Terraform will output the CloudFront distribution’s domain name, such as d123456789abcdef.cloudfront.net. Access this URL in a browser to verify the CDN is serving content over HTTP.

Step 4: Provision an SSL Certificate with ACM

To enforce HTTPS, provision an SSL certificate using AWS Certificate Manager (ACM). Follow these steps:

  1. Request a certificate for your domain in the ACM console.
  2. Validate the domain via DNS or email.
  3. Copy the certificate ARN for use in CloudFront.

Update the CloudFront distribution to use the ACM certificate:

viewer_certificate {
  acm_certificate_arn      = var.acm_certificate_arn
  ssl_support_method       = "sni-only"
  minimum_protocol_version = "TLSv1.2_2021"
}

Add the certificate ARN variable:

variable "acm_certificate_arn" {
  type = string
}

Reapply Terraform to update the distribution with HTTPS support.

Step 5: Route Traffic via Route53 to CloudFront

Create a Route53 A-record that points your domain to the CloudFront distribution. Replace the existing A-record for your domain:

resource "aws_route53_record" "www" {
  zone_id = aws_route53_zone.main.zone_id
  name    = "www.your-domain.com"
  type    = "A"

  alias {
    name                   = module.cloudfront.distribution_domain
    zone_id                = module.cloudfront.hosted_zone_id
    evaluate_target_health = false
  }
}

This alias record ensures all traffic routes through CloudFront, benefiting from its global cache and HTTPS enforcement.

Final Checklist and Next Steps

Before deploying to production, validate:

  • CloudFront distribution is Enabled.
  • SSL certificate is issued and verified.
  • Route53 alias records point to CloudFront.
  • Security groups restrict unnecessary access.

With these steps complete, your website benefits from faster load times, automatic HTTPS, and global scalability. Future enhancements might include:

  • Custom cache policies to optimize performance for dynamic content.
  • Lambda@Edge functions to modify requests at the edge.
  • Multi-region failover for high availability.

By treating your CDN as code, you future-proof your infrastructure and streamline deployments across environments.

AI summary

Automate CloudFront CDN deployment with Terraform to secure and accelerate your website. Learn to integrate Route53, ACM, and EC2 in 5 steps for a fully automated HTTPS setup.

Comments

00
LEAVE A COMMENT
ID #P0K59D

0 / 1200 CHARACTERS

Human check

7 + 8 = ?

Will appear after editor review

Moderation · Spam protection active

No approved comments yet. Be first.