If you are using Terraform to manage a static site (perhaps built with generators like Gatsby, Hugo, or mdBook) and you want to configure CloudFront via the built-in support (perhaps to leverage their CDN or for gzip encoding of static sites in S3 buckets) there are some gotchas you may hit.
TLS/SSL certs need to be created manually
Terraform cannot currently create and manage your TLS/SSL certs, as there is a manual email verification process. Sadly you’ll need to have everything set up via the AWS console UI before you run terraform apply
.
Custom TLS/SSL certs must be created in aws-east-1
Your certs for the static site must be created in the aws-east-1
region, even if your static site S3 bucket is in a different one. This is a CloudFront limitation rather than a Terraform one.
The aws_acm_certificate
data source needs to query aws-east-1
One should use Terraform’s data source support to pull down the ARN of the TLS/SSL cert you previously created manually. But, if your default aws
provider isn’t in aws-east-1
you will need to create a new provider that points the data source at aws-east-1
for the CloudFront-supported cert. If you aren’t already using multiple providers, you can just override the region
of your provider for the data source defintion:
provider "aws" {
alias = "virginia"
region = "us-east-1"
}
// See https://www.terraform.io/docs/providers/aws/d/acm_certificate.html
data "aws_acm_certificate" "my-example-cert" {
// NOTE the new provider setting.
provider = "aws.virginia"
domain = "*.example.com"
statuses = ["ISSUED"]
}
If you don’t do this, you will get a terraform error that the cert cannot be found in the region terraform is querying:
data.aws_acm_certificate.my-example-cert: data.aws_acm_certificate.my-example-cert: No certificate for domain "*.example.com" found in this region.
aws_cloudfront_distribution
settings need to be set correctly
There are some settings in the viewer_certificate
section of aws_cloudfront_distribution
that can throw errors if they don’t match. While the terraform docs mention this, it is easy to miss.
If you see an error similar to:
aws_cloudfront_distribution.my-cloudfront: InvalidProtocolSettings: The parameter ViewerCertificate The specified distribution is configured for SNI and the minimum SSL protocol version is specified as SSLv3. You cannot specify both.
status code: 400, request id: XXXXXXX
It means you need to add minimum_protocol_version
to your viewer_certificate
section.
This:
viewer_certificate {
acm_certificate_arn = "${data.aws_acm_certificate.my-example-cert.arn}"
ssl_support_method = "sni-only"
}
becomes this:
viewer_certificate {
acm_certificate_arn = "${data.aws_acm_certificate.my-example-cert.arn}"
// NOTE: This line was added.
minimum_protocol_version = "TLSv1"
ssl_support_method = "sni-only"
}