Skip to content

🌐 Terraform module to provision CloudFront and securely serve HTTPS requests to a static website hosted on S3

License

Notifications You must be signed in to change notification settings

ArtiomL/aws-cloudfront-s3

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

   aws-cloudfront-s3  

Releases Commits Maintenance Issues License

  

Table of Contents

  

Description

Terraform AWS module to provision CloudFront CDN and securely serve HTTPS requests to a static website hosted on Amazon S3.

Architecture

The module creates:

  • S3 bucket to host static website content
  • S3 bucket to store CloudFront access log files in
  • Block Public Access settings for both S3 buckets (all four settings set to true)
  • CloudFront origin access identity
  • S3 bucket policy to ensure CloudFront OAI has permissions to read files in the S3 bucket, but users don't
  • ACM public SSL/TLS certificate for your domain, using DNS validation
  • Route 53 CNAME record for ACM validation
  • CloudFront distribution with IPv6, TLS, SNI and HTTP/2 support targeting an S3 origin
  • Lambda@Edge function to customize the content CloudFront delivers
  • Route 53 A and AAAA alias records to the CloudFront distribution

Security

The default Lambda@Edge function is used to add the following HTTP security response headers, triggered by the Origin Response CloudFront event:

Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Referrer-Policy: no-referrer
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self'; font-src 'self';
Feature-Policy: geolocation 'none'; midi 'none'; sync-xhr 'none'; microphone 'none'; camera 'none'; magnetometer 'none'; gyroscope 'none'; speaker 'self'; vibrate 'none'; fullscreen 'self'; payment 'none';

Scanning the website with HTTP Observatory results in:

Use the module input variables to specify a filename with custom function code (source_file) and the CloudFront event to trigger it (event_type).

  

Input Variables

Name Description Type Default Required
allowed_methods Controls which HTTP methods CloudFront processes and forwards to your S3 bucket list <list> no
aws_region AWS region string "eu-west-1" no
cached_methods Controls whether CloudFront caches responses to requests using the specified HTTP methods list <list> no
comment Distribution comments string "Managed by Terraform" no
compress Compress content for web requests that include Accept-Encoding: gzip in the request header string "true" no
default_root_object An object CloudFront returns when the end user requests the root URL string "index.html" no
default_ttl Default amount of time (in seconds) an object is in a CloudFront cache string "3600" no
domain_name DNS domain name string n/a yes
enabled Whether the distribution is enabled to accept end user requests for content string "true" no
event_type The specific event to trigger the function string "origin-response" no
force_destroy All objects should be deleted from the bucket so that the bucket can be destroyed without error string "true" no
geo_restriction_locations ISO 3166-1-alpha-2 country codes list <list> no
geo_restriction_type The method to restrict distribution of your content by country (none, whitelist, blacklist) string "none" no
handler The function entrypoint in your code string "index.handler" no
include_body Expose the request body to the Lambda function string "false" no
is_ipv6_enabled Whether IPv6 is enabled for the distribution string "true" no
log_days The number of days to keep the log files string "7" no
max_ttl Maximum amount of time an object is in a CloudFront cache string "86400" no
min_ttl Minimum amount of time you want objects to stay in CloudFront caches string "0" no
minimum_protocol_version The minimum TLS version that you want CloudFront to use for HTTPS connections string "TLSv1.2_2018" no
origin_path Causes CloudFront to request content from a directory in your S3 bucket string "" no
price_class The price class for this distribution (PriceClass_All, PriceClass_200, PriceClass_100) string "PriceClass_All" no
runtime Function runtime identifier string "nodejs10.x" no
source_file Package this file into the function archive (index.js local to the module path is used by default) string "" no
tag_environment Environment tag string "Prod" no
tag_name Name tag string "AWSLabs" no
tags_shared Other tags assigned to all resources map <map> no
viewer_protocol_policy The protocol users can use to access the origin files (allow-all, https-only, redirect-to-https) string "redirect-to-https" no
wait_for_deployment Wait for the distribution status to change from InProgress to Deployed string "false" no
web_acl_id AWS WAFv2 Web ACL ARN string "" no
zone_id Route 53 zone ID string n/a yes

  

Output Values

Name Description
alias_fqdn DNS alias record FQDN
bucket_id S3 bucket name
bucket_regional S3 bucket region-specific domain name, also used as CloudFront Origin ID
cert_arn ACM certificate ARN
dist_arn CloudFront distribution ARN
dist_domain CloudFront distribution domain name
dist_id CloudFront distribution ID
dist_zone_id CloudFront zone ID that can be used to point Route 53 alias records to

  

Example

# S3, IAM, ACM, CloudFront
module "aws_cloudfront_s3" {
  source          = "github.com/ArtiomL/aws-cloudfront-s3"
  aws_region      = "eu-north-1"
  domain_name     = "artl.dev"
  source_file     = "custom.js"
  zone_id         = aws_route53_zone.main.zone_id
  tag_name        = "AWSLabs"
  tag_environment = "Dev"
}