# 📐 Infrastructure Provisioning with Terraform This document covers the Infrastructure as Code (IaC) configuration and execution steps used to provision the homelab virtual machine guests on the KVM hypervisor. --- ## 🛠️ Automated Provisioning Pipeline The lifecycle of the virtual machines---from storage volume creation to system configuration injection---is managed declaratively. ```mermaid graph TD %% My Color Palette classDef inputNode fill:#212c21,stroke:#9580ff,color:#f8f8f2,stroke-width:1.5px; classDef tfNode fill:#2b3b38,stroke:#70a99f,color:#f8f8f2,stroke-width:2px; classDef hostNode fill:#161dc,stroke:#415854,color:#f8f8f2,stroke-width:2px; classDef guestNode fill:#2b3b38,stroke:#8aff80,color:#f8f8f2,stroke-width:1.5px; subgraph Configs ["Declarative Configuration Files"] MainTF["📄 main.tf
(Resource Specifications)"]:::inputNode CloudInit["📄 cloud_init.cfg
(User Provisioning Template)"]:::inputNode NetConfig["📄 network_config.cfg.tpl
(Static IP Mappings)"]:::inputNode end Terraform["🚀 Terraform Provider
(dmacvicar/libvirt)"]:::tfNode subgraph Host ["hypervisor.lab.local (172.30.1.200)"] BaseImages["💿 Cloud base OS templates
(Alma10 & Deb12)"]:::hostNode StoragePool["🗂️ VM Storage Pool
(/var/lib/libvirt/images/vm_pool)"]:::hostNode end subgraph Guests ["Provisional Virtual Machines"] freeipa["🔑 freeipa VM"]:::guestNode portfolio["📄 portfolio VM"]:::guestNode minecraft["⚔️ minecraft VM"]:::guestNode navidrome["🎵 navidrome VM"]:::guestNode end MainTF & CloudInit & NetConfig ===>|Parsed on Apply| Terraform Terraform ===>|Executes Provisioning via SSH| Host StoragePool -.->|Clones thin OS volumes from| BaseImages Host ===>|Boots with CLoud-Init ISOs| Guests %% Subgraph Colors style Configs fill:#161d1c,stroke:#9580ff,stroke-width:1px; style Host fill:#161d1c,stroke:#415854,stroke-width:1px; style Guests fill:#161d1c,stroke:#8aff80,stroke-width:1px; ``` --- ## 🔌 Libvirt Provider Terraform targets the KVM hypervisor remotely using the community-supported `dmacvicar/libvirt` provider. The connection is established over SSH: ```hcl provider "libvirt" { uri = "qemu+ssh://sho@172.30.1.200/system" } ``` *This utilizes SSH Agent Forwarding inside the Dev Container to authenticate to the hypervisor without copying private SSH keys into the workspace.* --- ## 💾 Storage Pool & Image Management Virtual machines are provisioned with storage volumes allocated from a single directory-backed storage pool: * **Storage Path**: `/var/lib/libvirt/images/vm_pool` * **Base Volumes**: Cloud images are downloaded directly from upstream repositories and set as read-only base templates: * `almalinux10-base.qcow2` (AlmaLinux Generic Cloud Image) * `debian12-base.qcow2` (Debian Bookworm Generic Cloud Image) * **Instance Volumes**: The storage volumes for individual VMs are created as clones pointing to these base templates, enabling thin-provisioning and near-instant VM creation. --- ## ⚙️ Bootstrapping with Cloud-Init VM custom attributes(like networks, users, and packages) are configured on first boot via Cloud-Init. ### 1. User Configuration (`terraform/templates/cloud_init.cfg`) Sets up the admin user and secures the host: * Injects the administrator user `sho`. * Adds the user to the `wheel`(sudoers) group with passwordless privileges(`NOPASSWD:ALL`). * Injects the public SSH key. * **Hardening**: Disables password authentication in `/etc/ssh/sshd_config` and restarts the SSH daemon. ### 2. Network Configuration (`terraform/templates/network_config.cfg.tpl`) Applies static networking configuration: ```yaml version: 2 ethernets: ${interface_name}: dhcp4: no addresses: - ${ip_address}/24 routes: - to: default via: ${gateway_ip} nameservers: addresses: - ${dns_ip} - 1.1.1.1 ``` *Note: The primary nameserver points to `172.30.1.85`(the FreeIPA DNS server), with a fallback to `1.1.1.1`. --- ## 🖥️ VM Guest Resources Virtual machines are declared with `host-passthrough` CPU modes to expose modern instruction sets(critical for AlmaLinux 10's `x86-64-v3` architecture requirement): * **freeipa**: 3072 MB RAM, 2 vCPUs, 40 GB Storage * **portfolio**: 1024 MB RAM, 1 vCPU, 10 GB Storage * **minecraft**: 6144 MB RAM, 2 vCPU, 20 GB Storage * **navidrome**: 1024 MB RAM, 1 vCPU, 15 GB Storage --- ## 🚀 Execution Command Sequence Run the following commands inside the `terraform/` directory: ```bash # Initialize provider plugins terraform init # Validate configuration syntaxes terraform validate # Review proposed changes terraform plan # Apply deployment changes terraform apply ```