ansible can't find a python package even if it is installed

Viewed 1770

Trying to use docker-compose within an ansible playbook using the docker_compose module. Note that I can successfully use the docker module in ansible but running into problems with docker_compose module. I'm using plaintext vars for testing locally, I use ansible-vault for storing secrets.

On the ansible documentation it explains that their docker-compose module only supports version 1 and 2 of docker-compose.

Here is my docker-compose.yml:

---
version: "2.4"
services:
   my_demo:
       build: .
       networks:
          demo_net:
             ipv4_address: 172.0.1.2
       ports:
          - 8080:8080
       image: demo_image

networks:
    demo_net:
       driver: bridge
       ipam:
         driver: default
         config:
           - subnet: 172.0.1.0/30
             gateway: 172.0.1.1

Here is my main.yml:

---
- hosts: localhost
  connection: local
  become: true

  vars:
    - ansible_sudo_pass: password
    - ansible_python_interpreter: /usr/bin/python3

  tasks:
    - name: Docker compose
      docker_compose:
         project_name: docker_fhe_ansible
         project_src: .
         build: yes
      register: output

    - debug:
        var: output

Output:

PLAY [localhost] **********************************************************************************************************************************************************************************

TASK [Gathering Facts] ****************************************************************************************************************************************************************************
ok: [localhost]

TASK [Docker compose] *****************************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Failed to import the required Python library (Docker SDK for Python: docker (Python >= 2.7) or docker-py (Python 2.6)) on ubuntu's Python /usr/bin/python3. Please read module documentation and install in the appropriate location. If the required library is installed, but Ansible is using the wrong Python interpreter, please consult the documentation on ansible_python_interpreter, for example via `pip install docker` or `pip install docker-py` (Python 2.6). The error was: No module named 'docker'"}

PLAY RECAP ****************************************************************************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   

The error is "no module named docker", I can verify python3 has the module:

john@ubuntu:~/Documents/docker-ansible$ python3
Python 3.8.10 (default, Jun  2 2021, 10:49:15) 
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import docker
>>> import ansible
2 Answers

You state, you verified that those packages are present, but you can install packages in many ways which do not make them globally available. For example, you can install them in a virtualenv or for your user only.
If ansible tells you that it is missing those packages, it can't find them. You are running ansible as root on the machine (become: true), so you need to make sure those packages are available to root.
(Edit: This was actually the problem. The package was available for the user john, but not for root)

You are missing the docker module (and probably other requirements as well).
Install them at the beginning of your play using

- name: ensure required pip-packages are installed
  pip:
    name: 
      - docker>=1.8.0
      - PyYAML>=3.11
      - docker-compose>=1.7.0

If you install them using a separate playbook, make sure to use become: true on that one as well, otherwise it will again be installed for your user only.

What I usually do when writing playbooks or roles is to make sure that all required packages are installed first. This means I would put the task in the same playbook/role that uses the docker_compose module. Like this, I'm sure that my stuff will work even if a colleague messes around on the machine and they can also use my code "as-is" without having to install something first.

Further notes:

  • Always check the documentation for module requirements and install them before using the module. For example for the docker_compose module.
  • Also be aware, that you need to install them on the remote host, not the ansible-controller!
  • Take a look at the documentation of the pip module in case you are using a virtualenv.
Failed to import [...] on ubuntu's Python /usr/bin/python3 [...] error was: No module named 'docker'

However you are able to import the module from your local Python interpreter.

Check the python3 you are using to test is indeed /usr/bin/python3 (with which python3 for example). If not, you can use Ansible ansible_python_interpreter to specify the proper Python interpreter.

Related