AWS Certificate ManagerのDNS認証レコードの登録を少し楽にした

2023.04.12

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

初めに

CloudFormationでAWS Certificate Manager(以降ACM)のSSL証明書をDNS認証で発行する場合、
自アカウントにホストゾーンがあればそのまま登録して認証まで済ませてくれて非常に便利です。

一方で利用しているホストゾーンが別アカウント上であったり、そもそもRoute 53外となると自動登録がされず手動での登録作業が必要となります。

現時点の仕様ではACMのレコードはマネジメントコンソール上一覧から一括で確認ではできず、個々の証明書の画面に確認しに行く必要があり数が多くなってくるとレコードの確認自体が非常に手間です。

またマネジメントコンソール上で証明書ごとの検証レコードのCSVの出力機能は存在しますが、別のアカウントのRoute 53のホストゾーンを使ってる!という場合でも特にこれがそのまま使えるわけではなく取り込み作業も手間です。

流石に別のネームサーバサービスまでの対応となると難しいですが、管理上の問題でRoute 53が別アカウントになってしまっている程の環境であればどうにかサクッと登録したい!と思い作業ツールを作成しましたので紹介します。

注意

本ツールは個人的な作業ツールとして作成されており、検証が網羅的に行われていいません。
予期せぬ動作発生する可能性や対応できないパターンが含まれている可能性があります。

ツールによって発生した事象について責任を負いかねますので自己責任にてご利用をお願いいたします。

コード

以下のリポジトリに格納しています。

最小バージョンは確認していませんがPython 3.11.2で動作を確認しています。 セイウチ演算子を利用しているため最低でも3.8以上のバージョンが必要となるはずです。

追記(2023/04/14)

CloudShell環境(Python3.8.16)でも動きそうです。
後方互換のためにコードを修正したくない為Python3.7対応は予定していません。

$ sudo amazon-linux-extras install python3.8 -y
...
$ python3.8 --version
Python 3.8.16
$ pip3.8 install boto3 fire -t lib
...
$ python3.8 acm-validation-tool.py export
Domain,Name,Type,Value
...

バージョン問題とは別件のバグが1件あり本日17時以前のコードだとCloudShell上では動かないため最新化してください。

機能

作業リージョン上の検証保留中のレコードを一括で書き出すexportとそのレコードをRoute 53に書き込みを行うregist機能を用意しています。

Docstringの記載上--yes_allになっていますが--yes-allのようにアンダースコア部分はハイフンで指定可能です。

$ python3 acm-validation-tool.py --help
NAME
    acm-validation-tool.py - ACMの検証保留中のレコードの一括出力/登録ツール

SYNOPSIS
    acm-validation-tool.py <flags>

DESCRIPTION
    SubCommand:
        export: 標準出力にcsv形式でレコードを出力する
        regist: 指定したcsvファイルからRoute53にレコードを登録

    Examples:
        python3 acm-validation-tool.py export
        python3 acm-validation-tool.py regist export.csv
FLAGS
    -p, --profile=PROFILE
        実行時に利用するAWSプロファイル
    -r, --region=REGION
        実行先リージョン
    -d, --dry=DRY
        Trueの場合、確認メッセージの出力後の登録処理を行いません
    -y, --yes_all=YES_ALL
        Trueの場合全ての確認を自動的にyesとして処理する

エクスポート

該当アカウントの指定リージョン内の検証保留中の認証レコードをCSVフォーマットで標準出力に書き出します。
フォーマットはヘッダ名以外は執筆時点でのACMのマネジメントコンソールからのエクスポートの形式に合わせています。

取り込み先がRoute 53外でもCSV取り込みに対応して居れば少しシェルを書いて追加加工すれば対応できるかもしれません。

% python3 acm-validation-tools.py export
Domain,Name,Type,Value
example.com,_xxxxxx.example.com.,CNAME,_xxxxxxxx.xxx.acm-validations.aws.
mail.example.com,_xxxxxx.mail.example.com.,CNAME,_xxxxxx.xxx.acm-validations.aws.

検証保留中のレコードの一覧が出力されるため進行状態の確認用途にも使えなくはないですが、期限切れ等で失敗したレコードは出力されない点はご注意ください。

登録

エクスポートしたCSVを指定することでRoute 53のゾーンに検証レコードを登録します。

--dryオプションでドライラン機能ライクなものも実装しているので事前に取り込み先のホストゾーンは確認可能です。

% python3 acm-validation-tool.py regist export.csv --dry
[Start] Domain: example.com
Regist confirm: '_xxxxxx.example.com.' to {'Id': '/hostedzone/Zxxxxx', 'Name': 'example.com.'}] Skkiped...
[End] Domain: example.com
[Start] Domain: mail.example.com
Regist confirm: '_xxxxx.mail.example.com.' to {'Id': '/hostedzone/Zxxxxx', 'Name': 'example.com.'}] Skkiped...
[End] Domain: mail.example.com

レコードが登録されるゾーンは元のドメイン列の値に対してホストゾーン名が最長で一致するホストゾーンになります。
なお複数同条件で一致する場合は取得順で最初の方を選択します。

終わりに

新規構築や移行などで新たにACMで証明書を多量に発行したい人のお役に立てれば幸いです。