Voltar ao ranking

dmacvicar/terraform-provider-libvirt

Go

Terraform provider to provision infrastructure with Linux's KVM using libvirt

terraformterraform-providerlibvirtkvmvirtualization
Crescimento de estrelas
Estrelas
1.9k
Forks
517
Crescimento semanal
Issues
38
5001k1.5k
fev. de 2016jul. de 2019jan. de 2023jul. de 2026
ArtefatosGo Modulesgo get github.com/dmacvicar/terraform-provider-libvirt
README

Terraform provider for libvirt

Build and Test

This provider allows managing libvirt resources (virtual machines, storage pools, networks) using Terraform. It communicates with libvirt using its API to define, configure, and manage virtualization resources.

This is a complete rewrite of the legacy provider. The legacy provider (v0.8.x and earlier) is maintained in the v0.8 branch. Starting from v0.9.0, all releases will be based on this new rewrite.

Goals

This rewrite improves upon the legacy provider in several ways:

  1. API Fidelity - Models the libvirt XML schemas directly instead of abstracting them, giving users full access to libvirt features. Schema coverage is bounded by what libvirtxml supports.
  2. Current Framework - Built with Terraform Plugin Framework, as the SDK v2 used in the legacy provider is deprecated
  3. Best Practices - Follows HashiCorp's provider design principles

Supported Resources & XML Coverage

Resource Status XML Coverage
libvirt_domain ✅ Supported Full coverage of libvirtxml’s domain schema (devices, CPU, memory, features, RNG, TPM, etc.).
libvirt_network ✅ Supported Full coverage of libvirtxml network schema (forwarding modes, bridge, DHCP, VLAN, virtual ports, etc.).
libvirt_pool ✅ Supported Full coverage of libvirtxml storage pool schema (dir/logical/iscsi/etc.).
libvirt_volume ✅ Supported Full coverage of libvirtxml storage volume schema (target, backing_store, encryption, timestamps).

Everything exposed in these resources maps directly to the corresponding libvirt XML; if libvirtxml adds new fields we regenerate and pick them up automatically. Additional libvirt resources (secrets, nodes, interfaces, etc.) may be added in the future.

Using the provider

terraform {
  required_providers {
    libvirt = {
      source = "dmacvicar/libvirt"
    }
  }
}

provider "libvirt" {
  uri = "qemu:///system"
}

resource "libvirt_domain" "example" {
  name         = "example-vm"
  type         = "kvm"
  memory       = 512
  memory_unit  = "MiB"
  vcpu         = 1
  
  os = {
    type         = "hvm"
    type_arch    = "x86_64"
    type_machine = "q35"
  }
}

Connection URIs

The provider supports multiple connection transports:

# Local system socket
provider "libvirt" {
  uri = "qemu:///system"
}

# Remote via SSH (Go library)
provider "libvirt" {
  uri = "qemu+ssh://user@host.example.com/system"
}

# Remote via SSH (native command, respects ~/.ssh/config)
provider "libvirt" {
  uri = "qemu+sshcmd://user@host.example.com/system"
}

# Remote via TLS
provider "libvirt" {
  uri = "qemu+tls://host.example.com/system"
}

See docs/transports.md for detailed transport configuration and examples.

See the examples directory for more usage examples.

Documentation

You can find an overview of the XML <-> HCL mapping and the resource schema in the documentation hosted at the Terraform registry and OpenTofu registry.

For non-released versions, see XML <-> HCL mapping and for an overview of the HCL to XML mapping patterns and the documentation source.

Development information

Design Principles

  • Schema Coverage: We support all fields that libvirt.org/go/libvirtxml implements from the official libvirt schemas (located at https://gitlab.com/libvirt/libvirt/-/tree/master/src/conf/schemas). If libvirtxml doesn't support a feature yet, neither do we, as we depend on libvirtxml internally.
  • No Abstraction: The Terraform schema mirrors the libvirt XML structure as closely as possible, providing full access to underlying features rather than simplified abstractions.
  • Preserve intent: We try to generate state for what the user specified. That is, if the user did not specify something, we let libvirt handle it. We ignore then those when diffing state.

Schema Mapping

All resources use a single XML <-> HCL mapping spec (flattening rules, unions, presence booleans, nested attributes). See XML <-> HCL mapping documentation for the canonical rules.

Lifecycle Operation Controls

Some resources expose provider-specific lifecycle operation controls using nested create/destroy objects. These fields control post-define and pre-undefine API operations (for example build/start/delete behavior), and are not direct libvirt XML fields. Current lifecycle controls are experimental and may change in future releases.

Example (libvirt_pool):

resource "libvirt_pool" "data" {
  name = "data-pool"
  type = "dir"
  target = {
    path = "/var/lib/libvirt/data"
  }

  create = {
    build     = true
    start     = true
    autostart = true
  }

  destroy = {
    delete = false
  }
}

Development

This is the first project where I leveraged AI quite heavily not only to do a major cleanup and rewrite of pieces of code, and to implement a new design, but we also use it to inject documentation into the schema.

I am aware of the consequences, advantages and drawbacks. It is my learning platform, and I own the outcome.

Code Generation

To reduce boilerplate and ensure consistency, this provider uses a code generation system that automatically produces:

  • Terraform models with proper tfsdk tags
  • Plugin Framework schemas with correct types and optionality
  • XML conversion functions implementing the "preserve user intent" pattern

See codegen documentation for architecture and for the documentation tooling (docindex/docgen) used to inject schema descriptions.

Building and running the provider from source

git clone https://github.com/dmacvicar/terraform-provider-libvirt
cd terraform-provider-libvirt
make build

To install the provider locally:

make install

This installs to ~/.terraform.d/plugins/registry.terraform.io/dmacvicar/libvirt/dev/linux_amd64/

Then override the provider like this in $HOME/.terraformrc:

provider_installation {
    dev_overrides {
      "registry.terraform.io/dmacvicar/libvirt" = "/home/duncan/src/terraform-provider-libvirt"
    }

    # For all other providers, install them directly from their origin provider
    # registries as normal.
    direct {}
  }

Running tests

# Run linter
make lint

# Run unit tests
make test

# Run acceptance tests (requires libvirt)
make testacc

On Github, the tests use a hack we have in place to override the domain type (TF_PROVIDER_LIBVIRT_DOMAIN_TYPE=qemu), which allows to run acceptance tests without nested virtualization, but using the tcg accelerator instead of KVM.

Migration from Legacy Provider (v0.8.x)

Getting Domain IP Addresses

The legacy provider exposed IP addresses directly on the domain resource via network_interface.*.addresses. The new provider uses a separate data source for querying IP addresses:

Legacy provider (v0.8.x):

resource "libvirt_domain" "example" {
  # ... domain config ...
}

output "ip" {
  value = libvirt_domain.example.network_interface[0].addresses[0]
}

New provider (v0.9+):

resource "libvirt_domain" "example" {
  # ... domain config ...
}

data "libvirt_domain_interface_addresses" "example" {
  domain = libvirt_domain.example.id
  source = "lease"  # or "agent" or "any"
}

output "ip" {
  value = data.libvirt_domain_interface_addresses.example.interfaces[0].addrs[0].addr
}

Alternatively, use the wait_for_ip property on the domain's interface configuration to ensure the domain has an IP before creation completes:

resource "libvirt_domain" "example" {
  name   = "example-vm"
  memory = 512
  vcpu   = 1

  devices = {
    interfaces = [
      {
        type = "network"
        source = {
          network = "default"
        }
        wait_for_ip = {
          timeout = 300  # seconds
          source  = "lease"
        }
      }
    ]
  }
}

Volume Source URLs

If you're migrating from the legacy provider and used the source attribute on volumes to download cloud images, note that this feature is now available via the create.content.url block:

Legacy provider (v0.8.x):

resource "libvirt_volume" "ubuntu" {
  name   = "ubuntu.qcow2"
  pool   = "default"
  source = "https://cloud-images.ubuntu.com/releases/22.04/release/ubuntu-22.04-server-cloudimg-amd64.img"
  # size was automatically detected from Content-Length
}

New provider (v0.9+):

resource "libvirt_volume" "ubuntu" {
  name   = "ubuntu.qcow2"
  pool   = "default"
  format = "qcow2"  # Must specify format

  create = {
    content = {
      url = "https://cloud-images.ubuntu.com/releases/22.04/release/ubuntu-22.04-server-cloudimg-amd64.img"
    }
  }
  # capacity is automatically detected from Content-Length when available
}

Important notes:

  1. Format is required: You must explicitly specify the format attribute (e.g., "qcow2", "raw"). The legacy provider auto-detected format from file extension, but the new provider requires it.
  2. Capacity is computed when possible: The provider uses the HTTP Content-Length header when available, or the file size for local files.
  3. Local files supported: You can use absolute paths or file:// URIs for local files: url = "/path/to/local.qcow2" or url = "file:///path/to/local.qcow2"
  4. Set capacity when Content-Length is missing: For HTTP(S) URLs that do not provide Content-Length, specify capacity explicitly.

Contributing

Opening issues

Issues should be open for clearly actionable bugs. For getting help on your stack not working, please use the discussions first.

Pull Requests

In general, you should not contribute significant features or code without a previous discussion and agreement with the maintainers. This involve transferring code maintenance burden to the maintainers and in general is not desired.

Use of AI

The author uses AI for this project, but as the maintainer, he owns the outcome and consequences.

If you contribute code or issues and used AI, you are required to disclose it, including full details (tools, prompts).

Author

  • Duncan Mac-Vicar P. (upstream)

License

  • Apache 2.0
Repositórios relacionados
bregman-arie/devops-exercises

Linux, Jenkins, AWS, SRE, Prometheus, Docker, Python, Ansible, Git, Kubernetes, Terraform, OpenStack, SQL, NoSQL, Azure, GCP, DNS, Elastic, Network, Virtualization. DevOps Interview Questions

PythonPyPIOtherdevopsaws
83.3k19.8k
hashicorp/terraform

Terraform enables you to safely and predictably create, change, and improve infrastructure. It is a source-available tool that codifies APIs into declarative configuration files that can be shared amongst team members, treated as code, edited, reviewed, and versioned.

GoGo ModulesOthergraphinfrastructure-as-code
developer.hashicorp.com/terraform
49.3k10.5k
MichaelCade/90DaysOfDevOps

This repository started out as a learning in public project for myself and has now become a structured learning map for many in the community. We have 3 years under our belt covering all things DevOps, including Principles, Processes, Tooling and Use Cases surrounding this vast topic.

ShellOtherdevopskubernetes
90daysofdevops.com
29.6k6.8k
GoogleCloudPlatform/microservices-demo

Sample cloud-first application with 10 microservices showcasing Kubernetes, Istio, and gRPC.

GoGo ModulesApache License 2.0kubernetesgrpc
cymbal-shops.retail.cymbal.dev
20.6k10.2k
mikefarah/yq

yq is a portable command-line YAML, JSON, XML, CSV, TOML, HCL and properties processor

GoGo ModulesMIT Licenseyaml-processoryaml
mikefarah.gitbook.io/yq/
15.7k797
budtmo/docker-android

Android in docker solution with noVNC supported and video recording

PythonPyPIOtherdocker-androidandroid
15.6k1.7k
GoogleCloudPlatform/terraformer

CLI tool to generate terraform files from existing infrastructure (reverse Terraform). Infrastructure to Code

GoGo ModulesApache License 2.0cloudterraform
14.6k1.8k
coder/coder

Secure environments for developers and their agents

GoGo ModulesGNU Affero General Public License v3.0remote-developmentdevelopment-environment
coder.com
13.9k1.4k
semaphoreui/semaphore

Modern UI and powerful API for Ansible, Terraform/OpenTofu/Terragrunt, PowerShell and other DevOps tools.

GoGo ModulesMIT Licenseansibledevops
semaphoreui.com
13.9k1.3k
infracost/infracost

Cloud cost intelligence for engineers, AI coding agents, and CI/CD 💰📉 Shift FinOps Left!

GoGo ModulesApache License 2.0terraformcost-estimation
infracost.io
12.4k679
hashicorp/terraform-provider-aws

The AWS Provider enables Terraform to manage AWS resources.

GoGo ModulesMozilla Public License 2.0terraformterraform-provider
registry.terraform.io/providers/hashicorp/aws
11k10.3k
gruntwork-io/terragrunt

Terragrunt is a flexible orchestration tool that allows Infrastructure as Code written in OpenTofu/Terraform to scale.

GoGo ModulesMIT Licenseterraformdevops
terragrunt.com
9.7k1.2k