Terraform configuration for an Ubuntu 26.04 LTS VM on KVM/libvirt.
| Setting | Value |
|---|---|
| Name | agent-vm |
| CPU / memory | 2 vCPU / 4 GiB |
| Disk | 60 GiB sparse QCOW2 |
| Network | default libvirt NAT |
| User | ubuntu |
| SSH key | ~/.ssh/id_rsa.pub |
| Autostart | Enabled |
SSH is key-only, root login is disabled, and ubuntu has passwordless sudo.
See infrastructure/variables.tf to override
defaults.
- Terraform 1.6 or newer.
- KVM/libvirt with access to
qemu:///system. - Existing libvirt pool and NAT network named
default. - An SSH public key at
~/.ssh/id_rsa.pubor an override throughssh_public_key_pathorssh_public_key.
terraform -chdir=infrastructure init
terraform -chdir=infrastructure fmt -check
terraform -chdir=infrastructure validate
terraform -chdir=infrastructure plan
terraform -chdir=infrastructure applyConnect using the generated command:
terraform -chdir=infrastructure output -raw ssh_commandGet the assigned address with
terraform -chdir=infrastructure output -raw ipv4_address, then add:
Host agent-vm
HostName <guest-ip>
User ubuntu
IdentityFile ~/.ssh/id_rsa
IdentitiesOnly yes
PreferredAuthentications publickey
PasswordAuthentication no
HostKeyAlias agent-vmConnect with ssh agent-vm.
ssh agent-vm '. /etc/os-release; echo "$PRETTY_NAME"'
ssh agent-vm 'nproc; free -h; lsblk; df -hT /'
ssh agent-vm 'sudo -n id -u'
ssh agent-vm 'ping -c 3 1.1.1.1'
ssh agent-vm 'curl --fail --head https://ubuntu.com/'
terraform -chdir=infrastructure plan- Terraform state and variable files are ignored because rendered cloud-init contains the SSH public key and infrastructure metadata.
- The pinned libvirt provider may replace an existing disk when its configured
size changes. Review
terraform -chdir=infrastructure planbefore applying a resize. - The QCOW2 disk is sparse; host storage grows as guest data is written.
terraform -chdir=infrastructure destroypermanently removes the VM, disk, and cloud-init ISO.
Run Gitleaks before pushing:
gitleaks dir . --no-banner --redact
gitleaks git . --no-banner --redact