AnsibleのWindows管理入門|WinRM設定とansible.windows collectionで混在環境を自動化する方法

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Ansible > AnsibleのWindows管理入門|WinRM設定とansible.windows collectionで混在環境を自動化する方法
「LinuxサーバーはAnsibleで管理しているが、Windows Serverだけは手作業のまま残っている」
インフラを自動化していても、社内に数台ある 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でサービス・パッケージ・ファイルを一括管理できる


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
図解60P/登録10秒/解除も3秒 / 詳細はこちら

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)"

Linux コントロールノード側からも接続前にポート疎通を確認しておくと便利です。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 の問題なのかが切り分けにくくなるため、必ずここで疎通を確認してから次に進みましょう。
WindowsとLinuxが混在するインフラの自動化設計を体系的に身につけたい方へ、20年以上の運用経験を持つ現役エンジニアが基礎から教えます。
Ansible実践ハンズオンの詳細を見る >>

ansible.windows collection の主要モジュール

ansible パッケージをインストールすると ansible.windows collection は標準で含まれます。個別にインストールする場合は次のコマンドを使います。

ansible-galaxy collection install ansible.windows

1. win_service で Windows サービスを管理する

ansible.windows.win_serviceansible.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

パスの区切り文字はバックスラッシュでも、スラッシュでも Ansible 内部では動作します。Playbook の可読性のためにスラッシュで統一している現場もあります。

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.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

Playbook を実行した時の実機出力はこのとおりです(検証サーバー win-server01 で確認)。

$ 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

2 回目に同じ Playbook を実行すると、冪等性が正しく機能していれば全タスクが 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..." }

NTLM 認証が有効でない:Windows 側で winrm get winrm/config/service/auth を実行し、Negotiate = true になっているか確認する。無効なら winrm set winrm/config/service/auth @{Negotiate="true"} で有効化する
ユーザー名・パスワードが間違っている:インベントリの ansible_useransible_password(Vault 変数)を確認する
ローカルアカウントへの UAC 制限:ローカル管理者は WinRM 経由でフルアクセスが制限される場合がある。LocalAccountTokenFilterPolicy1 に設定することで解消できる(前節の 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 の Windows 管理で最初に覚えてほしいことは「WinRM は Windows における SSH」と捉えることです。SSH で Linux を管理するのと同じ感覚で、WinRM 経由で Windows を管理できます。コントロールノード側に pywinrm をインストールし、インベントリに ansible_connection: winrm を設定するだけで、Linux 向けの Playbook 構造がそのまま使えます。

Linux サーバーと Windows Server が共存するインフラを Ansible で一元管理できるようになると、構成管理の抜け漏れが大幅に減ります。まずは検証サーバーで HTTP(5985)+NTLM 認証から試してください。本番環境へ移行する際には必ず HTTPS(5986)+ Kerberos に切り替えること。HTTP(5985)のまま本番で使うと通信が平文になるため注意が必要です。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、20年以上の運用経験を持つ現役エンジニアが基礎から教えます。
Ansible実践ハンズオンの詳細を見る >>

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

登録10秒/合わなければ解除3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。