diff --git a/life-church/playbooks/thinkcenter-update.yml b/life-church/playbooks/thinkcenter-update.yml new file mode 100644 index 0000000..95f8d80 --- /dev/null +++ b/life-church/playbooks/thinkcenter-update.yml @@ -0,0 +1,101 @@ +--- +# ============================================================================ +# life-church/playbooks/thinkcenter-update.yml +# Update + upgrade thinkcenter ONLY (apt). CHANGES the system. +# +# - Refreshes apt cache, performs a full dist-upgrade, autoremoves orphans. +# - become password fetched from Infisical /lc-hosts at runtime (never hardcoded). +# - Reports whether a reboot is required afterwards (does NOT reboot automatically). +# +# UNDO: apt upgrades are not auto-reversible. To roll back a specific package use +# `apt install =` and hold it (`apt-mark hold `). +# `/var/log/apt/history.log` on the host records exactly what changed. +# ============================================================================ + +# --- Play 1 (localhost): fetch thinkcenter's sudo password from Infisical ---- +- name: "thinkcenter update — resolve become password from Infisical" + hosts: localhost + gather_facts: false + tasks: + - name: "[resolve] Infisical creds from env" + ansible.builtin.set_fact: + infisical_client_id: "{{ lookup('env','INFISICAL_CLIENT_ID') }}" + infisical_client_secret: "{{ lookup('env','INFISICAL_CLIENT_SECRET') }}" + infisical_project_id: "{{ lookup('env','INFISICAL_PROJECT_ID') }}" + infisical_url: "{{ lookup('env','INFISICAL_API_URL') | default('http://192.168.122.41:8080', true) }}" + infisical_env_slug: "{{ lookup('env','INFISICAL_ENV_SLUG') | default('prod', true) }}" + + - name: "[resolve] Assert Infisical creds present" + ansible.builtin.assert: + that: + - infisical_client_id | length > 0 + - infisical_client_secret | length > 0 + - infisical_project_id | length > 0 + fail_msg: "Infisical creds missing from Semaphore environment 'infisical-dev'." + + - name: "[infisical] Log in" + infisical.vault.login: + url: "{{ infisical_url }}" + auth_method: universal_auth + universal_auth_client_id: "{{ infisical_client_id }}" + universal_auth_client_secret: "{{ infisical_client_secret }}" + register: infisical_login + no_log: true + + - name: "[infisical] Read /lc-hosts" + infisical.vault.read_secrets: + login_data: "{{ infisical_login.login_data }}" + project_id: "{{ infisical_project_id }}" + env_slug: "{{ infisical_env_slug }}" + path: "/lc-hosts" + as_dict: true + register: lc_secrets + no_log: true + + - name: "[set] Stash thinkcenter sudo pass" + ansible.builtin.set_fact: + thinkcenter_become_pass: "{{ lc_secrets.secrets['THINKCENTER_SUDO_PASS'] }}" + no_log: true + +# --- Play 2: update + upgrade thinkcenter ONLY ------------------------------- +- name: "Update + upgrade thinkcenter" + hosts: thinkcenter # thinkcenter only — tc1 is not targeted + gather_facts: true + become: true + vars: + ansible_become_pass: "{{ hostvars['localhost'].thinkcenter_become_pass }}" + tasks: + - name: "[safety] Confirm we are on thinkcenter" + ansible.builtin.assert: + that: inventory_hostname == 'thinkcenter' + fail_msg: "Refusing to run — this play is scoped to thinkcenter only." + + - name: "[apt] Update cache + full dist-upgrade" + ansible.builtin.apt: + update_cache: true + cache_valid_time: 0 + upgrade: dist + register: upgrade_result + + - name: "[apt] Autoremove unused dependencies" + ansible.builtin.apt: + autoremove: true + register: autoremove_result + + - name: "[apt] Autoclean cached package files" + ansible.builtin.apt: + autoclean: true + + - name: "[reboot] Reboot-required flag present?" + ansible.builtin.stat: + path: /var/run/reboot-required + register: reboot_required + + - name: "[report] Update summary" + ansible.builtin.debug: + msg: + - "===== thinkcenter update =====" + - "Upgrade changed system : {{ upgrade_result.changed }}" + - "Autoremove changed : {{ autoremove_result.changed }}" + - "Reboot required : {{ 'YES — reboot when convenient' if reboot_required.stat.exists else 'no' }}" + - "Details in /var/log/apt/history.log on the host."