Ansible tasks fail on nixos target due to missing python packaging

Hey folks,

As part of a legacy situation I have a bunch of ansible playbooks that I would to run against nixos targets. Specifically, I have one that starts a docker container on the target via docker compose. I can start the container using the compose file directly on the nixos target, so that works. However, when I run the ansible playbook remotely pointing at my nixos target, I get an error:


─ ansible-playbook -i inventory.yaml test_nixos.yaml                                             ─╯

PLAY [media] ****************************************************************************************

TASK [Gathering Facts] ******************************************************************************
[WARNING]: Platform linux on host mb is using the discovered Python interpreter at /run/current-
system/sw/bin/python3.11, but future installation of another Python interpreter could change the
meaning of that path. See https://docs.ansible.com/ansible-
core/2.15/reference_appendices/interpreter_discovery.html for more information.
ok: [mb]

TASK [speedtest] ************************************************************************************
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: ModuleNotFoundError: No module named 'requests'
fatal: [mb]: FAILED! => {"changed": false, "msg": "Failed to import the required Python library (Docker SDK for Python: docker>=5.0.0 (Python >= 3.6) or docker<5.0.0 (Python 2.7)) on mb's Python /run/current-system/sw/bin/python3.11. Please read the module documentation and install it 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` (Python >= 3.6) or `pip install docker==4.4.4` (Python 2.7). The error was: No module named 'requests'"}
...ignoring

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

I tried adding some packages to my configuration.nix

  environment.systemPackages = [
    pkgs.python3
    pkgs.ansible
    pkgs.python311Packages.ansible
    pkgs.python311Packages.pip
    pkgs.python311Packages.requests
  ];

But no joy. I guess that ansible can’t install the required python packages when it ssh’s into the target?

Thanks in advance

This makes the packages available on your system, but not as part of a python environment. Try:

environment.systemPackages = [
    pkgs.ansible
    (pkgs.python3.withPackages(ps: [ ps.ansible ps.pip ps.requests ]))
  ];

That helped, and got me to a different error:

fatal: [mb]: FAILED! => {"changed": false, "msg": "Unable to load docker-compose. Try pip install docker-compose. Error: Traceback (most recent call last):\n File \"/tmp/ansible_docker_compose_payload_yz30z8je/ansible_docker_compose_payload.zip/ansible_collections/community/docker/plugins/modules/docker_compose.py\", line 522, in <module>\nModuleNotFoundError: No module named 'compose'\n"}
I tried:


  environment.systemPackages = [
    pkgs.ansible
    (pkgs.python3.withPackages(ps: [
         ps.ansible ps.pip ps.requests ps.docker ps.compose
          ]))
  ];

&


  environment.systemPackages = [
    pkgs.ansible
    (pkgs.python3.withPackages(ps: [
         ps.ansible ps.pip ps.requests ps.docker ps.compose
          ]))
  ];

But I get this kind of error


nixos-rebuild switch
building Nix...
building the system configuration...
error:
       … while calling the 'head' builtin

         at /nix/store/qfk7rip8inpbq0sr6x7724f0binzbbx1-nixos-23.11/nixos/lib/attrsets.nix:922:11:

          921|         || pred here (elemAt values 1) (head values) then
          922|           head values
             |           ^
          923|         else

       … while evaluating the attribute 'value'

         at /nix/store/qfk7rip8inpbq0sr6x7724f0binzbbx1-nixos-23.11/nixos/lib/modules.nix:807:9:

          806|     in warnDeprecation opt //
          807|       { value = builtins.addErrorContext "while evaluating the option `${showOption loc}':" value;
             |         ^
          808|         inherit (res.defsFinal') highestPrio;

       (stack trace truncated; use '--show-trace' to show the full trace)

       error: attribute 'compose' missing

       at /home/john/repos/homelab/nixos/mb/configuration.nix:59:50:

           58|     (pkgs.python3.withPackages(ps: [
           59|          ps.ansible ps.pip ps.requests ps.docker ps.compose
             |                                                  ^
           60|           ]))

any ideas?

There is no Python package called compose in Nixpkgs.

Configure docker in you system configuration using these options:

https://search.nixos.org/options?channel=23.11&from=0&size=50&sort=relevance&type=packages&query=virtualisation.docker

and

 environment.systemPackages = [
    pkgs.ansible
    pkgs.docker-compose
    (pkgs.python3.withPackages(ps: [
         ps.ansible ps.pip ps.requests
          ]))
  ];

and ensure the ansible user is in the docker group.

You might also be interested in GitHub - hercules-ci/arion: Run docker-compose with help from Nix/NixOS