ACMにLet’s Encryptの証明書をアップロード(更新)する作業を半自動化する

https://qiita.com/hidekuro/items/482520f220a305dc147b
↑を参考しながら自分流にアレンジした 事情として、DNSがAWS上で管理されていないためACMによる証明書が使えないかつ、アプリケーションのコードに影響を与えずに証明書を管理したいためwebrootを使えなかった。
それとTXTレコードによる認証の場合、ワイルドカードが使えるとのことで……

まずは証明書を更新する為にt3.nanoインスタンスでUbuntu18.04を立ち上げます。
その後は上の資料と同じくして https://github.com/letsencrypt/letsencrypt からletsencrypt-autoを導入。
EC2のUbuntuは最初からawsが入ってるので認証情報をセットアップしておく。
#!/bin/bash
set -e
cd $(dirname $0)
# 取得したい証明書のドメイン
DOMAINS=(
  "*.hoge.example.jp"
  "*.piyo.example.jp"
  "*.example.jp"
)
# それぞれACMを操作できるユーザーをap-northeast-1, us-east-1で事前に作成しておく
EXEC_AWS="aws --profile elb_update_cert"
EXEC_AWS_US="aws --profile elb_update_cert_us"
# Let's Encrypt の連絡用メールアドレス
LE_EMAIL=no-reply@example.jp
# Let's Encrypt Client を clone したパス
LE_HOME=/home/ubuntu/letsencrypt
# letsencrypt-auto 実行コマンド
EXEC_LE_AUTO="${LE_HOME}/letsencrypt-auto --email $LE_EMAIL --agree-tos"
# 取得した証明書ファイルのリンク群が配置されるディレクトリ
# letsencrypt-auto に与えた最初のドメイン名が採用される
LE_FILES_ROOT=/etc/letsencrypt/live/hoge.example.jp
# 証明書ファイル群のシンボリックリンクのパス
CERT_PATH=$LE_FILES_ROOT/cert.pem
CHAIN_PATH=$LE_FILES_ROOT/chain.pem
PRIVKEY_PATH=$LE_FILES_ROOT/privkey.pem
# DOMAINS を "-d" とペアで繋げたパラメータ (-d "yourdomain.com" -d "www1.yourdomain.com" ... )
LE_PARAM_DOMAINS=()
for domain in "${DOMAINS[@]}"; do
  LE_PARAM_DOMAINS+=("-d" "$domain")
done
LE_PARAM_DOMAINS="${LE_PARAM_DOMAINS[@]}"
# 証明書を(再)発行。
$EXEC_LE_AUTO certonly --manual \
    --renew-by-default \
    --preferred-challenges dns-01 \
    $LE_PARAM_DOMAINS
# 初回実行時は --certificate-arnの行は書かない
$EXEC_AWS acm import-certificate \
  --certificate file://$CERT_PATH\
  --certificate-chain file://$CHAIN_PATH\
  --private-key file://$PRIVKEY_PATH\
  --certificate-arn arn:aws:acm:ap-northeast-1:xxxxxxxxxxxxxxxxxxx
$EXEC_AWS_US acm import-certificate \
  --certificate file://$CERT_PATH\
  --certificate-chain file://$CHAIN_PATH\
  --private-key file://$PRIVKEY_PATH\
  --certificate-arn arn:aws:acm:us-east-1:xxxxxxxxxxxxxxxxxxxx
echo "ACMへの証明証アップロードAPIをコールしました。"
初回実行時は手動で –certificate-arn 行を抜いて実行。対話式でTXTレコードの設定ダイアログがドメイン数分流れてくるので、適宜設定を行えばAWSにアップロードした証明書のARNがコンソールに返ってくる。ACMに証明書がアップロードされていることを確認したら終了。

DNSに設定するTXTレコードは次回更新時には変わっているので、単純に1度やれば後はDNS変更不要……というわけにも行かないらしい。

上記例ではus-east-1(CloudFrontとか)とap-northeast-1(EBとかEKSとか)用に2種類のprofileを作成してスクリプト化している。
使いたい証明書のリージョンに合わせてスクリプトは変更するし、厳格な権限管理が不要ならAWSのprofileも1つで良い。(取得した証明書自体はリージョンに縛られないので、Let’s Encryptの実行は1回のみで良い。)