2026年6月5日

2026年6月5日

AWS ACM の自動化方法:DNS検証・自動更新・期限切れ通知をコードで整える

AWS Certificate Manager(ACM)の公開証明書は、DNS検証で発行し、AWSのサービスに関連付けて使っている限り、更新をACMが自動で行います。自動化で手を入れるのは「発行と検証をコード化すること」「自動更新が止まる条件をつくらないこと」「更新できなかったときに気づける通知を用意すること」の3点です。この記事では、Terraform・CloudFormation・AWS CLI での発行の自動化と、更新状況の監視方法を説明します。

ACM の自動更新が働く条件

ACM の管理する更新(マネージド更新)は、有効期限が近づくと自動で始まります。ただし、次の条件を満たしていないと更新されない、または途中で止まります。

  • DNS検証で発行していること: メール検証の証明書は、更新のたびに承認メールへの操作が必要です。自動化を前提にするならDNS検証を選びます。
  • 検証用のCNAMEレコードを残していること: DNS検証で追加したCNAMEは、発行後も消さずに残します。ACMは更新時にこのレコードを使ってドメインの管理を再確認します。
  • 証明書がサービスに関連付けられていること: ロードバランサー(ALB/NLB)、CloudFront、API Gateway などで使用中の証明書が更新の対象です。どこにも関連付けていない証明書は、更新の対象外になることがあります。
  • CAAレコードで Amazon の認証局を許可していること: ドメインにCAAレコードを設定している場合、Amazon の発行を許可していないと発行も更新も失敗します。

証明書の有効期間や更新を始める時期は、業界の基準の変更に合わせて見直されることがあります(2026年10月現在)。具体的な日数は ACM のドキュメントで確認し、運用の前提を固定の日数に置かないようにしておくと安全です。

WordPress をACMで HTTPS 化する構成

ACM の公開証明書は、原則として秘密鍵を取り出せず、AWSのサービス上で使う前提です。EC2 上の WordPress を HTTPS にするには、手前に ALB か CloudFront を置き、そこに証明書を関連付ける構成が基本になります。秘密鍵を取り出せる公開証明書の選択肢も追加されていますが、利用条件があり、その場合は更新後の証明書をサーバーへ配る処理を自分で用意することになります。

CloudFront で使う証明書は、バージニア北部リージョン(us-east-1)で発行する必要があります。ALB で使う証明書は、ALB と同じリージョンで発行します。リージョンを間違えると、証明書は発行されてもサービスの選択肢に表示されません。

ALB や CloudFront で HTTPS を終端すると、WordPress から見たリクエストは HTTP になることがあります。X-Forwarded-Proto ヘッダーを見て HTTPS と判定する設定を wp-config.php に入れないと、ログイン画面のリダイレクトが繰り返される原因になります。

// wp-config.php(「編集が必要なのはここまでです」の行より前に記述)
// ALB/CloudFront 経由のときだけ HTTPS と判定する
if ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && 'https' === $_SERVER['HTTP_X_FORWARDED_PROTO'] ) {
    $_SERVER['HTTPS'] = 'on';
}

このヘッダーは誰でも付けられるため、サーバーへの接続をロードバランサーからに限るよう、EC2 のセキュリティグループを ALB のセキュリティグループからの通信だけに絞っておきます。

Terraform で発行と検証を自動化する

DNS を Route 53 で管理している場合、証明書の申請、検証用レコードの作成、検証完了の待ち合わせまでを1回の適用で行えます。適用前に terraform plan で、既存のレコードを書き換えないかを確認してください。

data "aws_route53_zone" "main" {
  name         = "example.com"
  private_zone = false
}

resource "aws_acm_certificate" "site" {
  domain_name               = "example.com"
  subject_alternative_names = ["www.example.com"]
  validation_method         = "DNS"

  lifecycle {
    create_before_destroy = true
  }
}

resource "aws_route53_record" "site_validation" {
  for_each = {
    for dvo in aws_acm_certificate.site.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         = data.aws_route53_zone.main.zone_id
}

resource "aws_acm_certificate_validation" "site" {
  certificate_arn         = aws_acm_certificate.site.arn
  validation_record_fqdns = [for r in aws_route53_record.site_validation : r.fqdn]
}

create_before_destroy は、ドメインを追加するなどで証明書を作り直すときに、新しい証明書を先に作ってから古いものを外すための指定です。ALB のリスナーなどには aws_acm_certificate_validation.site.certificate_arn を渡すと、検証が終わってから関連付けが行われます。CloudFront 用なら、provider に us-east-1 を指定したエイリアスを使います。

CloudFormation と AWS CLI の場合

CloudFormation では、AWS::CertificateManager::Certificate の DomainValidationOptions に Route 53 のホストゾーンIDを指定すると、検証用レコードの作成まで自動で行われます。

Resources:
  SiteCertificate:
    Type: AWS::CertificateManager::Certificate
    Properties:
      DomainName: example.com
      SubjectAlternativeNames:
        - www.example.com
      ValidationMethod: DNS
      DomainValidationOptions:
        - DomainName: example.com
          HostedZoneId: Z0123456789EXAMPLE
        - DomainName: www.example.com
          HostedZoneId: Z0123456789EXAMPLE

DNS を Route 53 以外で管理している場合は、AWS CLI で申請し、表示された CNAME を DNS サービスの API や管理画面で登録します。

# 申請(CloudFront 用なら --region us-east-1)
aws acm request-certificate --domain-name example.com \
  --subject-alternative-names www.example.com \
  --validation-method DNS --region ap-northeast-1

# 登録すべき CNAME を確認する
aws acm describe-certificate --certificate-arn (証明書のARN) \
  --query 'Certificate.DomainValidationOptions[].ResourceRecord'

# 検証が終わるまで待つ
aws acm wait certificate-validated --certificate-arn (証明書のARN)

更新状況を監視して通知する

自動更新でも、CNAMEが消された、CAAが変更された、といった理由で更新が止まることがあります。止まったことに気づける仕組みを用意しておきます。

EventBridge で期限切れが近い証明書を通知する

ACM は、有効期限が近い証明書についてイベントを送ります。EventBridge のルールで受け取り、SNS などへ流すと、メールやチャットに通知できます。

{
  "source": ["aws.acm"],
  "detail-type": ["ACM Certificate Approaching Expiration"]
}

このイベントを何日前から送るかは、アカウント単位で変更できます。

aws acm put-account-configuration \
  --expiry-events DaysBeforeExpiry=30 \
  --idempotency-token acm-expiry-config

正常に自動更新されていれば、期限が迫る前に新しい有効期限に切り替わるため、このイベントが届くこと自体が「更新が進んでいない」という合図になります。

更新の状況を確認する

aws acm describe-certificate --certificate-arn (証明書のARN) \
  --query 'Certificate.{NotAfter:NotAfter,Eligibility:RenewalEligibility,Renewal:RenewalSummary}'

RenewalEligibility が更新の対象になっているか、RenewalSummary に失敗の理由が出ていないかを見ます。AWS Config のマネージドルール(証明書の期限を確認するもの)や、CloudWatch の証明書の残り日数のメトリクスを併用する方法もあります。

外部からも、実際に配信されている証明書の期限を確認しておくと、関連付けの誤りに気づけます。

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

まとめ

  • ACM の自動更新は、DNS検証・検証用CNAMEの維持・サービスへの関連付けが条件です。CAAレコードも確認します。
  • EC2 上の WordPress は ALB か CloudFront で HTTPS を終端し、X-Forwarded-Proto の判定と通信元の制限をセットで設定します。
  • Terraform や CloudFormation で、申請から検証レコードの作成、検証完了の待ち合わせまでをコード化できます。CloudFront 用は us-east-1 で発行します。
  • EventBridge の期限切れ通知、describe-certificate の更新状況、外部からの openssl 確認を組み合わせ、更新が止まったときに気づける状態にします。

お気軽にご相談ください

お見積りへ お問い合わせへ
▲