Skip to main content

AWS Certificate Manager: Create Managed TLS Certificate via Terraform, Verify the Certificate Status via AWS CLI

426 words·
AWS AWS CLI Terraform AWS Certificate Manager (ACM) Route 53
Table of Contents

AWS Managed Certificate Terraform Configuration
#

Project Folder
#

# Create Terraform project folder
TF_PROJECT_NAME=aws-managed-certificate
mkdir $TF_PROJECT_NAME && cd $TF_PROJECT_NAME

Terraform Provider
#

  • terraform.tf
# Terraform Provider
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

# Provider AWS Region: us-east-1 
provider "aws" {
  alias  = "us_east_1"
  region = "us-east-1"
}

Variables
#

  • variables.tf
# AWS Region
variable "aws_region" {
  description = "AWS Region"
  type        = string
  default     = "eu-central-1"
}

# Route 53 Hosted Zone ID
variable "route53_zone_id" {
  description = "Route 53 Hosted Zone ID"
  type        = string
  default     = "Z05838622L1SDLImyzone" 
}

# Route 53 Domain Name
variable "domain_name" {
  description   = "Route 53 Domain Name"
  type          = string
  default       = "route53-test.jklug.work"
}

Managed TLS Certificate
#

  • certificate.tf
# AWS Managed TLS Certificate
resource "aws_acm_certificate" "managed_cert" {
  provider = aws.us_east_1
  domain_name       = var.domain_name
  validation_method = "DNS"

  lifecycle {
    create_before_destroy = true
  }
}

# Route 53 Entry for Certificate Validation
resource "aws_route53_record" "cert_validation" {
  provider = aws.us_east_1

  for_each = {
    for dvo in aws_acm_certificate.managed_cert.domain_validation_options : dvo.domain_name => dvo
  }

  zone_id = var.route53_zone_id
  name    = each.value.resource_record_name
  type    = each.value.resource_record_type
  records = [each.value.resource_record_value]
  ttl     = 300
}

Outputs
#

  • outputs.tf
# Managed Certificate ARN
output "acm_certificate_arn" {
  description = "Managed Certificate ARN"
  value       = aws_acm_certificate.managed_cert.arn
}



Apply Configuration
#

Initialize Terraform Project
#

This will download and install the AWS Terraform provider:

# Initialize the Terraform project
terraform init

Validate Configuration Files
#

# Validates the syntax and structure of Terraform configuration files
terraform validate

# Shell output:
Success! The configuration is valid.

Plan the Deployment
#

# Dry run / preview changes before applying them
terraform plan

Apply the Configuration
#

# Create network stack
terraform apply -auto-approve

# Shell output:
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

Outputs:

acm_certificate_arn = "arn:aws:acm:us-east-1:012345678912:certificate/7ff61866-5118-4797-839a-394c96b0d27b"



Verify the Certificate Status
#

Wait till the “ValidationStatus” changes to “SUCCESS”:

# List certificate details: Define certificate ARN
aws acm describe-certificate \
  --certificate-arn arn:aws:acm:us-east-1:012345678912:certificate/7ff61866-5118-4797-839a-394c96b0d27b \
  --region us-east-1

# Shell output:
{
    "Certificate": {
        "CertificateArn": "arn:aws:acm:us-east-1:012345678912:certificate/7ff61866-5118-4797-839a-394c96b0d27b",
        "DomainName": "route53-test.jklug.work",
        "SubjectAlternativeNames": [
            "route53-test.jklug.work"
        ],
        "DomainValidationOptions": [
            {
                "DomainName": "route53-test.jklug.work",
                "ValidationDomain": "route53-test.jklug.work",
                "ValidationStatus": "SUCCESS",
                "ResourceRecord": {
                    "Name": "_6a0c3e8d3ebf9ea7f423d7033bd18a41.route53-test.jklug.work.",
                    "Type": "CNAME",
                    "Value": "_46aeceda7b261be8f60743eeee9ede10.zfyfvmchrl.acm-validations.aws."
                },
                "ValidationMethod": "DNS"
            }
        ],
        "Serial": "09:a4:c4:5b:51:d6:ae:ed:4f:2a:a2:38:ea:6e:b6:be",
        "Subject": "CN=route53-test.jklug.work",
        "Issuer": "Amazon",
        "CreatedAt": "2025-02-12T16:05:03.737000+00:00",
        "IssuedAt": "2025-02-12T16:05:19.404000+00:00",
        "Status": "ISSUED",
        "NotBefore": "2025-02-12T00:00:00+00:00",
        "NotAfter": "2026-03-13T23:59:59+00:00",
        "KeyAlgorithm": "RSA-2048",
        "SignatureAlgorithm": "SHA256WITHRSA",
        "InUseBy": [],
        "Type": "AMAZON_ISSUED",
        "KeyUsages": [
            {
                "Name": "DIGITAL_SIGNATURE"
            },
            {
                "Name": "KEY_ENCIPHERMENT"
            }
        ],
        "ExtendedKeyUsages": [
            {
                "Name": "TLS_WEB_SERVER_AUTHENTICATION",
                "OID": "1.3.6.1.5.5.7.3.1"
            },
            {
                "Name": "TLS_WEB_CLIENT_AUTHENTICATION",
                "OID": "1.3.6.1.5.5.7.3.2"
            }
        ],
        "RenewalEligibility": "INELIGIBLE",
        "Options": {
            "CertificateTransparencyLoggingPreference": "ENABLED"
        }
    }
}