Eliminate localhost tasks to fix sudo issue on Semaphore runner
- Play 3: Run Portainer API calls from remote hosts directly (no delegate_to: localhost). Add validate_certs: false for self-signed cert. - Play 4: Replace localhost file report with debug output using run_once. No filesystem writes = no privilege escalation needed on the runner. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
b8dde7f2ca
commit
6db20117fd
@ -140,6 +140,9 @@
|
|||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Play 3: Register Docker hosts in Portainer
|
# Play 3: Register Docker hosts in Portainer
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
# Runs the Portainer API calls FROM each remote host (not delegate_to localhost)
|
||||||
|
# to avoid privilege escalation issues on the Semaphore runner.
|
||||||
|
# validate_certs: false needed for Portainer's self-signed cert.
|
||||||
|
|
||||||
- name: Register Docker hosts in Portainer
|
- name: Register Docker hosts in Portainer
|
||||||
hosts: all
|
hosts: all
|
||||||
@ -161,10 +164,8 @@
|
|||||||
X-API-Key: "{{ portainer_api_token }}"
|
X-API-Key: "{{ portainer_api_token }}"
|
||||||
return_content: true
|
return_content: true
|
||||||
status_code: 200
|
status_code: 200
|
||||||
|
validate_certs: false
|
||||||
register: existing_endpoints
|
register: existing_endpoints
|
||||||
delegate_to: localhost
|
|
||||||
become: false
|
|
||||||
run_once: false
|
|
||||||
|
|
||||||
- name: Determine if this host is already enrolled
|
- name: Determine if this host is already enrolled
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
@ -188,9 +189,8 @@
|
|||||||
URL: "tcp://{{ ansible_host }}:{{ portainer_agent_port }}"
|
URL: "tcp://{{ ansible_host }}:{{ portainer_agent_port }}"
|
||||||
status_code: [200, 201]
|
status_code: [200, 201]
|
||||||
return_content: true
|
return_content: true
|
||||||
|
validate_certs: false
|
||||||
register: portainer_enroll
|
register: portainer_enroll
|
||||||
delegate_to: localhost
|
|
||||||
become: false
|
|
||||||
when: not already_enrolled
|
when: not already_enrolled
|
||||||
|
|
||||||
- name: Store enrollment result
|
- name: Store enrollment result
|
||||||
@ -209,24 +209,17 @@
|
|||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Play 4: Generate local report
|
# Play 4: Print discovery report to Semaphore output
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
# Runs on all hosts but only executes once (run_once: true per task).
|
||||||
|
# Uses debug instead of file I/O to avoid any privilege issues on the runner.
|
||||||
|
|
||||||
- name: Generate Docker host discovery report
|
- name: Print Docker host discovery report
|
||||||
hosts: localhost
|
hosts: all
|
||||||
gather_facts: false
|
gather_facts: false
|
||||||
become: false
|
|
||||||
vars:
|
|
||||||
report_path: "{{ playbook_dir }}/../semaphore/reports/docker_hosts_{{ ansible_date_time.date }}.txt"
|
|
||||||
tasks:
|
tasks:
|
||||||
|
|
||||||
- name: Ensure reports directory exists
|
- name: Collect discovery results
|
||||||
ansible.builtin.file:
|
|
||||||
path: "{{ playbook_dir }}/../semaphore/reports"
|
|
||||||
state: directory
|
|
||||||
mode: "0755"
|
|
||||||
|
|
||||||
- name: Collect results from all hosts
|
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
docker_hosts_found: >-
|
docker_hosts_found: >-
|
||||||
{{
|
{{
|
||||||
@ -250,44 +243,30 @@
|
|||||||
| rejectattr('value.ssh_reachable', 'equalto', false)
|
| rejectattr('value.ssh_reachable', 'equalto', false)
|
||||||
| map(attribute='key') | list | sort
|
| map(attribute='key') | list | sort
|
||||||
}}
|
}}
|
||||||
|
run_once: true
|
||||||
|
|
||||||
- name: Write report to file
|
- name: Print discovery report
|
||||||
ansible.builtin.copy:
|
|
||||||
dest: "{{ report_path }}"
|
|
||||||
mode: "0644"
|
|
||||||
content: |
|
|
||||||
Docker Host Discovery Report
|
|
||||||
============================
|
|
||||||
Generated: {{ ansible_date_time.iso8601 }}
|
|
||||||
Portainer: {{ portainer_url }}
|
|
||||||
|
|
||||||
DOCKER HOSTS FOUND ({{ docker_hosts_found | length }})
|
|
||||||
{% for h in docker_hosts_found %}
|
|
||||||
- {{ h }}
|
|
||||||
IP: {{ hostvars[h].ansible_host | default('unknown') }}
|
|
||||||
Docker version: {{ hostvars[h].docker_version | default('unknown') }}
|
|
||||||
Portainer ID: {{ hostvars[h].portainer_endpoint_id | default('not enrolled') }}
|
|
||||||
Enrolled now: {{ hostvars[h].portainer_enrolled_now | default(false) }}
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
NO DOCKER ({{ no_docker_hosts | length }})
|
|
||||||
{% for h in no_docker_hosts %}
|
|
||||||
- {{ h }} ({{ hostvars[h].ansible_host | default('?') }})
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
UNREACHABLE ({{ unreachable_hosts | length }})
|
|
||||||
{% for h in unreachable_hosts %}
|
|
||||||
- {{ h }} ({{ hostvars[h].ansible_host | default('?') }})
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
- name: Print report path
|
|
||||||
ansible.builtin.debug:
|
|
||||||
msg: "Report written to {{ report_path }}"
|
|
||||||
|
|
||||||
- name: Print Docker hosts summary
|
|
||||||
ansible.builtin.debug:
|
ansible.builtin.debug:
|
||||||
msg: |
|
msg: |
|
||||||
Docker hosts found ({{ docker_hosts_found | length }}):
|
============================================================
|
||||||
|
Docker Host Discovery Report — {{ portainer_url }}
|
||||||
|
============================================================
|
||||||
|
|
||||||
|
DOCKER FOUND ({{ docker_hosts_found | length }}):
|
||||||
{% for h in docker_hosts_found %}
|
{% for h in docker_hosts_found %}
|
||||||
- {{ h }} ({{ hostvars[h].ansible_host | default('?') }}) Docker {{ hostvars[h].docker_version | default('?') }}
|
{{ h }} ({{ hostvars[h].ansible_host | default('?') }})
|
||||||
|
Docker: {{ hostvars[h].docker_version | default('?') }}
|
||||||
|
Portainer: ID={{ hostvars[h].portainer_endpoint_id | default('n/a') }} enrolled_now={{ hostvars[h].portainer_enrolled_now | default(false) }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
|
NO DOCKER ({{ no_docker_hosts | length }}):
|
||||||
|
{% for h in no_docker_hosts %}
|
||||||
|
{{ h }} ({{ hostvars[h].ansible_host | default('?') }})
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
UNREACHABLE ({{ unreachable_hosts | length }}):
|
||||||
|
{% for h in unreachable_hosts %}
|
||||||
|
{{ h }} ({{ hostvars[h].ansible_host | default('?') }})
|
||||||
|
{% endfor %}
|
||||||
|
============================================================
|
||||||
|
run_once: true
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user