Ansibleは、今日の最も一般的な設定管理ツールの1つとなっています。Ansibleは、DevOpsエンジニアやシステムエンジニア/管理者が全ての環境でインフラストラクチャを適用・維持するための便利な(そしてほとんどの場合無料の)ツールです。ただし、AnsibleをWindowsとWinRM経由で連携する設定は、課題となるかもしれません。
他のインフラストラクチャコンポーネントと同様に、AnsibleはWindowsホストに対して設定状態を展開・維持することができます。AnsibleはWinRM経由でこれらのWindowsホストに接続しますが、SSHを試験的に使用している場合もあります。
AnsibleのWinRMの設定では、セットアップの容易さやセキュリティ上の影響など、いくつかの異なるオプションがあります。多くの人々は簡単な方法を選択します。HTTPを用いた基本認証。証明書に関連する追加作業を省くことはできますが、必要がない限り、ネットワーク上で暗号化されていないデータを送信するのは良いアイデアではありません。
この記事では、自己署名証明書を使用した証明書ベースの認証を使用して、AnsibleがWinRmと通信できるようにする方法について学びます。
このチュートリアルで学ぶセットアップは、Ansibleクライアントに限らず、他のWindowsホストなどのWinRmクライアントにも同様に適用できます。
前提条件
この記事はチュートリアル形式の手順書です。WinRmをAnsibleに設定するためにここで提示された手順に従う意図がある場合、以下の前提条件があるものとします。
- LinuxホストにAnsibleがすでにインストールされていること。
- Windowsホストに基づいたAnsibleインベントリが設定されていること。
- 管理するためのWindows Server 2016以降のサーバーがあること。このチュートリアルで使用される一部のコマンドレットは、古いバージョンのWindowsでは動作しません。
- Windowsホストがドメインに属していないこと。例はドメインに参加していないホストで実行されたものですが、この構成はドメインに参加しているホストでも動作するはずです。
- WindowsホストにRDPまたはコンソールアクセスがあり、ローカル管理者としてログインしていること。
- PowerShellに精通していること。ほとんどの例では、PowerShellコードを使用してWindowsホスト上で変更を行います。
各セクションは、前のセクションに依存するコードスニペットを使用します。一部のスニペットは、以前に定義された変数を参照します。このコードをコピー&ペーストする際には、コンソールを開いたままにしておいてください。
説明なしでコードだけが必要な場合は、このGitHubのgistをダウンロードしてください。
AnsibleのWinRmのためにPowerShellリモートを有効にする
すべてのWindows Server 2016以降のサーバーには、PowerShellリモートが有効になっていますが、確認することは常に良いアイデアです。
管理するWindowsホストで、管理者としてPowerShellコンソールを開き、次のコードスニペットを実行します。このコードスニペットは、WinRmサービスが起動しており、システムの起動時に自動的に開始されるようにします。
次に、PowerShellリモートが有効になっていることを確認するために、まずアクティブなセッション構成があるかどうかをチェックします。それがない場合は、リスナーが利用可能でないことを確認します。AnsibleのWinRmには、少なくとも1つのリスナーが必要です。これらの条件のいずれかが何も返さない場合は、Enable-PSRemoting
を実行してください。

証明書ベースの認証を有効にする
デフォルトでは、WinRMは証明書ベースの認証に設定されていません。以下のようにWSManを設定して有効にする必要があります。
ローカルユーザーアカウントの作成
Ansibleの認証には証明書ベースのWinRMを使用するため、ローカルユーザーアカウントを証明書に「マップ」する必要があります。これにはローカル管理者アカウントを使用することもできますが、管理を容易にするために特定のアカウントを作成することをお勧めします。
次のコードスニペットは、WinRm for Ansible用のローカルユーザーアカウントansibletestuser
を作成し、存在しない場合はパスワードp@$$w0rd12
を設定します。常にアクティブな状態に保つため、このアカウントのパスワードは期限切れになりません。
クライアント証明書の作成
Ansible用のWinRm(安全に)では、クライアント証明書とサーバー証明書の2つの証明書が必要です。
クライアント/サーバーの両方に同じ証明書を使用することもできますが、このアプローチでは問題が発生する可能性があります。Ansibleのドキュメントや他の多くの情報源では、PowerShellの
New-SelfSignedCert
コマンドレットを使用してクライアント証明書を生成する方法が説明されています。この方法でも動作するかもしれませんが、私は簡単に動作させることができませんでした。
WinRM for Ansibleのクライアント証明書を作成するには、プライベートキーとパブリックキーを作成する必要があります。まず、AnsibleホストにSSHで接続し、以下のopenssl
コマンドを実行します。このコマンドは、cert_key.pemという名前のファイルにプライベートキーを作成し、cert.pemという名前の公開キーを作成します。キーの使用法は、クライアント認証(1.3.6.1.4.1.311.20.2.3)で、以前に作成したansibletestuserという名前のローカルユーザーアカウントに「マップされます。」。
Ansible WinRM認証への一歩近づきました!
クライアント証明書のインポート
AnsibleのWinRM用クライアント証明書を作成したら、WinRMが動作するWindowsホストの2つの証明書ストアにインポートする必要があります。そのためには、まずcert.pem公開キーをWindowsホストに転送します。以下の例では、キーがC:\cert.pemに存在すると仮定しています。
Windowsホストに公開証明書がある場合は、以下のようにImport-Certificate
を使用して、信頼されたルート証明機関と信頼された人々の証明書ストアにインポートします。
サーバー証明書の作成
AnsibleのWinRMには、サーバー認証のためにキー使用法が定義された証明書が必要です。この証明書は、WindowsホストのLocalMachine\My証明書ストアに保存されます。以下のコードスニペットを使用して、自己署名証明書を作成します。
Ansible WinRmリスナーを作成します。
両方の証明書を作成したら、Windowsホスト上にWinRmリスナーを作成する必要があります。このリスナーは、着信接続のためにポート5986でリッスンを開始します。作成されると、このリスナーは着信接続を受け入れ、上記で作成したサーバー証明書を使用してデータを暗号化しようとします。
PowerShellリモーティングは、認証が行われるとこのWinRMリスナーを転送先として使用します。
以下のコードスニペットでは、既存のHTTPSリスナーの存在を確認する良い例が示されています。上記で作成したサーバー証明書を使用したリスナーが見つからない場合、新しいリスナーが作成されます。
クライアント証明書をローカルユーザーアカウントにマップ
次のステップは、Ansibleがサーバー証明書を使用してWindowsホストに接続する際に、すべての指示をローカルユーザーアカウントで実行することを確認することです。この場合、AnsibleのためにWinRmが実行するすべてのアクティビティは、ansibletestuserというローカルユーザーアカウントを使用します。
AnsibleでUser Account Control(UAC)を使用してWinRMを許可する
証明書をマップするためにローカルアカウントを使用する場合、LocalAccountTokenFilterPolicy
を1に設定する必要があります。これにより、UACが邪魔にならないようにします。 LocalAccountTokenFilterPolicy
はすべてのローカルアカウント(ドメインアカウントではない)に適用され、ネットワークログオンがトークンの制限部分になるため、Windowsはそれを管理者として認識しないため、WinRMはデフォルトではユーザーがローカル管理者である必要があります。
LocalAccountTokenFilterPolicy
を設定することで、Windowsに対してローカルアカウントによるネットワークログオンのための制限トークンを作成しないようにし、フルトークンを使用するように指示しています。
Windowsファイアウォールでポート5986を開く
WinRm over HTTPSはポート5986を使用します。Windowsファイアウォールが有効になっている場合は、このポートを開く必要があります。次のPowerShellコードスニペットを実行することで開くことができます。このコードスニペットは非常に緩い設定であり、すべてのコンピュータが使用できるようになっています。さらに制限する場合は、LocalAddress
パラメータを使用してAnsibleのIPを指定してください。
ローカルユーザーを管理者グループに追加する
このチュートリアルで最初からローカルユーザーを管理者グループに追加しなかった理由について疑問に思うかもしれません。その理由は、クライアント証明書をユーザーにマッピングしようとする際、ユーザーアカウントがローカル管理者であってはならないという不明な理由があるためです。
次のコードスニペットを実行して、ansibletestuserというローカルユーザーアカウントを管理者グループに追加します。
結論
これらの手順を正確に実行した場合、Windowsホストに対してAnsibleコマンドを実行することができるようになります。テストにはwin_shellモジュールを使用してください。このモジュールが成功した場合、Ansibleと証明書ベースの認証が正常に設定されています!