💡 はじめに
みなさんはSSL/TLSサーバ証明書の有効期限が短縮されることをご存知でしょうか?
証明書の最長有効期間が、次のとおり短縮されます。
本日から 2026 年 3 月 14 日までは、TLS 証明書の最長有効期間を 397 日とする。
2026 年 3 月 15 日以降は、TLS 証明書の最長有効期間を 200 日とする。
2027 年 3 月 15 日以降は、TLS 証明書の最長有効期間を 100 日とする。
2029 年 3 月 15 日以降は、TLS 証明書の最長有効期間を 47 日とする。
引用:https://www.digicert.com/jp/blog/tls-certificate-lifetimes-will-officially-reduce-to-47-days
47日更新の時代になれば、「担当者が手動で更新」 は現実的ではなくなります。
そこで本記事では、AWS と DigiCert CertCentral API を組み合わせて、
“運用ゼロ”の証明書自動更新基盤を構築する方法を紹介します!
🎯 ゴール
期限チェック〜更新〜ACM登録〜HTTPS疎通確認まで自動化
以下をすべて自動化します。
✅ 証明書の期限チェック
✅ CSR / 秘密鍵の生成
✅ DigiCert への証明書発行リクエスト
✅ ステータス確認 (ポーリング)
✅ 証明書の取得/格納
✅ 承認プロセス (メール通知 + API Gateway)
✅ ACM インポート
✅ HTTPS 疎通確認 (CloudWatch Synthetics Canary)
人の手が入るのは “承認リンクをクリックするとき” のみ。
📘 全体アーキテクチャ
🧩 システム全体フロー
1. 証明書期限チェック
EventBridge によって、証明書の有効期限を定期的に確認し、
更新期限(例:30日前)を切ったタイミングで Step Functions① を起動します。
import boto3
from datetime import datetime, timedelta
acm = boto3.client('acm')
sf = boto3.client('stepfunctions')
def lambda_handler(event, context):
certs = acm.list_certificates()['CertificateSummaryList']
for c in certs:
detail = acm.describe_certificate(CertificateArn=c['CertificateArn'])
not_after = detail['Certificate']['NotAfter']
if not_after < datetime.now(not_after.tzinfo) + timedelta(days=30):
sf.start_execution(stateMachineArn='arn:aws:states:xxx:stateMachine:CertRenewFlow1')
2. CSR と秘密鍵生成 → Secrets Manager / S3 へ格納
Python の cryptography を使い、秘密鍵 + CSR を生成。
秘密鍵は Secrets Manager (復号ログを残せる) 、CSR と公開鍵は S3 に保存します。
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography import x509
# RSA生成 → CSR生成 → SecretsManager格納 → S3格納
3. DigiCert CertCentral API による発行リクエスト
DigiCert CertCentral API 1 を使って、証明書発行リクエストを送信。
API Key は Secrets Manager に保存して安全に取得。
import requests
url = "https://www.digicert.com/services/v2/order/certificate/ssl"
payload = {
"certificate": {
"csr": csr_data,
"common_name": "example.com"
},
"validity": {"valid_days": 398},
"payment_method": "balance"
}
res = requests.post(url, json=payload, headers=headers)
order_id = res.json()["id"]
4. ステータス確認 (ポーリング)
DigiCert の “issued” を待つ必要があるため、
Step Functions の Wait → Lambda → Choice → Wait… を使用してポーリングします。
Lambda 単体でのポーリングは、タイムアウトやコスト増の問題があるため
Step Functions を使うのがベストプラクティス。
5. 証明書取得 (S3 へ格納)
GET /services/v2/order/certificate/{order_id}/download/platform/aws
結果は S3 に格納し、再実行に問題が出ないよう 冪等性を確保。
6. 承認リンク生成 → SNS 通知
運用部門による最終承認が必要な場合のため、
API Gateway の URL に ワンタイムトークン (TaskToken) を付けてメール送信。
https://xxxx.execute-api.ap-northeast-1.amazonaws.com/prod/approve?token=XYZ
承認者がクリックすると Lambda が実行され、
Step Functions② に TaskToken を返して再開される。
7. ACM へのインポート → 検証
秘密鍵・証明書・中間証明書を ACM に登録。
acm.import_certificate(
Certificate=cert,
PrivateKey=private_key,
CertificateChain=chain
)
登録後に、有効期限やステータスが正当であるか確認。
8. CloudWatch Synthetics Canary による HTTPS疎通確認
Canary を “証明書期限チェック用” に設計し、対象サイトに対して TLS ハンドシェイクを実行して成功/失敗を確認。
const https = require("https");
await new Promise((resolve, reject) => {
const req = https.request("https://example.com", res => {
const cert = res.socket.getPeerCertificate();
if (!cert.valid_to) reject("Invalid certificate");
resolve();
});
req.on("error", reject);
req.end();
});
Lambda からは以下で起動可能。
synthetics = boto3.client('synthetics')
synthetics.start_canary(Name='tls-checker')
結果が “Failed” の場合は SNS でアラート通知。
🔍 この構成のポイント
| 目的 | 採用サービス | 理由 |
|---|---|---|
| 秘密鍵管理 | Secrets Manager | KMS 保護・復号履歴の取得 |
| 長時間待ちの制御 | Step Functions | Lambda タイムアウト回避 |
| 発行状況確認 | Step Functions Wait | ポーリングのベストプラクティス |
| 承認フロー | API Gateway + SNS | シンプルでセキュア |
| HTTPS疎通確認 | Synthetics Canary | TLS ハンドシェイクまで確認 |
✨ 証明書更新は“自動化する時代”へ
証明書有効期限の短縮により、手動更新は今後確実に限界を迎えます。
本記事の構成では、
- 証明書の期限チェック
- CSR / 秘密鍵の生成
- DigiCert への証明書発行リクエスト
- ステータス確認
- 証明書の取得/格納
- 承認プロセス
- ACM インポート
- HTTPS 疎通確認
これらをすべて自動化できます。
運用ゼロの証明書管理に向けて、ぜひ参考にしてみてください!
