Amazon Certificate Managerの証明書DNS認証を自動化するbashスクリプト
先日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. $
簡単ではありますが、以上です。お役立てください。