IaC Bazaar
AWSStatic-verified

CloudFront Site (S3 + ACM + Route53)

Complete HTTPS site/CDN: CloudFront distribution, OAC-locked S3 origin, ACM cert, and Route53 alias records.

terraformAWS#aws

Compare CDN & Edge Delivery across clouds →

aws-cloudfront-siteterraform v1.7

Verification

Static-verified

Passed: validated and lint-clean (provider-schema-validated for AWS/Azure/GCP; Terraform-language lint elsewhere).

Conformance

  • Static validation (fmt · validate · tflint)
  • Security scan: findings disclosed (Checkov)
  • Plan tests (mocked: validation rules · outputs)

Provenance

  • SHA-256 checksum
  • Signature (pending)

Functional

  • Live test pending (no cloud run yet)

Last verified 2026-06-28 · how we verify

Documentation

aws-cloudfront-site

Complete HTTPS site/CDN: CloudFront distribution, OAC-locked S3 origin, ACM cert, and Route53 alias records. Works with Terraform and OpenTofu (>= 1.6), AWS provider >= 6.0, < 7.0.

Secure defaults:

  • Origin bucket is private (full public-access block), encrypted, versioned, and readable only by this distribution (Origin Access Control, SigV4, AWS:SourceArn condition) — plus a non-TLS deny policy
  • ACM certificate issued in us-east-1 with fully automated Route 53 DNS validation (the classic cross-region footgun, handled)
  • HTTPS enforced (redirect-to-https), TLS 1.2 (2021 policy) minimum, HTTP/2 + HTTP/3, compression on
  • Security response headers (HSTS 2y, nosniff, SAMEORIGIN, strict referrer) attached by default
  • A + AAAA alias records created for the apex/primary domain and every SAN

Dual provider requirement

CloudFront only accepts certificates from us-east-1, so the module takes a second provider configuration via configuration_aliases. Wire it like this:

provider "aws" {
  region = "eu-west-1" # bucket + Route 53 live here
}

provider "aws" {
  alias  = "us_east_1"
  region = "us-east-1" # certificate must live here
}

module "site" {
  source = "./aws-cloudfront-site"
  providers = {
    aws           = aws
    aws.us_east_1 = aws.us_east_1
  }

  domain_name               = "example.com"
  subject_alternative_names = ["www.example.com"]
  route53_zone_id           = "Z0123456789ABCDEFGHIJ"
  single_page_application   = true

  tags = { Environment = "prod" }
}

Deploy content with aws s3 sync ./dist s3://<bucket_id> and invalidate with aws cloudfront create-invalidation --distribution-id <distribution_id> --paths "/*".

Inputs

NameTypeDefaultDescription
domain_namestringPrimary site domain (required)
subject_alternative_nameslist(string)[]Extra domains (cert SANs + aliases + DNS)
route53_zone_idstringHosted zone for validation + alias records (required)
bucket_namestringnullOrigin bucket name; null = domain_name
force_destroyboolfalseAllow destroying a non-empty bucket
versioning_enabledbooltrueOrigin bucket versioning
default_root_objectstring"index.html"Root object
single_page_applicationboolfalseRewrite 403/404 to the root object (HTTP 200)
custom_error_responseslist(object)[]Extra error responses
price_classstring"PriceClass_100"Edge footprint
minimum_protocol_versionstring"TLSv1.2_2021"Viewer TLS floor
ipv6_enabledbooltrueIPv6 + AAAA records
security_headers_enabledbooltrueHSTS/nosniff/frame/referrer policy
geo_restrictionobjectnonenone/whitelist/blacklist + locations
web_acl_idstringnullWAFv2 ACL ARN (CLOUDFRONT scope)
loggingobjectnullStandard access logs { bucket, prefix? }
tagsmap(string){}Tags applied to all resources

Outputs

distribution_id, distribution_arn, distribution_domain_name, distribution_hosted_zone_id, bucket_id, bucket_arn, bucket_regional_domain_name, certificate_arn, site_urls.

Requirements

  • Terraform or OpenTofu >= 1.6
  • AWS provider >= 6.0, < 7.0, two configurations (default + aws.us_east_1)
  • A registered domain with a Route 53 public hosted zone you control

Notes

  • Uses the AWS managed CachingOptimized cache policy — right for static assets; fingerprint your filenames for cache busting.
  • Distribution create takes ~5-10 min; destroy disables first, then deletes (15-30 min total). That is CloudFront, not the module.
  • logging uses CloudFront standard (v1) logs and requires a log bucket with ACLs enabled.

Verification

Static-validated (fmt, validate, tflint). Live apply/destroy testing pending cloud sandbox availability — see catalog status.

License

Commercial — IaC Bazaar EULA. © IaC Bazaar. Original work (not derived from a third-party module).