This module will create and configure a CloudFront Distribution and S3 bucket to allow a static website to be hosted. This is secured using a CloudFront Origin Access Control, as such this module will not configure the S3 bucket to be directly accessible, instead requests must go through the CloudFront Distribution.
There are some limitations with this configuration as it requires that Website hosting is not enabled on the S3 bucket. Additionally CloudFront only applies the default root object on the root of the website itself (eg example.com
> example.com/index.html
). This is not performed on any subdirectories (eg example.com/about/
). To work around this limitation, A CloudFront Function is also deployed to append index.html
to requests that don’t include a file name or extension in the URL.
For DNS hosting, you can supply a Route53 zone ID using var.route53_zone_id
. DNS records will be created in when this is supplied. The zone itself is not created or managed by this module. When this is not supplied the relevent DNS records will be supplied in outputs.
The CloudFront distribution is configured with Cache Policies. The Cache policy is set to CachingOptimized
, the Origin request policy is set to CORS-S3Origin
. Additionally the Reponse headers policy is also set, the policy used is configurable and is set to Managed-CORS-with-preflight-and-SecurityHeadersPolicy
by default.
If you want to redirect your website's www domain to the non-www domain (eg www.example.com
to example.com
), you can do this using by enabling the website_redirect_www
variable. Enabling this will do a couple of things at once:
- Includes the www version of the website in the list of alias domains. This impacts the configuration of the ACM certificate and CloudFront Distribution.
- Include code in the CloudFront Function to perform a 302 redirect from www to non-www (eg this will redirect
www.example.com
toexample.com
).
Note: If you want to include the www domain but _ DO NOT_ want to redirect it, you will need to include it in the website_aliases
variable instead.
This module prefers OpenID Connect for authenticating against AWS for deploying files to S3 and invalidating CloudFront cache. The intended use case for this is as part of a Github Action, or a Bitbucket Pipeline.
If you do not use any of the above to manage/deploy your code to S3, you can make use of the IAM Policy Document provided as the iam_policy_data_json
output to configure your own IAM access.
Intial Deployment
When first using this module, you will need to run a Terraform Apply twice. This is because of the ACM data resource that is used to ensure that the ACM certificate is issued before adding it to CloudFront regardless of how the DNS validation records are created.
The first Terraform Apply will create everything, the second Terraform Apply will add the domain/s and ACM certificate to the CloudFront Distribution.
ACM Certificate Replacement
If the ACM certicate needs to be replaced by Terraform, the Apply will fail with the following error:
multiple certificates for domain "example.com" found in this Region
This is caused by the ACM data resource finding multiple records. To resolve this take the following steps in the AWS Console (or via API).
- Update the CloudFront Distribution to remove the Aliases and ACM Certificate.
- Delete the old SSL Certificate that does not contain the new domain configuration.
After this is done you can then run another Terraform Apply to finalise the changes.
Note: The ACM Certificate will need to be replaced in the following situations:
- Changing the
website_redirect_www
variable. - Updating the
website_aliases
variable.
If you need to do any of the above activities, you should treat this as a breaking change for the purposes of change/downtime management.
In version 1.0 of this module, there was capability to create an IAM user to be used for uploading files. From version 2.0.0 onwards, this has been removed in favour of OpenID Connect. If this is not desired, this module will still output an IAM Policy Document that can be used for providing access.
Version 2.0.0 of this module also replaces the S3 bucket and CloudFront Distribution previously only used for redirecting www to non-www with a CloudFront Function that is associated with the primary CloudFront Distribution. This may cause an outage if the www version of a website is pointing to the CLoudFront Distribution that gets removed.
Default (External DNS)
module "website-aws-s3-cloudfront-cloudflare" {
source = "eyulf/website-aws-s3-cloudfront/module"
version = "2.0.0"
website_domain = "example.com"
providers = {
aws.virginia = aws.n_virginia
}
}
Default (Route53)
module "website-aws-s3-cloudfront-route53" {
source = "eyulf/website-aws-s3-cloudfront/module"
version = "2.0.0"
website_domain = "example.com"
route53_zone_id = <ROUTE53 ZONE ID>
providers = {
aws.virginia = aws.n_virginia
}
}
Create GitHub OpenId Connect
module "website-aws-s3-cloudfront-route53" {
source = "eyulf/website-aws-s3-cloudfront/module"
version = "2.0.0"
website_domain = "example.com"
openid_provider_create = true
github_repo = "organisation/repo"
providers = {
aws.virginia = aws.n_virginia
}
}
Existing GitHub OpenId Connect
module "website-aws-s3-cloudfront-route53" {
source = "eyulf/website-aws-s3-cloudfront/module"
version = "2.0.0"
website_domain = "example.com"
github_openid_arn = "<OPENID CONNECT PROVIDER ARN>"
github_repo = "organisation/repo"
providers = {
aws.virginia = aws.n_virginia
}
}
Name | Version |
---|---|
terraform | >= 1.0 |
aws | >= 4.0 |
Name | Version |
---|---|
aws | >= 4.0 |
aws.virginia | >= 4.0 |
No modules.
Name | Description | Type | Default | Required |
---|---|---|---|---|
bitbucket_openid_arn | The ARN for an existing BitBucket OpenID Connect provider. | string |
"" |
no |
bitbucket_repo_uuid | A list of Repo UUID's | string |
"" |
no |
bitbucket_workspace_name | The name of the BitBucket workspace. | string |
"" |
no |
bitbucket_workspace_uuid | BitBucket Workspace UUID. | string |
"" |
no |
cloudfront_default_cache_allowed_methods | List of allowed methods for the CloudFront default cache behaviour configuration. | list(string) |
[ |
no |
cloudfront_default_cache_cached_methods | List of cached_methods for the CloudFront default cache behaviour configuration. | list(string) |
[ |
no |
cloudfront_price_class | The price class to use for CloudFront. Must be one of PriceClass_All , PriceClass_200 or PriceClass_100 . |
string |
"PriceClass_All" |
no |
cloudfront_response_headers_policy_name | The Name of the Response headers policy to use. | string |
"Managed-CORS-with-preflight-and-SecurityHeadersPolicy" |
no |
cloudfront_ssl_minimum_protocol | The minimum SSL protocol to use for the CloudFront viewer certificate configuration. | string |
"TLSv1.2_2021" |
no |
cloudfront_web_acl_arn | The ARN of an AWS WAF web ACL to associate with CloudFront. | string |
"" |
no |
github_openid_arn | The ARN for an existing GitHub OpenID Connect provider. | string |
"" |
no |
github_repo | The name of the GitHub repo in the format of 'organisation/repo'. | string |
"" |
no |
openid_provider_create | Create the OpenID Connect Provider. | bool |
false |
no |
route53_zone_id | The Route53 Zone ID. If not set DNS records will be returned in outputs. | string |
"" |
no |
s3_cors_allowed_headers | List of allowed headers for the S3 Bucket's CORS configuration. | list(string) |
[] |
no |
s3_cors_allowed_methods | List of allowed methods for the S3 Bucket's CORS configuration. | list(string) |
[ |
no |
s3_cors_allowed_origins | List of allowed origins for the S3 Bucket's CORS configuration. | list(string) |
[ |
no |
s3_cors_expose_headers | List of expose headers for the S3 Bucket's CORS configuration. | list(string) |
[] |
no |
s3_lifecycle_noncurrent_expiration | The number of days after which a non current version of a S3 object will be expired. | number |
30 |
no |
website_aliases | Additional domain names to use for the website. | list(string) |
[] |
no |
website_domain | The primary domain name to use for the website. | string |
n/a | yes |
website_redirect_www | Include www in the Cloudfront Alias and ACM Certificate as well as add code to redirect www to non-www in the Cloudfront Function. | bool |
false |
no |
Name | Description |
---|---|
acm_validation_dns_records | The DNS records required to validate the ACM Certificate. |
bitbucket_openid_connect_arn | The ARN of the BitBucket OpenID Connect Provider. |
bitbucket_openid_connect_role | The name of the BitBucket OpenID Connect IAM Role. |
cloudfront_arn | The ARN of the Cloudfront Distribution. |
cloudfront_url | The name of the Cloudfront Distribution's URL. |
github_openid_connect_arn | The ARN of the GitHub OpenID Connect Provider. |
github_openid_connect_role | The name of the GitHub OpenID Connect IAM Role. |
iam_policy_data_json | IAM policy data that can be used for S3 uploads and CloudFront invalidation. |
s3_bucket | The name of the S3 Bucket. |