用 Ansible 管理 Windows
嗯~Ansible 很好用
所以很希望也可以用在 Windows 上~
開始
- 首先要參考 Ansible Windows Support 的文件
- 確認 Windows 本身的 Powershell 版本要在 3.0 以上 (沒有的話,就可以下載這個 upgrade_to_ps3.ps1 來執行)
- 設定 winrm - 執行 setup.ps1
- Windows 7/2008R2 版本還要先安裝 http://support.microsoft.com/kb/2842230
- Windows 8.1/2012 以後版本已經安裝了 .Net 4.0,所以不需要特別作什麼事情
測試
因為想在本機測試,所以用 Vagrant 來測試
- 我這次用的是 win2012-r2 的 box
- 很簡單的用
vagrant init opentable/win-2012r2-standard-amd64-nocm; vagrant up --provider virtualbox
就可以啟動了 - 當然,需要進入 Windows 裡面去設定 winrm,參考上面的步驟,但是我懶得手動下載後才執行,所以我用了 chocolatey 的技巧,直接下載後執行。開啟 Powershell 視窗,執行下面指令就可以:
1
iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/ansible/ansible/devel/examples/scripts/ConfigureRemotingForAnsible.ps1'))
- 執行完畢之後,我本來以為可以直接用 Vagrant 的 provision 功能,結果碰壁了~
問題一
1 | $ ansible default -i .vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory -m win_ping -vvvv |
2 | default | FAILED! => { |
3 | "failed": true, |
4 | "msg": "ERROR! ssl: 500 WinRMTransport. [SSL: UNKNOWN_PROTOCOL] unknown protocol (_ssl.c:590)" |
5 | } |
原本以為直接用 Vagrant 產生的 inventory 檔案就可以執行,所以先用 win_ping
指令測試一下
結果就出現了上面的錯誤
找了一下資料以及對照 Vagrant 產生的 vagrant_ansible_inventory
檔案,才發現他產生出來的檔案是這樣:
1 | # Generated by Vagrant |
2 | |
3 | default ansible_connection=winrm ansible_ssh_host=127.0.0.1 ansible_ssh_port=55985 ansible_ssh_user='vagrant' ansible_ssh_pass='vagrant' |
麻煩的是,產生出來的 ansible_ssh_port
走的是 http port
內部啟動 winrm 會有兩個 port,對應 http/https。分別是 5985/5986
virtualbox 會幫忙 mapping 這兩個 port,分別對應 55985/55986
但是 ansible 需要走 https,所以就出現了上面的錯誤訊息
改法就是自己產生一個 inventory 檔案 (你不能改 .vagrant 下面產生出來的檔案,因為每次執行 vagrant provision 都會重新產生)
1 | [windows] |
2 | default ansible_connection=winrm ansible_ssh_host=127.0.0.1 ansible_ssh_port=55986 ansible_ssh_user='vagrant' ansible_ssh_pass='vagrant' |
問題二
1 | $ ansible windows -i hosts -m win_ping -vvvv |
2 | default | FAILED! => { |
3 | "failed": true, |
4 | "msg": "ERROR! ssl: 500 WinRMTransport. [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)" |
5 | } |
本來以為改完後,一切幸福美滿~ 結果一執行就給我拋另外一個錯誤
不過這個錯誤看起來就是 SSL 憑證問題!靠!這怎麼改???
我前兩天升級了 Ansible 2.0,所以我還在想說是不是因為這個原因
果不其然,找到了這篇文章: Packer – Vagrant – Ansible – Windows (WinRMTransport Error)
Ansible 也有一個 Issue 在解釋這個問題
改法就是,在現在的目錄下,建立一個 callback_plugins
目錄。然後建立一個 fix_ssl.py
檔案:
1 | import ssl |
2 | if hasattr(ssl, '_create_default_https_context') and hasattr(ssl, '_create_unverified_context'): |
3 | ssl._create_default_https_context = ssl._create_unverified_context |
4 | |
5 | class CallbackModule(object): |
6 | pass |
根據這段程式碼英文的意思,我猜測就是忽略自簽章的 SSL 憑證驗證~因為我在 .Net 幹過一樣的事情~
所以這次執行就成功了~
1 | $ ansible windows -i hosts -m win_ping -vvvv |
2 | default | SUCCESS => { |
3 | "changed": false, |
4 | "invocation": { |
5 | "module_name": "win_ping" |
6 | }, |
7 | "ping": "pong" |
8 | } |
結語
以上是我碰到的兩個問題,還好網路都有找到解法~
所以之後應該只需要參考 Windows Modules 試試看用法,應該之後就可以拿來管理 Windows 了~
不過可能還是要注意下面的事情:
- 注意自己安裝的 Ansible 版本,我目前測試的版本是 2.0,所以我不知道 1.x 版本是不是沒有我遇到的問題
- 注意 winrm 設定,因為我這次測試是用 Vagrant box,所以是直接用 Port forwarding 做到。
如果是實機,就得自己去找 winrm 的 port - 之後如果要在實機測試的話,可能還要另外注意帳號密碼問題