この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
先日AWSの機能追加があり、Amazon Certificate Manager(ACM)の証明書認証がDNS CNAMEレコードで行えるようになったことが発表され、弊社ブログでも取り上げました。
- AWS Certificate Manager: DNS を使用した、証明書のより簡単な検証
- Certificate Manager (ACM) がDNSの検証をサポートしました | Developers.IO
今まではメール認証にしか対応していなかったため、自動化の障壁が少し高いというのが現実でしたが、DNS認証に対応したということで自動化がかなりしやすくなりました。
今回は、ACMの証明書リクエストからRoute53を利用してDNSの認証レコード登録を行い、実際に認証が受理されてACMの証明書が発行されるまでを自動化したbashのスクリプトを作成しました。
仕様
スクリプトの仕様および動作前提は以下のとおりです。
仕様
- スクリプトの引数でドメイン名を指定する
- 引数で指定されたドメインのワイルドカード証明書を発行する
- DNSレコード登録後、認証処理が完了するまで何度かリトライを実施する
動作前提
- AWSのクレデンシャル設定が適切に行われていること
- Route53のHostedZoneが作成済であること
- Route53のHostedZoneのNameが、そのAWSアカウント内でただ一つであること。言い換えると、同名のHostedZoneが存在しないこと
実装
以下のシェルスクリプトが全てです。
#!/bin/bash
set -e
# 証明書リクエストと必要なDNSレコードの取得
domainName=$1
certificateArn=$(aws acm request-certificate --domain-name *.${domainName} --validation-method DNS | jq -r '.CertificateArn')
echo "request certificate: DONE"
dnsOptions=$(aws acm describe-certificate --certificate-arn ${certificateArn} | jq -r '.Certificate.DomainValidationOptions[0].ResourceRecord')
# Route53に認証のためのDNSレコードを登録
hostedZoneId=$(aws route53 list-hosted-zones | jq -r '.HostedZones[] | select(.Name == "'${domainName}'.") | .Id')
changeBatch=$(cat << EOS
{
"Changes": [
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": $(echo ${dnsOptions} | jq .Name),
"Type": $(echo ${dnsOptions} | jq .Type),
"TTL": 300,
"ResourceRecords": [
{ "Value": $(echo ${dnsOptions} | jq .Value) }
]
}
}
]
}
EOS
)
aws route53 change-resource-record-sets \
--hosted-zone-id ${hostedZoneId} \
--change-batch "${changeBatch}" > /dev/null
echo "register DNS record: DONE"
# 証明書の認証が通るまでリトライ
DESIRED_STATUS="ISSUED"
status=""
counter=1
MAX_RETRIES=10
while [ "${DESIRED_STATUS}" != "${status}" ] ; do
echo "checking certificate status...(${counter}/${MAX_RETRIES})"
status=$(aws acm describe-certificate --certificate-arn ${certificateArn} | jq -r '.Certificate.Status')
counter=$((counter + 1))
if [ ${counter} -gt ${MAX_RETRIES} ]; then
>&2 echo "Failed to validate domain. Program exits in error."
exit 1
fi
sleep 15
done
echo "validate DNS record: DONE."
exit 0
ACMのrequest-certificate
APIで証明書リクエストを発行した後、describe-certificate
APIを実行することで証明書認証のためのDNSレコードを取得することが可能です。
その値をRoute53 APIを利用して登録し、CertificateのステータスがPENDING
(認証待ち)からISSUED
(発行済み)に変わるのを待っています。
このスクリプトをissue-certificate.sh
として保存して実行すると、以下のような出力となります。引数のドメイン名は適宜変更してください。
$ ./issue-certificate.sh example.com
request certificate: DONE
register DNS record: DONE
checking certificate status...(1/10)
validate DNS record: DONE.
$
簡単ではありますが、以上です。お役立てください。