--- - name: Set next release hosts: all tasks: - debug: msg: "{{lookup('vars', ansible_distribution+'_releases', default=[])}}" - debug: msg: "{{ansible_distribution_release}}" - set_fact: release_index: "{{lookup('ansible.utils.index_of', data=lookup('vars', ansible_distribution+'_releases', default=[]), test='eq', value=ansible_distribution_release)}}" # If there is not a next release available (as defined below in Debian_releasess # or Ubuntu_releases), the execution of the playbook will fail at this step. - set_fact: next_release: "{{lookup('vars', ansible_distribution+'_releases')[release_index|int + 1]}}" - debug: msg: "{{next_release}}" vars: # 'stable' releases ordered from oldest to newest Debian_releases: - buster - bullseye - bookworm Ubuntu_releases: - xenial - bionic - focal - jammy - name: Run any outstanding upgrades hosts: all tasks: - apt: update_cache: true - apt: upgrade: dist - apt: autoremove: true purge: true - name: Pre-upgrade backups hosts: all tasks: - name: Check if /etc is a git repo register: etckeeper command: cmd: test -d /etc/.git ignore_errors: true - name: Tag etc configuration when: etckeeper.rc == 0 block: - command: chdir: /etc argv: - git - tag - "pre-{{next_release}}" - command: chdir: /etc cmd: 'git gc --prune' - name: Backup package state block: - shell: cmd: "tar czf /var/backups/pre-{{next_release}}-backup.tgz /etc /var/lib/dpkg /var/lib/apt/extended_states" # Mitogen doesn't seem to work with the 'archive' module, since tarfile is # "present in the Mitogent importer blacklist", so a shell command is used # here instead warn: false - shell: cmd: "dpkg --get-selections '*' > /var/backups/dpkg-selections-pre-{{next_release}}.txt" - file: path: "{{item}}" mode: '0600' with_items: - "/var/backups/pre-{{next_release}}-backup.tgz" - "/var/backups/dpkg-selections-pre-{{next_release}}.txt" - name: Debian major version upgrade hosts: all when: ansible_distribution == 'Debian' vars: apt_noninteractive_environment: DEBIAN_FRONTEND: noninteractive APT_LISTCHANGES_FRONTEND: mail tasks: # @TODO: Remove pins # @TODO: Should 3rd party sources be removed? # @TODO: Ensure kernel package is installed # @TODO: Should a 2nd sshd be started on a non-standard port in case of failure? - name: dpkg audit command: cmd: 'dpkg --audit' - name: show holds command: cmd: 'apt-mark showhold' - name: remove all holds command: cmd: "apt-mark unhold '*'" - name: Replace release in apt sources.list replace: regexp: "{{ansible_distribution_release}}" replace: "{{next_release}}" path: /etc/apt/sources.list - name: Replace release in apt sources.list.d shell: cmd: "sed -i 's/{{ansible_distribution_release}}/{{next_release}}/' /etc/apt/sources.list.d/*" warn: false ignore_errors: true - apt: update_cache: true # @TODO: Check required disk space and available disk space - name: Download packages command: cmd: 'apt-get -y -d upgrade' warn: false environment: "{{apt_noninteractive_environment}}" - name: Minimal upgrade run command: cmd: 'apt upgrade -y --without-new-pkgs' warn: false environment: "{{apt_noninteractive_environment}}" - name: Full upgrade run command: cmd: 'apt full-upgrade -y' warn: false environment: "{{apt_noninteractive_environment}}" # @TODO: reconfigure grub if installed # `dpkg-reconfigure grub-pc` on many systems, but not all # @TODO: Our instances often have an OS version identifier, # it would be handy to do a replace in /etc/hostname # before rebooting - name: Reboot command: /usr/sbin/reboot async: 0 poll: 0 ignore_errors: true register: last_result - name: wait for the server to reboot local_action: wait_for host={{ inventory_hostname }} port=22 delay=1 timeout=300 state=started when: last_result.changed become: false - name: Purge configuration of removed packages command: cmd: "apt -y purge '~c'" warn: false environment: "{{apt_noninteractive_environment}}" - name: Purge obsolete packages command: cmd: "apt -y purge '~o'" warn: false environment: "{{apt_noninteractive_environment}}" - name: Ubuntu major version upgrade hosts: all when: ansible_distribution == 'Ubuntu' tasks: - name: Do release upgrade command: cmd: 'do-release-upgrade -m server --frontend=DistUpgradeViewNonInteractive' - name: Post-upgrade tasks hosts: all tasks: - name: Mark rsyslog as auto when: next_release == 'bookworm' command: cmd: 'apt-mark auto rsyslog' - name: Autoremove any packages apt: autoremove: true purge: true - name: Clean apt cache apt: autoclean: true