インフラを自動化していても、社内に数台ある Windows Server だけが Ansible の管理外に置かれてしまうケースは多くあります。「Windows は別のツールが必要では」と思われがちですが、Ansible は Linux と同じ Playbook 形式で Windows Server を自動管理できます。
この記事では、Ansible から Windows Server を管理するための接続設定(WinRM)と、ansible.windows collection の主要モジュールの使い方を解説します。WinRM 有効化・インベントリ設定・認証方式の選択から、win_service・win_package・win_copy の実践例まで、RHEL 10 / Rocky Linux 9 のコントロールノードと Windows Server 2022 ターゲットの環境で動作確認しています。
この記事のポイント
・AnsibleはWinRM(ポート5985/5986)でWindows Serverに接続して管理できる
・Windows側でEnable-PSRemoting -Forceを実行してWinRMを有効化する
・インベントリにansible_connection: winrmを設定するだけで既存のPlaybook形式が使える
・win_service・win_package・win_copyでサービス・パッケージ・ファイルを一括管理できる
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
AnsibleがWindowsを管理できる仕組み|WinRMとは
Ansible が Linux を管理するとき、通信の下回りは SSH です。Windows には SSH が標準で有効になっていない(Windows Server 2019 以降は OpenSSH オプションで選択可能ですがデフォルト無効)ため、代わりに WinRM(Windows Remote Management) が使われます。WinRM は Microsoft が策定したリモート管理プロトコルで、SOAP/HTTP をベースにしています。PowerShell のリモーティング(
Invoke-Command -ComputerName)も内部では WinRM を使っており、Windows Server 2008 R2 以降で利用できます。Ansible との関係を整理するとこうなります。
・Linux ターゲット:Ansible コントロールノードが SSH で接続 → Python を実行
・Windows ターゲット:Ansible コントロールノードが WinRM で接続 → PowerShell を実行
Windows ターゲットに Python は不要です。Ansible が WinRM 経由で PowerShell スクリプトを送り込んで実行するため、ターゲット側の準備は「WinRM を有効化する」だけです。Linux サーバーと Windows サーバーが混在するインフラでも、同じ Playbook 構造(vars・roles・handlers・Jinja2 テンプレート)をそのまま使えます。なお、Windows ファイル共有を Samba 経由で行う構成とは異なり、Ansible WinRM は OS の構成変更・ソフトウェア管理・サービス制御に特化した自動化アプローチです(Samba によるファイル共有設定はこちら)。
WinRM の接続方式を選ぶ|HTTP・HTTPS と認証の関係
WinRM には 2 つのポートがあります。・ポート 5985(HTTP):通信は暗号化されないが設定が簡単。社内テスト環境や VPC 内のプライベートネットワークで使う
・ポート 5986(HTTPS):通信を TLS で暗号化。本番環境での推奨構成
認証方式も複数あります。
・NTLM:ドメイン不要。ローカル管理者アカウントで認証できる。テスト環境で最も設定が簡単
・Kerberos:Active Directory ドメイン環境で推奨。ドメインアカウントを使った安全な認証が可能
・Basic:シンプルだが平文送信のリスクがあるため HTTPS と必ず組み合わせること
・Certificate:クライアント証明書で認証する。高セキュリティ要件の本番環境向け
現場での典型的な選択はこのとおりです。
・検証サーバー / プライベートネット内:HTTP(5985)+ NTLM → pywinrm だけで動き設定が最小
・本番環境:HTTPS(5986)+ Kerberos → AD ドメイン設計と一体で考える
この記事では検証サーバー向けの HTTP(5985)+ NTLM 構成を中心に手順を進めます。
WinRM を有効化する手順|Windows Server 側の準備
1. PowerShell で WinRM を有効化する
Windows Server に管理者権限で PowerShell を起動し、次のコマンドを実行します。# WinRM リスナーを有効化(HTTP・ポート 5985 でリスナーが作られる) Enable-PSRemoting -Force # 実行後にリスナーを確認 winrm enumerate winrm/config/listener # 出力例(Windows Server 2022 実機) Listener Address = * Transport = HTTP Port = 5985 Hostname Enabled = true URLPrefix = wsman CertificateThumbprint ListeningOn = 192.168.xxx.xxx, 127.0.0.1
Enable-PSRemoting -Force を実行すると次の処理が自動で行われます。・WinRM サービスの起動と自動起動設定
・HTTP リスナー(ポート 5985)の作成
・Windows ファイアウォールの例外追加(ドメインおよびプライベートプロファイル)
パブリックネットワークプロファイルのサーバーでエラーが出るときは、
Set-NetConnectionProfile でプロファイルを「Private」に変更してから再実行してください。2. ファイアウォールのポート開放を確認する
# ポート 5985 の受信規則を確認する Get-NetFirewallRule -DisplayName "*Windows Remote Management*" # ルールが無効の場合は有効化する Enable-NetFirewallRule -DisplayName "Windows Remote Management (HTTP-In)"
ss コマンドや nc で Windows ターゲットのポート 5985 への到達性を確かめてください(Linux でのポート確認コマンドの全手順はこちら)。3. コントロールノードに pywinrm をインストールする
Ansible コントロールノード(Linux 側)には、WinRM クライアントライブラリpywinrm が必要です。# pywinrm をインストール(RHEL 10 / Rocky Linux 9 の場合) pip3 install pywinrm # インストール確認 python3 -c "import winrm; print(winrm.__version__)" # 出力例: 0.4.3 # Kerberos 認証を使う場合は追加でインストール pip3 install pywinrm[kerberos]
インベントリと ansible.cfg の設定
1. YAML インベントリに Windows 接続変数を記述する
Windows ターゲットのインベントリファイルに、WinRM 接続専用の変数を設定します。# inventory/hosts.yml all: children: windows: hosts: win-server01: ansible_host: 192.168.1.100 win-server02: ansible_host: 192.168.1.101 vars: ansible_user: Administrator ansible_password: "{{ vault_windows_password }}" ansible_connection: winrm ansible_winrm_transport: ntlm ansible_port: 5985 ansible_winrm_server_cert_validation: ignore # テスト環境のみ
・ansible_connection: winrm:Windows への WinRM 接続を明示的に指定
・ansible_winrm_transport: ntlm:NTLM 認証(Active Directory ドメイン不要)
・ansible_port: 5985:HTTP リスナーのポート番号(本番環境は 5986)
・ansible_winrm_server_cert_validation: ignore:自己署名証明書の検証をスキップ(テスト環境限定)
パスワードは平文で書かずに Ansible Vault で暗号化した変数を渡してください。
vault_windows_password のように変数名でラップして ansible-vault で管理するのが定石です。2. 接続テストで WinRM 疎通を確認する(実機出力例)
インベントリとコントロールノードの設定が完了したら、win_ping モジュールで接続を確認します。# ansible コマンドで win_ping を実行 $ ansible windows -m ansible.windows.win_ping -i inventory/hosts.yml # 接続成功時の出力例(検証サーバー 192.168.1.100/101 で確認) win-server01 | SUCCESS => { "changed": false, "ping": "pong" } win-server02 | SUCCESS => { "changed": false, "ping": "pong" }
pong が返れば WinRM 接続・NTLM 認証ともに成功です。この確認を飛ばして Playbook を実行すると、接続問題なのか Playbook の問題なのかが切り分けにくくなるため、必ずここで疎通を確認してから次に進みましょう。
Ansible実践ハンズオンの詳細を見る >>
ansible.windows collection の主要モジュール
ansible パッケージをインストールすると ansible.windows collection は標準で含まれます。個別にインストールする場合は次のコマンドを使います。ansible-galaxy collection install ansible.windows
1. win_service で Windows サービスを管理する
ansible.windows.win_service は ansible.builtin.service の Windows 版です。Windows サービスの起動・停止・自動起動設定を行います。# IIS(W3SVC)を起動して自動起動を有効にする - name: IIS サービスを起動・自動起動に設定する ansible.windows.win_service: name: W3SVC state: started start_mode: auto # SQL Server エージェントを停止する - name: SQL Server エージェントサービスを停止する ansible.windows.win_service: name: SQLSERVERAGENT state: stopped start_mode: manual
2. win_file と win_copy でファイル・ディレクトリを操作する
# ディレクトリを作成する - name: アプリケーションログディレクトリを作成する ansible.windows.win_file: path: C:\App\logs state: directory # Linux 側のファイルを Windows サーバーにコピーする - name: 設定ファイルをコピーする ansible.windows.win_copy: src: files/app.config dest: C:\App\config\app.config
3. win_package でソフトウェアをインストールする
ansible.windows.win_package は MSI・EXE インストーラーを扱うモジュールです。# 7-Zip をサイレントインストールする - name: 7-Zip をインストールする ansible.windows.win_package: path: \\nas01\packages\7z2301-x64.msi state: present arguments: /quiet /norestart # インストール状態を確認する(product_id はアプリ名または GUID) - name: 7-Zip のインストール状態を確認する ansible.windows.win_package: product_id: 7-Zip state: present
chocolatey.chocolatey.win_chocolatey モジュールが適しています。chocolatey.chocolatey collection を別途インストールすることで利用できます。4. win_regedit でレジストリを管理する
Windows 固有の自動化としてレジストリの管理があります。ansible.windows.win_regedit を使います。# ローカル管理者の UAC リモートトークンフィルタリングを無効にする # (NTLM 認証でフルアクセスが必要な場合に設定) - name: LocalAccountTokenFilterPolicy を有効にする ansible.windows.win_regedit: path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System name: LocalAccountTokenFilterPolicy data: 1 type: dword
実践 Playbook|IIS セットアップを自動化する
ここまでのモジュールを組み合わせた実践的な Playbook 例を示します。IIS のインストール・サービス起動・ドキュメントルートの準備を一気通貫で行います。# playbook/setup-iis.yml --- - name: IIS セットアップ hosts: windows tasks: - name: IIS の Windows 機能をインストールする ansible.windows.win_feature: name: Web-Server state: present include_management_tools: yes - name: IIS サービスを起動して自動起動に設定する ansible.windows.win_service: name: W3SVC state: started start_mode: auto - name: アプリケーションのドキュメントルートを作成する ansible.windows.win_file: path: C:\inetpub\wwwroot\myapp state: directory - name: index.html をコピーする ansible.windows.win_copy: src: files/index.html dest: C:\inetpub\wwwroot\myapp\index.html
$ ansible-playbook playbook/setup-iis.yml -i inventory/hosts.yml PLAY [IIS セットアップ] ********************************** TASK [Gathering Facts] *********************************** ok: [win-server01] TASK [IIS の Windows 機能をインストールする] ************** changed: [win-server01] TASK [IIS サービスを起動して自動起動に設定する] ********** changed: [win-server01] TASK [アプリケーションのドキュメントルートを作成する] **** changed: [win-server01] TASK [index.html をコピーする] *************************** changed: [win-server01] PLAY RECAP *********************************************** win-server01 : ok=5 changed=4 unreachable=0 failed=0 skipped=0
changed=0 になります。win_feature は IIS インストール済みを検出してスキップし、win_service は既に起動中のサービスに対して変更なし扱いになります。トラブルシュート|WinRM 接続エラーへの対処法
1. 「UNREACHABLE」で WinRM に繋がらない時
# エラーメッセージ例 win-server01 | UNREACHABLE! => { "changed": false, "msg": "winrm connection error: ...[WinError 10061] 接続が拒否されました", "unreachable": true }
・WinRM サービスが停止している:Windows 側で
Get-Service WinRM を確認し、Start-Service WinRM で起動する・ファイアウォールでブロックされている:Windows のファイアウォールでポート 5985/5986 が開放されているか確認する
・IP アドレスが間違っている:インベントリの
ansible_host 値と実際の IP を照合する2. 「AuthenticationError」で認証に失敗する時
# エラーメッセージ例 win-server01 | UNREACHABLE! => { "msg": "...(401) Unauthorized..." }
winrm get winrm/config/service/auth を実行し、Negotiate = true になっているか確認する。無効なら winrm set winrm/config/service/auth @{Negotiate="true"} で有効化する・ユーザー名・パスワードが間違っている:インベントリの
ansible_user と ansible_password(Vault 変数)を確認する・ローカルアカウントへの UAC 制限:ローカル管理者は WinRM 経由でフルアクセスが制限される場合がある。
LocalAccountTokenFilterPolicy を 1 に設定することで解消できる(前節の win_regedit タスク例を参照)3. SSL 証明書エラーが出る時(HTTPS・5986 使用時)
# エラーメッセージ例 msg: "...[SSL: CERTIFICATE_VERIFY_FAILED]..."
ansible_winrm_server_cert_validation: ignore でスキップできます。本番環境では正規の TLS 証明書を Windows Server に設定するか、社内認証局(CA)の証明書を Ansible コントロールノードに信頼させてください(DNS と証明書の CN/SAN 名前解決が必要な場合はこちら)。本記事のまとめ
| やりたいこと | コマンド/設定 |
|---|---|
| Windows で WinRM を有効化する | Enable-PSRemoting -Force |
| WinRM リスナーを確認する | winrm enumerate winrm/config/listener |
| コントロールノードに pywinrm をインストールする | pip3 install pywinrm |
| Windows への接続テストをする | ansible windows -m ansible.windows.win_ping -i hosts.yml |
| Windows サービスを起動・自動起動設定する | ansible.windows.win_service: name: W3SVC state: started |
| MSI インストーラーでソフトをインストールする | ansible.windows.win_package: path: xxx.msi state: present |
ansible_connection: winrm を設定するだけで、Linux 向けの Playbook 構造がそのまま使えます。Linux サーバーと Windows Server が共存するインフラを Ansible で一元管理できるようになると、構成管理の抜け漏れが大幅に減ります。まずは検証サーバーで HTTP(5985)+NTLM 認証から試してください。本番環境へ移行する際には必ず HTTPS(5986)+ Kerberos に切り替えること。HTTP(5985)のまま本番で使うと通信が平文になるため注意が必要です。
Ansible実践ハンズオンの詳細を見る >>
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
登録10秒/合わなければ解除3秒 / 詳細はこちら
- 前のページへ:Ansibleのimport_tasksとinclude_tasksの違いと使い分け|静的・動的読み込みの設計判断
- この記事の属するカテゴリ:Ansibleへ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。
登録無料・いつでも解除できます