AWS WAF Web Application Firewall with Terraform
Protect your applications with AWS WAF rules managed by Terraform — rate limiting, IP blocking, and SQL injection prevention.
Cloud Computing
Configure AWS CloudFront distribution with S3 origin, custom domain, SSL certificate, and cache policies using Terraform.
CloudFront is AWS's global content delivery network. It caches your content at edge locations worldwide, reducing latency for users regardless of their location. This guide covers setting up a complete CloudFront distribution with Terraform, including S3 origin, custom domain, SSL, and optimized cache policies.
resource "aws_s3_bucket" "website" {
bucket = "my-website-${var.environment}"
}
resource "aws_s3_bucket_public_access_block" "website" {
bucket = aws_s3_bucket.website.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
resource "aws_s3_bucket_versioning" "website" {
bucket = aws_s3_bucket.website.id
versioning_configuration {
status = "Enabled"
}
}resource "aws_cloudfront_origin_access_control" "main" {
name = "s3-oac"
description = "OAC for S3 website"
origin_access_control_origin_type = "s3"
signing_behavior = "always"
signing_protocol = "sigv4"
}
data "aws_iam_policy_document" "s3_policy" {
statement {
principals {
type = "Service"
identifiers = ["cloudfront.amazonaws.com"]
}
actions = ["s3:GetObject"]
resources = ["${aws_s3_bucket.website.arn}/*"]
condition {
test = "StringEquals"
variable = "AWS:SourceArn"
values = [aws_cloudfront_distribution.main.arn]
}
}
}
resource "aws_s3_bucket_policy" "website" {
bucket = aws_s3_bucket.website.id
policy = data.aws_iam_policy_document.s3_policy.json
}resource "aws_cloudfront_distribution" "main" {
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, "www.${var.domain_name}"]
price_class = "PriceClass_100"
default_cache_behavior {
allowed_methods = ["GET", "HEAD", "OPTIONS"]
cached_methods = ["GET", "HEAD"]
target_origin_id = "S3Origin"
cache_policy_id = aws_cloudfront_cache_policy.optimized.id
origin_request_policy_id = aws_cloudfront_origin_request_policy.cors.id
response_headers_policy_id = aws_cloudfront_response_headers_policy.security.id
viewer_protocol_policy = "redirect-to-https"
compress = true
}
# Cache static assets longer
ordered_cache_behavior {
path_pattern = "/assets/*"
allowed_methods = ["GET", "HEAD"]
cached_methods = ["GET", "HEAD"]
target_origin_id = "S3Origin"
cache_policy_id = aws_cloudfront_cache_policy.static_assets.id
viewer_protocol_policy = "redirect-to-https"
compress = true
}
custom_error_response {
error_code = 404
response_code = 200
response_page_path = "/index.html"
error_caching_min_ttl = 10
}
restrictions {
geo_restriction {
restriction_type = "none"
}
}
viewer_certificate {
acm_certificate_arn = aws_acm_certificate.main.arn
ssl_support_method = "sni-only"
minimum_protocol_version = "TLSv1.2_2021"
}
tags = {
Environment = var.environment
ManagedBy = "terraform"
}
}resource "aws_cloudfront_cache_policy" "optimized" {
name = "optimized-caching"
default_ttl = 86400
max_ttl = 31536000
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_brotli = true
enable_accept_encoding_gzip = true
}
}
resource "aws_cloudfront_cache_policy" "static_assets" {
name = "static-assets"
default_ttl = 604800
max_ttl = 31536000
min_ttl = 604800
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_brotli = true
enable_accept_encoding_gzip = true
}
}resource "aws_cloudfront_response_headers_policy" "security" {
name = "security-headers"
security_headers_config {
strict_transport_security {
access_control_max_age_sec = 63072000
include_subdomains = true
preload = true
override = true
}
content_type_options {
override = true
}
frame_options {
frame_option = "DENY"
override = true
}
xss_protection {
mode_block = true
protection = true
override = true
}
referrer_policy {
referrer_policy = "strict-origin-when-cross-origin"
override = true
}
}
}resource "aws_acm_certificate" "main" {
provider = aws.us_east_1 # CloudFront requires us-east-1
domain_name = var.domain_name
subject_alternative_names = ["*.${var.domain_name}"]
validation_method = "DNS"
lifecycle {
create_before_destroy = true
}
}Learn by doing with interactive courses on CopyPasteLearn:
CloudFront with Terraform provides a scalable, secure CDN setup that's fully reproducible. By combining S3, OAC, custom cache policies, and security headers, you get a production-ready content delivery infrastructure that serves your users from the nearest edge location with optimal performance and security.
Protect your applications with AWS WAF rules managed by Terraform — rate limiting, IP blocking, and SQL injection prevention.
Manage secrets securely with AWS Secrets Manager and Terraform — rotation, replication, and application integration. Step-by-step guide with code examples an...
Set up a production Redis cluster on AWS ElastiCache with replication, encryption, and automatic failover using Terraform.
Create and configure DynamoDB tables with Terraform including GSIs, auto-scaling, TTL, and point-in-time recovery. Step-by-step guide with code examples and ...