infrastructure-as-code
Use when the user asks about Terraform, Ansible, or infrastructure-as-code approaches for managing Unraid servers, VMs, or configuration. Examples: "terraform unraid", "ansible unraid", "infrastructure as code", "iac unraid", "terraform libvirt".
From unraid-assistantnpx claudepluginhub jamesprial/prial-plugins --plugin unraid-assistantThis skill uses the workspace's default tool permissions.
Infrastructure as Code for Unraid
No first-class Unraid provider exists for Terraform or Ansible. All IaC uses generic tools (libvirt provider, raw SSH). This contrasts with Proxmox and ESXi which have dedicated providers.
Terraform with libvirt Provider
The dmacvicar/libvirt Terraform provider manages VMs on any libvirt/KVM host, including Unraid.
Provider Configuration
terraform {
required_providers {
libvirt = {
source = "dmacvicar/libvirt"
version = "~> 0.8"
}
}
}
# Local connection (run Terraform on Unraid itself)
provider "libvirt" {
uri = "qemu:///system"
}
# Remote connection over SSH
provider "libvirt" {
uri = "qemu+ssh://root@192.168.1.100/system"
}
# Remote connection over TCP (requires libvirtd config)
provider "libvirt" {
uri = "qemu+tcp://192.168.1.100/system"
}
Enable Remote libvirt TCP Access
Edit /etc/libvirt/libvirtd.conf on the Unraid host (set listen_tls = 0, listen_tcp = 1, auth_tcp = "none", tcp_port = "16509"), then restart with /etc/rc.d/rc.libvirt restart. IMPORTANT: TCP with auth_tcp = "none" has no authentication. Use SSH transport in production.
Resource Types
| Resource | Purpose |
|---|---|
libvirt_domain | VM definition (CPU, memory, disk, network) |
libvirt_volume | Disk image (qcow2, raw) in a storage pool |
libvirt_network | Virtual network definition |
libvirt_cloudinit_disk | Cloud-init NoCloud ISO generation |
libvirt_pool | Storage pool definition |
Example: Provision a Linux VM
resource "libvirt_volume" "ubuntu_base" {
name = "ubuntu-base.qcow2"
pool = "domains"
source = "/mnt/user/isos/jammy-server-cloudimg-amd64.img"
format = "qcow2"
}
resource "libvirt_volume" "vm_disk" {
name = "myvm-disk.qcow2"
pool = "domains"
base_volume_id = libvirt_volume.ubuntu_base.id
size = 42949672960 # 40 GiB in bytes
}
resource "libvirt_cloudinit_disk" "vm_cloudinit" {
name = "myvm-cloudinit.iso"
pool = "domains"
user_data = <<-EOF
#cloud-config
hostname: myvm
users:
- name: admin
sudo: ALL=(ALL) NOPASSWD:ALL
ssh_authorized_keys:
- ${var.ssh_public_key}
packages:
- qemu-guest-agent
runcmd:
- systemctl enable --now qemu-guest-agent
EOF
}
resource "libvirt_domain" "myvm" {
name = "MyVM"
memory = 4096
vcpu = 4
cpu {
mode = "host-passthrough"
}
disk {
volume_id = libvirt_volume.vm_disk.id
scsi = true
}
cloudinit = libvirt_cloudinit_disk.vm_cloudinit.id
network_interface {
bridge = "br0"
}
graphics {
type = "vnc"
listen_type = "address"
}
boot_device {
dev = ["hd"]
}
firmware = "/usr/share/qemu/ovmf-x64/OVMF_CODE-pure-efi.fd"
}
output "vm_ip" {
value = libvirt_domain.myvm.network_interface[0].addresses
}
The libvirt_cloudinit_disk resource auto-generates a NoCloud ISO. Combine with base_volume_id on libvirt_volume to create VMs from cloud images without manual ISO creation. VM provisioning typically completes in under 2 minutes. See mcreekmore/unraid-terraform on GitHub for a working reference.
Ansible over SSH
Prerequisites
- Python on Unraid: Install via the Nerd Scripts plugin (Community Applications)
- SSH key access: Copy your public key to
/root/.ssh/authorized_keyson Unraid - Persist SSH keys: Add key restoration to
/boot/config/gosince Unraid runs from RAM
Inventory
[unraid]
tower ansible_host=192.168.1.100 ansible_user=root ansible_python_interpreter=/usr/bin/python3
Example Playbook
---
- name: Configure Unraid server
hosts: unraid
gather_facts: false # Unraid may lack standard fact paths
tasks:
- name: Ensure appdata directory exists
file:
path: /mnt/user/appdata/myapp
state: directory
mode: "0755"
- name: Copy Docker template
copy:
src: templates/myapp.xml
dest: /boot/config/plugins/dockerMan/templates-user/my-myapp.xml
mode: "0644"
- name: Start container via Docker CLI
command: docker start myapp
ignore_errors: true
- name: Define VM from XML
command: virsh define /tmp/myvm.xml
- name: Copy user script
copy:
src: scripts/backup.sh
dest: /boot/config/plugins/user.scripts/scripts/backup/script
mode: "0755"
Community Projects
| Project | Description |
|---|---|
digilink/unraid-ansible | Ansible roles for Unraid configuration |
zance1054/unraidAnsible | Playbooks for common Unraid tasks |
Ansible Limitations on Unraid
- No Ansible Galaxy collection exists for Unraid
- Many Ansible modules assume systemd, which Unraid does not use (Slackware-based)
- Use
commandorrawmodules for Unraid-specific CLI tools (mdcmd,emcmd,virsh) - Fact gathering may fail; use
gather_facts: falseand collect manually
Known Gaps
No dedicated Unraid Terraform provider or Ansible Galaxy collection exists. Proxmox and ESXi both have first-class IaC support. The libvirt provider covers VM provisioning, but Unraid-specific features (array, shares, Docker templates, plugins) have no IaC abstractions.