Terraform Driven ACM Certificate Provisioning and Validation

The integration of AWS Certificate Manager with Terraform enables fully automated provisioning and lifecycle management of SSL/TLS certificates for public and private AWS workloads. AWS Certificate Manager provides SSL/TLS certificates for securing applications. Managing AWS Certificate Manager with Terraform is demonstrated as the method to handle certificates using Terraform, with architecture covering Certificate Management, Public Certificate Usage, and Private Certificate Usage.

User traffic flows through CloudFront and Application Load Balancer with SSL/TLS encryption. Certificate Management relies on ACM for public certificates, Private CA for internal certificates, and Route 53 for DNS validation. Public Certificate Usage is shown with Application Load Balancer and CloudFront distributing traffic to various compute services such as ECS, EKS, and Elastic Beanstalk. Private Certificate Usage is illustrated with Internal ALB with private certificates for internal services.

The material covers requesting ACM certificates, automating DNS validation, handling wildcard certificates, and dealing with regional constraints that affect CloudFront and other services.

Introduction

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.

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. However, 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. 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.

ACM supports two validation methods: DNS and email. DNS validation is strongly preferred because it can be fully automated. This article demonstrates how to provision and manage SSL/TLS certificates using AWS Certificate Manager and Terraform, including validation and integration with other AWS services.

Prerequisites

The prerequisites for working with ACM and Terraform are documented across the reference materials.

  • AWS CLI configured with appropriate permissions
  • Terraform installed
  • Terraform installed version 1.0.0 or later
  • Domain name registered in Route 53 for DNS validation
  • Basic understanding of SSL/TLS certificates
  • An AWS Account
  • A basic understanding of how to configure Terraform to access your AWS account, and how to plan and apply with Terraform

When making use of the azavea terraform-aws-acm-certificate module, ensure that either the AWSDEFAULTREGION or AWS_REGION environment variable is set. This helps bypass validation checks that want the provider blocks within this module to have a region attribute specified.

Project Structure

A typical terraform-acm project is organized to separate configuration, modules, and domain data.

terraform-acm/ ├── main.tf ├── variables.tf ├── outputs.tf ├── modules/ │ └── acm/ │ ├── main.tf │ ├── variables.tf │ └── outputs.tf └── config/ └── domains.json

The structure isolates ACM logic in a reusable module and keeps domain configuration externalized.

ACM Configuration Core Resource

The public certificate resource is created in modules/acm/main.tf.

resource "aws_acm_certificate" "main" { domain_name = var.domain_name validation_method = "DNS" subject_alternative_names = var.subject_alternative_names options { certificate_transparency_logging_preference = "ENABLED" } lifecycle { create_before_destroy = true } tags = merge( var.tags, { Name = var.domain_name } ) }

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 basic certificate request is simple.

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.

Validation Method and DNS Automation

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

The validation method choice has direct impact on automation. DNS validation can be fully automated with Terraform and Route 53. Email validation requires manual intervention and is not suitable for CI/CD pipelines.

The module azavea/terraform-aws-acm-certificate creates an Amazon Certificate Manager ACM certificate with Route 53 DNS validation.

Provider configuration for the module uses aliased providers to separate certificate creation region from DNS region.

provider "aws" { region = "us-east-1" alias = "certificates" } provider "aws" { region = "us-west-2" alias = "dns" }

The certificate is then requested with:

resource "aws_route53_zone" "default" { name = "azavea.com" } module "cert" { source = "github.com/azavea/terraform-aws-acm-certificate" providers = { aws.acm_account = "aws.certificates" aws.route53_account = "aws.dns" } domain_name = "azavea.com" subject_alternative_names = ["*.azavea.com"] hosted_zone_id = "${aws_route53_zone.default.zone_id}" validation_record_ttl = "60" allow_validation_record_overwrite = true }

Regional constraints affect CloudFront and other services. ACM certificates used with CloudFront must be requested in us-east-1.

Module Parameters and Outputs

The azavea terraform-aws-acm-certificate module exposes specific inputs and outputs.

Module inputs include:

  • domain_name
  • Primary domain name associated with certificate. Also used for the Name tag of the ACM certificate.
  • subjectalternativenames
  • Subject alternative domain names.
  • hostedzoneid
  • Route 53 hosted zone ID for domain_name.
  • validationrecordttl
  • Route 53 record time-to-live for validation record default 60.
  • allowvalidationrecord_overwrite
  • Allow Route 53 record creation to overwrite existing records default true.
  • tags
  • A map of extra tags that is associated with the ACM Certificate.

Module outputs include:

  • arn
  • The Amazon Resource Name of the ACM certificate

A summary table of module configuration is provided below.

| Parameter | Description | Default |
| domainname | Primary domain name associated with certificate. Also used for Name tag | required |
| subject
alternativenames | Subject alternative domain names | - |
| hosted
zoneid | Route 53 hosted zone ID for domainname | required |
| validationrecordttl | Route 53 record TTL for validation record | 60 |
| allowvalidationrecord_overwrite | Allow overwrite of existing validation records | true |
| tags | Extra tags for ACM Certificate | - |

| Output | Description |
| arn | Amazon Resource Name of the ACM certificate |

DNS Validation with Route 53 Implementation

DNS validation requires creation of validation records in Route 53.

The reference material notes:

For using this certificate with CloudFront, see our post on creating CloudFront distributions with Terraform.

Using the certificate once validated requires referencing the certificate ARN in resources.

resource "aws_lb_listener" "https" { load_balancer_arn = aws_lb.main.arn port = 443 protocol = "HTTPS" ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06" certificate_arn = aws_acm_certificate_validation.main.certificate_arn default_action { type = "forward" target_group_arn = aws_lb_target_group.app.arn } }

Notice we reference awsacmcertificatevalidation.main.certificatearn instead of awsacmcertificate.main.arn.

Referencing the validation resource ensures Terraform waits until ACM confirms DNS validation is complete before attaching the certificate to the listener. Using the raw certificate ARN can result in an invalid state where the certificate is not yet issued.

Data Source for Existing Certificates

awsacmcertificate provides details about a specific ACM Certificate.

A minimal configuration to get started is:

```
data "awsacmcertificate" "example" {

Required arguments

Refer to the Terraform Registry docs for details

}
```

The data source is used when importing existing certificates managed outside Terraform or when referencing certificates created by other teams. It allows Terraform to read attributes such as arn, domain_name, and status without attempting to manage the certificate lifecycle.

Integration Patterns

Public Certificate Usage integrates with Application Load Balancer and CloudFront distributing traffic to various compute services.

Private Certificate Usage is demonstrated with Internal ALB with private certificates for internal services.

Once validated, reference the certificate ARN in your resources. For ALB HTTPS listener using the ACM certificate, the certificatearn is set to awsacmcertificatevalidation.main.certificate_arn.

Certificate Management architecture shows ACM for public certificates, Private CA for internal certificates, and Route 53 for DNS validation.

Lifecycle and Renewal Behavior

AWS Certificate Manager provides public certificates for integrated AWS services at no additional cost, and those certificates auto-renew. These certificates are free, and as long as you maintain the DNS setup described, will be automatically renewed annually.

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

Certificate transparency logging preference can be enabled via options block.

options { certificate_transparency_logging_preference = "ENABLED" }

Best Practices Derived from Reference

  • Prefer DNS validation over email validation for full automation.
  • Set validationrecordttl to 60 seconds for faster propagation and quicker updates.
  • Allow validation record overwrite to avoid failures on re-runs.
  • Use createbeforedestroy lifecycle for any certificate resource.
  • Reference awsacmcertificate_validation resource output, not the raw certificate ARN, when attaching to ALB, CloudFront, or API Gateway.
  • Request certificates for CloudFront in us-east-1 due to regional constraints.
  • Tag certificates with Environment and ManagedBy for governance.
  • Use aliased providers when separating ACM and Route 53 accounts or regions.

Conclusion

The exhaustive treatment of terraform aws acm certificate shows that provisioning ACM certificates with Terraform is not limited to declaring a resource. It requires understanding validation automation, provider aliasing, lifecycle management, and correct referencing of validation outputs.

DNS validation with Route 53 provides full automation, but requires correct hosted zone identification, TTL settings, and overwrite permissions. Module usage such as azavea/terraform-aws-acm-certificate encapsulates provider separation and validation record creation, reducing boilerplate.

Regional constraints, particularly for CloudFront, dictate where certificates must be created. Lifecycle rules prevent downtime during rotation. Data sources allow safe read-only access to existing certificates.

Together these patterns enable a reliable, automated, and cost-free SSL/TLS strategy using AWS Certificate Manager and Terraform, with certificates that auto-renew annually and maintain trust for public-facing services.

Sources

  1. Managing AWS Certificate Manager (ACM) with Terraform
  2. terraform-aws-acm-certificate
  3. Manage AWS ACM Certificates with Terraform
  4. acm-certificate-data
  5. Managing ACM with Terraform

Related Posts