Ansibleの複数バージョン共存

新しいバージョン試そうかなまたは旧いバージョンに合うように動確が要るみたいなことでやってみた備忘録です。

もしとりあえずグローバルじゃなくてローカルなユーザ環境のホームディレクトリに入れたいというとき
`export PATH=$HOME/.local/bin:$PATH`して同じのを`~/.bashrc`とかに書いて`pip install ansible=2.0.0.2 --user`とするとそこに入り優先的に読まれる。
https://qiita.com/ymko/items/7757e9801ae784a8347c


以下はvirtualenvつかう方法でpython2.6だとうまくvirtualenvwrapperが入らずpython2.7ならうまくいきました。
[CentOS6にpython2.7の入れ方は検索するとbaseじゃないリポジトリから入れてる感じ](https://qiita.com/TatsuNet/items/7719ddcdf856de7cfc9a)でした。
あともし実行させてる[Jenkins移すならむかしやったときこんなかんじ](https://qiita.com/smallpalace/items/538912137b7321f2511d)でした。

・pipとpython-devel入れる

```
curl -kL https://bootstrap.pypa.io/get-pip.py | python
yum install python-devel
```
・virtualenvいれる

```
pip install virtualenv
pip install virtualenvwrapper
find /usr -name virtualenvwrapper.sh
vi .bashrc
以下を追記
if [ -f /usr/bin/virtualenvwrapper.sh ]; then
    export WORKON_HOME=$HOME/.virtualenvs
    source /usr/bin/virtualenvwrapper.sh
fi

source .bashrc
```
・mkvirtualenvでバージョンごとに環境をつくりworkonで環境名を指定して切り替える

```
mkvirtualenv ansible2.5
workon ansible2.5
pip install ansible
ansible --version
pip list|grep ansible
```
・環境名指定しないと環境の一覧が出る

```
workon
```
・ansible2.0用の環境をつくりそれをいれる

```
mkvirtualenv ansible2.0
which ansible
pip install ansible==2.0
ansible --version
```
・virtualenvからぬける（プロンプトが元に戻る）

```
deactivate
```

まあつまりansible-playbook実行の手前でworkon ansible2.0して終わったらdeactivateすることになるかな。

ちょっとやってみたところyumモジュールまわりで`No module named yum`と言われるので、以下のように切り替えると出なくなりました。

```
  - set_fact:
#      ansible_python_interpreter="/root/.virtualenvs/ansible2.0/bin/python"
      ansible_python_interpreter="/usr/bin/python"

  - name: install needed network manager libs
    yum:
      name: '{{ item }}'
      state: installed
    with_items:
      - NetworkManager-glib
      - nm-connection-editor.x86_64
      - libsemanage-python
      - policycoreutils-python

  - set_fact:
      ansible_python_interpreter="/root/.virtualenvs/ansible2.0/bin/python"
```


あと、開発中のモジュールの新機能だけが使いたいとなった場合についてpython詳しい人に教えてもらったところ
gitcloneでコピーかrawでダウンロードしてきて以下のあたりに置いたらふつうに動くらしい。
たとえば[nmcliならここらにあるやつ](https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/net_tools/nmcli.py)を以下のあたりに置くといいそうです。
`/usr/lib/python2.x/site-packages/ansible/modules/network/`
virtualenvだと以下のあたりっぽい
`/root/.virtualenvs/ansible2.0/lib/python2.7/site-packages/ansible/`

playbook側の条件分岐いれるなら以下のようになるかな、と思ってやってみたけど低いバージョンだと存在しないモジュール名でsyntaxエラーでてしまうようでした。残念。そもそも2.0だとansible_version.fullが存在しない模様。
https://github.com/awailly/cis-ubuntu-ansible/issues/98

playbook側でバージョン指定する方法について書いてる人がいたので貼っておきます。
http://muziyoshiz.hatenablog.com/entry/2018/03/12/215422

```yaml:2.0だとsyntaxエラーで動かなかったやつ
- name: check systemd
  stat:
    path: /usr/bin/systemctl
  register: check_systemd

- name: set timezone to common_timezone(default value is Asia/Tokyo)
  timezone:
    name: "{{ common_timezone }}"
  when:
    - ansible_version.full >= '2.3'
    - check_systemd.stat.xusr

- block:
  - name: check if timezone is common_timezone
    command: /usr/bin/timedatectl status|grep -i 'time zone'|awk '{print $3}'
    register: check_timezone
    ignore_errors: true
    when: check_systemd.stat.xusr
  - name: set timezone to common_timezone
    command: /usr/bin/timedatectl set-timezone '{{ common_timezone }}'
    when: check_timezone != common_timezone
  when: ansible_version.full < '2.3'
```

事情によりansible2.4でかいたのを2.0で動かないやつを比べて特定しないといけなかったのですが、
ザックリ以下のあたりが該当しました。

```yaml
include_tasks ## -> include
import_tasks ## -> include
loop_controls,loop_vars ## -> with_items等に使うloop内の変数はitemのみ
replace: path ## ->dest
when:
  - check_result1.rc == 0 ## ansible2.4~ check_result1|succeeded
  - check_result2.rc == 1 ## ansible2.4~ check_result2|failed
yum: # enablerepoは2.0ではつかえず  
```
あとwith_indexes,with_nestedもまともに動いてない気がした（たぶん

それとチェックするタスクが実行されなくて変数がとれない場合などに以下のようなのが出る傾向
`UnicodeDecodeError: 'ascii' codec can't decode byte 0xe3 in position 239: ordinal not in range(128)`


なのでshellやcommandの情報取るだけで環境を操作しないチェックタスクには以下を根こそぎ入れるとよさそう
`always_run: yes ## ansible2.4~ checkmode: no`

、、と思いきや、
`0xe3`のようなエラーコードでるやつはansibleでなくてpythonのエラーであるらしい。
具体的には[このバグ](https://github.com/ansible/ansible/commit/9ddb4a985c86684100bef85df25088957283e963)だそうです。
あとパッチバージョン0ピッタリのやつはバグだらけ([セマンティック バージョニング](https://semver.org/lang/ja/))だから[安定板](http://docs.ansible.com/ansible/latest/reference_appendices/release_and_maintenance.html)を使うのがよいそう。（最新安定版が既存環境などの都合で難しい場合にはパッチバージョンの最新つかうなど。）（あとエラーメッセージはissueで検索すると大体でてくるときいた）
そんな時はvirtualenvで違うバージョンで確認するとまともな構文エラーが出て場所が特定しやすかったりするようでした。

参考
https://dev.classmethod.jp/server-side/ansible/select_ansible_version_via_virtualenv/
https://qiita.com/TatsuNet/items/7719ddcdf856de7cfc9a