From 942cd43c2efa64c521ade9a5123e836b0b950f23 Mon Sep 17 00:00:00 2001 From: Isshi0417 Date: Tue, 7 Jul 2026 05:53:19 +0000 Subject: [PATCH] Implement FreeIPA server and enroll the pre-existing servers to it --- ansible/configure_dns.yml | 24 ++++++ ansible/deploy_ipa.yml | 66 +++++++++++++++++ ansible/enroll_clients.yml | 32 ++++++++ ansible/inventory.ini | 3 + terraform/main.tf | 140 ++++++++++++++++------------------- terraform/network_config.cfg | 2 +- 6 files changed, 190 insertions(+), 77 deletions(-) create mode 100644 ansible/configure_dns.yml create mode 100644 ansible/deploy_ipa.yml create mode 100644 ansible/enroll_clients.yml diff --git a/ansible/configure_dns.yml b/ansible/configure_dns.yml new file mode 100644 index 0000000..9e3e9b8 --- /dev/null +++ b/ansible/configure_dns.yml @@ -0,0 +1,24 @@ +--- +- name: Point VM DNS to central FreeIPA server + hosts: control, web, media + become: true + + tasks: + - name: Get current DNS settings + ansible.builtin.command: + cmd: nmcli -g ipv4.dns connection show "cloud-init ens3" + register: current_dns + changed_when: false + + - name: Set DNS servers to FreeIPA + ansible.builtin.command: + cmd: nmcli con mod "cloud-init ens3" ipv4.dns "172.30.1.100 1.1.1.1" + when: (current_dns.stdout | trim) != "172.30.1.100,1.1.1.1" + changed_when: true + notify: Restart network connection + + handlers: + - name: Restart network connection + ansible.builtin.command: + cmd: nmcli con up "cloud-init ens3" + changed_when: false diff --git a/ansible/deploy_ipa.yml b/ansible/deploy_ipa.yml new file mode 100644 index 0000000..9fa061e --- /dev/null +++ b/ansible/deploy_ipa.yml @@ -0,0 +1,66 @@ +--- +- name: Deploy Central FreeIPA Server + hosts: ipa + become: true + + vars_files: + - vault.yml + + tasks: + - name: Set fully qualified domain name + ansible.builtin.hostname: + name: ipa.shooey.local + + - name: Ensure local FQDN resolves in /etc/hosts + ansible.builtin.lineinfile: + path: /etc/hosts + line: "172.30.1.100 ipa.shooey.local ipa" + state: present + + - name: Install FreeIPA server and firewall dependencies + ansible.builtin.dnf: + name: + - firewalld + - python3-firewall + - freeipa-server + - freeipa-server-dns + - bind-dyndb-ldap + state: present + + - name: Ensure firewalld is running and enabled + ansible.builtin.systemd: + name: firewalld + state: started + enabled: true + + - name: Allow FreeIPA services in firewalld + ansible.posix.firewalld: + service: "{{ item }}" + permanent: true + immediate: true + state: enabled + loop: + - freeipa-ldap + - freeipa-ldaps + - dns + - kerberos + - kpasswd + + - name: Check if FreeIPA is already installed + ansible.builtin.stat: + path: /etc/ipa/default.conf + register: ipa_installed + + - name: Run FreeIPA unattended installer + ansible.builtin.command: + cmd: > + ipa-server-install + --unattended + --realm=SHOOEY.LOCAL + --ds-password="{{ vault_ipa_ds_password }}" + --admin-password="{{ vault_ipa_admin_password }}" + --setup-dns + --forwarder=1.1.1.1 + --forwarder=8.8.8.8 + --auto-reverse + when: not ipa_installed.stat.exists diff --git a/ansible/enroll_clients.yml b/ansible/enroll_clients.yml new file mode 100644 index 0000000..dc8cd44 --- /dev/null +++ b/ansible/enroll_clients.yml @@ -0,0 +1,32 @@ +--- +- name: Enroll client VMs into FreeIPA realm + hosts: control, web, media + become: true + + vars_files: + - vault.yml + + tasks: + - name: Install FreeIPA client packages + ansible.builtin.dnf: + name: freeipa-client + state: present + + - name: Check if already enrolled in FreeIPA + ansible.builtin.stat: + path: /etc/ipa/default.conf + register: ipa_client_config + + - name: Run FreeIPA client enrollment + ansible.builtin.command: + cmd: > + ipa-client-install + --unattended + --domain=shooey.local + --realm=SHOOEY.LOCAL + --server=ipa.shooey.local + --principal=admin + --password="{{ vault_ipa_admin_password }}" + --mkhomedir + when: not ipa_client_config.stat.exists + changed_when: true diff --git a/ansible/inventory.ini b/ansible/inventory.ini index b41ef23..53339fc 100644 --- a/ansible/inventory.ini +++ b/ansible/inventory.ini @@ -7,6 +7,9 @@ web-portfolio ansible_host=172.30.1.201 [media] media-stream ansible_host=172.30.1.202 +[ipa] +ipa-dns ansible_host=172.30.1.100 + [all:vars] ansible_user=ansible ansible_ssh_private_key_file=~/.ssh/id_ed25519 \ No newline at end of file diff --git a/terraform/main.tf b/terraform/main.tf index 9b8c2d2..ca8f7e6 100644 --- a/terraform/main.tf +++ b/terraform/main.tf @@ -1,103 +1,91 @@ terraform { - required_version = ">= 1.0" - required_providers { - libvirt = { - source = "dmacvicar/libvirt" - version = "0.7.6" - } + required_version = ">= 1.0" + required_providers { + libvirt = { + source = "dmacvicar/libvirt" + version = "0.7.6" } + } } provider "libvirt" { - uri = "qemu+ssh://sho@hypervisor.lab.local/system" + uri = "qemu+ssh://sho@hypervisor.lab.local/system" } locals { - ssh_key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJHwJzj/dCMOC+zJviqO32+/22kABZBdwC+NvyM+7+Vz sho@nobara" + ssh_key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJHwJzj/dCMOC+zJviqO32+/22kABZBdwC+NvyM+7+Vz sho@nobara" - vms = { - "ansible-control" = { - vcpu = 2 - memory = 2048 - ip = "172.30.1.200" - } - - "web-portfolio" = { - vcpu = 2 - memory = 2048 - ip = "172.30.1.201" - } - - "media-stream" = { - vcpu = 2 - memory = 4096 - ip = "172.30.1.202" - } + vms = { + "freeipa" = { + vcpu = 2 + memory = 4096 + ip = "172.30.1.100" } + } } resource "libvirt_volume" "vm_disk" { - for_each = local.vms - name = "${each.key}.qcow" - pool = "images" - base_volume_name = "rhel-10-guest.qcow2" - size = 21474836480 - format = "qcow2" + for_each = local.vms + name = "${each.key}.qcow" + pool = "images" + base_volume_name = "rhel-10-guest.qcow2" + size = 21474836480 + format = "qcow2" } resource "libvirt_cloudinit_disk" "commoninit" { - for_each = local.vms - name = "commoninit-${each.key}.raw" - pool = "images" - user_data = templatefile("${path.module}/cloud_init.cfg", { - hostname = each.key - ssh_key = local.ssh_key - }) - network_config = templatefile("${path.module}/network_config.cfg", { - ip_address = each.value.ip - }) + for_each = local.vms + name = "commoninit-${each.key}.raw" + pool = "images" + user_data = templatefile("${path.module}/cloud_init.cfg", { + hostname = each.key + ssh_key = local.ssh_key + }) + network_config = templatefile("${path.module}/network_config.cfg", { + ip_address = each.value.ip + }) } resource "libvirt_domain" "rhel_vm" { - for_each = local.vms - name = each.key - memory = each.value.memory - vcpu = each.value.vcpu + for_each = local.vms + name = each.key + memory = each.value.memory + vcpu = each.value.vcpu - cpu { - mode = "host-passthrough" - } + cpu { + mode = "host-passthrough" + } - firmware = "/usr/share/edk2/ovmf/OVMF_CODE.fd" - nvram { - file = "/var/lib/libvirt/qemu/nvram/${each.key}_VARS.fd" - template = "/usr/share/edk2/ovmf/OVMF_VARS.fd" - } + firmware = "/usr/share/edk2/ovmf/OVMF_CODE.fd" + nvram { + file = "/var/lib/libvirt/qemu/nvram/${each.key}_VARS.fd" + template = "/usr/share/edk2/ovmf/OVMF_VARS.fd" + } - qemu_agent = false + qemu_agent = false - disk { - volume_id = libvirt_volume.vm_disk[each.key].id - } + disk { + volume_id = libvirt_volume.vm_disk[each.key].id + } - disk { - file = "/var/lib/libvirt/images/commoninit-${each.key}.raw" - scsi = true - } + disk { + file = "/var/lib/libvirt/images/commoninit-${each.key}.raw" + scsi = true + } - network_interface { - bridge = "br0" - } + network_interface { + bridge = "br0" + } - console { - type = "pty" - target_port = "0" - target_type = "serial" - } + console { + type = "pty" + target_port = "0" + target_type = "serial" + } - graphics { - type = "vnc" - listen_type = "address" - autoport = true - } -} \ No newline at end of file + graphics { + type = "vnc" + listen_type = "address" + autoport = true + } +} diff --git a/terraform/network_config.cfg b/terraform/network_config.cfg index d1ae1e0..082f196 100644 --- a/terraform/network_config.cfg +++ b/terraform/network_config.cfg @@ -6,4 +6,4 @@ ethernets: - ${ip_address}/24 gateway4: 172.30.1.254 nameservers: - addresses: [8.8.8.8, 1.1.1.1] \ No newline at end of file + addresses: [172.30.1.100, 1.1.1.1] \ No newline at end of file