From unraid-assistant
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".
npx claudepluginhub jamesprial/prial-plugins --plugin unraid-assistantThis skill uses the workspace's default tool permissions.
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.
Generates Ansible playbooks, roles, inventories, and configs for server provisioning, app deployment, service configuration, and idempotent automation.
Guides writing simple Ansible playbooks for server hardening, package installation, and post-provisioning tasks beyond cloud-init.
Terraform, CloudFormation, reproducible infrastructure, version control, and IaC best practices.
Share bugs, ideas, or general feedback.
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.
The dmacvicar/libvirt Terraform provider manages VMs on any libvirt/KVM host, including Unraid.
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"
}
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 | 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 |
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.
/root/.ssh/authorized_keys on Unraid/boot/config/go since Unraid runs from RAM[unraid]
tower ansible_host=192.168.1.100 ansible_user=root ansible_python_interpreter=/usr/bin/python3
---
- 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"
| Project | Description |
|---|---|
digilink/unraid-ansible | Ansible roles for Unraid configuration |
zance1054/unraidAnsible | Playbooks for common Unraid tasks |
command or raw modules for Unraid-specific CLI tools (mdcmd, emcmd, virsh)gather_facts: false and collect manuallyNo 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.