Skip to main content

ACM Certificate Expiration Check

Overview

This check verifies that your AWS Certificate Manager (ACM) certificates are not approaching expiration. ACM certificates are used to secure connections to your applications via HTTPS/TLS. The check flags certificates that will expire within a configurable threshold (typically 30 days).

Risk

When ACM certificates expire:

  • Service outages occur as HTTPS connections fail for websites, APIs, and applications
  • Browser warnings display security errors to your users, damaging trust
  • API integrations break when TLS handshakes fail between services
  • Emergency fixes under pressure may lead to security shortcuts like disabling certificate validation
  • Man-in-the-middle attacks become possible if encryption is weakened during rushed remediation

Remediation Steps

Prerequisites

  • AWS account access with permission to manage ACM certificates
  • For ACM-issued certificates: Access to validate domain ownership (DNS or email)
  • For imported certificates: Access to your certificate authority or certificate files
Required IAM permissions

To manage ACM certificates, you need these permissions:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"acm:DescribeCertificate",
"acm:ListCertificates",
"acm:RequestCertificate",
"acm:ImportCertificate",
"acm:DeleteCertificate",
"acm:RenewCertificate"
],
"Resource": "*"
}
]
}

AWS Console Method

ACM-issued certificates renew automatically if they are:

  1. In use by an AWS service (ALB, CloudFront, API Gateway, etc.)
  2. Successfully validated via DNS or email

To check and fix renewal:

  1. Sign in to the AWS Management Console
  2. Navigate to Certificate Manager (ACM)
  3. Select the region where your certificate exists (e.g., us-east-1)
  4. Find the expiring certificate in the list
  5. Click on the certificate to view details
  6. Check the Renewal status:
    • If Pending validation: Complete the DNS or email validation (see below)
    • If Ineligible: The certificate is not attached to any AWS service

To complete DNS validation:

  1. In the certificate details, expand Domains
  2. Click Create record in Route 53 if your domain uses Route 53
  3. Otherwise, copy the CNAME record shown and add it to your DNS provider
  4. Wait for validation (usually a few minutes, up to 72 hours)

To complete email validation:

  1. Check the email addresses listed in the certificate for a validation email from AWS
  2. Click the approval link in the email
  3. The certificate will renew automatically after validation

For Imported Certificates

Imported certificates (from external certificate authorities) do not auto-renew. You must manually replace them before expiration.

  1. Obtain a new certificate from your certificate authority
  2. In ACM, click Import > Import certificate
  3. Paste or upload:
    • Certificate body: Your new certificate (PEM format)
    • Certificate private key: The private key (PEM format, unencrypted)
    • Certificate chain: Intermediate certificates (optional but recommended)
  4. Click Import
  5. Update your services (ALB, CloudFront, etc.) to use the new certificate
  6. Delete the old certificate once all services are updated
AWS CLI (optional)

List certificates approaching expiration:

aws acm list-certificates \
--certificate-statuses ISSUED \
--region us-east-1 \
--query 'CertificateSummaryList[*].[CertificateArn,DomainName]' \
--output table

Get details for a specific certificate:

aws acm describe-certificate \
--certificate-arn arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012 \
--region us-east-1

Check expiration date:

aws acm describe-certificate \
--certificate-arn arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012 \
--region us-east-1 \
--query 'Certificate.NotAfter'

Import a replacement certificate:

aws acm import-certificate \
--certificate fileb://certificate.pem \
--private-key fileb://private-key.pem \
--certificate-chain fileb://certificate-chain.pem \
--region us-east-1

Request a new ACM-issued certificate:

aws acm request-certificate \
--domain-name example.com \
--subject-alternative-names www.example.com \
--validation-method DNS \
--region us-east-1
CloudFormation (optional)

Request an ACM certificate with DNS validation:

AWSTemplateFormatVersion: '2010-09-09'
Description: Request ACM certificate with DNS validation

Parameters:
DomainName:
Type: String
Description: Primary domain name for the certificate
Default: example.com

HostedZoneId:
Type: String
Description: Route 53 Hosted Zone ID for DNS validation

Resources:
Certificate:
Type: AWS::CertificateManager::Certificate
Properties:
DomainName: !Ref DomainName
SubjectAlternativeNames:
- !Sub 'www.${DomainName}'
ValidationMethod: DNS
DomainValidationOptions:
- DomainName: !Ref DomainName
HostedZoneId: !Ref HostedZoneId
Tags:
- Key: Name
Value: !Sub '${DomainName}-certificate'

Outputs:
CertificateArn:
Description: ARN of the created certificate
Value: !Ref Certificate
Export:
Name: !Sub '${AWS::StackName}-CertificateArn'

Deploy the template:

aws cloudformation deploy \
--template-file acm-certificate.yaml \
--stack-name acm-certificate-stack \
--parameter-overrides \
DomainName=example.com \
HostedZoneId=Z1234567890ABC \
--region us-east-1
Terraform (optional)

Request an ACM certificate with DNS validation:

variable "domain_name" {
description = "Primary domain name for the certificate"
type = string
default = "example.com"
}

variable "hosted_zone_id" {
description = "Route 53 Hosted Zone ID"
type = string
}

resource "aws_acm_certificate" "main" {
domain_name = var.domain_name
validation_method = "DNS"

subject_alternative_names = [
"www.${var.domain_name}"
]

tags = {
Name = "${var.domain_name}-certificate"
}

lifecycle {
create_before_destroy = true
}
}

resource "aws_route53_record" "validation" {
for_each = {
for dvo in aws_acm_certificate.main.domain_validation_options : dvo.domain_name => {
name = dvo.resource_record_name
record = dvo.resource_record_value
type = dvo.resource_record_type
}
}

allow_overwrite = true
name = each.value.name
records = [each.value.record]
ttl = 60
type = each.value.type
zone_id = var.hosted_zone_id
}

resource "aws_acm_certificate_validation" "main" {
certificate_arn = aws_acm_certificate.main.arn
validation_record_fqdns = [for record in aws_route53_record.validation : record.fqdn]
}

output "certificate_arn" {
description = "ARN of the validated certificate"
value = aws_acm_certificate_validation.main.certificate_arn
}

Verification

After renewing or replacing your certificate:

  1. Go to Certificate Manager in the AWS Console

  2. Click on your certificate and verify:

    • Status shows Issued
    • Not after date is in the future (typically 13 months for ACM-issued certificates)
    • Renewal status shows Success or Eligible
  3. Test your application's HTTPS endpoint in a browser to confirm the new certificate is active

CLI verification commands

Verify certificate status and expiration:

aws acm describe-certificate \
--certificate-arn arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012 \
--region us-east-1 \
--query 'Certificate.[Status,NotAfter,RenewalSummary.RenewalStatus]' \
--output table

List all certificates with expiration dates:

aws acm list-certificates \
--certificate-statuses ISSUED \
--region us-east-1 \
--output json | \
jq -r '.CertificateSummaryList[] | [.DomainName, .CertificateArn] | @tsv'

Check certificate from the endpoint (using OpenSSL):

echo | openssl s_client -servername example.com -connect example.com:443 2>/dev/null | \
openssl x509 -noout -dates

Additional Resources

Notes

  • Auto-renewal requires validation: ACM-issued certificates auto-renew only if DNS or email validation remains valid. Keep your DNS CNAME records in place.
  • Certificate must be in use: ACM auto-renews certificates only if they are associated with an AWS service (ALB, CloudFront, API Gateway, etc.)
  • Imported certificates never auto-renew: You must manually replace imported certificates before they expire
  • Regional considerations: ACM certificates are region-specific. For CloudFront, certificates must be in us-east-1
  • Renewal timing: ACM begins the renewal process 60 days before expiration
  • Set up alerts: Use Amazon EventBridge or AWS Config to alert you before certificates expire