akishin999の日記

調べた事などを書いて行きます。

Ansible で標準のパス以外の場所に入れた Python を使用する

Ansible はデフォルトではリモートのホストに入っている標準の python を使用します。
これを virtualenv 環境など、標準のパス以外の場所の python を使いたい場合には、ansible_python_interpreter 変数で python インタプリタのパスを指定するようです。

List of Behavioral Inventory Parameters
http://docs.ansible.com/ansible/latest/intro_inventory.html#list-of-behavioral-inventory-parameters

vars:
  ansible_python_interpreter="/root/python-venv/bin/python"

ただ、手元の CentOS 6.4 環境で、この方法で virtualenv 環境の python を指定したところ、yum モジュールを使った箇所で以下のようなエラーが出てしまいました。

TASK: [install mysql-server] **************************************************
failed: [192.0.2.1] => {"failed": true, "parsed": false}
invalid output was: Traceback (most recent call last):
  File "/root/.ansible/tmp/ansible-1378480574.36-133423455605286/yum", line 26, in <module>
    import yum
ImportError: No module named yum


FATAL: all hosts have already failed -- aborting

ここ以外は上手く動くようなので、yum モジュールまでは標準の python、virtualenv 環境を使う時だけそちらの python、という感じで指定できれば回避できそう。
何か方法はないかと調べてみたところ、1.2 から追加された set_fact を使う事で回避することができました。

set_fact - Set host facts from a task
http://docs.ansible.com/ansible/latest/set_fact_module.html

以下のような感じで、virtualenv 環境を使いたい task の直前で set_fact を使用して ansible_python_interpreter 変数を指定してやります。

・
・
・
- name: install mysql-server
  yum: name=mysql-server state=installed

- name: start mysql
  action: service name=mysqld state=started enabled=yes

# ここで python インタプリタを切り替え
- name: set ansible_python_interpreter
  set_fact: ansible_python_interpreter="/root/python-venv/bin/python"

- name: create mysql_python_test database
  mysql_db: name=mysql_python_test state=present encoding=utf8
・
・
・

これで先ほどのエラーを回避でき、virtualenv 環境に入れた mysql-python を使用して mysql_db モジュールを実行することが出来ました。

以下に実際の playbook を置いておきます。

https://github.com/akishin/ansible-playbooks/blob/master/snippets/virtualenv-mysql-python.yml

それほど使う機会もないかと思いますが、何かの参考になれば幸いです。