ct-Open-Source / telerec-t-base

Basic Ansible Setup for a server with Traefik, Portainer and Watchtower
GNU General Public License v3.0
48 stars 11 forks source link

portainer overwrites traefik #6

Open DanielK990 opened 5 months ago

DanielK990 commented 5 months ago

If I install each of the four services separately, everything works fine.

But when I run system-setup.yml (in the article erroneously called server-setup.yml), the portainer installation seems to use the service_cfg of traefik.

The traefik/docker-compose.yml contains the content of the portainer compose file and the installation fails because "admin_user" variable cannot be found (I assume because ansible searches for this variable below the traefik section).

The problem also appears for other services, e.g. when I only install watchtower and autoheal - then autoheal overwrites the docker-compose.yml of watchtower.

Really weird - can somebody reproduce this?

I am suspecting the use of set_fact in facts.yml of compose_hull, but I am not sure.

rogue73 commented 5 months ago

I've noticed the same behavior on my side. I agree that the misinterpreting of the variables happen within compose_hull. But currently i haven't debug it in detail.

nameless66 commented 5 months ago

The problem is, When using vars: within the roles: section of a playbook, the variables are added to the play variables, making them available to all tasks within the play before and after the role. This behavior can be changed by DEFAULT_PRIVATE_ROLE_VARS. see

But setting private_role_vars = True in ansible.cfg did't work.

So here is my working system-setup.yml:

---
- hosts: server
  become: true
  tasks:
    - name: Set service_cfg to traefik
      set_fact:
        service_cfg: "{{ traefik }}"
    - name: Deploy Traefik
      include_role:
        name: traefik
    - name: Set service_cfg to watchtower
      set_fact:
        service_cfg: "{{ watchtower }}"
    - name: Deploy Watchtower
      include_role:
        name: watchtower
    - name: Set service_cfg to autoheal
      set_fact:
        service_cfg: "{{ autoheal }}"
    - name: Deploy Autoheal
      include_role:
        name: autoheal
    - name: Set service_cfg to portainer
      set_fact:
        service_cfg: "{{ portainer }}"
    - name: Deploy Portainer
      include_role:
        name: portainer
rogue73 commented 5 months ago

The problem is, When using vars: within the roles: section of a playbook, the variables are added to the play variables, making them available to all tasks within the play before and after the role. This behavior can be changed by DEFAULT_PRIVATE_ROLE_VARS. see

But setting private_role_vars = True in ansible.cfg did't work.

So here is my working system-setup.yml:

---
- hosts: server
  become: true
  tasks:
    - name: Set service_cfg to traefik
      set_fact:
        service_cfg: "{{ traefik }}"
    - name: Deploy Traefik
      include_role:
        name: traefik
    - name: Set service_cfg to watchtower
      set_fact:
        service_cfg: "{{ watchtower }}"
    - name: Deploy Watchtower
      include_role:
        name: watchtower
    - name: Set service_cfg to autoheal
      set_fact:
        service_cfg: "{{ autoheal }}"
    - name: Deploy Autoheal
      include_role:
        name: autoheal
    - name: Set service_cfg to portainer
      set_fact:
        service_cfg: "{{ portainer }}"
    - name: Deploy Portainer
      include_role:
        name: portainer

ok thanks for your reply and "workaround". It works for me as well.

DanielK990 commented 5 months ago

Thanks! So the original code must have been untested ...

AndreasCS commented 3 months ago

As far as I understand it, this is a problem with the variable precedence in ansible (https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html#understanding-variable-precedence). The variable "service_cfg" is overwritten in the role compose_hull, file "facts.yml" (merged with the different defaults an the values set in the playbook ). After the first call of the role compose_hull the variable is set in the role and can not be changed from the outside of the role. To avoid such problems, the best solution is not to set the same variable inside and outside of the role. I changed the name "service_cfg" to "srv_cfg" in the playbooks and also in the file "facts.yml", task "Merge service config and service defaults": service_cfg: "{{ service_base_defaults | ansible.builtin.combine(service_defaults, all_service_defaults, srv_cfg, recursive=true) }}" After this change the playbook system-setup.yml works correctly.

W11T commented 2 months ago

@AndreasCS , thanks for your workaround! I made the changes. But additionally i have to insert items owner and subdirs in each of the sections in group_vars/all.yml. Do you confirm? Else, maybe, i made a mistake.