This repository has been archived on 2026-07-30. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
nixos/ansible/roles/freeipa/tasks/main.yml
T
beatzaplentyandClaude Sonnet 4.6 f85c65870f Initial infrastructure mono-repo scaffold
Consolidates nixos, docker, raspi, and debian-configuration into a single
infrastructure-as-code repo. Includes:

- ansible/: full inventory + proxmox-hardening, freeipa, and raspberrypi
  roles (converted from debian-configuration bash scripts)
- terraform/: Proxmox VMs, Dynu DNS, Pi-hole (decommissioned stub),
  Docker container catalog — migrated from docker/infrastructure/terraform/
- stacks/docker/, stacks/raspi/, nixos/: placeholder READMEs pending
  git subtree population (see implementation plan)
- docs/: internal MkDocs site with architecture, network topology, runbooks,
  and drift-detection guide; external sanitized site
- scripts/: drift-detect.sh, docs-build.sh, install-hooks.sh, check-secrets.sh
- CI: secret-scan (push/PR), drift-detect (daily), docs-build (on change)
- Pi-hole removed throughout — DNS is FreeIPA, DHCP is router

See docs/internal/implementation-plan.md for the phased rollout after
pushing to Gitea.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UvNjoxTWEDkhXsd1Dq2ETP
2026-07-30 07:07:47 +10:00

134 lines
4.2 KiB
YAML

---
# freeipa/tasks/main.yml
# Provisions a FreeIPA 4.x server on Rocky Linux 9.
# The ipa-server-install step is intentionally NOT idempotent — it will
# refuse to run if IPA is already installed, which acts as a safety guard.
# ── Pre-flight ────────────────────────────────────────────────────────────────
- name: Check IPA is not already installed
ansible.builtin.stat:
path: /etc/ipa/default.conf
register: ipa_installed
tags: always
- name: Skip install tasks if IPA already exists
ansible.builtin.debug:
msg: "FreeIPA already installed — skipping install tasks. Use verify tasks to check health."
when: ipa_installed.stat.exists
tags: install
- name: Assert hostname is correct FQDN
ansible.builtin.command:
cmd: hostname -f
register: fqdn_check
changed_when: false
failed_when: fqdn_check.stdout != ipa_hostname
when:
- not ipa_installed.stat.exists
- ipa_hostname is defined
tags: install, preflight
- name: Assert /etc/hosts has correct entry
ansible.builtin.lineinfile:
path: /etc/hosts
line: "{{ ipa_ip }} {{ ipa_hostname }} {{ ipa_hostname.split('.')[0] }}"
state: present
when:
- not ipa_installed.stat.exists
- ipa_ip is defined
- ipa_hostname is defined
tags: install, preflight
# ── Swap ──────────────────────────────────────────────────────────────────────
- name: Check current swap
ansible.builtin.command:
cmd: swapon --show
register: swap_check
changed_when: false
tags: install, swap
- name: Create swap file if absent
block:
- name: Create swap file
ansible.builtin.command:
cmd: "dd if=/dev/zero of=/swapfile bs=1M count={{ ipa_swap_size_mb }} status=none"
args:
creates: /swapfile
- name: Set swap permissions
ansible.builtin.file:
path: /swapfile
mode: "0600"
- name: Format swap
ansible.builtin.command:
cmd: mkswap /swapfile
changed_when: true
- name: Enable swap
ansible.builtin.command:
cmd: swapon /swapfile
changed_when: true
- name: Add swap to fstab
ansible.builtin.lineinfile:
path: /etc/fstab
line: "/swapfile none swap defaults 0 0"
state: present
when:
- not ipa_installed.stat.exists
- swap_check.stdout == ""
tags: install, swap
# ── Package install ───────────────────────────────────────────────────────────
- name: Install FreeIPA server packages
ansible.builtin.dnf:
name:
- freeipa-server
- freeipa-server-dns
state: present
when: not ipa_installed.stat.exists
tags: install, packages
# ── IPA server install ────────────────────────────────────────────────────────
- name: Run ipa-server-install (interactive passwords via env vars)
ansible.builtin.shell:
cmd: >
ipa-server-install
--realm={{ ipa_realm }}
--domain={{ ipa_domain }}
--hostname={{ ipa_hostname }}
--ip-address={{ ipa_ip }}
--forwarder={{ ipa_dns_forwarder }}
--setup-dns
--auto-reverse
--no-host-dns
--mkhomedir
--unattended
--ds-password="${IPA_DM_PASSWORD}"
--admin-password="${IPA_ADMIN_PASSWORD}"
environment:
IPA_DM_PASSWORD: "{{ ipa_dm_password }}"
IPA_ADMIN_PASSWORD: "{{ ipa_admin_password }}"
no_log: true
when: not ipa_installed.stat.exists
tags: install
# ── Verification ──────────────────────────────────────────────────────────────
- name: Verify IPA services are running
ansible.builtin.command:
cmd: ipactl status
register: ipa_status
changed_when: false
tags: verify
- name: Print IPA service status
ansible.builtin.debug:
var: ipa_status.stdout_lines
tags: verify