- 公開日
- 最終更新日
【やってみた】EC2上のAnsibleからTLS証明書を自動配布(Linux、Windows)
この記事を共有する
目次
パーソル&サーバーワークスの髙井です。
AWS を中心としたクラウドインフラの設計・構築・運用を担当しています。
はじめに
本ブログでは、 TLS 証明書を Ansible で Linux サーバーと Windows サーバーへ配布する という題材を通して、Ansible を実行すると実際に何が起きるのかを見ていきます。
Linux へは SSH、Windows へは WinRM で接続します。
本ブログは Playbook の書き方を1行ずつ解説するものではありません。
インベントリや Playbook の中身には深入りせず、 コマンドを実行した結果、証明書が配布されサーバーが HTTPS を終端するようになる という Ansible の実用性に焦点を当てます。
設定ファイルの具体的な記述よりも、動かした結果の実行画面を中心に見ていきます。
Ansible の基本的な用語については、 入門編 で解説しています。あわせてご確認ください。
想定読者
- Ansible の基本用語を理解していて、実際に動かすと何が起きるのかを知りたい方
今回やること
Control Node(Ansible 実行元)から、2台の Managed Node へ同じ証明書を配布します。
Control Node ──SSH(22)──▶ Linux Node(httpd で HTTPS 公開)
└─WinRM(5986)─▶ Windows Node(IIS で HTTPS 公開)
配布する証明書は、検証用の自己署名 CA で発行したものです。配布先ごとに扱いが少し異なります。
自己署名証明書そのものの作り方は本ブログでは扱いませんが、手順は OpenSSL のコマンドリファレンス( openssl-req / openssl-x509 )を参考にしてください。
| 配布先 | 接続方式 | 配布するもの | 配布後の状態 |
|---|---|---|---|
| Linux Node | SSH | 証明書・秘密鍵・CA 証明書 | httpd(mod_ssl)が HTTPS を終端 |
| Windows Node | WinRM | PFX(証明書+秘密鍵の束) | IIS が HTTPS を終端 |
Linux と Windows で配布物が違うのは、各サーバーが証明書を取り込む形式に合わせているためです。
Linux の httpd は証明書ファイルと秘密鍵ファイルを個別に参照します。
Windows の IIS は証明書と秘密鍵をまとめた PFX(PKCS#12)で取り込むのが扱いやすいため、同じ鍵素材から PFX も作っておきます。
配布の前に接続を確認する
配布先の接続情報は、あらかじめインベントリにまとめてあります。
インベントリには、Linux へ SSH で接続するための定義と、Windows へ WinRM で接続するための定義が書かれています。
Linux は秘密鍵を使って接続し、Windows はポート 5986 の WinRM で接続します。
Windows の接続パスワードはインベントリに平文で書かず、実行時に環境変数から読み込む形にしています。
このため、接続確認の前に環境変数へパスワードを渡しておく必要があります。
本番の Playbook を流す前に、ping で「対象と通信できて、処理を実行できる状態か」を確認します。
Linux と Windows でモジュールが異なります。
ansible linux -m ansible.builtin.ping
ansible windows -m ansible.windows.win_ping
ansible.builtin.ping は SSH で接続でき、対象上で Python が実行できることを確認します。
ansible.windows.win_ping は WinRM で接続でき、対象上で PowerShell が実行できることを確認します。
両方が SUCCESS で pong を返せば、配布に進める状態です。

Linux への配布
Linux への配布 Playbook は、SSH で接続して証明書・秘密鍵・CA 証明書を所定の場所へ配置し、httpd の HTTPS を有効化します。
証明書を OS の所定ディレクトリへ置き httpd を操作するため、root 権限で実行します。
配布は下記のコマンドで実行します。
ansible-playbook -i inventory playbooks/deploy_cert_linux.yml
配置と Handler
この Playbook では、証明書・秘密鍵・SSL 設定ファイルを配置する各処理に「変更があったら httpd を reload する」という通知(notify)を付けています。これが notify と Handler の実演です。
証明書・秘密鍵・設定のどれかが実際に変わったときだけ、処理の最後に httpd が1回だけ reload されます。
複数のファイルを配置してすべてが同じ reload を通知しても、reload は1回にまとまります。

冪等性の確認
同じコマンドをもう一度実行すると、ファイルはすでに配置済みなので変更が発生しません。
changed が出ず、reload httpd も実行されません。これが 冪等性 です。

配布結果の確認
配布後、Linux Node は httpd で HTTPS を終端します。
配布した証明書が実際に提示されているかは、下記で確認できます。
openssl s_client -connect <Linux サーバーの IP アドレス>:443 </dev/null 2>/dev/null \
| openssl x509 -noout -subject -issuer -dates

Windows への配布
Windows への配布 Playbook は、WinRM で接続して PFX を配置し、証明書ストアへインポートして IIS の HTTPS バインドを設定します。
接続した Administrator の権限でそのまま処理します。
配布は下記のコマンドで実行します。
ansible-playbook -i inventory playbooks/deploy_cert_windows.yml
PFX のインポートとバインド
処理は3ステップです。
| ステップ | 内容 |
|---|---|
| PFX を配置 | PFX を Windows 上へ転送する |
| 証明書ストアへインポート | LocalMachine の証明書ストアへ取り込む |
| IIS へバインド | 既定サイトの 443 へ証明書を紐付ける |
証明書ストアへのインポートと IIS バインドの Task には notify: restart iis を付けています。
Linux と同じく、 変わったときだけ IIS を再起動する 動きです。

配布結果の確認
配布後、Windows Node は IIS で HTTPS を終端します。
ブラウザーまたは openssl で、配布した証明書が提示されることを確認できます。

秘密鍵をログに出さない工夫
証明書の配布では秘密鍵や PFX を扱います。これらが実行ログに平文で出ると危険です。
そこで、秘密鍵や PFX を扱う処理には、引数と結果をログに出さない設定(no_log)を付けています。
配布の自動化では秘密情報を扱う場面が多いため、どの処理に秘密が乗るかを意識して設定しておきます。
まとめ
本ブログの要点は下記のとおりです。
- Ansible はエージェントレスで、Linux へは SSH、Windows へは WinRM で接続して証明書を配布します
- 配布前に ping / win_ping で「操作できる状態か」を確認してから本番を流します
- Linux は証明書ファイルと秘密鍵を、Windows は PFX を配布し、それぞれ httpd と IIS が HTTPS を終端します
- notify と Handler により、証明書が変わったときだけサービスを reload / restart します
- 2回目の実行は変更が出ず、冪等性が効いていることを確認できます
- 秘密鍵や PFX を扱う Task には no_log を付け、ログに平文を残しません
次は、同じ証明書を AWS Certificate Manager(ACM)へインポートし、Application Load Balancer(ALB)で HTTPS 公開して、端から端まで暗号化する経路を見ていきます。
最後までお読みいただきありがとうございました。
参照ドキュメント
- Ansible Documentation
- ansible.builtin.copy module
- ansible.windows.wincertificatestore module
- Handlers: running operations on change
- Windows Remote Management
この記事は私が書きました
髙井 大暉
記事一覧頑張ってインフラエンジニアやってます。