Skip to content

Deploy secure, static websites leveraging CloudFront w/ Origin Access Control (OAC), private s3 buckets and Route 53 or Gandi LiveDNS.

License

Notifications You must be signed in to change notification settings

garyrule/terraform-aws-static-website

Repository files navigation

terraform-aws-static-website

Deploy secure, cost-effective static websites using CloudFront, S3, ACM and Route 53.

With support for using Gandi LiveDNS.

terraform-aws-static-website

Components

Function Service
DNS records - Website and certificate validation Route 53 or Gandi LiveDNS
SSL Certificate ACM
Content Delivery Network CloudFront
Static Asset Storage and CloudFront Logs S3

Prerequisites

Feature Overview

  • Quickly and easily configure a secure static website.
    • Minimal inputs required to get started
    • Highly configurable S3 and CloudFront distributions to allow for customization.
    • Input validation to reduce errors.
    • Additional input validation and output boolean that can be evaluated by your deployment framework or policy enforcement tools such as Sentinel.
  • Security by default
    • Private encrypted buckets with managed access for CloudFront via Origin Access Control.
      • Amazon S3 SSE managed keys by default and the ability to use your own KMS keys
    • Default viewer protocol redirects to HTTPS
    • Module defaults to TLSv1.2 and allows TLS protocol v1+ only.
  • Cost conscious defaults
    • S3 Bucket keys enabled by default which will reduce costs when using a KMS key.
    • Option for customers of Gandi to use their DNS service, which is provided at no extra cost.
    • Static asset bucket has versioning on by default which, when used effectively, can reduce CloudFront cache invalidation costs.
    • CloudFront Price Class set to 100 by default.

Examples

Example directories include a minimal configuration in main.tf. The README.md file for each example shows a more detailed configuration example.

Configuration Overiew

CloudFront

There are a number of input variables that determine the behavior of the CloudFront distribtution. Please see the Input section of this document or the Example directories for more details.

Logging

CloudFront Standard Logging is enabled by default to a separate logging bucket.

The option is provided to disable standard logging and/or enable real-time logging by providing a real-time logging configuration ARN to the input variable realtime_log_config_arn

Cache Behavior

The default cache behavior of the CloudFront distribution is managed by a CloudFront Cache Policy. The cache policy can be modified in a number of ways. Please look at the Input variables that start with cloudfront_cache for descriptions, options and defaults.

Lambda Function Associations

Pass a list of Lambda functions via the Input variable: cloudfront_cache_behavior_lambda_function_associations

CloudFront Function Association

Pass a list of CloudFront Functions via the Input variable cloudfront_cache_behavior_function_associations

Geographic Restrictions

Manage Geo restrictions, disabled by default, with the cloudfront_geo_restriction_type and cloudfront_geo_restriction_locations Input variables.

Security Policy

Choose Security Policy with the cloudfront_viewer_security_policy Input variable.

Field Level Encryption

Pass the ID of a Field Level Encryption Configuration via the Input variable cloudfront_field_level_encryption_id to enable Field Level Encryption for the CloudFront distribution.

Price Class

Select an appropriate Price Class with the cloudfront_price_class Input variable.

Dedicated IP for SSL

⚠️ Warning ⚠️ This option is not required for most use-cases and is relatively 💵 expensive 💵

Ability to select the "Dedicated IP Custom SSL" feature with cloudfront_viewer_ssl_support_method

S3

Versioning

Enable versioning for static assets (enabled by default) or CloudFront log buckets (disabled by default).

Access Control

Access to private static assets bucket granted to CloudFront via Origin Access Control

  • Default policy allows s3:GetObject, s3:GetObjectVersion and s3:ListBucket to static asset bucket.
  • Create and pass Custom Bucket IAM Policy to customize CloudFront access to S3.

Server Side Encryption

  • Bucket Keys enabled by default
  • Server Side Encryption using either S3 managed keys (default) or with AWS Key Management Service.
    • To use your own KMS key
      • Update one or more of the Input variables: bucket_website_sse_algo and bucket_cloudfront_logs_sse_algo
      • Then update one or more of the Input variables: bucket_website_sse_kms_key_id and bucket_cloudfront_logs_kms_key_id

Requirements

Name Version
terraform >= 1.4.6, < 2.0.0
aws ~> 5.8.0
gandi = 2.2.3

Providers

Name Version
aws 5.8.0
aws.use1 5.8.0
gandi 2.2.3

Resources

Name Type
aws_acm_certificate.site resource
aws_acm_certificate_validation.site-aws resource
aws_acm_certificate_validation.site-gandi resource
aws_cloudfront_cache_policy.site resource
aws_cloudfront_distribution.site resource
aws_cloudfront_origin_access_control.site resource
aws_route53_record.site resource
aws_route53_record.site-validation resource
aws_s3_bucket.cloudfront_logs resource
aws_s3_bucket.site resource
aws_s3_bucket_acl.cloudfront_logs resource
aws_s3_bucket_ownership_controls.cloudfront_logs resource
aws_s3_bucket_policy.site resource
aws_s3_bucket_server_side_encryption_configuration.cloudfront_logs resource
aws_s3_bucket_server_side_encryption_configuration.site resource
aws_s3_bucket_versioning.cloudfront_logs resource
aws_s3_bucket_versioning.site resource
gandi_livedns_record.site resource
gandi_livedns_record.site-validation resource
aws_iam_policy_document.cloudfront_readonly data source

Inputs

Name Description Type Default Required
website_hostname Fully qualified domain name for website - static.yourdomain.com string n/a yes
bucket_cloudfront_logs_force_destroy Force Destroy S3 Bucket? bool false no
bucket_cloudfront_logs_key_enabled S3 Bucket Key Enabled for CloudFront logs
See here: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-key.html
bool true no
bucket_cloudfront_logs_sse_algo Website Bucket SSE Algorithm for CloudFront logs
See here: https://docs.aws.amazon.com/AmazonS3/latest/userguide/specifying-kms-encryption.html
string "AES256" no
bucket_cloudfront_logs_sse_kms_key_id Website Bucket SSE KMS Key ID for CloudFront logs
See Here: https://registry.terraform.io/providers/hashicorp/aws/4.8.0/docs/resources/s3_bucket_server_side_encryption_configuration#kms_master_key_id
string "" no
bucket_cloudfront_logs_versioning S3 Bucket Versioning for CloudFront logs bool false no
bucket_website_force_destroy Force Destroy S3 Bucket? bool false no
bucket_website_key_enabled S3 Bucket Key Enabled for static assets
See here: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-key.html
bool true no
bucket_website_policy JSON representation of your custom S3 Bucket Policy for static assets.
If blank, the default policy will be used.
string "" no
bucket_website_sse_algo Website Bucket SSE Algorithm for static assets
See here: https://docs.aws.amazon.com/AmazonS3/latest/userguide/specifying-kms-encryption.html
string "AES256" no
bucket_website_sse_kms_key_id Website Bucket SSE KMS Key ARN for static assets
See Here: https://registry.terraform.io/providers/hashicorp/aws/4.8.0/docs/resources/s3_bucket_server_side_encryption_configuration#kms_master_key_id
string "" no
bucket_website_versioning S3 Bucket Versioning for static assets bool true no
cloudfront_cache_accept_encoding_brotli Whether CloudFront caches compressed versions of files in the origin using
the Brotli compression format.
bool true no
cloudfront_cache_accept_encoding_gzip Whether CloudFront caches compressed versions of files in the origin using
the Gzip compression format.
bool true no
cloudfront_cache_allowed_methods CloudFront Allowed Cache Methods -
Controls which HTTP methods CloudFront processes and forwards to your Amazon
S3 bucket or your custom origin.
list(string)
[
"GET",
"HEAD"
]
no
cloudfront_cache_behavior_function_associations A list of function associations for this cache behavior. list(map(string)) [] no
cloudfront_cache_behavior_lambda_function_associations A list of Lambda function associations for this cache behavior. list(map(string)) [] no
cloudfront_cache_behavior_viewer_protocol_policy The protocol that viewers can use to access the files in the origin
specified by TargetOriginId when a request matches the path pattern in
PathPattern. Valid values are allow-all, redirect-to-https, and
https-only.
string "redirect-to-https" no
cloudfront_cache_compress Whether you want CloudFront to automatically compress content for web
requests that include Accept-Encoding: gzip in the request header
bool true no
cloudfront_cache_default_ttl CloudFront Default TTL -
Default amount of time (in seconds) that an object is in a CloudFront cache
before CloudFront forwards another request in the absence of an Cache-Control
max-age or Expires header.
number 3600 no
cloudfront_cache_max_ttl Specify the maximum amount of time, in seconds, that you want objects to stay
in CloudFront caches before CloudFront queries your origin to see whether the
object has been updated. The value that you specify for Maximum TTL applies
only when your origin adds HTTP headers such as Cache-Control max-age,
Cache-Control s-maxage, or Expires to objects.
number 86400 no
cloudfront_cache_min_ttl Specify the minimum amount of time, in seconds, that you want objects to stay
in the CloudFront cache before CloudFront sends another request to the origin
to determine whether the object has been updated.
number 0 no
cloudfront_cache_policy_cookie_behavior Whether any cookies in viewer requests are included in the cache key and
automatically included in requests that CloudFront sends to the origin.
Valid values for cookie_behavior are none, whitelist, allExcept, and
all.
string "none" no
cloudfront_cache_policy_cookies List of cookie names used by cloudfront_cache_policy_cookie_behavior list(string) [] no
cloudfront_cache_policy_field_level_encryption_id The ID of the field-level encryption configuration that you want CloudFront
to use for encrypting specific fields of data for a cache behavior or for
the default cache behavior in your distribution.
string "" no
cloudfront_cache_policy_header_behavior Whether any HTTP headers are included in the cache key and automatically
included in requests that CloudFront sends to the origin. Valid values for
header_behavior are none and whitelist.
string "none" no
cloudfront_cache_policy_headers List of header names used by cloudfront_cache_policy_header_behavior list(string) [] no
cloudfront_cache_policy_query_string_behavior Whether URL query strings in viewer requests are included in the cache key
and automatically included in requests that CloudFront sends to the origin.
Valid values for query_string_behavior are none, whitelist, allExcept,
and all.
string "none" no
cloudfront_cache_policy_query_strings List of query string names used by
cloudfront_cache_policy_query_string_behavior
list(string) [] no
cloudfront_cached_methods CloudFront Cached Methods -
Controls whether CloudFront caches the response to requests using the
specified HTTP methods.
list(string)
[
"GET",
"HEAD"
]
no
cloudfront_comment Comment for the CloudFront Distribution string "CloudFront Distribution for Static Website" no
cloudfront_custom_error_min_ttl The minimum amount of time, in seconds, that you want CloudFront to cache
the HTTP status code specified in ErrorCode.
number 0 no
cloudfront_custom_error_response_error_code 4xx or 5xx HTTP status code that you want to customize number 404 no
cloudfront_custom_error_response_page_path HTML page you want CloudFront to return with the custom error response to the viewer. string "/error.html" no
cloudfront_custom_error_response_response_code The HTTP status code that you want CloudFront to return to the viewer
along with the custom error page.
number 200 no
cloudfront_default_root_object The default index page that CloudFront will serve when no path is provided. string "index.html" no
cloudfront_enabled Enable the Cloudfront Distribution? bool true no
cloudfront_geo_restriction_locations ISO 3166-1-alpha-2 codes for which you want CloudFront either to distribute
your content (whitelist) or not distribute your content (blacklist).
See https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 for a list of codes.
list(string) [] no
cloudfront_geo_restriction_type Method that you want to use to restrict distribution of your content by
country: none, whitelist, or blacklist.
string "none" no
cloudfront_ipv6_enabled Whether the IPv6 protocol is enabled for the distribution. bool true no
cloudfront_logging Whether CloudFront logs requests. bool true no
cloudfront_logging_cookies Whether CloudFront logs cookies. bool false no
cloudfront_logging_prefix Logging prefix for CloudFront logs. If you don't specify a prefix, the
prefix will be the website hostname with dashes instead of dots.
string "" no
cloudfront_maximum_http_version Maximum HTTP version to support on the distribution. Allowed values are
http1.1, http2, http2and3, http3.
string "http2" no
cloudfront_origin_connection_attempts The number of times that CloudFront attempts to connect to the origin. number 3 no
cloudfront_origin_connection_timeout The number of seconds that CloudFront waits when trying to establish a
connection to the origin.
number 10 no
cloudfront_origin_custom_headers Custom Headers to send to the origin.
By default there is a limit of 10 headers. A call to AWS Support can increase
this limit.
list(object({
name = string
value = string
}))
[] no
cloudfront_price_class Which CloudFront Price Class to use. Consult this table:
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/PriceClass.html
string "PriceClass_100" no
cloudfront_realtime_log_config_arn The ARN of the Kinesis Firehose stream that receives real-time log data
from CloudFront.
string "" no
cloudfront_retain_on_delete Retain the CloudFront Distribution when the Terraform resource is deleted. bool false no
cloudfront_viewer_security_policy Which Security Policy to use. Consult this table:
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/secure-connections-supported-viewer-protocols-ciphers.html
string "TLSv1.2_2021" no
cloudfront_viewer_ssl_support_method Which SSL support method to use. sni-only or vip supported

PLEASE NOTE: that setting this value to vip will incur significant
additional charges
.

Please read this prior to setting this value to vip:
https://aws.amazon.com/cloudfront/pricing/
string "sni-only" no
cloudfront_wait_for_deployment Wait for the CloudFront Distribution to be deployed before continuing. bool false no
dns_type Either aws or gandi depending on where your DNS Zone is hosted string "aws" no
gandi_key Gandi API Key - Required if using Gandi for DNS string "" no
gandi_sharing_id Gandi API Sharing ID - Optional
See: https://api.gandi.net/docs/reference/#Sharing-ID
string "" no
region AWS Region to use for S3 Buckets string "us-west-2" no
route53_zone_id Route 53 Zone ID for website TLD string "" no

Outputs

Name Description
bucket_cloudfront_logs_arn CLoudFront Standard Logs Bucket ARN
bucket_cloudfront_logs_bucket_key_enabled CloudFront Standard Logs Bucket Key Enabled
bucket_cloudfront_logs_bucket_sse_algo SSE Algorithm for CloudFront Standard Logs Bucket
bucket_cloudfront_logs_bucket_sse_kms_key_id SSE KMS Key ID for CloudFront Standard Logs Bucket
bucket_cloudfront_logs_force_destroy Is force destroy set for the CloudFront Standard Logs bucket?
bucket_cloudfront_logs_id CloudFront Standard Logs Bucket ID
bucket_cloudfront_logs_oac_policy CloudFront Origin Access Control
bucket_cloudfront_logs_region CloudFront Standard Logs S3 Bucket Region
bucket_cloudfront_logs_versioning_enabled Whether versioning is enabled on the CloudFront logs bucket
bucket_cloudfront_logs_versioning_mfa_delete Whether MFA delete is enabled on the CloudFront logs bucket
bucket_website_arn Static asset S3 Bucket ARN
bucket_website_bucket_key_enabled Website Bucket Key Enabled
bucket_website_bucket_sse_algo SSE Algorithm for Website Bucket
bucket_website_bucket_sse_kms_key_id SSE KMS Key ID for Website Bucket
bucket_website_force_destroy Is force destroy set for the static asset bucket?
bucket_website_id Static asset S3 Bucket ID
bucket_website_region Static asset S3 Bucket Region
bucket_website_versioning_enabled Static asset Bucket Versioning
bucket_website_versioning_mfa_delete Static asset Bucket Versioning MFA Delete
certificate_website_arn Site Certificate ARN
certificate_website_domain_name Site Certificate domain name
certificate_website_domain_validation_name The resource record name for domain validation.
certificate_website_domain_validation_type The resource record type for domain validation.
certificate_website_domain_validation_value The resource record value for domain validation.
certificate_website_expiration Site Certificate Expiration
certificate_website_issued Site Certificate Issued
certificate_website_status Site Certificate provisioning status
cloudfront_cache_policy_id CloudFront Cache Policy ID
cloudfront_distribution_arn CloudFront Distribution ARN
cloudfront_distribution_domain_name CloudFront Distribution Domain Name
cloudfront_distribution_http_last_modified_time CloudFront Distribution Last Modified
cloudfront_distribution_http_version CloudFront Distribution HTTP Version
cloudfront_distribution_id CloudFront Distribution ID
cloudfront_distribution_status CloudFront Distribution Status
cloudfront_distribution_zone_id CloudFront Distribution Zone ID
cloudfront_enabled Boolean to determine if CloudFront is enabled
cloudfront_logging Is CloudFront logging enabled?
cloudfront_logging_prefix CloudFront Logging Prefix. Can be used in a lifecycle rule filter
cloudfront_origin_access_control_id CloudFront Origin Access Control
dns_website_record This is the Website DNS Record
dns_website_record_target This is the CloudFront Distribution Domain Name
z_gandi_domain Are we a Gandi Domain Boolean
z_valid_inputs Will be true if all inputs are valid

About

Deploy secure, static websites leveraging CloudFront w/ Origin Access Control (OAC), private s3 buckets and Route 53 or Gandi LiveDNS.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published