Terraform AWS ACM Certificate Provisioning and Validation Workflow

Introduction

AWS Certificate Manager provides SSL/TLS certificates for securing applications and Terraform provides declarative management of those certificates through the awsacmcertificate resource and the acmcertificatevalidation resource. The combination converts a traditionally manual, multi-step validation process into a single infrastructure configuration that provisions certificates, waits for validation, and then wires the validated certificate ARN into CloudFront distributions, Application Load Balancers, Elastic Load Balancers, and API Gateway endpoints.

Managing AWS Certificate Manager with Terraform is presented as learning how to provision and manage SSL/TLS certificates using AWS Certificate Manager and Terraform, including validation and integration with other AWS services. AWS Certificate Manager provides SSL/TLS certificates for securing applications.

The core interaction is that because the AWS Go SDK has support for it, Terraform can manage ACM resources. The awsacmcertificate resource is the entry point for requesting and managing ACM certificates.

The workflow is not complete with the request alone. The real magic comes when it is combined with acmcertificatevalidation. That is because acmcertificatevalidation represents the successful validation of an awsacmcertificate. More concretely, acmcertificatevalidation provides a mechanism to wait for an awsacmcertificate resource to be validated before it can be used in your Terraform configuration.

Amazon Certificate Manager is a service provided by Amazon that issues on-demand TLS certificates at no cost. Much like Let’s Encrypt, Amazon controls the Certificate Authority behind the certificates, as well as the accompanying API to manage them. The only gotcha is that ACM certificates can only be associated with AWS Elastic and Application Load Balancers, CloudFront distributions, and API Gateway endpoints.

Because there is an HTTP API defined for ACM, we can manage ACM certificates via Amazon’s suite of SDKs. Because the AWS Go SDK has support for it, Terraform can manage ACM resources.

SSL/TLS certificates are a non-negotiable part of modern web infrastructure. Every public-facing service needs HTTPS, and AWS Certificate Manager provides public certificates for integrated AWS services at no additional cost, and those certificates auto-renew. The catch is that they need to be validated, and that validation process has a few nuances that trip people up when working with Terraform.

AWS Certificate Manager Fundamentals for Terraform

AWS Certificate Manager is a service provided by Amazon that issues on-demand TLS certificates at no cost. Much like Let’s Encrypt, Amazon controls the Certificate Authority behind the certificates, as well as the accompanying API to manage them.

The service scope is limited to AWS native integrations. The only gotcha is that ACM certificates can only be associated with AWS Elastic and Application Load Balancers, CloudFront distributions, and API Gateway endpoints.

Certificates are free and automatically renewed annually as long as the DNS setup is maintained. AWS announced the introduction of the AWS Certificate Manager in 2016. These certificates are free, and as long as you maintain the DNS setup described in this post, will be automatically renewed annually.

Given that maintaining trust is a function of SSL certificates, verifying that the certificate belongs to the site using it is important.

SSL certificates are generally seen as a requirement to ensure users’ data is protected, and to demonstrate that you are trustworthy. Indeed some browsers will warn you if you try to access a site without a certificate or if you try to use self-signed certificates.

ACM supports two validation methods: DNS and email. DNS validation is strongly preferred because it can be fully automated.

The basic certificate request is simple. ACM supports two validation methods: DNS and email.

The awsacmcertificate Resource

Enter awsacmcertificate, a Terraform resource for requesting and managing ACM certificates.

The minimal declaration is:

resource "aws_acm_certificate" "cert" { domain_name = "example.com" validation_method = "DNS" }

A more complete example with tags and lifecycle control is:

resource "aws_acm_certificate" "main" { domain_name = "example.com" validation_method = "DNS" tags = { Environment = "production" ManagedBy = "terraform" } lifecycle { create_before_destroy = true } }

The createbeforedestroy lifecycle rule is important. Without it, Terraform would destroy the existing certificate before creating the new one, causing downtime for any services using it.

The createbeforedestroy lifecycle rule is important. Without it, Terraform would destroy the existing certificate before creating the new one, causing downtime for any services using it.

Resource arguments map directly to ACM request parameters. Domain name specifies the FQDN to be covered. Validation method selects DNS or EMAIL. Tags provide cost allocation and ownership metadata. Lifecycle controls prevent in-place replacement churn.

The output of awsacmcertificate includes certificatearn. Making use of the awsacmcertifcatevalidation output is important, because the one provided by awsacmcertificate looks identical, but is almost always going to be invalid right away. Using the output from the validation resource ensures that Terraform will wait for ACM to validate the certificate before resolving its ARN.

The acmcertificatevalidation Resource

acmcertificatevalidation represents the successful validation of an awsacmcertificate.

Example with Terraform Resources

To walk through an example with pure Terraform resources, imagine that we’ve already created a hosted zone for example.com and associated it with a CloudFront distribution. Now, we want to serve traffic with that domain over HTTPS.

The validation resource is required to block Terraform from proceeding until ACM reports SUCCESS.

The typical pattern couples awsacmcertificate with awsroute53record resources that create the DNS validation records.

To complete DNS validation, you need to create specific DNS records that ACM uses to verify domain ownership.

The resource depends on the domain validation options exposed by the certificate. Terraform can reference certificate.domainvalidationoptions to generate the exact CNAME records needed.

DNS Validation with Route 53

DNS Validation with Route 53

To complete DNS validation, you need to create specific DNS records that ACM uses to verify domain ownership.

When validation_method is DNS, ACM returns a set of validation domains and DNS names. For each domain, a CNAME record must be created in the authoritative DNS zone.

The reference implementation uses data source awsroute53zone to discover the hosted zone ID.

data "aws_route53_zone" "external" { name = "example.com" }

The validation records are then created with a TTL such as 60 seconds to allow rapid propagation and cleanup.

The validationrecordttl is a module parameter used to control how long the validation CNAME remains in Route 53.

Once the records are in place, ACM polls DNS and transitions the certificate status from PENDING_VALIDATION to ISSUED.

Automation is only possible with DNS validation. Email validation requires manual interaction and cannot be fully automated in Terraform.

Integration with CloudFront, Load Balancers, and API Gateway

ACM certificates can only be associated with AWS Elastic and Application Load Balancers, CloudFront distributions, and API Gateway endpoints.

The CloudFront integration pattern is:

resource "aws_cloudfront_distribution" "s3_distribution" { ... aliases = ["example.com"] viewer_certificate { acm_certificate_arn = "${aws_acm_certificate_validation.default.certificate_arn}" minimum_protocol_version = "TLSv1" ssl_support_method = "sni-only" } }

Aliases point to the domain covered by the certificate. Viewer certificate block references the validated ARN.

The same pattern applies to Application Load Balancer listeners and API Gateway custom domain names.

Regional constraints affect CloudFront and other services. CloudFront requires ACM certificates to be issued in us-east-1 regardless of where the distribution is configured.

Terraform Module Encapsulation

In an effort to reduce these steps even further, we assembled a reusable Terraform module to encapsulate the ACM and Route 53 resources used above.

Now, the process of creating, validating, and waiting for a valid certificate looks like this:

data "aws_route53_zone" "external" { name = "example.com" } module "cert" { source = "github.com/azavea/terraform-aws-acm-certificate?ref=0.1.0" domain_name = "example.com" hosted_zone_id = "${data.aws_route53_zone.external.zone_id}" validation_record_ttl = "60" } resource "aws_cloudfront_distribution" "s3_distribution" { ... aliases = ["example.com"] viewer_certificate { acm_certificate_arn = "${module.cert.arn}" minimum_protocol_version = "TLSv1" ssl_support_method = "sni-only" } }

Voilà! Provisioning, validating, and configuring TLS certificates in a single, concise Terraform module.

The module hides the creation of awsacmcertificate, the generation of validation records, and the acmcertificatevalidation wait.

Terraform AWS ACM

ACM certificates and validation records for public or private TLS, certificate renewal, and associations used by load balancers, CloudFront distributions, and APIs.

Quick start

Migration from upstream

Already using terraform-aws-modules? Change only the source URL:

Same arguments. Same outputs. Controls are checked at terraform plan.

Compliance Controls and Framework Mapping

Controls enforced

These compliance controls are checked at terraform plan time.

Mapped compliance frameworks

Framework coverage

Which controls from this module are active under each framework endpoint.

Control PCI DSS v4.0
ACM certificates should not use wildcard certificates
ACM RSA certificates should use a key length of at least 2,048 bits
ACM certificates should have transparency logging enabled

● enforced by default · ○ not activated by this endpoint

The module tracks compliance at plan time. ACM certificates should not use wildcard certificates is a control. ACM RSA certificates should use a key length of at least 2,048 bits is enforced by default. ACM certificates should have transparency logging enabled is a control.

Reversibility

No lock-in. Switch back by reverting the source URL:

Run terraform init -upgrade. Terraform state is unchanged — same resource addresses, same provider, no compliance.tf-specific resources. Controls you already applied remain in AWS.

Prerequisites and Operational Notes

This article assumes you have the following

  • An AWS Account
  • Terraform installed
  • A basic understanding of how to configure Terraform to access your AWS account, and how to plan and apply with Terraform.

SSL certificates are generally seen as a requirement to ensure your users’ data is protected, and to demonstrate that you are trustworthy.

Traditionally SSL certificates have been an extra expense. Over the last decade or so, there have been several approaches to reduce this cost, from rolling your own with openssl, lets-encrypt, but in 2016, AWS announced the introduction of the AWS Certificate Manager.

Validation Timing and State Management

Every once in a while, technology provides you with an elegant way to convert a cumbersome multi-step process into a single, concise operation. Amazon Certificate Manager does this for the process of provisioning, validating, and configuring Transport Layer Security certificates. But, when ACM is combined with Terraform, that single, concise operation gets woven directly into your infrastructure configuration in a way that’ll leave you never wanting to provision ACM certificates through the console again.

The validation resource ensures Terraform does not return success until ACM reports ISSUED. This prevents downstream resources from referencing an invalid certificate ARN.

The createbeforedestroy lifecycle prevents replacement gaps. Without it, Terraform would destroy the existing certificate before creating the new one, causing downtime for any services using it.

The output from acmcertificatevalidation is the authoritative ARN to use. Using the output from the validation resource ensures that Terraform will wait for ACM to validate the certificate before resolving its ARN.

Regional Constraints and Service Limitations

The catch is that they need to be validated, and that validation process has a few nuances that trip people up when working with Terraform.

In this post, we'll cover requesting ACM certificates, automating DNS validation, handling wildcard certificates, and dealing with the regional constraints that affect CloudFront and other services.

CloudFront distributions require certificates in us-east-1. Application Load Balancers require certificates in the same region as the load balancer. API Gateway custom domains require certificates in the same region as the API.

Wildcard certificates are supported by ACM but are subject to compliance controls. ACM certificates should not use wildcard certificates is a control tracked by compliance modules.

Practical Implementation Patterns

The post is part of a series about hosting a static website, specifically a Hugo-based blog hosted in AWS but this process is useful anytime we need to create a SSL certificate in Amazon Certificate Manager.

The typical workflow is:

  • Discover or create the Route 53 hosted zone
  • Request an ACM certificate with validation_method = DNS
  • Create DNS validation CNAME records via awsroute53record
  • Use acmcertificatevalidation to wait for ISSUED status
  • Reference the validated certificate ARN in CloudFront, ALB, or API Gateway resources

The module approach reduces boilerplate and centralizes validationrecordttl and hostedzoneid handling.

Conclusion

Terraform AWS ACM integration transforms certificate provisioning from a manual console workflow into declarative infrastructure. The awsacmcertificate resource initiates the request, the acmcertificatevalidation resource enforces a wait for successful DNS validation, and Route 53 records provide the proof of domain ownership required by ACM.

The combination ensures that certificates are requested, validated, and only then attached to CloudFront distributions, load balancers, and API Gateway endpoints. Lifecycle rules such as createbeforedestroy prevent downtime during rotations. Module encapsulation hides the multi-resource choreography behind a single domain_name input.

Compliance controls can be checked at plan time for key length, wildcard usage, and transparency logging. Regional constraints must be respected for CloudFront versus regional services.

The result is a concise, repeatable, and auditable path to HTTPS for AWS workloads using Terraform and ACM.

Sources

  1. Managing AWS Certificate Manager (ACM) with Terraform
  2. Provisioning ACM Certificates on AWS with Terraform
  3. Terraform AWS ACM
  4. Managing ACM with Terraform
  5. Manage AWS ACM Certificates with Terraform

Related Posts