# Raspberry Pi Ansible Management Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Add `naruto` and `pi` Raspberry Pis to Ansible inventory under a new `raspberry_pi` role, starting with `common` as the base. **Architecture:** New inventory group `raspberry_pi` with a dedicated role of the same name. The playbook applies both `common` and `raspberry_pi` roles. Two ARM incompatibilities in `extra_packages.yaml` are fixed in the `common` role itself so all future ARM hosts benefit. **Tech Stack:** Ansible, Debian 11 (Bullseye), aarch64 --- ## File Map | Action | Path | Responsibility | |--------|------|----------------| | Create | `vars/raspberry_pi.ini` | Inventory group with naruto and pi | | Create | `vars/group_vars/raspberry_pi/vars.yaml` | Group-level vars (empty, inherits from `all`) | | Modify | `roles/common/tasks/extra_packages.yaml` | Fix `bottom` arch and Neovim AppImage for ARM | | Create | `roles/raspberry_pi/tasks/main.yaml` | Role entry point, placeholder for future Pi tasks | | Create | `playbooks/raspberry-pi.yaml` | Playbook targeting `raspberry_pi` group | --- ### Task 1: Add inventory and group vars **Files:** - Create: `vars/raspberry_pi.ini` - Create: `vars/group_vars/raspberry_pi/vars.yaml` - [ ] **Create inventory file** ```ini [raspberry_pi] naruto pi ``` Save to `vars/raspberry_pi.ini`. - [ ] **Create group vars file** ```yaml --- ``` Save to `vars/group_vars/raspberry_pi/vars.yaml`. Empty for now — both hosts inherit all vars from `vars/group_vars/all/`. - [ ] **Verify Ansible can see both hosts** ```bash ansible raspberry_pi --list-hosts ``` Expected output: ``` hosts (2): naruto pi ``` - [ ] **Commit** ```bash git add vars/raspberry_pi.ini vars/group_vars/raspberry_pi/vars.yaml git commit -m "feat(raspberry_pi): add inventory and group vars" ``` --- ### Task 2: Fix ARM incompatibilities in `common/tasks/extra_packages.yaml` **Files:** - Modify: `roles/common/tasks/extra_packages.yaml` Two issues to fix: **Issue 1 — `bottom` deb URL is hardcoded to `amd64`.** The global `arch` variable already resolves to `arm64` on aarch64 hosts. **Issue 2 — Neovim AppImage doesn't run on aarch64.** `neovim` is already installed via apt in `common_packages`, so on ARM we skip the AppImage entirely and the apt version is used. - [ ] **Fix `bottom` URL to use `arch` variable** In `roles/common/tasks/extra_packages.yaml`, replace: ```yaml - name: Install bottom package ansible.builtin.apt: deb: https://github.com/ClementTsang/bottom/releases/download/0.9.6/bottom_0.9.6_amd64.deb state: present become: true ``` With: ```yaml - name: Install bottom package ansible.builtin.apt: deb: https://github.com/ClementTsang/bottom/releases/download/0.9.6/bottom_0.9.6_{{ arch }}.deb state: present become: true ``` - [ ] **Add `when: ansible_architecture != 'aarch64'` to all Neovim AppImage tasks** Replace the six Neovim AppImage tasks (from "Check if Neovim is already installed" through "Remove Neovim AppImage") with the version below. The neovim config clone tasks at the end are architecture-independent and stay unchanged. ```yaml - name: Check if Neovim is already installed ansible.builtin.command: "which nvim" register: neovim_installed changed_when: false ignore_errors: true when: ansible_architecture != 'aarch64' - name: Download Neovim AppImage ansible.builtin.get_url: url: https://github.com/neovim/neovim/releases/download/v0.10.0/nvim.appimage dest: /tmp/nvim.appimage mode: "0755" when: ansible_architecture != 'aarch64' and neovim_installed.rc != 0 register: download_result - name: Extract Neovim AppImage ansible.builtin.command: cmd: "./nvim.appimage --appimage-extract" chdir: /tmp when: ansible_architecture != 'aarch64' and download_result.changed register: extract_result - name: Copy extracted Neovim files to /usr ansible.builtin.copy: src: /tmp/squashfs-root/usr/ dest: /usr/ remote_src: true mode: "0755" become: true when: ansible_architecture != 'aarch64' and extract_result.changed - name: Clean up extracted Neovim files ansible.builtin.file: path: /tmp/squashfs-root state: absent when: ansible_architecture != 'aarch64' and extract_result.changed - name: Remove Neovim AppImage ansible.builtin.file: path: /tmp/nvim.appimage state: absent when: ansible_architecture != 'aarch64' and download_result.changed ``` - [ ] **Commit** ```bash git add roles/common/tasks/extra_packages.yaml git commit -m "fix(common): support aarch64 in extra_packages" ``` --- ### Task 3: Create `raspberry_pi` role **Files:** - Create: `roles/raspberry_pi/tasks/main.yaml` - [ ] **Create role task entry point** ```yaml --- ``` Save to `roles/raspberry_pi/tasks/main.yaml`. Intentionally empty for now — Pi-specific workloads (Newt on naruto, docker stack on pi) are added in future tasks. - [ ] **Commit** ```bash git add roles/raspberry_pi/tasks/main.yaml git commit -m "feat(raspberry_pi): add empty role scaffold" ``` --- ### Task 4: Create playbook **Files:** - Create: `playbooks/raspberry-pi.yaml` - [ ] **Create playbook** ```yaml --- - name: Set up Raspberry Pis hosts: raspberry_pi gather_facts: true roles: - role: common tags: - common - role: raspberry_pi tags: - raspberry_pi ``` Save to `playbooks/raspberry-pi.yaml`. - [ ] **Commit** ```bash git add playbooks/raspberry-pi.yaml git commit -m "feat(raspberry_pi): add playbook" ``` --- ### Task 5: Run and verify - [ ] **Dry-run against both hosts** ```bash ansible-playbook playbooks/raspberry-pi.yaml --check ``` Note: the `apt upgrade` task will fail in check mode without `python3-apt` on the remote (same issue seen with mii). If it fails there, proceed to the real run. - [ ] **Run for real** ```bash ansible-playbook playbooks/raspberry-pi.yaml ``` Expected: all tasks `ok` or `changed`, no failures. Watch for: - `bottom` task — should download `arm64` deb - Neovim AppImage tasks — should be skipped on both hosts - Hostname task — `pi` will be renamed from `raspberrypi` to `pi` - [ ] **Verify hostname on pi was updated** ```bash ssh pi "hostname" ``` Expected: `pi` - [ ] **Verify bottom installed correctly on both** ```bash ansible raspberry_pi -a "btm --version" ``` Expected: version string printed for both hosts, no errors.