feat: add Ansible playbook to mask avahi-daemon on all Ubuntu VMs (#28) #39

Closed
Claude wants to merge 0 commits from issue/28-ansible-playbook-mask-avahi-daemon-across-all-ubun into main
Collaborator

Closes #28

Summary

  • New file: ansible/playbooks/mask-avahi.yml — targets the vms:physical inventory groups (all 5 Ubuntu QEMU VMs + ubuntu-manticore physical server). Stops, masks, and verifies avahi-daemon is permanently disabled.
  • Updated: vm-management/scripts/cloud-init-user-data.yaml — adds avahi masking to the runcmd section so any future VM provisioned from this template is hardened from first boot.

Implementation notes

  • The playbook targets vms:physical which matches the existing inventory groups on the Ansible controller (LXC 304 at 10.10.0.232) — no inventory changes needed, all Ubuntu VMs are already managed.
  • ignore_errors: true on the stop task handles hosts where avahi is already stopped or not installed.
  • changed_when: false on the verify task suppresses false-positive changed status.
  • | trim filter on the stdout check handles trailing newlines from systemctl is-enabled.

Usage

# SSH to the Ansible controller
ssh ansible

# Dry run first
ansible-playbook /opt/ansible/playbooks/mask-avahi.yml --check

# Test on one VM
ansible-playbook /opt/ansible/playbooks/mask-avahi.yml --limit discord-bots

# Roll out to all
ansible-playbook /opt/ansible/playbooks/mask-avahi.yml

Rollback

# On any host, if mDNS is ever needed:
systemctl unmask avahi-daemon
Closes #28 ## Summary - **New file**: `ansible/playbooks/mask-avahi.yml` — targets the `vms:physical` inventory groups (all 5 Ubuntu QEMU VMs + ubuntu-manticore physical server). Stops, masks, and verifies avahi-daemon is permanently disabled. - **Updated**: `vm-management/scripts/cloud-init-user-data.yaml` — adds avahi masking to the `runcmd` section so any future VM provisioned from this template is hardened from first boot. ## Implementation notes - The playbook targets `vms:physical` which matches the existing inventory groups on the Ansible controller (LXC 304 at 10.10.0.232) — no inventory changes needed, all Ubuntu VMs are already managed. - `ignore_errors: true` on the stop task handles hosts where avahi is already stopped or not installed. - `changed_when: false` on the verify task suppresses false-positive changed status. - `| trim` filter on the stdout check handles trailing newlines from `systemctl is-enabled`. ## Usage ```bash # SSH to the Ansible controller ssh ansible # Dry run first ansible-playbook /opt/ansible/playbooks/mask-avahi.yml --check # Test on one VM ansible-playbook /opt/ansible/playbooks/mask-avahi.yml --limit discord-bots # Roll out to all ansible-playbook /opt/ansible/playbooks/mask-avahi.yml ``` ## Rollback ```bash # On any host, if mDNS is ever needed: systemctl unmask avahi-daemon ```
Claude added 1 commit 2026-04-03 04:33:06 +00:00
feat: add Ansible playbook to mask avahi-daemon on all Ubuntu VMs (#28)
All checks were successful
Auto-merge docs-only PRs / auto-merge-docs (pull_request) Successful in 2s
4234351cfa
Closes #28

Adds mask-avahi.yml targeting the vms:physical inventory groups (all
Ubuntu QEMU VMs + ubuntu-manticore). Also adds avahi masking to the
cloud-init template so future VMs are hardened from first boot.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude added the
ai-reviewing
label 2026-04-03 04:45:08 +00:00
Claude reviewed 2026-04-03 04:46:44 +00:00
Claude left a comment
Author
Collaborator

AI Code Review

Files Reviewed

  • ansible/playbooks/mask-avahi.yml (added)
  • vm-management/scripts/cloud-init-user-data.yaml (modified)

Findings

Correctness

  • Verify task exit code handling: systemctl is-enabled avahi-daemon exits with rc=1 for masked units. Since failed_when is specified, it replaces Ansible's default "fail on non-zero rc" behavior — the task correctly succeeds when stdout is masked regardless of exit code. This is intentional and correct.
  • Stop task with ignore_errors: true: Handles hosts where avahi is already stopped or not installed. Appropriate scope.
  • Mask task without ignore_errors: systemctl mask creates a /dev/null symlink and works even when the package isn't installed — no guard needed here.
  • cloud-init || true: Mirrors the ignore_errors pattern correctly for the shell context.
  • Both files implement the same intent consistently.

Security

  • No issues. No hardcoded secrets or credentials in the playbook.
  • The SSH public keys in the cloud-init template are deployment keys (public material) — expected for a VM provisioning template.

Style & Conventions

  • Uses FQCN (ansible.builtin.systemd, ansible.builtin.command) — Ansible best practice.
  • Comprehensive header comment explains the why, targets, usage, and rollback — excellent documentation.
  • changed_when: false on the verify task correctly suppresses false-positive changed status.
  • | trim filter on the failed_when condition cleanly handles trailing newline from systemctl.

Suggestions

  • Could add gather_facts: false to the play — no facts are used, so skipping fact gathering would shorten the playbook run by a few seconds per host. Minor optimization, not a blocker.

Verdict: APPROVED

Clean, correct, and well-documented. The failed_when exit-code interaction is the only subtle point and it's handled correctly. The cloud-init update ensures future VMs are hardened from first boot, which is the right place to put this.


Automated review by Claude PR Reviewer

## AI Code Review ### Files Reviewed - `ansible/playbooks/mask-avahi.yml` (added) - `vm-management/scripts/cloud-init-user-data.yaml` (modified) ### Findings #### Correctness - **Verify task exit code handling**: `systemctl is-enabled avahi-daemon` exits with rc=1 for masked units. Since `failed_when` is specified, it replaces Ansible's default "fail on non-zero rc" behavior — the task correctly succeeds when stdout is `masked` regardless of exit code. This is intentional and correct. - **Stop task with `ignore_errors: true`**: Handles hosts where avahi is already stopped or not installed. Appropriate scope. - **Mask task without `ignore_errors`**: `systemctl mask` creates a `/dev/null` symlink and works even when the package isn't installed — no guard needed here. - **cloud-init `|| true`**: Mirrors the `ignore_errors` pattern correctly for the shell context. - Both files implement the same intent consistently. #### Security - No issues. No hardcoded secrets or credentials in the playbook. - The SSH public keys in the cloud-init template are deployment keys (public material) — expected for a VM provisioning template. #### Style & Conventions - Uses FQCN (`ansible.builtin.systemd`, `ansible.builtin.command`) — Ansible best practice. - Comprehensive header comment explains the why, targets, usage, and rollback — excellent documentation. - `changed_when: false` on the verify task correctly suppresses false-positive changed status. - `| trim` filter on the `failed_when` condition cleanly handles trailing newline from `systemctl`. #### Suggestions - Could add `gather_facts: false` to the play — no facts are used, so skipping fact gathering would shorten the playbook run by a few seconds per host. Minor optimization, not a blocker. ### Verdict: APPROVED Clean, correct, and well-documented. The `failed_when` exit-code interaction is the only subtle point and it's handled correctly. The cloud-init update ensures future VMs are hardened from first boot, which is the right place to put this. --- *Automated review by Claude PR Reviewer*
Claude added
ai-reviewed
and removed
ai-reviewing
labels 2026-04-03 04:46:48 +00:00
cal closed this pull request 2026-04-03 20:05:11 +00:00
All checks were successful
Auto-merge docs-only PRs / auto-merge-docs (pull_request) Successful in 2s

Pull request closed

Sign in to join this conversation.
No description provided.