Vagrant+Ansibleで"ansible_winrm_server_cert_validation=ignore"が動作しない問題

本記事の目的

VagrantとAnsibleの連携実行を学習中に、winrmに関する一部の記述が動作しないケースに遭遇した。
解決までに時間が掛かったこともあり、回避策も含め記録しておく。

結論

pywinrm 0.3.0 では、"ansible_winrm_server_cert_validation=ignore"が正常に動作しない。
pywinrm 0.2.2 に戻すことで回避可能*1

検証環境

Hardware MacBookPro 13-inch 2016, 8GB RAM, 256GB SSD
OS MacOS 10.13.6 High Sierra
Ansible 2.6.2
Vagrant 2.1.2
Python 2.7.15
pywinrm 0.3.0
Hypervisor Virtualbox
Virtual Machine (for verification) Windows Server 2016 (IP:192.168.33.11)

経緯

"vagrant up"もしくは"vagrant provision"コマンドでvagrantfileからansibleを実行するときだけ、下記のエラーが出て実行できない。

fatal: [192.168.33.11]: UNREACHABLE! => { 
    "changed": false,  
    "msg": "ssl: HTTPSConnectionPool(host='192.168.33.11', port=5986): Max retries exceeded with url: /wsman (Caused by SSLError(SSLError(\"bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')],)\",),))",  
    "unreachable": true 
}

ansibleを直接コマンドで実行*2したり、HTTPで接続するようにすると問題なく動いた。

インベントリファイルには、参考にさせていただいた記事と同じように次のように書いている。
上記の検証から、"ansible_winrm_server_cert_validation=ignore"の部分が動作していないように思えた。

[windows]
192.168.33.11

[windows:vars]
ansible_user= vagrant
ansible_password= vagrant
ansible_port= 5986
ansible_connection= winrm
ansible_winrm_server_cert_validation=ignore

エラーメッセージでググって色々と調べた結果、次のissueを見つけた。
server_cert_validation 'ignore' no longer works in 0.3.0 · Issue #201 · diyan/pywinrm · GitHub
ansible_winrm_server_cert_validation no longer works with pywinrm 0.3.0 · Issue #34378 · ansible/ansible · GitHub

pywnrm 0.3.0をアンインストール後ver.0.2.2をインストールし、vagrant provisionを実行したら成功した。

結局、pywinrm 0.3.0 の問題(?)のようである。
このissueはpywinrm 0.3.1で修正されるかもしれないので、リリースされたらまた試してみる。

*1:動作を理解するための学習の範囲で、一番手っ取り早い。実サービスでは通用しないかも。

*2:"$ ansible-playbook -i hosts site.yml" など

Ansible+MacOS10.13 HighSierraでのfork()の不具合回避策

Ansibleの学習のため、MacOS10.13 HighSierraにインストールしたAnsible*1で、WindowServer2016に接続することを試していた。しかし次のエラーメッセージが表示され、何回試してもクラッシュしてしまう。

$ ansible -i hosts windows -m win_ping
objc[1371]: +[__NSPlaceholderDate initialize] may have been in progress in another thread when fork() was called.
objc[1371]: +[__NSPlaceholderDate initialize] may have been in progress in another thread when fork() was called. We cannot safely call it or ignore it in the fork() child process. Crashing instead. Set a breakpoint on objc_initializeAfterForkError to debug.

エラーメッセージを参考に調べたところ、issueが見つかった。

Preforking issue on OSX (10.13) when attempting to connect to windows server via WinRM #34056
https://github.com/ansible/ansible/issues/34056#issuecomment-352862252

このissueによると、MacOS 10.13のpythonにおけるfork()の不具合によって、AnsibleからWinRMで接続時にpythonがクラッシュするようだった。

上記で示されている回避策である、MacOSへの次の環境変数の追加

export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES

によって回避できることを確認できた。 

*1:検証環境:MacBookPro 13-inch 2016, MacOS 10.13.4/8GB RAM/256GB SSD, Python 2.7.15, Ansible 2.6.2