DEV Community

Cover image for AWS Networking with Terraform : Deploying a CloudFront distribution for EC2 Website
Chinmay Tonape
Chinmay Tonape

Posted on • Updated on

AWS Networking with Terraform : Deploying a CloudFront distribution for EC2 Website

In our earlier post, we implemented the seamless integration of Amazon S3 with CloudFront for hosting static websites. Today, we're taking it a step further by exploring how to integrate Amazon Content Delivery Networks (CDNs) CloudFront with websites hosted on EC2 instances. We'll be leveraging Terraform modules to streamline the process, ensuring modularity and scalability.

Architecture Overview:

Before diving into the implementation details, let's outline the architecture we'll be working with:

Architecture Diagram

Step 1: Create an EC2 Web Server Instance in a VPC

We'll initiate the process by provisioning an EC2 instance within a Virtual Private Cloud (VPC). We have used modules to create the components. Please refer to my GitHub repo in resources section.

####################################################
# Create two VPC and components
####################################################

module "vpc" {
  source               = "./modules/vpc"
  name                 = "VPC-A"
  aws_region           = var.aws_region
  vpc_cidr_block       = var.vpc_cidr_block #"10.1.0.0/16"
  public_subnets_cidrs = [cidrsubnet(var.vpc_cidr_block, 8, 1)]
  enable_dns_hostnames = var.enable_dns_hostnames
  aws_azs              = var.aws_azs
  common_tags          = local.common_tags
  naming_prefix        = local.naming_prefix
}

####################################################
# Create EC2 Server Instances
####################################################

module "web_server" {
  source           = "./modules/web"
  instance_type    = var.instance_type
  instance_key     = var.instance_key
  subnet_id        = module.vpc.public_subnets[0]
  vpc_id           = module.vpc.vpc_id
  ec2_name         = "Web Server"
  sg_ingress_ports = var.sg_ingress_public
  common_tags      = local.common_tags
  naming_prefix    = local.naming_prefix
}
Enter fullscreen mode Exit fullscreen mode

Step 2: Create a CloudFront Distribution

Next, we'll set up a CloudFront distribution with origin of public DNS of EC2 instance hosting website.

####################################################
# Create AWS Cloudfront distribution
####################################################
resource "aws_cloudfront_distribution" "cf-dist" {
  enabled             = true
  default_root_object = "index.html"

  origin {
    domain_name = var.ec2_public_dns
    origin_id   = var.ec2_public_dns
    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.ec2_public_dns
    forwarded_values {
      query_string = false

      cookies {
        forward = "none"
      }
    }
    viewer_protocol_policy = "allow-all"
    min_ttl                = 0
    default_ttl            = 3600
    max_ttl                = 86400
  }

  price_class = "PriceClass_All"

  restrictions {
    geo_restriction {
      restriction_type = "whitelist"
      locations        = ["IN", "US", "CA"]
    }
  }

  viewer_certificate {
    cloudfront_default_certificate = true
  }

  tags = merge(var.common_tags, {
    Name = "${var.naming_prefix}-cloudfront"
  })
}
Enter fullscreen mode Exit fullscreen mode

Steps to Run Terraform

Follow these steps to execute the Terraform configuration:

terraform init
terraform plan 
terraform apply -auto-approve
Enter fullscreen mode Exit fullscreen mode

Upon successful completion, Terraform will provide relevant outputs.

Apply complete! Resources: 8 added, 0 changed, 0 destroyed.

Outputs:

cloudfront_domain_name = "http://d3q4caj22i0xed.cloudfront.net"
Enter fullscreen mode Exit fullscreen mode

Testing the outcome

EC2 Instance with hosted website

EC2 Instance

CloudFront Distribution:

Cloudfront Distribution

CloudFront Distribution Origin as EC2 as origin:
CF Dist as EC2 as Origin

Using cloudfront domain name to access EC2 Website

Website

Website accessed from country which is not in allowlist (used soft VPN)

Geo Allowlist

Cleanup

Remember to stop AWS components to avoid large bills.

terraform destroy -auto-approve
Enter fullscreen mode Exit fullscreen mode

With the EC2-CloudFront integration successfully implemented, we've significantly enhanced our website's performance and reliability.

In our upcoming module, we'll delve into setting up a failover website using S3 in conjunction with CloudFront distributions.

Resources:

GitHub Repo: https://github.com/chinmayto/terraform-aws-cloudfront-ec2
AWS CloudFront: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Introduction.html

Top comments (0)