Help us understand the problem. What is going on with this article?

AnsibleでChocolateyを使ってWindowsアプリをインストールする

More than 3 years have passed since last update.

はじめに

前回で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%\chocolatey\bin'

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:\ProgramData\chocolatey\bin\chocolatey.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:\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は必要ない。

site.yml
- 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モジュールを利用して同等のことはできる。
Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away