93 lines
3.8 KiB
YAML
93 lines
3.8 KiB
YAML
---
|
|
# Update Portainer Edge Agent across homelab hosts
|
|
#
|
|
# Usage:
|
|
# ansible-playbook -i hosts.ini playbooks/update_portainer_agent.yml
|
|
# ansible-playbook -i hosts.ini playbooks/update_portainer_agent.yml -e "agent_version=2.33.7"
|
|
# ansible-playbook -i hosts.ini playbooks/update_portainer_agent.yml --limit vish-concord-nuc
|
|
#
|
|
# Notes:
|
|
# - Reads EDGE_ID and EDGE_KEY from the running container — no secrets needed in vars
|
|
# - Set docker_bin in host_vars to override the docker binary path per host
|
|
# - For Synology (calypso): docker_bin includes sudo prefix since Ansible become
|
|
# does not reliably escalate on DSM
|
|
|
|
- name: Update Portainer Edge Agent
|
|
hosts: portainer_edge_agents
|
|
gather_facts: false
|
|
vars:
|
|
agent_version: "2.33.7"
|
|
agent_image: "portainer/agent:{{ agent_version }}"
|
|
container_name: portainer_edge_agent
|
|
|
|
tasks:
|
|
- name: Check container exists
|
|
shell: "{{ docker_bin | default('docker') }} inspect {{ container_name }} --format '{{ '{{' }}.Id{{ '}}' }}'"
|
|
register: container_check
|
|
changed_when: false
|
|
failed_when: container_check.rc != 0
|
|
|
|
- name: Get current image
|
|
shell: "{{ docker_bin | default('docker') }} inspect {{ container_name }} --format '{{ '{{' }}.Config.Image{{ '}}' }}'"
|
|
register: current_image
|
|
changed_when: false
|
|
|
|
- name: Get EDGE environment vars from running container
|
|
shell: "{{ docker_bin | default('docker') }} inspect {{ container_name }} --format '{{ '{{' }}json .Config.Env{{ '}}' }}'"
|
|
register: container_env
|
|
changed_when: false
|
|
|
|
- name: Parse EDGE_ID
|
|
set_fact:
|
|
edge_id: "{{ (container_env.stdout | from_json | select('match', 'EDGE_ID=.*') | list | first).split('=', 1)[1] }}"
|
|
|
|
- name: Parse EDGE_KEY
|
|
set_fact:
|
|
edge_key: "{{ (container_env.stdout | from_json | select('match', 'EDGE_KEY=.*') | list | first).split('=', 1)[1] }}"
|
|
|
|
- name: Pull new agent image
|
|
shell: "{{ docker_bin | default('docker') }} pull {{ agent_image }}"
|
|
register: pull_result
|
|
changed_when: "'Status: Downloaded newer image' in pull_result.stdout"
|
|
|
|
- name: Skip if already on target version
|
|
debug:
|
|
msg: "{{ inventory_hostname }}: already running {{ agent_image }}, skipping recreate"
|
|
when: current_image.stdout == agent_image and not pull_result.changed
|
|
|
|
- name: Stop old container
|
|
shell: "{{ docker_bin | default('docker') }} stop {{ container_name }}"
|
|
when: current_image.stdout != agent_image or pull_result.changed
|
|
|
|
- name: Remove old container
|
|
shell: "{{ docker_bin | default('docker') }} rm {{ container_name }}"
|
|
when: current_image.stdout != agent_image or pull_result.changed
|
|
|
|
- name: Start new container
|
|
shell: >
|
|
{{ docker_bin | default('docker') }} run -d
|
|
--name {{ container_name }}
|
|
--restart always
|
|
-v /var/run/docker.sock:/var/run/docker.sock
|
|
-v {{ docker_volumes_path | default('/var/lib/docker/volumes') }}:/var/lib/docker/volumes
|
|
-v /:/host
|
|
-v portainer_agent_data:/data
|
|
-e EDGE=1
|
|
-e EDGE_ID={{ edge_id }}
|
|
-e EDGE_KEY={{ edge_key }}
|
|
-e EDGE_INSECURE_POLL=1
|
|
{{ agent_image }}
|
|
when: current_image.stdout != agent_image or pull_result.changed
|
|
|
|
- name: Wait for container to be running
|
|
shell: "{{ docker_bin | default('docker') }} ps --filter 'name={{ container_name }}' --format '{{ '{{' }}.Status{{ '}}' }}'"
|
|
register: container_status
|
|
retries: 5
|
|
delay: 3
|
|
until: "'Up' in container_status.stdout"
|
|
when: current_image.stdout != agent_image or pull_result.changed
|
|
|
|
- name: Report result
|
|
debug:
|
|
msg: "{{ inventory_hostname }}: {{ current_image.stdout }} → {{ agent_image }} | {{ container_status.stdout | default('no change') }}"
|