AWS ElastiCache Redis with Terraform - Complete Guide
Deploy AWS ElastiCache Redis with Terraform. Cluster mode, replication groups, subnet groups, encryption, and parameter group configuration.
Terraform
Deploy AWS CloudFront distributions with Terraform. S3 origin, ALB origin, custom domains, SSL certificates, cache policies, and WAF integration.
resource "aws_cloudfront_distribution" "cdn" {
origin {
domain_name = aws_s3_bucket.website.bucket_regional_domain_name
origin_id = "S3"
origin_access_control_id = aws_cloudfront_origin_access_control.main.id
}
enabled = true
default_root_object = "index.html"
default_cache_behavior {
allowed_methods = ["GET", "HEAD"]
cached_methods = ["GET", "HEAD"]
target_origin_id = "S3"
viewer_protocol_policy = "redirect-to-https"
cache_policy_id = "658327ea-f89d-4fab-a63d-7e88639e58f6"
}
viewer_certificate {
cloudfront_default_certificate = true
}
restrictions {
geo_restriction { restriction_type = "none" }
}
}resource "aws_cloudfront_origin_access_control" "main" {
name = "${var.project}-oac"
origin_access_control_origin_type = "s3"
signing_behavior = "always"
signing_protocol = "sigv4"
}
resource "aws_s3_bucket" "website" {
bucket = "${var.project}-website"
}
resource "aws_s3_bucket_policy" "cdn" {
bucket = aws_s3_bucket.website.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Sid = "AllowCloudFront"
Effect = "Allow"
Principal = { Service = "cloudfront.amazonaws.com" }
Action = "s3:GetObject"
Resource = "${aws_s3_bucket.website.arn}/*"
Condition = {
StringEquals = {
"AWS:SourceArn" = aws_cloudfront_distribution.cdn.arn
}
}
}]
})
}resource "aws_cloudfront_distribution" "cdn" {
origin {
domain_name = aws_s3_bucket.website.bucket_regional_domain_name
origin_id = "S3Origin"
origin_access_control_id = aws_cloudfront_origin_access_control.main.id
}
enabled = true
is_ipv6_enabled = true
default_root_object = "index.html"
aliases = [var.domain_name]
price_class = "PriceClass_100" # US, Canada, Europe only
default_cache_behavior {
allowed_methods = ["GET", "HEAD", "OPTIONS"]
cached_methods = ["GET", "HEAD"]
target_origin_id = "S3Origin"
viewer_protocol_policy = "redirect-to-https"
compress = true
cache_policy_id = aws_cloudfront_cache_policy.static.id
origin_request_policy_id = null
}
custom_error_response {
error_code = 404
response_code = 404
response_page_path = "/404.html"
}
custom_error_response {
error_code = 403
response_code = 404
response_page_path = "/404.html"
}
viewer_certificate {
acm_certificate_arn = aws_acm_certificate.main.arn
ssl_support_method = "sni-only"
minimum_protocol_version = "TLSv1.2_2021"
}
restrictions {
geo_restriction {
restriction_type = "none"
}
}
tags = { Environment = var.environment }
}resource "aws_cloudfront_cache_policy" "static" {
name = "${var.project}-static-cache"
default_ttl = 86400 # 1 day
max_ttl = 31536000 # 1 year
min_ttl = 0
parameters_in_cache_key_and_forwarded_to_origin {
cookies_config {
cookie_behavior = "none"
}
headers_config {
header_behavior = "none"
}
query_strings_config {
query_string_behavior = "none"
}
enable_accept_encoding_gzip = true
enable_accept_encoding_brotli = true
}
}provider "aws" {
alias = "us_east_1"
region = "us-east-1"
}
resource "aws_acm_certificate" "main" {
provider = aws.us_east_1
domain_name = var.domain_name
validation_method = "DNS"
subject_alternative_names = ["*.${var.domain_name}"]
lifecycle {
create_before_destroy = true
}
}
resource "aws_route53_record" "cert_validation" {
for_each = {
for dvo in aws_acm_certificate.main.domain_validation_options : dvo.domain_name => dvo
}
zone_id = aws_route53_zone.main.zone_id
name = each.value.resource_record_name
type = each.value.resource_record_type
records = [each.value.resource_record_value]
ttl = 60
}
resource "aws_acm_certificate_validation" "main" {
provider = aws.us_east_1
certificate_arn = aws_acm_certificate.main.arn
validation_record_fqdns = [for r in aws_route53_record.cert_validation : r.fqdn]
}resource "aws_cloudfront_distribution" "api" {
origin {
domain_name = aws_lb.main.dns_name
origin_id = "ALBOrigin"
custom_origin_config {
http_port = 80
https_port = 443
origin_protocol_policy = "https-only"
origin_ssl_protocols = ["TLSv1.2"]
}
}
default_cache_behavior {
allowed_methods = ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"]
cached_methods = ["GET", "HEAD"]
target_origin_id = "ALBOrigin"
viewer_protocol_policy = "redirect-to-https"
cache_policy_id = "4135ea2d-6df8-44a3-9df3-4b5a84be39ad" # CachingDisabled
origin_request_policy_id = "216adef6-5c7f-47e4-b989-5492eafa07d3" # AllViewer
}
}| Price Class | Regions | Cost |
|---|---|---|
PriceClass_100 | US, Canada, Europe | Lowest |
PriceClass_200 | + Asia, Middle East, Africa | Medium |
PriceClass_All | All edge locations | Highest |
Use OAC (not OAI) for S3 origins, ACM certificates in us-east-1 for custom domains, and cache policies with Brotli/gzip compression. Set PriceClass_100 to optimize costs if your audience is US/EU focused. CloudFront distributions take 15-30 minutes to deploy — set appropriate timeouts.
Deploy AWS ElastiCache Redis with Terraform. Cluster mode, replication groups, subnet groups, encryption, and parameter group configuration.
Deploy AWS Kinesis Data Streams with Terraform. Stream configuration, shard management, Lambda consumers, Firehose delivery, and encryption settings.
Deploy AWS Lambda functions with Terraform. Complete guide with IAM roles, API Gateway triggers, S3 triggers, layers, environment variables, and VPC...
Deploy AWS MSK (Managed Streaming for Kafka) with Terraform. Cluster configuration, MSK Serverless, encryption, monitoring, and topic management.