This module helps you create a S3 website that performs HTTPS redirection, assuming that:
-
it runs HTTPS via Amazon’s Certificate Manager ("ACM")
-
its domain is backed by a Route53 zone
-
and of course, your AWS account provides you access to all these resources necessary.
This module is available on the Terraform Registry.
This module is a pair with terraform-aws-s3-cloudfront-website, which handles hosting of a static S3 website with CloudFront and ACM.
You can literally copy and paste the following example, change the following attributes, and you’re ready to go:
-
fqdn
set to your static website’s hostname -
redirect_target
set to where you want the hostname to redirect to (e.g.example.com
⇒ (this one)www.example.com
)
# AWS Region for S3 and other resources
provider "aws" {
region = "us-west-2"
alias = "main"
}
# AWS Region for Cloudfront (ACM certs only supports us-east-1)
provider "aws" {
region = "us-east-1"
alias = "cloudfront"
}
# Variables
variable "fqdn" {
description = "The fully-qualified domain name root of the resulting S3 website."
default = "example.com"
}
variable "redirect_target" {
description = "The fully-qualified domain name to redirect to."
default = "www.example.com"
}
# Using this module
module "main" {
source = "github.com/riboseinc/terraform-aws-s3-cloudfront-redirect"
fqdn = "${var.fqdn}"
redirect_target = "${var.redirect_target}"
ssl_certificate_arn = "${aws_acm_certificate_validation.cert.certificate_arn}"
refer_secret = "${base64sha512("REFER-SECRET-19265125-${var.fqdn}-52865926")}"
force_destroy = "true"
providers = {
aws.main = aws.main
aws.cloudfront = aws.cloudfront
}
# Optional WAF Web ACL ID, defaults to none.
web_acl_id = "${data.terraform_remote_state.site.waf-web-acl-id}"
}
# ACM Certificate generation
resource "aws_acm_certificate" "cert" {
provider = "aws.cloudfront"
domain_name = "${var.fqdn}"
validation_method = "DNS"
}
resource "aws_route53_record" "cert_validation" {
provider = aws.cloudfront
for_each = {
for dvo in aws_acm_certificate.cert.domain_validation_options : dvo.domain_name => {
name = dvo.resource_record_name
record = dvo.resource_record_value
type = dvo.resource_record_type
}
}
allow_overwrite = true
name = each.value.name
records = [each.value.record]
ttl = 60
type = each.value.type
zone_id = data.aws_route53_zone.main.zone_id
}
resource "aws_acm_certificate_validation" "cert" {
provider = aws.cloudfront
certificate_arn = aws_acm_certificate.cert.arn
validation_record_fqdns = [for record in aws_route53_record.cert_validation : record.fqdn]
}
# Route 53 record for the static site
data "aws_route53_zone" "main" {
provider = "aws.main"
name = "${var.fqdn}"
private_zone = false
}
resource "aws_route53_record" "web" {
provider = "aws.main"
zone_id = "${data.aws_route53_zone.main.zone_id}"
name = "${var.fqdn}"
type = "A"
alias {
name = "${module.main.cf_domain_name}"
zone_id = "${module.main.cf_hosted_zone_id}"
evaluate_target_health = false
}
}
# Outputs
output "s3_bucket_id" {
value = "${module.main.s3_bucket_id}"
}
output "s3_domain" {
value = "${module.main.s3_website_endpoint}"
}
output "s3_hosted_zone_id" {
value = "${module.main.s3_hosted_zone_id}"
}
output "cloudfront_domain" {
value = "${module.main.cf_domain_name}"
}
output "cloudfront_hosted_zone_id" {
value = "${module.main.cf_hosted_zone_id}"
}
output "cloudfront_distribution_id" {
value = "${module.main.cf_distribution_id}"
}
output "route53_fqdn" {
value = "${aws_route53_record.web.fqdn}"
}
output "acm_certificate_arn" {
value = "${aws_acm_certificate_validation.cert.certificate_arn}"
}
Note
|
In this section you need to have tfenv
installed.
|
Remove the version restriction on the module:
module "site-root" {
source = "github.com/riboseinc/terraform-aws-s3-cloudfront-redirect"
# ...
}
Then:
tfenv use 0.15.4
terraform init -upgrade
terraform plan
When upgrading to 0.15.4, you need to update the ACM config from:
Original:
resource "aws_route53_record" "cert_validation" {
provider = aws.cloudfront
name = aws_acm_certificate.cert.domain_validation_options[0].resource_record_name
type = aws_acm_certificate.cert.domain_validation_options[0].resource_record_type
zone_id = data.aws_route53_zone.main.id
records = [aws_acm_certificate.cert.domain_validation_options[0].resource_record_value]
ttl = 60
}
resource "aws_acm_certificate_validation" "cert" {
provider = aws.cloudfront
certificate_arn = aws_acm_certificate.cert.arn
validation_record_fqdns = [aws_route53_record.cert_validation.fqdn]
}
Now:
resource "aws_route53_record" "cert_validation" {
provider = aws.cloudfront
for_each = {
for dvo in aws_acm_certificate.cert.domain_validation_options : dvo.domain_name => {
name = dvo.resource_record_name
record = dvo.resource_record_value
type = dvo.resource_record_type
}
}
allow_overwrite = true
name = each.value.name
records = [each.value.record]
ttl = 60
type = each.value.type
zone_id = data.aws_route53_zone.main.zone_id
}
resource "aws_acm_certificate_validation" "cert" {
provider = aws.cloudfront
certificate_arn = aws_acm_certificate.cert.arn
validation_record_fqdns = [for record in aws_route53_record.cert_validation : record.fqdn]
}
First, link the module to a version that supported 0.13:
module "site-root" {
source = "github.com/riboseinc/terraform-aws-s3-cloudfront-redirect?ref=b4ab4a1ec7f373484074b27c73d93ce4bbe60b14"
# ...
}
Assume you are using Terraform 0.12, update module version and verify that you can run Terraform properly:
tfenv use 0.12.31
terraform init -upgrade
If all went well, you can use Terraform 0.13, and upgrade the providers:
tfenv use 0.13.7
terraform 0.13upgrade -yes
terraform init -upgrade
terraform state replace-provider -auto-approve registry.terraform.io/-/aws hashicorp/aws
terraform state replace-provider -auto-approve registry.terraform.io/-/null registry.terraform.io/hashicorp/null
terraform state replace-provider -auto-approve registry.terraform.io/-/archive registry.terraform.io/hashicorp/archive
terraform state replace-provider -auto-approve registry.terraform.io/-/local registry.terraform.io/hashicorp/local
Then this will succeed:
terraform plan
terraform apply -auto-approve