Files
homelab-optimized/ansible/automation/playbooks/update_portainer_agent.yml
Gitea Mirror Bot e7652c8dab
Some checks failed
Documentation / Build Docusaurus (push) Failing after 5m3s
Documentation / Deploy to GitHub Pages (push) Has been skipped
Sanitized mirror from private repository - 2026-04-20 01:32:01 UTC
2026-04-20 01:32:01 +00:00

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') }}"