0

I have a docker_container which I want to deploy for multiple users and name traefik routes after the users. But i'm confused on how I can achieve this.

Here is what I have:

- name: Run syncthing
  docker_container:
    name: "{{ item.name }}-syncthing"
    image: "lscr.io/linuxserver/syncthing"
    state: started
    restart_policy: "always"
    env:
      PUID: "1000"
      PGID: "1000"
    volumes:
      - "{{ item.data_dir }}:/data"
... other volumes
    labels:
      traefik.enable: true
      "traefik.http.routers.{{ item.name }}-syncthing.entrypoints": websecure
      "traefik.http.routers.{{ item.name }}-syncthing.rule": Host(`{{ item.name }}.{{ fqdn_real }}`)
      "traefik.http.routers.{{ item.name }}-syncthing.tls": true
      "traefik.http.routers.{{ item.name }}-syncthing.tls.certresolver": le 
      "traefik.http.routers.{{ item.name }}-syncthing.service": "{{ item.name }}-syncthing"
      "traefik.http.routers.{{ item.name }}-syncthing.middlewares": "{{ item.name }}-basicauth"
      "traefik.http.services.{{ item.name }}-syncthing.loadbalancer.server.port": 8080
      "traefik.http.middlewares.{{ item.name }}-syncthing-basicauth.basicauth.users": "{{ item.auth }}"
  with_items: "{{ syncthing_containers_info }}"

And a syncthing_config_info like this:

syncthing_containers_info:
  - { name: "c1", data_dir: "/mnt/data/c1/data", auth: "..." }
  - { name: "c2", data_dir: "/mnt/data/c2/data", auth: "..." }
  - { name: "c3", data_dir: "/mnt/data/c3/data", auth: "..." }

That snippet doesn't work because ansible doesn't like the syntax so I have tried this with a with_nested but I faced a similar problem there with the nested loop issue while trying to set_fact as in the example since the set of labels depends on syncthing_containers_info. Is there a better way for me to do this?

xmd
  • 3
  • 2

1 Answers1

0

It sounds like you need the labels: to be an actual dict since yaml keys are not subject to jinja2 interpolation

    labels: >-
      {%- set key_prefix = "traefik.http.routers." ~ item.name ~"-syncthing" -%}
      {{ {
      "traefik.enable": True,
      key_prefix ~ ".entrypoints": "websecure",
      key_prefix ~ ".rule": "Host(`" ~ item.name ~"."~ fqdn_real ~"`)",
      key_prefix ~ ".tls": True,
      key_prefix ~ ".tls.certresolver": "le",
      key_prefix ~ ".service": item.name ~ "-syncthing",
      key_prefix ~ ".middlewares": item.name ~ "-basicauth",
      "traefik.http.services." ~ item.name ~ "-syncthing.loadbalancer.server.port": 8080,
      "traefik.http.middlewares." ~ item.name ~"-syncthing-basicauth.basicauth.users": item.auth,
      } }}

(be aware I didn't test that, just eyeballed it from your question, but that's the general idea)

mdaniel
  • 31,240
  • 5
  • 55
  • 58
  • This worked perfectly, thank you! I just had to update the `True` to `"true"` and it just worked. Can you tell me what this syntax is called or point me to docs on it? – xmd Oct 25 '21 at 22:22
  • ah, yes, because labels are string-string pairs; sorry about that! that is [jinja2](https://jinja.palletsprojects.com/en/2.11.x/), the templating/scripting language shipped with ansible. it's _mostly_ python syntax, but there are for sure some weird differences that make for a lot of SO questions :-( – mdaniel Oct 26 '21 at 16:01