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"
  }
Tagged with:  

Leave a Reply

Your email address will not be published. Required fields are marked *