ansible: Add playbook for Debian major version upgrades
authorKienan Stewart <kstewart@efficios.com>
Mon, 12 Jun 2023 19:38:32 +0000 (15:38 -0400)
committerKienan Stewart <kstewart@efficios.com>
Tue, 13 Jun 2023 17:34:47 +0000 (13:34 -0400)
Useful when recreating the node from scratch isn't a quick option

Change-Id: I5ebd413604a0f0f48474c205ae88a8a7bf99c2ee

automation/ansible/playbooks/debian-upgrade.yml [new file with mode: 0644]

diff --git a/automation/ansible/playbooks/debian-upgrade.yml b/automation/ansible/playbooks/debian-upgrade.yml
new file mode 100644 (file)
index 0000000..6e6ce6d
--- /dev/null
@@ -0,0 +1,172 @@
+---
+- 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
This page took 0.025494 seconds and 4 git commands to generate.