community.general.tss lookup fails inside Docker (Semaphore)

Hello,

Environment:

  • Ansible Controller Host: Ubuntu / Debian

  • Automation Platform: Semaphore running inside a Docker container

  • Secret Server: On-Premise

  • Plugin: community.general.tss

I am facing a strange authentication issue with the community.general.tss (Delinea/Thycotic Secret Server) lookup plugin when running inside a Semaphore (docker rootless) environment, whereas the exact same playbook runs flawlessly when executed directly via the host’s CLI.

The Problem:

When calling the lookup plugin from within the Semaphore container, it constantly fails with:

\[ERROR\]: Task failed: Finalization of task args for 'ansible.builtin.set_fact' failed: Error while resolving value for '\_secret': The lookup plugin 'community.general.tss' failed: Secret Server lookup failure: Unable to detect server type via health check endpoints.

I have the same ansible project on my host machine. When I test my playbook, everything works fine. But it always fails when executing with Semaphore UI. Semaphore uses my Gitlab repo to execute the playbooks.

Here is my logic of “auth_tss” role:

---
- name: "[tss] Create local download directory for SSH keys"
  ansible.builtin.file:
    path: "{{ key_download_path }}"
    state: directory
    mode: "0700"
  delegate_to: localhost
  become: false
  when: inventory_hostname != 'localhost'

- name: "[tss] Fetch secret and SSH key from Secret Server"
  ansible.builtin.set_fact:
    _secret: "{{ lookup('community.general.tss', tss_secret_id,
      fetch_attachments=True,
      file_download_path=key_download_path,
      base_url=tss_base_url,
      username=tss_ansible_user,
      password=tss_ansible_pass,
      domain=tss_domain) }}"
    #_fields: "{{ _secret['items'] | items2dict(key_name='slug', value_name='itemValue') }}"
  no_log: false
  delegate_to: localhost
  become: false
  when: inventory_hostname != 'localhost'

- name: "[tss] Build field dict from secret"
  ansible.builtin.set_fact:
    _fields: "{{ _secret['items'] | items2dict(key_name='slug', value_name='itemValue') }}"
  no_log: true
  when: inventory_hostname != 'localhost'

- name: "[tss] Set restrictive permissions on SSH private key"
  ansible.builtin.file:
    path: "{{ key_download_path }}/{{ tss_secret_id }}_private-key"
    mode: "0600"
  delegate_to: localhost
  become: false
  when: inventory_hostname != 'localhost'


- name: "[tss] Set Ansible connection credentials from TSS secret"
  ansible.builtin.set_fact:
    ansible_user: "{{ _fields['username'] }}"
    ansible_become_password: "{{ _fields['password'] | default('') }}"
    ansible_ssh_private_key_file: "{{ key_download_path }}/{{ tss_secret_id }}_private-key"
    ansible_ssh_private_key_file_passphrase: "{{ _fields['private-key-passphrase'] | default('') }}"
  no_log: false
  when: inventory_hostname != 'localhost'


and here is my playbook im testing:

---
- name: Configure unattended upgrades (custom secure setup)
  hosts: ubuntu
  gather_facts: false

  pre_tasks:
    - name: TSS Authentication
      ansible.builtin.import_role:
        name: auth_tss
      tags: [always]

  roles:
    - unattended_upgrades_custom

I really don’t know what the problem is. Do I miss something? Do I need to define the variables like “tss_ansible_user” in semaphore UI or in my repo?

Any help would be appreciated!