diff --git a/ansible/playbooks/home-assistant.yml b/ansible/playbooks/home-assistant.yml new file mode 100644 index 0000000..bfb1722 --- /dev/null +++ b/ansible/playbooks/home-assistant.yml @@ -0,0 +1,151 @@ +--- +# Deploy Home Assistant Container on RPi 4B (Debian 12 Bookworm). +# HA runs directly on the metal via Docker with host networking so it can +# discover LAN devices (mDNS, SSDP, etc.). Traefik in k3s reverse-proxies +# https://ha.apps.lab.home.arpa → 192.168.1.116:8123. +# +# Run: +# ansible-playbook -i inventory/hosts.yml playbooks/home-assistant.yml \ +# --vault-password-file .vault_pass --check +# ansible-playbook -i inventory/hosts.yml playbooks/home-assistant.yml \ +# --vault-password-file .vault_pass + +- name: Home Assistant Container (RPi 4B) + hosts: home_assistant + become: true + + vars: + ha_config_dir: /srv/homeassistant + ha_image: ghcr.io/home-assistant/home-assistant:stable + # Pod CIDR in the k3s cluster — HA must trust Traefik's source IPs. + # Adjust if your cluster uses a non-default pod CIDR. + k3s_pod_cidr: 10.42.0.0/16 + + tasks: + # ── Docker ────────────────────────────────────────────────────────────────── + - name: Install Docker prerequisites + ansible.builtin.apt: + name: [ca-certificates, curl, gnupg] + state: present + update_cache: true + + - name: Add Docker GPG key + ansible.builtin.shell: | + install -m 0755 -d /etc/apt/keyrings + curl -fsSL https://download.docker.com/linux/debian/gpg \ + | gpg --dearmor -o /etc/apt/keyrings/docker.gpg + chmod a+r /etc/apt/keyrings/docker.gpg + args: + creates: /etc/apt/keyrings/docker.gpg + + - name: Add Docker apt repository + ansible.builtin.apt_repository: + repo: > + deb [arch={{ 'arm64' if ansible_architecture == 'aarch64' else ansible_architecture }} + signed-by=/etc/apt/keyrings/docker.gpg] + https://download.docker.com/linux/debian + {{ ansible_distribution_release }} stable + filename: docker + state: present + + - name: Install Docker CE + ansible.builtin.apt: + name: [docker-ce, docker-ce-cli, containerd.io] + state: present + update_cache: true + + - name: Enable + start Docker + ansible.builtin.systemd: + name: docker + enabled: true + state: started + + - name: Add ansible user to docker group + ansible.builtin.user: + name: "{{ ansible_user }}" + groups: docker + append: true + + # ── Home Assistant ────────────────────────────────────────────────────────── + - name: Create HA config directory + ansible.builtin.file: + path: "{{ ha_config_dir }}" + state: directory + owner: root + mode: "0755" + + - name: Pull HA image + community.docker.docker_image: + name: "{{ ha_image }}" + source: pull + ignore_errors: true # non-fatal — systemd will pull on first start + + - name: Deploy HA systemd service + ansible.builtin.copy: + dest: /etc/systemd/system/home-assistant.service + mode: "0644" + content: | + [Unit] + Description=Home Assistant + After=docker.service network-online.target + Requires=docker.service + + [Service] + Restart=on-failure + RestartSec=10 + ExecStartPre=-/usr/bin/docker rm -f home-assistant + ExecStart=/usr/bin/docker run --rm \ + --name home-assistant \ + --network host \ + --privileged \ + -v {{ ha_config_dir }}:/config \ + -e TZ=America/Chicago \ + {{ ha_image }} + ExecStop=/usr/bin/docker stop home-assistant + + [Install] + WantedBy=multi-user.target + notify: restart home-assistant + + - name: Enable + start Home Assistant + ansible.builtin.systemd: + name: home-assistant + daemon_reload: true + enabled: true + state: started + + # ── Traefik trusted_proxies config ────────────────────────────────────────── + # HA must trust the k3s pod CIDR so Traefik can forward requests without + # triggering "IP ban" on the proxy IP. + - name: Ensure HA http trusted_proxies config is present + ansible.builtin.blockinfile: + path: "{{ ha_config_dir }}/configuration.yaml" + create: true + marker: "# {mark} ANSIBLE MANAGED — Traefik trusted proxy" + block: | + http: + use_x_forwarded_for: true + trusted_proxies: + - {{ k3s_pod_cidr }} + - 127.0.0.1 + notify: restart home-assistant + + - name: Wait for HA to be reachable on :8123 + ansible.builtin.uri: + url: "http://{{ ansible_host }}:8123" + status_code: [200, 302] + register: ha_check + until: ha_check.status in [200, 302] + retries: 18 + delay: 10 + changed_when: false + + - name: Show HA URL + ansible.builtin.debug: + msg: "Home Assistant reachable at http://{{ ansible_host }}:8123 — complete onboarding there." + + handlers: + - name: restart home-assistant + ansible.builtin.systemd: + name: home-assistant + state: restarted