ansible-collections / community.docker

Community Docker Collection for Ansible: modules and plugins for working with Docker
https://galaxy.ansible.com/ui/repo/published/community/docker/
GNU General Public License v3.0
196 stars 109 forks source link

docker_stack: expand variables for service name #939

Closed SheevaPlug closed 1 month ago

SheevaPlug commented 1 month ago
SUMMARY

Currently community.docker.docker_stack module is able to use variables (lookups, ...) for several parts of the compose file, like the name of the stack or the image. Unfortunately, this does not work with the service name, neither if quoted nor not.

ISSUE TYPE

Support Jinja2 variable expansion for the service name, too.

COMPONENT NAME

This refers to the docker_stack module in community.docker.

ADDITIONAL INFORMATION

Let's have a look at the following example playbook section:

- name: Start example-opa on cluster
  community.docker.docker_stack:
    state: present
    name: "{{ stack_name }}"
    compose:
      - version: "3.7"
        services:
          {{ service_name }}: # this does not work, neither with nor without quotes
            image: "{{ registry_url }}/{{ image_name }}:{{ image_tag }}"

When written like this, Ansible reports a "Syntax error while loading YAML. found unacceptable key (unhashable type: 'AnsibleMapping')" and suggests that this might be a consequence of missing quotes. Thus, I put double quotes around "{{ service_name }}" and get the message "docker stack up deploy command failed" with "services Additional property {{service_name}} is not allowed" written to stdout.

For values like the stack name and the image URL, everything works fine, and not embedding the compose file but using ansible.builtin.template with an additional file can serve as a workaround. But then, IMHO it's nice to keep all the settings for deployments together in one file. Is it possible to make variable substitution work for keys, too?

felixfontein commented 1 month ago

This is a restriction by Ansible, not by the module, and the module has no way to work around this restriction by Ansible itself.

If you want to adjust key names, you need to use Jinja2 functions or filters to generate these dictionaries. Maybe this will work:

- name: Start example-opa on cluster
  community.docker.docker_stack:
    state: present
    name: "{{ stack_name }}"
    compose:
      - version: "3.7"
        services: "{{ dict([[service_name, service_data]]) }}"
  vars:
    service_data:
      image: "{{ registry_url }}/{{ image_name }}:{{ image_tag }}"
SheevaPlug commented 1 month ago

That works fine, thank you very much!