はじめに
前回でAnsibleを使ってWindowsを操作する準備はできた。
今回は実践として、Windows用のパッケージマネージャChocolateyのインストールと、Chocolateyを使ったアプリケーションのインストールを行いながら、AnsibleがWindowsに対してできることを見ていくことにする。
環境は前回と同じ、Ansible 1.7.1でWindows 8.1 Updateを操作している。
使用しているインベントリファイルを再掲する。
[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モジュールを使った時に自動的にインストールされる。
- 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%\chocolatey\bin'
10.0.2.172 | success | rc=0 >>
(以下省略)
というわけでこちらでは問題なくChocolateyをインストールできた。
scriptモジュールを使用する
rawモジュールでできないPowerShellコマンドを実行したければscriptモジュールを使えば良い。
上記のPowerShell用のインストールコマンドを書いた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:\ProgramData\chocolatey\bin\chocolatey.exe'
10.0.2.172 | success >> {
"changed": true,
"rc": 0,
"stderr": "",
"stdout": (以下省略)
「"changed": true」になっている、ということは効いていない。
ファイルがない時には実行しないオプションremovesも同様であった。
ここで期待した通りのことをしたければwin_statモジュールを使用する。
Playbookを作って実行する。
- hosts: windows
tasks:
- win_stat: path=C:\ProgramData\chocolatey\bin\chocolatey.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:\ProgramData\chocolatey\bin\chocolatey.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は必要ない。
- hosts: windows
tasks:
- win_stat: path=C:\ProgramData\chocolatey\bin\chocolatey.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:\ProgramData\chocolatey\bin\chocolatey.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モジュールを利用して同等のことはできる。