In our previous post, we integrated CloudFront distribution with website applications hosted on EC2 instances. Building upon that foundation, we now shift our focus to a critical aspect of cloud architecture: high availability origin failover.
In this blog post, we'll see how CloudFront can be used to fortify the resilience of your infrastructure, employing Terraform to prepare the setup seamlessly.
Architecture Overview:
Before diving into the implementation details, let's sketch out the architecture we'll be constructing:
Step 1: Creating Primary and Failover S3 Buckets:
Firstly, we'll set up two distinct S3 buckets, each serving as a primary and failover origin respectively. These buckets will host the static website content.
####################################################
# Create S3 Static Website
####################################################
module "s3_primary" {
source = "./modules/s3-static-website"
bucket_name = var.bucket_name_primary
source_files = "webfiles"
common_tags = local.common_tags
naming_prefix = local.naming_prefix
}
module "s3_failover" {
source = "./modules/s3-static-website"
bucket_name = var.bucket_name_failover
source_files = "webfiles_failover"
common_tags = local.common_tags
naming_prefix = local.naming_prefix
}
Step 2: Configuring CloudFront Distribution:
Next, we'll craft a CloudFront distribution, integrating both the primary and failover S3 buckets as origins. This configuration helps CloudFront to dynamically switch to the failover origin in case of an outage or unavailability of the primary source.
####################################################
# Create AWS Cloudfront distribution
####################################################
resource "aws_cloudfront_origin_access_control" "cf-s3-oac" {
name = "CloudFront S3 OAC"
description = "CloudFront S3 OAC"
origin_access_control_origin_type = "s3"
signing_behavior = "always"
signing_protocol = "sigv4"
}
resource "aws_cloudfront_distribution" "cf-dist" {
enabled = true
default_root_object = "index.html"
origin_group {
origin_id = "origin_group_id"
failover_criteria {
status_codes = [403, 404, 500, 502, 503, 504]
}
member {
origin_id = "s3_primary"
}
member {
origin_id = "s3_failover"
}
}
origin {
domain_name = data.aws_s3_bucket.s3_primary.bucket_regional_domain_name
origin_id = "s3_primary"
origin_access_control_id = aws_cloudfront_origin_access_control.cf-s3-oac.id
}
origin {
domain_name = data.aws_s3_bucket.s3_failover.bucket_regional_domain_name
origin_id = "s3_failover"
origin_access_control_id = aws_cloudfront_origin_access_control.cf-s3-oac.id
}
default_cache_behavior {
allowed_methods = ["GET", "HEAD"]
cached_methods = ["GET", "HEAD"]
target_origin_id = "origin_group_id"
forwarded_values {
query_string = false
cookies {
forward = "none"
}
}
viewer_protocol_policy = "allow-all"
min_ttl = 0
default_ttl = 360
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"
})
}
Step 3: Updating S3 Bucket Policies:
To facilitate seamless communication between CloudFront and the S3 buckets, we'll adjust the bucket policies accordingly.
####################################################
# S3 bucket policy to allow access from cloudfront
####################################################
data "aws_iam_policy_document" "s3_bucket_policy" {
statement {
actions = ["s3:GetObject"]
resources = ["${var.bucket_arn}/*"]
principals {
type = "Service"
identifiers = ["cloudfront.amazonaws.com"]
}
condition {
test = "StringEquals"
variable = "AWS:SourceArn"
values = [var.cloudfront_distribution_arn]
}
}
}
resource "aws_s3_bucket_policy" "static_site_bucket_policy" {
bucket = var.bucket_id
policy = data.aws_iam_policy_document.s3_bucket_policy.json
}
Steps to Run Terraform
Follow these steps to execute the Terraform configuration:
terraform init
terraform plan
terraform apply -auto-approve
Upon successful completion, Terraform will provide relevant outputs.
Apply complete! Resources: 9 added, 0 changed, 0 destroyed.
Outputs:
cloudfront_domain_name = "http://d1rwkmekbjnbkd.cloudfront.net"
Testing the outcome
S3 Primary and Failover Buckets
CloudFront Distribution:
CloudFront Distribution Origin as S3 primary and failover and origin group
S3 Bucket Policy to allow access from cloudfront - primary and failover bucket
Using cloudfront domain name to access S3 static website
Failover to S3 failover bucket by removing s3 primary bucket policy manually from console (after TTL timeout)
Cleanup
Remember to stop AWS components to avoid large bills.
terraform destroy -auto-approve
This how we can setup primary and failover access originas for CloudFront distribution for creating a robust high available architecture.
In our subsequent module, we'll embark on a journey into the realm of containerization with AWS, exploring how services like Amazon ECS can revolutionize application deployment and scalability.
Resources:
GitHub Repo: https://github.com/chinmayto/terraform-aws-cloudfront-s3-failover
AWS CloudFront: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Introduction.html
AWS CloudFront Origin Failover: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/high_availability_origin_failover.html
Top comments (0)