Archived
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
134 lines
4.2 KiB
YAML
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
|