{"id":13582540,"url":"https://github.com/dmacvicar/terraform-provider-libvirt","last_synced_at":"2026-04-02T00:03:17.008Z","repository":{"id":38355402,"uuid":"52690290","full_name":"dmacvicar/terraform-provider-libvirt","owner":"dmacvicar","description":"Terraform provider to provision infrastructure with Linux's KVM using libvirt","archived":false,"fork":false,"pushed_at":"2026-03-26T19:05:13.000Z","size":98392,"stargazers_count":1807,"open_issues_count":20,"forks_count":507,"subscribers_count":45,"default_branch":"main","last_synced_at":"2026-03-27T08:07:32.363Z","etag":null,"topics":["kvm","libvirt","terraform","terraform-provider","virtualization"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dmacvicar.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2016-02-27T21:44:36.000Z","updated_at":"2026-03-26T19:05:10.000Z","dependencies_parsed_at":"2023-12-27T21:32:42.373Z","dependency_job_id":"526fb073-e1b1-4964-a267-2157d8d2ecfb","html_url":"https://github.com/dmacvicar/terraform-provider-libvirt","commit_stats":{"total_commits":1005,"total_committers":140,"mean_commits":7.178571428571429,"dds":0.7373134328358208,"last_synced_commit":"1a889318823fd86b25ef48cb8e55eefa625cf015"},"previous_names":[],"tags_count":42,"template":false,"template_full_name":null,"purl":"pkg:github/dmacvicar/terraform-provider-libvirt","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmacvicar%2Fterraform-provider-libvirt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmacvicar%2Fterraform-provider-libvirt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmacvicar%2Fterraform-provider-libvirt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmacvicar%2Fterraform-provider-libvirt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dmacvicar","download_url":"https://codeload.github.com/dmacvicar/terraform-provider-libvirt/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmacvicar%2Fterraform-provider-libvirt/sbom","scorecard":{"id":347470,"data":{"date":"2025-08-11","repo":{"name":"github.com/dmacvicar/terraform-provider-libvirt","commit":"11dbcbf9e35ff0a7cd7594ad6382d67f69f59d7f"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.4,"checks":[{"name":"Code-Review","score":2,"reason":"Found 8/27 approved changesets -- score normalized to 2","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: topLevel 'contents' permission set to 'write': .github/workflows/release.yml:7","Info: topLevel 'contents' permission set to 'read': .github/workflows/test.yml:15","Info: topLevel 'pull-requests' permission set to 'read': .github/workflows/test.yml:16","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/release.yml:9"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Signed-Releases","score":8,"reason":"5 out of the last 5 releases have a total of 5 signed artifacts.","details":["Info: signed release artifact: terraform-provider-libvirt_0.8.3_SHA256SUMS.sig: https://github.com/dmacvicar/terraform-provider-libvirt/releases/tag/v0.8.3","Info: signed release artifact: terraform-provider-libvirt_0.8.2_SHA256SUMS.sig: https://github.com/dmacvicar/terraform-provider-libvirt/releases/tag/v0.8.2","Info: signed release artifact: terraform-provider-libvirt_0.8.1_SHA256SUMS.sig: https://github.com/dmacvicar/terraform-provider-libvirt/releases/tag/v0.8.1","Info: signed release artifact: terraform-provider-libvirt_0.8.0_SHA256SUMS.sig: https://github.com/dmacvicar/terraform-provider-libvirt/releases/tag/v0.8.0","Info: signed release artifact: terraform-provider-libvirt_0.7.6_SHA256SUMS.sig: https://github.com/dmacvicar/terraform-provider-libvirt/releases/tag/v0.7.6","Warn: release artifact v0.8.3 does not have provenance: https://api.github.com/repos/dmacvicar/terraform-provider-libvirt/releases/203551311","Warn: release artifact v0.8.2 does not have provenance: https://api.github.com/repos/dmacvicar/terraform-provider-libvirt/releases/203243610","Warn: release artifact v0.8.1 does not have provenance: https://api.github.com/repos/dmacvicar/terraform-provider-libvirt/releases/180798049","Warn: release artifact v0.8.0 does not have provenance: https://api.github.com/repos/dmacvicar/terraform-provider-libvirt/releases/176296764","Warn: release artifact v0.7.6 does not have provenance: https://api.github.com/repos/dmacvicar/terraform-provider-libvirt/releases/130236598"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":3,"reason":"branch protection is not maximal on development and all release branches","details":["Info: 'allow deletion' disabled on branch 'main'","Info: 'force pushes' disabled on branch 'main'","Warn: 'branch protection settings apply to administrators' is disabled on branch 'main'","Warn: 'stale review dismissal' is disabled on branch 'main'","Warn: branch 'main' does not require approvers","Warn: codeowners review is not required on branch 'main'","Warn: 'last push approval' is disabled on branch 'main'","Warn: no status checks found to merge onto branch 'main'","Info: PRs are required in order to make changes on branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/dmacvicar/terraform-provider-libvirt/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/dmacvicar/terraform-provider-libvirt/release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/dmacvicar/terraform-provider-libvirt/release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:31: update your workflow using https://app.stepsecurity.io/secureworkflow/dmacvicar/terraform-provider-libvirt/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/dmacvicar/terraform-provider-libvirt/test.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:28: update your workflow using https://app.stepsecurity.io/secureworkflow/dmacvicar/terraform-provider-libvirt/test.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/test.yml:32: update your workflow using https://app.stepsecurity.io/secureworkflow/dmacvicar/terraform-provider-libvirt/test.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/test.yml:37: update your workflow using https://app.stepsecurity.io/secureworkflow/dmacvicar/terraform-provider-libvirt/test.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:53: update your workflow using https://app.stepsecurity.io/secureworkflow/dmacvicar/terraform-provider-libvirt/test.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:58: update your workflow using https://app.stepsecurity.io/secureworkflow/dmacvicar/terraform-provider-libvirt/test.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/test.yml:60: update your workflow using https://app.stepsecurity.io/secureworkflow/dmacvicar/terraform-provider-libvirt/test.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:76: update your workflow using https://app.stepsecurity.io/secureworkflow/dmacvicar/terraform-provider-libvirt/test.yml/main?enable=pin","Warn: containerImage not pinned by hash: contrib/Alpine/Dockerfile_all_in_one:14","Warn: containerImage not pinned by hash: contrib/Alpine/Dockerfile_all_in_one:17","Warn: containerImage not pinned by hash: contrib/Alpine/Dockerfile_all_in_one:49: pin your Docker image by updating alpine:latest to alpine:latest@sha256:4bcff63911fcb4448bd4fdacec207030997caf25e9bea4045fa6c8c44de311d1","Warn: containerImage not pinned by hash: contrib/Alpine/Dockerfile_build_dependent:11","Warn: containerImage not pinned by hash: contrib/Alpine/Dockerfile_build_dependent:14","Warn: containerImage not pinned by hash: contrib/Alpine/Dockerfile_build_dependent:17: pin your Docker image by updating alpine:latest to alpine:latest@sha256:4bcff63911fcb4448bd4fdacec207030997caf25e9bea4045fa6c8c44de311d1","Warn: containerImage not pinned by hash: contrib/Build/Dockerfile_glibc:2: pin your Docker image by updating golang:stretch to golang:stretch@sha256:a9718cb62e77cc03411ea11fd71f3541e508f211169dd8f8d69ba2036545cd80","Warn: containerImage not pinned by hash: contrib/Build/Dockerfile_musl:2: pin your Docker image by updating golang:alpine to golang:alpine@sha256:fa0c7cf32e9df17129acf535223b02fd718f30d63e952ad56ea0d5d19f55b2e8","Warn: containerImage not pinned by hash: contrib/Debian/Dockerfile_all_in_one:14","Warn: containerImage not pinned by hash: contrib/Debian/Dockerfile_all_in_one:17","Warn: containerImage not pinned by hash: contrib/Debian/Dockerfile_all_in_one:52: pin your Docker image by updating ubuntu:18.04 to ubuntu:18.04@sha256:152dc042452c496007f07ca9127571cb9c29697f42acbfad72324b2bb2e43c98","Warn: containerImage not pinned by hash: contrib/Debian/Dockerfile_build_dependent:11","Warn: containerImage not pinned by hash: contrib/Debian/Dockerfile_build_dependent:14","Warn: containerImage not pinned by hash: contrib/Debian/Dockerfile_build_dependent:17: pin your Docker image by updating ubuntu:18.04 to ubuntu:18.04@sha256:152dc042452c496007f07ca9127571cb9c29697f42acbfad72324b2bb2e43c98","Warn: containerImage not pinned by hash: contrib/openSUSE/Dockerfile_all_in_one:14","Warn: containerImage not pinned by hash: contrib/openSUSE/Dockerfile_all_in_one:17","Warn: containerImage not pinned by hash: contrib/openSUSE/Dockerfile_all_in_one:52: pin your Docker image by updating opensuse/tumbleweed:latest to opensuse/tumbleweed:latest@sha256:dce11e3de113dd68adfee9edd8817e258fdb68cf1ef0ffc958c21425cacc8553","Warn: containerImage not pinned by hash: contrib/openSUSE/Dockerfile_build_dependent:11","Warn: containerImage not pinned by hash: contrib/openSUSE/Dockerfile_build_dependent:14","Warn: containerImage not pinned by hash: contrib/openSUSE/Dockerfile_build_dependent:17: pin your Docker image by updating opensuse/tumbleweed:latest to opensuse/tumbleweed:latest@sha256:dce11e3de113dd68adfee9edd8817e258fdb68cf1ef0ffc958c21425cacc8553","Warn: goCommand not pinned by hash: contrib/Alpine/Dockerfile_all_in_one:28","Warn: goCommand not pinned by hash: contrib/Build/Dockerfile_glibc:16","Warn: goCommand not pinned by hash: contrib/Build/Dockerfile_musl:13","Warn: goCommand not pinned by hash: contrib/Debian/Dockerfile_all_in_one:31","Warn: goCommand not pinned by hash: contrib/openSUSE/Dockerfile_all_in_one:31","Info:   0 out of   7 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   5 third-party GitHubAction dependencies pinned","Info:   0 out of  20 containerImage dependencies pinned","Info:   0 out of   5 goCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Vulnerabilities","score":8,"reason":"2 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GO-2025-3754 / GHSA-2x5j-vhc8-9cwm","Warn: Project is vulnerable to: GO-2025-3595 / GHSA-vvgc-356p-c3xw"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 12 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-18T07:28:02.797Z","repository_id":38355402,"created_at":"2025-08-18T07:28:02.797Z","updated_at":"2025-08-18T07:28:02.797Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31293159,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T21:15:39.731Z","status":"ssl_error","status_checked_at":"2026-04-01T21:15:34.046Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["kvm","libvirt","terraform","terraform-provider","virtualization"],"created_at":"2024-08-01T15:02:48.785Z","updated_at":"2026-04-02T00:03:16.202Z","avatar_url":"https://github.com/dmacvicar.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# Terraform provider for libvirt\n\n![Build and Test](https://github.com/dmacvicar/terraform-provider-libvirt/actions/workflows/test.yml/badge.svg)\n\nThis 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.\n\nThis is a complete rewrite of the legacy provider. The legacy provider (v0.8.x and earlier) is maintained in the [v0.8 branch](https://github.com/dmacvicar/terraform-provider-libvirt/tree/v0.8). Starting from v0.9.0, all releases will be based on this new rewrite.\n\n## Goals\n\nThis rewrite improves upon the legacy provider in several ways:\n\n1. **API Fidelity** - Models the [libvirt XML schemas](https://libvirt.org/format.html) directly instead of abstracting them, giving users full access to libvirt features. Schema coverage is bounded by what [libvirtxml](https://pkg.go.dev/libvirt.org/go/libvirtxml) supports.\n2. **Current Framework** - Built with Terraform Plugin Framework, as the SDK v2 used in the legacy provider is deprecated\n3. **Best Practices** - Follows [HashiCorp's provider design principles](https://developer.hashicorp.com/terraform/plugin/best-practices/hashicorp-provider-design-principles)\n\n## Supported Resources \u0026 XML Coverage\n\n| Resource | Status | XML Coverage |\n|----------|--------|--------------|\n| `libvirt_domain` | ✅ Supported | Full coverage of libvirtxml’s domain schema (devices, CPU, memory, features, RNG, TPM, etc.). |\n| `libvirt_network` | ✅ Supported | Full coverage of libvirtxml network schema (forwarding modes, bridge, DHCP, VLAN, virtual ports, etc.). |\n| `libvirt_pool` | ✅ Supported | Full coverage of libvirtxml storage pool schema (dir/logical/iscsi/etc.). |\n| `libvirt_volume` | ✅ Supported | Full coverage of libvirtxml storage volume schema (target, backing_store, encryption, timestamps). |\n\nEverything 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.\n\n## Using the provider\n\n```hcl\nterraform {\n  required_providers {\n    libvirt = {\n      source = \"dmacvicar/libvirt\"\n    }\n  }\n}\n\nprovider \"libvirt\" {\n  uri = \"qemu:///system\"\n}\n\nresource \"libvirt_domain\" \"example\" {\n  name         = \"example-vm\"\n  type         = \"kvm\"\n  memory       = 512\n  memory_unit  = \"MiB\"\n  vcpu         = 1\n  \n  os = {\n    type         = \"hvm\"\n    type_arch    = \"x86_64\"\n    type_machine = \"q35\"\n  }\n}\n```\n\n### Connection URIs\n\nThe provider supports multiple connection transports:\n\n```hcl\n# Local system socket\nprovider \"libvirt\" {\n  uri = \"qemu:///system\"\n}\n\n# Remote via SSH (Go library)\nprovider \"libvirt\" {\n  uri = \"qemu+ssh://user@host.example.com/system\"\n}\n\n# Remote via SSH (native command, respects ~/.ssh/config)\nprovider \"libvirt\" {\n  uri = \"qemu+sshcmd://user@host.example.com/system\"\n}\n\n# Remote via TLS\nprovider \"libvirt\" {\n  uri = \"qemu+tls://host.example.com/system\"\n}\n```\n\nSee [docs/transports.md](./docs/transports.md) for detailed transport configuration and examples.\n\nSee the [examples](./examples) directory for more usage examples.\n\n## Documentation\n\nYou can find an overview of the XML \u003c-\u003e HCL mapping and the resource schema in the documentation hosted at the [Terraform registry](https://registry.terraform.io/providers/dmacvicar/libvirt/latest/docs) and [OpenTofu registry](https://search.opentofu.org/provider/dmacvicar/libvirt/latest).\n\nFor non-released versions, see [XML \u003c-\u003e HCL mapping](docs/schema-mapping.md) and for an overview of the HCL to XML mapping patterns and [the documentation source](docs/index.md).\n\n## Development information\n\n### Design Principles\n\n- **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.\n- **No Abstraction**: The Terraform schema mirrors the libvirt XML structure as closely as possible, providing full access to underlying features rather than simplified abstractions.\n- **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.\n\n### Schema Mapping\n\nAll resources use a single XML \u003c-\u003e HCL mapping spec (flattening rules, unions, presence booleans, nested attributes). See [XML \u003c-\u003e HCL mapping](docs/schema-mapping.md) documentation for the canonical rules.\n\n### Lifecycle Operation Controls\n\nSome resources expose provider-specific lifecycle operation controls using nested `create`/`destroy` objects.\nThese fields control post-define and pre-undefine API operations (for example build/start/delete behavior), and are not direct libvirt XML fields.\nCurrent lifecycle controls are experimental and may change in future releases.\n\nExample (`libvirt_pool`):\n\n```hcl\nresource \"libvirt_pool\" \"data\" {\n  name = \"data-pool\"\n  type = \"dir\"\n  target = {\n    path = \"/var/lib/libvirt/data\"\n  }\n\n  create = {\n    build     = true\n    start     = true\n    autostart = true\n  }\n\n  destroy = {\n    delete = false\n  }\n}\n```\n\n### Development\n\nThis 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.\n\nI am aware of the consequences, advantages and drawbacks. It is my learning platform, and I own the outcome.\n\n### Code Generation\n\nTo reduce boilerplate and ensure consistency, this provider uses a code generation system that automatically produces:\n\n- **Terraform models** with proper `tfsdk` tags\n- **Plugin Framework schemas** with correct types and optionality\n- **XML conversion functions** implementing the \"preserve user intent\" pattern\n\nSee [codegen documentation](internal/codegen/README.md) for architecture and for the documentation tooling (docindex/docgen) used to inject schema descriptions.\n\n### Building and running the provider from source\n\n```bash\ngit clone https://github.com/dmacvicar/terraform-provider-libvirt\ncd terraform-provider-libvirt\nmake build\n```\n\nTo install the provider locally:\n\n```bash\nmake install\n```\n\nThis installs to `~/.terraform.d/plugins/registry.terraform.io/dmacvicar/libvirt/dev/linux_amd64/`\n\nThen override the provider like this in `$HOME/.terraformrc`:\n\n```hcl\nprovider_installation {\n    dev_overrides {\n      \"registry.terraform.io/dmacvicar/libvirt\" = \"/home/duncan/src/terraform-provider-libvirt\"\n    }\n\n    # For all other providers, install them directly from their origin provider\n    # registries as normal.\n    direct {}\n  }\n```\n\n### Running tests\n\n```bash\n# Run linter\nmake lint\n\n# Run unit tests\nmake test\n\n# Run acceptance tests (requires libvirt)\nmake testacc\n```\n\nOn 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](https://www.qemu.org/docs/master/devel/index-tcg.html) accelerator instead of KVM.\n\n## Migration from Legacy Provider (v0.8.x)\n\n### Getting Domain IP Addresses\n\nThe 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:\n\n**Legacy provider (v0.8.x):**\n```hcl\nresource \"libvirt_domain\" \"example\" {\n  # ... domain config ...\n}\n\noutput \"ip\" {\n  value = libvirt_domain.example.network_interface[0].addresses[0]\n}\n```\n\n**New provider (v0.9+):**\n```hcl\nresource \"libvirt_domain\" \"example\" {\n  # ... domain config ...\n}\n\ndata \"libvirt_domain_interface_addresses\" \"example\" {\n  domain = libvirt_domain.example.id\n  source = \"lease\"  # or \"agent\" or \"any\"\n}\n\noutput \"ip\" {\n  value = data.libvirt_domain_interface_addresses.example.interfaces[0].addrs[0].addr\n}\n```\n\nAlternatively, use the `wait_for_ip` property on the domain's interface configuration to ensure the domain has an IP before creation completes:\n\n```hcl\nresource \"libvirt_domain\" \"example\" {\n  name   = \"example-vm\"\n  memory = 512\n  vcpu   = 1\n\n  devices = {\n    interfaces = [\n      {\n        type = \"network\"\n        source = {\n          network = \"default\"\n        }\n        wait_for_ip = {\n          timeout = 300  # seconds\n          source  = \"lease\"\n        }\n      }\n    ]\n  }\n}\n```\n\n### Volume Source URLs\n\nIf 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:\n\n**Legacy provider (v0.8.x):**\n```hcl\nresource \"libvirt_volume\" \"ubuntu\" {\n  name   = \"ubuntu.qcow2\"\n  pool   = \"default\"\n  source = \"https://cloud-images.ubuntu.com/releases/22.04/release/ubuntu-22.04-server-cloudimg-amd64.img\"\n  # size was automatically detected from Content-Length\n}\n```\n\n**New provider (v0.9+):**\n```hcl\nresource \"libvirt_volume\" \"ubuntu\" {\n  name   = \"ubuntu.qcow2\"\n  pool   = \"default\"\n  format = \"qcow2\"  # Must specify format\n\n  create = {\n    content = {\n      url = \"https://cloud-images.ubuntu.com/releases/22.04/release/ubuntu-22.04-server-cloudimg-amd64.img\"\n    }\n  }\n  # capacity is automatically detected from Content-Length header\n}\n```\n\n**Important notes:**\n1. **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.\n2. **Capacity is computed**: Like the legacy provider, `capacity` is automatically computed from the HTTP `Content-Length` header (or file size for local files). You don't need to specify it.\n3. **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\"`\n4. **Content-Length required**: For HTTPS URLs, the server must provide a `Content-Length` header. If it doesn't, volume creation will fail.\n\n\n## Contributing\n\n### Opening issues\n\nIssues should be open for clearly actionable bugs. For getting help on your stack not working, please [use the discussions first](https://github.com/dmacvicar/terraform-provider-libvirt/discussions/categories/q-a).\n\n### Pull Requests\n\nIn 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.\n\n### Use of AI\n\nThe author uses AI for this project, but as the maintainer, he owns the outcome and consequences.\n\nIf you contribute code or issues and used AI, you are required to disclose it, including full details (tools, prompts).\n\n## Author\n\n* Duncan Mac-Vicar P.\n\n## License\n\n* Apache 2.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdmacvicar%2Fterraform-provider-libvirt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdmacvicar%2Fterraform-provider-libvirt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdmacvicar%2Fterraform-provider-libvirt/lists"}