Skip to content

S3 CDN

Terraform module for creating CloudFront distribution in front of S3 bucket to serve static content.

Usage example

Example for a single page application (SPA) with a custom error response for 403 errors. The custom_error_response block is optional and can be omitted if not needed.

module "s3_cdn" {
  source = "s3::https://apro-terraform-modules.s3.eu-west-1.amazonaws.com/SET_VERSION/s3_cdn.zip"

  name_prefix                           = "example-spa-website"
  aliases                               = ["website.example.com"]
  viewer_certificate_arn                = "arn:aws:acm:eu-west-1:123456789012:certificate/12345678-1234-1234-1234-123456789012"
  hosted_zone_name                      = "example.com"
  default_root_object                  = "index.html"

  custom_error_response = {
    error_code            = 403
    response_page_path    = "/index.html"
    response_code         = "200"
    error_caching_min_ttl = 0
  }

  web_acl_id = "arn:aws:wafv2:eu-west-1:123456789012:regional/webacl/example-webacl/12345678-1234-1234-1234-123456789012"
}

This example is for a website that has multiple directories and needs to serve each directory to the default index file. E.g. /about serves /about/index.html.

module "s3_cdn" {
  source = "s3::https://apro-terraform-modules.s3.eu-west-1.amazonaws.com/SET_VERSION/s3_cdn.zip"

  name_prefix                           = "example-webstie"
  aliases                               = ["website.example.com"]
  viewer_certificate_arn                = "arn:aws:acm:eu-west-1:123456789012:certificate/12345678-1234-1234-1234-123456789012"
  hosted_zone_name                      = "example.com"
  redirect_to_default_directory_indexes = true

  custom_error_response = {
    error_code            = 403
    response_page_path    = "/404.html"
    response_code         = "200"
    error_caching_min_ttl = 0
  }

  kms_key_id = "arn:aws:kms:eu-west-1:123456789012:key/12345678-1234-1234-1234-123456789012"
}

Modules

Name Source Version
cdn_bucket terraform-aws-modules/s3-bucket/aws 5.12.0
cloudfront terraform-aws-modules/cloudfront/aws 6.5.0
cloudfront_log_bucket terraform-aws-modules/s3-bucket/aws 5.12.0

Inputs

Name Description Type Default Required
aliases List of alias hostnames for the CloudFront distribution list(string) [] no
bucket_name Name of the main bucket. If not provided, the name will be {name_prefix}-assets. string null no
cognito_app_client_name Name for the Cognito app client. Defaults to name_prefix-cdn-auth. string null no
cognito_auth_enabled Enable Cognito authentication at the CDN edge bool false no
cognito_cookie_expiration_days Cookie expiration in days for the auth session number 365 no
cognito_log_level Log level for the Lambda@Edge auth function string "error" no
cognito_managed_login_branding_assets List of branding asset objects (bytes, category, color_mode, extension)
list(object({
bytes = string
category = string
color_mode = string
extension = string
}))
[] no
cognito_managed_login_branding_settings JSON settings for managed login branding. If null, uses Cognito defaults. any null no
cognito_oauth_scopes OAuth scopes for the Cognito app client list(string)
[
"openid",
"email",
"profile"
]
no
cognito_supported_identity_providers Supported identity providers for the Cognito app client list(string)
[
"COGNITO"
]
no
cognito_user_pool_domain Full Cognito User Pool domain (e.g. prefix.auth.region.amazoncognito.com). Required when cognito_auth_enabled is true. string null no
cognito_user_pool_id Cognito User Pool ID. Required when cognito_auth_enabled is true. string null no
cognito_user_pool_region Region of the Cognito User Pool. Required when cognito_auth_enabled is true. string null no
cors_origins List of CORS origins for the main bucket. By default it will not be set. any null no
create Create resources bool true no
create_records Create Route53 records for the CloudFront distribution bool true no
custom_error_response Custom error response for the CloudFront distribution any {} no
default_root_object Default root object for the CloudFront distribution string null no
enable_bucket_access_logs Enable access logging for the main bucket bool false no
hosted_zone_name Hosted zone to create the records for the CloudFront distribution in. Needs to be set if create_records is true. string null no
kms_key_id KMS key ID for encrypting the bucket and the log bucket. If not provided, the bucket will be encrypted with default AWS S3 encryption. string null no
lifecycle_rule Lifecycle rule for the main bucket. By default it will not be set. any null no
log_lifecycle_rule Lifecycle rule for the log bucket. By default, it will transition logs to STANDARD_IA after 30 days and to GLACIER after 365 days. any null no
name_prefix Prefix for the resources string n/a yes
price_class Price class for the CloudFront distribution string "PriceClass_100" no
redirect_to_default_directory_indexes Redirect to default directory indexes bool false no
versioning Enable versioning for the main bucket bool true no
viewer_certificate_arn ARN of the ACM certificate for the CloudFront distribution string null no
web_acl_id Web ACL ID for the CloudFront distribution string null no

Outputs

Name Description
cdn_bucket_arn The ARN of the S3 bucket used for the CDN content.
cdn_bucket_id The ID of the S3 bucket used for the CDN content.
cloudfront_distribution_arn The ARN of the CloudFront distribution.
cloudfront_distribution_domain_name The domain name of the CloudFront distribution.
cloudfront_distribution_hosted_zone_id The hosted zone ID of the CloudFront distribution.
cloudfront_distribution_id The ID of the CloudFront distribution.
cognito_app_client_id The ID of the Cognito app client for CDN authentication.
lambda_edge_function_arn The ARN of the Lambda@Edge authentication function.
lambda_edge_function_version The published version ARN of the Lambda@Edge authentication function.