使用Ansible通过Chocolatey安装Windows应用程序
首先
经过上一次的使用Ansible操作Windows的准备,现在我们将通过实践来安装Windows软件包管理器Chocolatey,并使用它来安装应用程序,同时观察Ansible在Windows上可以实现的功能。
环境和上一次一样,我正在使用Ansible 1.7.1来操作Windows 8.1更新版。
重新列出正在使用的库存文件。
[windows]
10.0.2.172
[windows:vars]
ansible_ssh_user=<Windows側のユーザ名>
ansible_ssh_pass=<Windows側ユーザのパスワード>
ansible_ssh_port=5986
ansible_connection=winrm
Ansible 1.9及以上版本中存在win_chocolatey模块。
自 Ansible 1.9 版本开始,win_chocolatey 模块被添加为 Extras 模块。
因此,此文档下一步及其后续工作不再需要。
2015年6月27日的备注:如果在Windows上安装了Chocolatey 0.9.9或更高版本,则Ansible 1.9.2中附带的win_chocolatey模块无法适应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应用程序。
当首次使用win_chocolatey模块时,Chocolatey本身会自动安装。
- hosts: windows
tasks:
- win_chocolatey: name={{ item }}
with_items:
- SourceTree
- sysinternals
可以用于Windows的Ansible模块。
目前,根据官方文件,大部分提供的Ansible模块都无法用于Windows操作系统。
-
- raw
-
- script
-
- fetch
-
- slurp
- setup
以及为Windows增加的模块。
-
- win_feature
-
- win_get_url
-
- win_group
-
- win_msi
-
- win_ping
-
- win_service
-
- win_stat
- win_user
追加注:截至2016年2月27日,Ansible 2.0版本时win_*模块已大幅增加。
我正在确认只有作为操作者才能执行处理的模块,例如debug等,是否可用。
总之,目前情况下,除了上传到某个合适的Web服务器上并使用win_get_url进行下载之外,似乎没有其他方法来在Windows环境中传输文件(假设没有安装SSH服务器或rsync服务器等在Windows上)。
如果你想创建应用程序的设置文件,可以使用template、lineinfile或ini_file创建配置文件,然后将其上传到Web服务器上,并使用win_get_url进行下载。或者,你也可以使用这些模块动态生成PowerShell脚本,并通过script模块执行。
安装chocolatey
使用原始模块
只能使用上面提到的模块,因此可以肯定地说,raw模块一定会发挥重要作用,所以首先使用raw模块。
我們先來試著輸入Chocolatey官方所提供的PowerShell指令來進行安裝。
为了方便阅读,将命令和输出分成了不同的行。
# 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命令(被称为“cmdlet”),在使用原始模块中执行都会引发错误。
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模块
如果要运行无法在原始模块中运行的PowerShell命令,可以使用脚本模块。
创建一个包含上述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モジュールを利用して同等のことはできる。