AWS ACM Terraform Provisioning and Validation

AWS Certificate Manager provides SSL/TLS certificates for securing applications. Managing AWS Certificate Manager with Terraform means provisioning and managing SSL/TLS certificates using AWS Certificate Manager and Terraform including validation and integration with other AWS services. The combination of ACM and Terraform converts a cumbersome multi-step process of provisioning validating and configuring Transport Layer Security certificates into a single concise operation woven directly into infrastructure configuration. AWS Certificate Manager is a service provided by Amazon that issues on-demand TLS certificates at no cost. Amazon controls the Certificate Authority Amazon Trust Services LLC 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 the AWS Go SDK has support for it Terraform can manage ACM resources. The AWS Go SDK support enables the Terraform AWS provider to expose ACM resources. Because there is an HTTP API defined for ACM we can manage ACM certificates via Amazon's suite of SDKs.

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 ACM. 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.

Core ACM Terraform Resources

awsacmcertificate

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

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

Now awsacmcertificate is a useful resource on its own but the real magic comes when it is combined with acmcertificatevalidation. That’s 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.

Making use of the awsacmcertifcatevalidation output is important because the one provided by awsacm_certificate 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.

acmcertificatevalidation

The validation resource is central to reliable Terraform workflows. The resource ensures that dependent resources such as CloudFront distributions do not receive an ARN for a certificate that is not yet validated. The impact for users is a plan that completes without dependency errors and a deployment that does not fail at runtime due to an unvalidated certificate.

The integration of validation into Terraform configuration creates a dense web of information because the validation state depends on Route53 DNS records created by ACM or by Terraform. The workflow connects ACM certificate request DNS validation record creation and CloudFront or Load Balancer attachment.

DNS Validation Workflow with Route53

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.

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 prerequisites assumed are An AWS Account Terraform installed and a basic understanding of how to configure Terraform to access your AWS account and how to plan and apply with Terraform.

The example with Terraform Resources shows the pattern of creating a certificate then creating validation records in Route53 and then referencing the validated ARN in a CloudFront 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" }

The viewer_certificate block ties the validated certificate ARN to the distribution. The impact layer for operators is that HTTPS is enforced at the edge without manual console steps. The contextual layer shows how this ties back to ACM’s restriction that certificates can only be associated with Elastic and Application Load Balancers CloudFront distributions and API Gateway endpoints.

Terraform Module Encapsulation

In an effort to reduce these steps even further we assembled a reusable Terraform module to encapsulate the ACM and Route53 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 data source awsroute53zone external fetches the hosted zone ID. The module cert consumes domainname hostedzoneid and validationrecord_ttl. The output arn from the module is consumed by the CloudFront distribution.

The impact for teams is reduced boilerplate and consistent DNS validation TTL. The contextual layer connects module reuse with compliance and drift prevention because the same validation logic is reused across environments.

Module Interface and Arguments

Terraform module which creates ACM certificates and validates them using Route53 DNS.

Here’s the gist of using it directly from github.

module acm { source = "terraform-module/acm/aws" version = "~> 2" domain_name = "example.com" zone_id = "Z0FK2F3K10ACF0" validation_method = "DNS" subject_alternative_names = [ "*.example.com" ] tags = {} }

Will not allow to add new SANS due to bug that shoulb de fixed here

Name and Version requirements:

Name Version
terraform >= 0.12
aws n/a

Name Description Type Default Required

Name Description Type Default Required
allowoverwriterecords Allow creation of this record in Terraform to overwrite an existing record if any. bool true no
domain_name A domain name for which the certificate should be issued string "" no
subjectalternativenames A list of domains that should be SANs in the issued certificate list(string) [] no
tags A mapping of tags to assign to the resource map(string) {} no
ttl The TTL of the record. number 60 no
validate_certificate Whether or not certificate should be validated bool true no
validation_method Which method to use for validation. DNS or EMAIL are valid NONE can be used for certificates that were imported into ACM and then into Terraform. string "DNS" no
zone_id The ID of the hosted zone to contain this record. string "" no

Name Description

Name Description
arn Certificate ARN.
distinctdomainnames Distinct domain names

The arguments allowoverwriterecords controls whether Terraform may overwrite existing DNS validation records. The impact is safety versus automation. The default true favors automation. The contextual layer ties this to compliance frameworks that require controlled DNS changes.

The domainname argument defines the primary name for certificate issuance. Subjectalternativenames allows additional SANs. The module version ~> 2 pins compatibility. The validationmethod defaults to DNS which aligns with ACM’s recommended automated validation.

Compliance and Controls

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

Controls enforced

These compliance controls are checked at terraform plan time.

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. See the Migration Guide for step-by-step instructions.

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.

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 control table shows enforcement status per PCI DSS v4.0. The enforced control for RSA key length of at least 2,048 bits ensures cryptographic strength. The impact is reduced risk of weak key compromise. The contextual layer links this to Terraform plan time checks which prevent non-compliant configurations from being applied.

The reversibility statement matters for adoption because teams can trial compliance controls without state migration risk.

Practical Integration Patterns

This 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 ACM.

The pattern of requesting a certificate via awsacmcertificate with validationmethod DNS then creating validation records via acmcertificatevalidation then referencing the validated ARN in viewercertificate is repeatable across Load Balancers and API Gateway.

The impact for operators is that Terraform becomes the single source of truth for certificate lifecycle. Renewal is handled by ACM automatically annually as long as DNS setup is maintained. The contextual layer shows that DNS maintenance is the operational responsibility left to the user while ACM handles issuance and renewal.

The module source github.com/azavea/terraform-aws-acm-certificate?ref=0.1.0 demonstrates encapsulation of hosted zone lookup validation record TTL and certificate creation. The TTL of 60 seconds for validation records enables rapid propagation during validation.

The workflow ensures that Terraform will wait for ACM to validate the certificate before resolving its ARN. This avoids race conditions where CloudFront or ALB receives an ARN for a pending certificate.

Conclusion

AWS ACM Terraform integration transforms certificate provisioning from a manual console task into declarative infrastructure. The awsacmcertificate resource requests certificates and acmcertificatevalidation ensures validation completion before downstream use. Route53 integration enables DNS validation with controlled TTL and overwrite behavior. Module encapsulation reduces repetitive configuration and aligns with compliance controls checked at plan time. The free automatic renewal offered by ACM reduces cost while Terraform enforces consistent validation and attachment patterns across CloudFront distributions Load Balancers and API Gateway endpoints. Reversibility of compliance modules and unchanged Terraform state preserves operational safety while controls enforce key length and certificate policy. The entire workflow remains within the constraint that ACM certificates can only be associated with Elastic and Application Load Balancers CloudFront distributions and API Gateway endpoints.

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. terraform-module/terraform-aws-acm

Related Posts