Deploying a Static Website on AWS S3 with CloudFront & Route 53 using Terraform

This task focuses on deploying a static website using AWS S3, CloudFront, and Route 53 with Terraform for infrastructure as code (IaC). The setup includes domain configuration via Route 53, enabling HTTPS with an AWS Certificate Manager (ACM) SSL certificate, and leveraging CloudFront as a CDN for performance and security.

Task Architecture

Prerequisites

Step 1: Set Up Terraform Configuration

Create a project directory:

mkdir static-website-terraform && cd static-website-terraform

Create Terraform files:

touch main.tf variables.tf outputs.tf

Step 2: Terraform Code

1. Define Providers

provider "aws" {
  region = "us-east-1" # ACM must be in us-east-1 for CloudFront
}

2. S3 Bucket for Static Website Hosting

resource "aws_s3_bucket" "static_site" {
  bucket = var.s3_bucket_name
}

resource "aws_s3_bucket_policy" "allow_public_read" {
  bucket = aws_s3_bucket.static_site.id
  policy = <

3. CloudFront Distribution

resource "aws_cloudfront_distribution" "s3_distribution" {
  origin {
    domain_name = aws_s3_bucket.static_site.bucket_regional_domain_name
    origin_id   = "S3-${var.s3_bucket_name}"
  }

  enabled             = true
  default_root_object = "index.html"

  default_cache_behavior {
    viewer_protocol_policy = "redirect-to-https"
    allowed_methods        = ["GET", "HEAD"]
    cached_methods         = ["GET", "HEAD"]
    target_origin_id       = "S3-${var.s3_bucket_name}"

    forwarded_values {
      query_string = false

      cookies {
        forward = "none"
      }
    }
  }

  viewer_certificate {
    acm_certificate_arn = aws_acm_certificate.cert.arn
    ssl_support_method  = "sni-only"
  }
}

4. ACM SSL Certificate for HTTPS

resource "aws_acm_certificate" "cert" {
  domain_name       = var.domain_name
  validation_method = "DNS"

  lifecycle {
    create_before_destroy = true
  }
}

5. Route 53 DNS Configuration

resource "aws_route53_record" "www" {
  zone_id = var.hosted_zone_id
  name    = var.domain_name
  type    = "A"

  alias {
    name                   = aws_cloudfront_distribution.s3_distribution.domain_name
    zone_id                = aws_cloudfront_distribution.s3_distribution.hosted_zone_id
    evaluate_target_health = false
  }
}

Step 3: Define Variables

variables.tf

variable "s3_bucket_name" {
  description = "The name of the S3 bucket"
  type        = string
}

variable "domain_name" {
  description = "The domain name for the website"
  type        = string
}

variable "hosted_zone_id" {
  description = "The Route 53 hosted zone ID"
  type        = string
}

Step 4: Define Outputs

outputs.tf

output "s3_bucket_name" {
  value = aws_s3_bucket.static_site.bucket
}

output "cloudfront_domain" {
  value = aws_cloudfront_distribution.s3_distribution.domain_name
}

output "website_url" {
  value = "https://${var.domain_name}"
}

Step 5: Deploy Infrastructure

Run the following commands:

  1. Initialize Terraform
  2. terraform init
  3. Validate Configuration
  4. terraform validate
  5. Plan Deployment
  6. terraform plan -out=tfplan
  7. Apply Changes
  8. terraform apply tfplan

Step 6: Upload Website Files to S3

After Terraform creates the infrastructure, upload website files:

aws s3 cp index.html s3://your-bucket-name/
aws s3 cp style.css s3://your-bucket-name/

Final Output

Conclusion

This project demonstrates how to deploy a static website efficiently using AWS S3, CloudFront, and Route 53 with Terraform. It provides a scalable, secure, and cost-effective hosting solution.