はじめに

前回でAnsibleを使ってWindowsを操作する準備はできた。
今回は実践として、Windows用のパッケージマネージャChocolateyのインストールと、Chocolateyを使ったアプリケーションのインストールを行いながら、AnsibleがWindowsに対してできることを見ていくことにする。

環境は前回と同じ、Ansible 1.7.1でWindows 8.1 Updateを操作している。

使用しているインベントリファイルを再掲する。

hosts
[windows]
10.0.2.172

[windows:vars]
ansible_ssh_user=<Windows側のユーザ名>
ansible_ssh_pass=<Windows側ユーザのパスワード>
ansible_ssh_port=5986
ansible_connection=winrm

win_chocolateyモジュール(Ansible 1.9以降)

Ansible 1.9よりExtras Moduleとしてwin_chocolateyモジュールが追加された。
そのため、この文書の次項以降の作業は不要となった。

2015-06-27追記: Windows側にChocolatey 0.9.9以降がインストールされた場合、chocolateyの仕様変更にAnsible 1.9.2までに同梱されているwin_chocolateyモジュールが対応できておらず正常に終了しない。簡単な対処としてはwin_chocolateyモジュールをdevelにあるものに差し替えることである。

# curl https://raw.githubusercontent.com/ansible/ansible-modules-extras/devel/windows/win_chocolatey.ps1 -o /usr/lib/python2.7/site-packages/ansible/modules/extras/windows/win_chocolatey.ps1
# curl https://raw.githubusercontent.com/ansible/ansible-modules-extras/devel/windows/win_chocolatey.py -o /usr/lib/python2.7/site-packages/ansible/modules/extras/windows/win_chocolatey.py

以下のようなplaybookでWindowsアプリをインストールできる。
Chocolatey自体も最初にwin_chocolateyモジュールを使った時に自動的にインストールされる。

site.yml
- hosts: windows
  tasks:
  - win_chocolatey: name={{ item }}
    with_items:
    - SourceTree
    - sysinternals

Windowsに対して使用できるAnsibleモジュール

現状、Ansibleに用意されたモジュールのほとんどがWindowsに対して使用することができない。使用できるのは公式ドキュメントによると、

および、Windows用に追加されたモジュール

2016-02-27追記: Ansible 2.0時点ではwin_*モジュールはもっと大量に増えている。

他にdebug等、操作する側でしか処理が行われないモジュールは使用できることを確認している。

つまり現状、Windows環境にファイルを受け渡す方法が、どこか適当なWebサーバにアップロードしてからwin_get_urlでダウンロードする以外にないようだ。
(SSHサーバやrsyncサーバなどがWindows側に立っていたりはしない前提で)

アプリの設定ファイルなんかも作りたければ、templateやlineinfile、ini_fileで作った設定ファイルをWebサーバにアップロードしてからwin_get_urlでダウンロードしろ、あるいはこれらのモジュールで動的に作ったPowerShellスクリプトをscriptで流し込め、ということになるのだろう。

chocolateyのインストール

rawモジュールを使用する

使用できるモジュールが上記の通りだけ、ということはrawモジュールが大活躍するに違いない、というわけでまずrawモジュールを使用する。

まずChocolatey公式の、PowerShellを使ってインストールする時に実行するコマンドを流してみる。

(見やすいようにコマンドと出力を1行開けている)

# ansible windows -i hosts -m raw -a 'iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))'

10.0.2.172 | FAILED | rc=1 >>
'iex' is not recognized as an internal or external command,
operable program or batch file.

エラーになった。
結局試した限りどんなPowerShellコマンド(「コマンドレット」と呼ぶ)もrawモジュールで流すとエラーになる、という結論になった。

2016-02-27追記: いつからなのかは調べていないが、Ansible 2.0.1で試す限りPowerShellコマンドがエラーにならず実行されるようだ。上のコマンドも-aの囲みを””にすれば通る。

今度はコマンドプロンプトからChocolateyをインストールする時に実行するコマンドを流してみよう。

# ansible windows -i hosts -m raw -a '@powershell -NoProfile -ExecutionPolicy unrestricted -Command "iex ((new-object net.webclient).DownloadString("https://chocolatey.org/install.ps1"))" && SET PATH=%PATH%;%ALLUSERSPROFILE%chocolateybin'

10.0.2.172 | success | rc=0 >>
(以下省略)

というわけでこちらでは問題なくChocolateyをインストールできた。

scriptモジュールを使用する

rawモジュールでできないPowerShellコマンドを実行したければscriptモジュールを使えば良い。
上記のPowerShell用のインストールコマンドを書いたps1ファイルを作る。

chocolatey.ps1
iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))

そしてscriptモジュールで流し込む。

# ansible windows -i hosts -m script -a 'chocolatey.ps1'

10.0.2.172 | success >> {
    "changed": true,
    "rc": 0,
    "stderr": "",
    "stdout": (以下省略)

問題ない。

scriptモジュールには、ファイルがある時には実行しないcreatesオプションがあるので試してみる。

# ansible windows -i hosts -m script -a 'chocolatey.ps1 creates=C:ProgramDatachocolateybinchocolatey.exe'
10.0.2.172 | success >> {
    "changed": true,
    "rc": 0,
    "stderr": "",
    "stdout": (以下省略)

「”changed”: true」になっている、ということは効いていない。
ファイルがない時には実行しないオプションremovesも同様であった。

ここで期待した通りのことをしたければwin_statモジュールを使用する。
Playbookを作って実行する。

site.yml
- hosts: windows
  tasks:
    - win_stat: path=C:ProgramDatachocolateybinchocolatey.exe
      register: file_info
    - script: chocolatey.ps1
      when: file_info.stat.exists == false
# ansible-playbook -i hosts site.yml

PLAY [windows] ****************************************************************

GATHERING FACTS ***************************************************************
ok: [10.0.2.172]

TASK: [win_stat path=C:ProgramDatachocolateybinchocolatey.exe] ************
ok: [10.0.2.172]

TASK: [script chocolatey.ps1] *************************************************
skipping: [10.0.2.172]

PLAY RECAP ********************************************************************
10.0.2.172                 : ok=2    changed=0    unreachable=0    failed=0

今度は期待通り「skipping」になった。

Windowsアプリのインストール

Chocolateyのパッケージインストール用のコマンドであるcinstはコマンドプロンプトでも実行できるのでrawモジュールを使うことができる。
先程のPlaybookに追加して実行することにする。

2015-06-27追記: Chocolatey 0.9.9以降、cinstに-yオプションを付けないとすぐにインストールしてくれなくなった。それより前のバージョンでは-yは必要ない。

site.yml
- hosts: windows
  tasks:
    - win_stat: path=C:ProgramDatachocolateybinchocolatey.exe
      register: file_info
    - script: chocolatey.ps1
      when: file_info.stat.exists == false
    - raw: cinst {{ item }} -y
      with_items:
        - SourceTree
        - sysinternals
# ansible-playbook -i hosts site.yml

PLAY [windows] ****************************************************************

GATHERING FACTS ***************************************************************
ok: [10.0.2.172]

TASK: [win_stat path=C:ProgramDatachocolateybinchocolatey.exe] ************
ok: [10.0.2.172]

TASK: [script chocolatey.ps1] *************************************************
skipping: [10.0.2.172]

TASK: [raw cinst {{ item }}] **************************************************
ok: [10.0.2.172] => (item=SourceTree)
ok: [10.0.2.172] => (item=sysinternals)

PLAY RECAP ********************************************************************
10.0.2.172                 : ok=3    changed=0    unreachable=0    failed=0

問題なくアプリケーションをインストールできた。

まとめ

Ansible 1.7.1時点での、今回使用したモジュールのまとめ。

  • rawモジュールではPowerShellコマンドを流すとエラーになり、コマンドプロンプトで実行できるものだけが実行できる。PowerShellコマンドを流すにはscriptモジュールを使用する。
  • scriptモジュールのcreatesオプション、removesオプションはWindowsに対しては利用できない。win_statモジュールを利用して同等のことはできる。
TOP