Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 151 additions & 0 deletions ansible/playbooks/home-assistant.yml
Original file line number Diff line number Diff line change
@@ -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
Loading