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.
Terraform
Deploy AWS Lambda functions with Terraform. Complete guide with IAM roles, API Gateway triggers, S3 triggers, layers, environment variables, and VPC...
resource "aws_lambda_function" "api" {
filename = "lambda.zip"
function_name = "my-api"
role = aws_iam_role.lambda.arn
handler = "index.handler"
runtime = "nodejs20.x"
source_code_hash = filebase64sha256("lambda.zip")
}.zip filedata "aws_iam_policy_document" "lambda_assume" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["lambda.amazonaws.com"]
}
}
}
resource "aws_iam_role" "lambda" {
name = "${var.project}-lambda-role"
assume_role_policy = data.aws_iam_policy_document.lambda_assume.json
}
resource "aws_iam_role_policy_attachment" "lambda_basic" {
role = aws_iam_role.lambda.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}data "archive_file" "lambda" {
type = "zip"
source_dir = "${path.module}/src"
output_path = "${path.module}/lambda.zip"
}
resource "aws_lambda_function" "api" {
filename = data.archive_file.lambda.output_path
function_name = "${var.project}-${var.environment}-api"
role = aws_iam_role.lambda.arn
handler = "index.handler"
runtime = "nodejs20.x"
timeout = 30
memory_size = 256
source_code_hash = data.archive_file.lambda.output_base64sha256
environment {
variables = {
ENVIRONMENT = var.environment
TABLE_NAME = aws_dynamodb_table.main.name
}
}
tracing_config {
mode = "Active" # X-Ray tracing
}
}resource "aws_apigatewayv2_api" "main" {
name = "${var.project}-api"
protocol_type = "HTTP"
}
resource "aws_apigatewayv2_stage" "default" {
api_id = aws_apigatewayv2_api.main.id
name = "$default"
auto_deploy = true
}
resource "aws_apigatewayv2_integration" "lambda" {
api_id = aws_apigatewayv2_api.main.id
integration_type = "AWS_PROXY"
integration_uri = aws_lambda_function.api.invoke_arn
payload_format_version = "2.0"
}
resource "aws_apigatewayv2_route" "api" {
api_id = aws_apigatewayv2_api.main.id
route_key = "ANY /{proxy+}"
target = "integrations/${aws_apigatewayv2_integration.lambda.id}"
}
resource "aws_lambda_permission" "apigw" {
statement_id = "AllowAPIGateway"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.api.function_name
principal = "apigateway.amazonaws.com"
source_arn = "${aws_apigatewayv2_api.main.execution_arn}/*/*"
}
output "api_url" {
value = aws_apigatewayv2_stage.default.invoke_url
}resource "aws_lambda_permission" "s3" {
statement_id = "AllowS3"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.processor.function_name
principal = "s3.amazonaws.com"
source_arn = aws_s3_bucket.uploads.arn
}
resource "aws_s3_bucket_notification" "trigger" {
bucket = aws_s3_bucket.uploads.id
lambda_function {
lambda_function_arn = aws_lambda_function.processor.arn
events = ["s3:ObjectCreated:*"]
filter_prefix = "uploads/"
filter_suffix = ".csv"
}
depends_on = [aws_lambda_permission.s3]
}resource "aws_lambda_layer_version" "dependencies" {
filename = "layer.zip"
layer_name = "${var.project}-dependencies"
compatible_runtimes = ["nodejs20.x"]
source_code_hash = filebase64sha256("layer.zip")
}
resource "aws_lambda_function" "api" {
# ...
layers = [aws_lambda_layer_version.dependencies.arn]
}resource "aws_lambda_function" "private" {
# ...
vpc_config {
subnet_ids = aws_subnet.private[*].id
security_group_ids = [aws_security_group.lambda.id]
}
}
# Lambda in VPC needs this additional policy
resource "aws_iam_role_policy_attachment" "lambda_vpc" {
role = aws_iam_role.lambda.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
}| Setting | Default | Recommendation |
|---|---|---|
timeout | 3s | 30s for API, 900s for batch |
memory_size | 128 MB | 256-512 MB for most APIs |
runtime | — | nodejs20.x, python3.12 |
architectures | x86_64 | arm64 for 20% cost savings |
Package code with archive_file, create an IAM role with least privilege, and connect triggers (API Gateway, S3, SQS). Use source_code_hash to trigger redeployments when code changes. Use arm64 architecture for cost savings and Lambda layers for shared dependencies.
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 MSK (Managed Streaming for Kafka) with Terraform. Cluster configuration, MSK Serverless, encryption, monitoring, and topic management.