I'm trying to use Ansible together with its CloudStack modules to e.g. create a computing instance at a cloud provider supporting CloudStack (here: Exoscale, shouldn't matter in this case).
tl;dr:
The CloudStack python library cs
is not found by ansible:
fatal: [localhost]: FAILED! => {"changed": false, "msg": "python library cs required: pip install cs"}
despite being installed.
Details:
My inventory/host file consists of one single line:
localhost ansible_connection=local
I now run a minimal test playbook play.yml
with ansible-playbook play.yml
The play.yml
content is:
---
- hosts: localhost
become: no
gather_facts: no
tasks:
- name: Include global variables
include_vars: vars/vars.yml
- name: Include global secrets
include_vars: vars/vault.yml
- name: python version
command: python --version
register: python_version
- name: print python version
debug:
msg: "{{ python_version }}"
- name: manual code execution
command: python -c "from cs import CloudStack; print(CloudStack)"
register: cs_output
- name: print manual code execution
debug:
msg: "{{ cs_output }}"
- name: Create debian instance
cs_instance:
api_key: "{{ vault.exoscale.key }}"
api_secret: "{{ vault.exoscale.secret }}"
api_url: "{{ exoscale.endpoints.compute }}"
name: test-vm-1
iso: Linux Debian 7 64-bit
hypervisor: VMware
Running this yields the following:
PLAY [localhost] *******************************************************************************************************
TASK [Include global variables] ****************************************************************************************
ok: [localhost]
TASK [Include global secrets] ******************************************************************************************
ok: [localhost]
TASK [print python version] ********************************************************************************************
ok: [localhost] => {
"msg": {
"changed": true,
"cmd": [
"python",
"--version"
],
"delta": "0:00:00.014565",
"end": "2018-04-20 08:14:04.997040",
"failed": false,
"rc": 0,
"start": "2018-04-20 08:14:04.982475",
"stderr": "Python 2.7.14",
"stderr_lines": [
"Python 2.7.14"
],
"stdout": "",
"stdout_lines": []
}
}
TASK [manual code execution] *******************************************************************************************
changed: [localhost]
TASK [print manual code execution] *************************************************************************************
ok: [localhost] => {
"msg": {
"changed": true,
"cmd": [
"python",
"-c",
"from cs import CloudStack; print(CloudStack)"
],
"delta": "0:00:00.263650",
"end": "2018-04-20 08:14:05.687666",
"failed": false,
"rc": 0,
"start": "2018-04-20 08:14:05.424016",
"stderr": "",
"stderr_lines": [],
"stdout": "<class 'cs.client.CloudStack'>",
"stdout_lines": [
"<class 'cs.client.CloudStack'>"
]
}
}
TASK [Create debian instance] ******************************************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "python library cs required: pip install cs"}
PLAY RECAP *************************************************************************************************************
localhost : ok=7 changed=2 unreachable=0 failed=1
which python
(python installed with anaconda, conda environment named ansible
)
/Users/ccauet/anaconda3/envs/ansible/bin/python
python --version
Python 2.7.14
which ansible
(installed via pip in the same conda environment)
/Users/ccauet/anaconda3/envs/ansible/bin/ansible
ansible --version
(incl definition of used python version)
ansible 2.5.0
config file = /Users/ccauet/Repositories/p8/exoscale/ansible.cfg
configured module search path = [u'/Users/ccauet/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /Users/ccauet/anaconda3/envs/ansible/lib/python2.7/site-packages/ansible
executable location = /Users/ccauet/anaconda3/envs/ansible/bin/ansible
python version = 2.7.14 | packaged by conda-forge | (default, Mar 30 2018, 18:21:11) [GCC 4.2.1 Compatible Apple LLVM 6.1.0 (clang-602.0.53)]
pip freeze
ansible==2.5.0
asn1crypto==0.24.0
bcrypt==3.1.4
certifi==2018.4.16
cffi==1.11.5
chardet==3.0.4
cryptography==2.2.2
cs==2.1.6
enum34==1.1.6
idna==2.6
ipaddress==1.0.22
Jinja2==2.10
MarkupSafe==1.0
paramiko==2.4.1
pyasn1==0.4.2
pycparser==2.18
PyNaCl==1.2.1
PyYAML==3.12
requests==2.18.4
six==1.11.0
urllib3==1.22
As you can see cs
is installed and can be invoked by hand inside the playbook. Nevertheless the CloudStack module does not find the library.
Tried so far:
Any help is welcome!
It sounds to me like the cs_instance
module is possibly using the system Python rather than conda virtual environment. I've had this problem before with other Ansible modules running locally.
You can make Ansible use the Python interpreter in your Conda virtual environment by setting the ansible_python_interpreter
fact in the inventory of localhost
. You can do this as a pre-task, if you're running Ansible in the same Conda environment that you want the local task to use as follows:
---
- hosts: localhost
become: no
gather_facts: no
pre_tasks:
- name: Get local python interpreter
command: which python
register: local_python_interpreter
- name: Set ansible_python_interpreter to local python interpreter
set_fact:
ansible_python_interpreter: "{{ local_python_interpreter.stdout }}"
tasks:
...