The lxd_container module for Ansible 2.5 contains this example:

# An example for creating a Ubuntu container and install python
- hosts: localhost
  connection: local
    - name: Create a started container
        name: mycontainer
        state: started
          type: image
          mode: pull
          server: https://images.linuxcontainers.org
          protocol: lxd
          alias: ubuntu/xenial/amd64
        profiles: ["default"]
        wait_for_ipv4_addresses: true
        timeout: 600

    - name: check python is installed in container
      delegate_to: mycontainer
      raw: dpkg -s python
      register: python_install_check
      failed_when: python_install_check.rc not in [0, 1]
      changed_when: false

    - name: install python in container
      delegate_to: mycontainer
      raw: apt-get install -y python
      when: python_install_check.rc == 1

Could anyone explain to me why the example makes use of the raw module instead of the apt module?

Is this some kind of insider knowledge that was used here and (prematurely?) optimizes how Ansible performs, based on the ansible_connection=lxd versus ansible_connection=ssh for mycontainer or something?

After all it's be much simpler to dispose of these last two tasks in favor of:

- name: install python in container
  delegate_to: mycontainer
  apt: pkg=python state=latest

... of course with the option to update the apt cache and all that.

So why resort to the raw module here?

NB: I am asking this mainly because usually the documentation shows the canonical way of doing things. But from what I understand, canonically I am supposed to use the specific modules such as apt rather than invoking shell or raw commands.


Meanwhile I found the reason.

So Ansible will normally generate a Python (2.x) script to execute on the remote machine via whatever connection method is configured for any particular host.

Alas, Python is a prerequisite of the apt module. The raw module does not seem to have this limitation and therefore can be used to install the prerequisites required to run Ansible tasks on the (remote) hosts, using dpkg and apt-get commands directly on the remote system. By the way, the shell module has the very same limitation, but the raw module does not. I wish this would have been mentioned a little more explicitly in the documentation, though.

In this case the result dictionary contains a key named module_stderr with the following value: module_stderr": "/bin/sh: 1: /usr/bin/python: not found\n. Make it visible by increasing the verbosity when invoking ansible-playbook.

Now that I know what's going on, this sentence from the raw module documentation makes a whole lot more sense:

This module does not require python on the remote system, much like the script module.

I did not find this earlier, because I was incrementally running my playbook, so the python package was already installed when I thought to myself "why not use the apt module?"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.