AWS CloudFront CDN with Terraform - Complete Guide
Deploy AWS CloudFront distributions with Terraform. S3 origin, ALB origin, custom domains, SSL certificates, cache policies, and WAF integration.
AWS
Create a production-ready AWS S3 bucket with Terraform. Covers versioning, encryption, lifecycle rules, bucket policies, CORS, and static website hosting.
Create an S3 bucket with aws_s3_bucket, then add versioning, encryption, and public access blocks as separate resources. Terraform 4.x split S3 configuration into individual resources for better modularity.
aws configure)provider "aws" {
region = "us-east-1"
}
resource "aws_s3_bucket" "main" {
bucket = "myapp-data-${var.environment}"
tags = {
Environment = var.environment
ManagedBy = "terraform"
}
}resource "aws_s3_bucket_versioning" "main" {
bucket = aws_s3_bucket.main.id
versioning_configuration {
status = "Enabled"
}
}resource "aws_s3_bucket_server_side_encryption_configuration" "main" {
bucket = aws_s3_bucket.main.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "aws:kms"
}
bucket_key_enabled = true
}
}resource "aws_s3_bucket_public_access_block" "main" {
bucket = aws_s3_bucket.main.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}resource "aws_s3_bucket_lifecycle_configuration" "main" {
bucket = aws_s3_bucket.main.id
rule {
id = "archive-old-objects"
status = "Enabled"
transition {
days = 90
storage_class = "STANDARD_IA"
}
transition {
days = 180
storage_class = "GLACIER"
}
expiration {
days = 365
}
noncurrent_version_expiration {
noncurrent_days = 30
}
}
}data "aws_iam_policy_document" "enforce_ssl" {
statement {
sid = "EnforceSSL"
effect = "Deny"
actions = ["s3:*"]
resources = [
aws_s3_bucket.main.arn,
"${aws_s3_bucket.main.arn}/*"
]
principals {
type = "*"
identifiers = ["*"]
}
condition {
test = "Bool"
variable = "aws:SecureTransport"
values = ["false"]
}
}
}
resource "aws_s3_bucket_policy" "main" {
bucket = aws_s3_bucket.main.id
policy = data.aws_iam_policy_document.enforce_ssl.json
}# variables.tf
variable "bucket_name" { type = string }
variable "environment" { type = string }
# main.tf
resource "aws_s3_bucket" "main" {
bucket = var.bucket_name
tags = { Environment = var.environment, ManagedBy = "terraform" }
}
resource "aws_s3_bucket_versioning" "main" {
bucket = aws_s3_bucket.main.id
versioning_configuration { status = "Enabled" }
}
resource "aws_s3_bucket_server_side_encryption_configuration" "main" {
bucket = aws_s3_bucket.main.id
rule {
apply_server_side_encryption_by_default { sse_algorithm = "aws:kms" }
bucket_key_enabled = true
}
}
resource "aws_s3_bucket_public_access_block" "main" {
bucket = aws_s3_bucket.main.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
# outputs.tf
output "bucket_arn" { value = aws_s3_bucket.main.arn }
output "bucket_name" { value = aws_s3_bucket.main.id }
output "bucket_domain" { value = aws_s3_bucket.main.bucket_regional_domain_name }resource "aws_s3_bucket_website_configuration" "website" {
bucket = aws_s3_bucket.main.id
index_document { suffix = "index.html" }
error_document { key = "error.html" }
}| Mistake | Fix |
|---|---|
Inline versioning in aws_s3_bucket | Use separate aws_s3_bucket_versioning resource |
| Bucket name with underscores | Use hyphens — underscores break DNS |
| Missing public access block | Always add — blocks accidental public exposure |
| Hardcoded bucket name | Add environment suffix for uniqueness |
A production-ready S3 bucket needs versioning, encryption, public access blocks, and lifecycle rules — all as separate Terraform resources. Use bucket policies to enforce SSL and restrict access. Always use unique bucket names with environment prefixes.
Deploy AWS CloudFront distributions with Terraform. S3 origin, ALB origin, custom domains, SSL certificates, cache policies, and WAF integration.
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...