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確認を組み合わせ、更新が止まったときに気づける状態にします。