Terraform Hands-On: Setting Up a CDN with AWS CloudFront, S3, and Route 53 using Terraform
Introduction
I will walk you through setting up a Content Delivery Network (CDN) on AWS using CloudFront, an S3 bucket, and Route 53 for DNS management. We will use Terraform to automate the infrastructure setup. This guide includes the Terraform configuration, step-by-step instructions for applying the configuration, and screenshots from the AWS console.
Prerequisites AWS Account Terraform installed GitHub repository Hashnode account Project Structure Our project will have the following structure:
├── main.tf
├── provider.tf
├── variables.tf
├── terraform.tfvars
├── outputs.tf
Step-by-Step Guide
Create the Terraform Files.
-
This file specifies the AWS provider and the region.
provider "aws" {
region = var.region
}
-
This file contains the main configuration for the S3 bucket, CloudFront distribution, and Route 53 record.
resource "aws_s3_bucket" "bucket" {
bucket = var.bucket_name
}
resource "aws_s3_bucket_website_configuration" "website" {
bucket = aws_s3_bucket.bucket.id
index_document {
suffix = "index.html"
}
error_document {
key = "error.html"
}
}
resource "aws_s3_bucket_policy" "bucket_policy" {
bucket = aws_s3_bucket.bucket.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = "*"
Action = "s3:GetObject"
Resource = "${aws_s3_bucket.bucket.arn}/*"
},
]
})
}
resource "aws_cloudfront_distribution" "cdn" {
origin {
domain_name = "${aws_s3_bucket.bucket.bucket_regional_domain_name}"
origin_id = "s3-bucket-origin"
s3_origin_config {
origin_access_identity = aws_cloudfront_origin_access_identity.origin_access_identity.cloudfront_access_identity_path
}
}
enabled = true
is_ipv6_enabled = true
comment = "CDN for ${var.bucket_name}"
default_root_object = "index.html"
default_cache_behavior {
allowed_methods = ["GET", "HEAD"]
cached_methods = ["GET", "HEAD"]
target_origin_id = "s3-bucket-origin"
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"
restrictions {
geo_restriction {
restriction_type = "none"
}
}
viewer_certificate {
cloudfront_default_certificate = true
}
aliases = [var.domain_name]
}
resource "aws_cloudfront_origin_access_identity" "origin_access_identity" {
comment = "Origin access identity for ${aws_s3_bucket.bucket.id}"
}
resource "aws_route53_record" "cdn" {
zone_id = var.hosted_zone_id
name = var.domain_name
type = "A"
alias {
name = aws_cloudfront_distribution.cdn.domain_name
zone_id = aws_cloudfront_distribution.cdn.hosted_zone_id
evaluate_target_health = false
}
}
-
This file defines the variables used in the configuration.
variable "region" {
description = "The AWS region to create resources in"
type = string
default = "us-east-2"
}
variable "bucket_name" {
description = "The name of the S3 bucket"
type = string
}
variable "domain_name" {
description = "The domain name for the CloudFront distribution"
type = string
}
variable "hosted_zone_id" {
description = "The Route 53 hosted zone ID"
type = string
}
terraform.tfvars
This file provides values for the variables.
region = "us-east-2"
bucket_name = "unique-buc-2412-website-21"
domain_name = "cdn.yourdomain.com"
hosted_zone_id = "YOUR_HOSTED_ZONE_ID"
dc
-
This file defines the outputs for the project.
output "s3_bucket_name" {
value = aws_s3_bucket.bucket.bucket
}
output "cloudfront_distribution_id" {
value = aws_cloudfront_distribution.cdn.id
}
output "cloudfront_domain_name" {
value = aws_cloudfront_distribution.cdn.domain_name
}
output "cdn_url" {
value = "https://${aws_cloudfront_distribution.cdn.domain_name}"
}
Steps to Apply the Terraform Configuration Initialize Terraform. Open your terminal and run the following command to initialize Terraform:
terraform init
Plan the Changes:
terraform plan
Apply the Changes:
terraform apply
Confirm with yes when prompted.
Verify the Setup
Go to the AWS Management Console and verify the following:
S3 Bucket: Ensure the bucket is created and has public access enabled via the bucket policy.
CloudFront Distribution: Verify the distribution is created and associated with the S3 bucket.
Route 53 Record: Confirm the DNS record is created and points to the CloudFront distribution.
Screenshots
Output the CDN URL
After running terraform apply, note the CDN URL provided in the output. You can use this URL to access your content delivered through CloudFront.
Conclusion
In this post, we've set up a CDN using AWS CloudFront, S3, and Route 53 with Terraform. This configuration helps in delivering static content with low latency and high availability. By automating the infrastructure setup, we ensure consistency and ease of management.
cvds