Skip to content

About

A KubeVirt add-on providing native, user-friendly templating workflows for KubeVirt virtual machines.

Resources

Code of conduct

Contributing

Security policy

Stars

6 stars

Watchers

1 watching

Forks

virt-template

A KubeVirt add-on providing native, user-friendly templating workflows for KubeVirt virtual machines.

Quick Example

cat <<'EOF' | kubectl apply -f -
apiVersion: template.kubevirt.io/v1alpha1
kind: VirtualMachineTemplate
metadata:
  name: fedora
spec:
  parameters:
    - name: NAME
      required: true
    - name: INSTANCETYPE
      value: u1.medium
    - name: PREFERENCE
      value: fedora
  virtualMachine:
    metadata:
      name: ${NAME}
    spec:
      runStrategy: Always
      instancetype:
        name: ${INSTANCETYPE}
      preference:
        name: ${PREFERENCE}
      template:
        spec:
          domain:
            devices: {}
          terminationGracePeriodSeconds: 180
          volumes:
            - containerDisk:
                image: quay.io/containerdisks/fedora:latest
              name: containerdisk-0
            - cloudInitNoCloud:
                userData: |
                  #cloud-config
                  password: fedora
                  chpasswd: { expire: False }
                  ssh_pwauth: True
              name: cloudinitdisk-0
EOF

Description

virt-template enables users to create, share, and manage VM blueprints directly within the cluster. The project provides native support for in-cluster templating through the VirtualMachineTemplate custom resource, which allows you to define reusable VM templates with configurable parameters that can be substituted at runtime to create VirtualMachine instances. Additionally, the VirtualMachineTemplateRequest custom resource enables creating templates from existing VirtualMachines.

Developed as a separate operator outside core KubeVirt, virt-template is influenced by OpenShift's Template CRD and designed to provide a more traditional virtualization experience within Kubernetes.

Components

  • virt-template-controller: Kubernetes controller that watches and validates VirtualMachineTemplate and VirtualMachineTemplateRequest resources
  • virt-template-apiserver: API server providing subresource APIs for templates

Key Features

  • VM Blueprints: Create reusable VM templates with parameter placeholders using ${NAME} syntax
  • Parameter Substitution: Define static values, generated values, or required parameters for flexible template instantiation
  • Server-Side Processing: Process templates in-cluster via the process subresource API
  • Cross-Namespace Sharing: Share and reuse templates across namespaces within your cluster
  • Template Creation from VMs: Create templates from existing VirtualMachines using VirtualMachineTemplateRequest

Getting Started

Prerequisites

For development:

  • Go version v1.24.0+
  • Container tool: Podman (default) or Docker
  • kubectl

For deployment on Kubernetes:

  • cert-manager installed in the cluster
  • KubeVirt installed in the cluster

For deployment on OpenShift:

  • OpenShift Virtualization installed in the cluster

Development

Build binaries locally:

make build              # Build controller binary
make build-apiserver    # Build apiserver binary

Run linting and formatting:

make fmt vet lint

Run unit tests:

make test

Deployment

Installing a release version on your existing cluster

The easiest way to deploy virt-template to your existing cluster is using a released version.

On Kubernetes (requires cert-manager):

This will deploy virt-template into the kubevirt namespace.

export VERSION=v0.1.1
kubectl apply -f "https://github.com/kubevirt/virt-template/releases/download/${VERSION}/install.yaml"

On OpenShift:

This will deploy virt-template into the openshift-cnv namespace.

export VERSION=v0.1.1
kubectl apply -f "https://github.com/kubevirt/virt-template/releases/download/${VERSION}/install-openshift.yaml"

See the releases page for available versions.

Quick Start with kubevirtci

The easiest way to develop and test is using kubevirtci:

make cluster-up        # Start local KubeVirt cluster
make cluster-sync      # Build, push, and deploy to cluster
make cluster-functest  # Run functional tests
make cluster-down      # Stop cluster

Manual Deployment

virt-template supports two deployment configurations:

  • config/default - Standard Kubernetes deployment (requires cert-manager)
  • config/openshift - OpenShift deployment (uses built-in Service CA operator)

Build and push container images:

make container-build container-push \
  IMG_REGISTRY=<registry> \
  VERSION=<tag>

The build supports multi-arch images (amd64, arm64, s390x). Use CONTAINER_TOOL=docker or CONTAINER_TOOL=podman.

Deploy on Kubernetes:

make install
make deploy IMG_REGISTRY=<registry> VERSION=<tag>

Deploy on OpenShift:

make install
make deploy-openshift IMG_REGISTRY=<registry> VERSION=<tag>

Create sample resources:

kubectl apply -f config/samples/template_v1alpha1_virtualmachinetemplate.yaml
kubectl apply -f config/samples/template_v1alpha1_virtualmachinetemplaterequest.yaml

Uninstall

Uninstall from Kubernetes:

kubectl delete vmt,vmtr --all  # Delete sample instances
make undeploy                  # Remove controllers
make uninstall                 # Remove CRDs

Uninstall from OpenShift:

kubectl delete vmt,vmtr --all  # Delete sample instances
make undeploy-openshift        # Remove controllers
make uninstall                 # Remove CRDs

Usage

VirtualMachineTemplate CRD

The VirtualMachineTemplate custom resource allows you to define reusable VM blueprints with parameters:

apiVersion: template.kubevirt.io/v1alpha1
kind: VirtualMachineTemplate
metadata:
  name: my-template
spec:
  parameters:
    - name: NAME
      description: Name of the VM
      required: true
    - name: MEMORY
      description: Memory size
      value: "2Gi"
    - name: PASSWORD
      generate: expression
      from: "[a-zA-Z0-9]{16}"
  virtualMachine:
    metadata:
      name: ${NAME}
[...]

Parameter Substitution

Parameters are referenced using ${PARAMETER_NAME} syntax. They can have:

  • Static values: Pre-defined default values (value: "2Gi")
  • Generated values: Random values from expression generator
  • Required flag: Mark parameters as mandatory (required: true)

Parameter Generation

The expression generator creates random values using regex-like syntax:

parameters:
  - name: PASSWORD
    generate: expression
    from: "[a-zA-Z0-9]{16}"  # Generates 16 random alphanumeric chars
  - name: API_KEY
    generate: expression
    from: "[A-F0-9]{32}"      # Generates 32 random hex chars (uppercase)

Supported character classes:

  • [a-z] - lowercase letters
  • [A-Z] - uppercase letters
  • [0-9] - digits
  • [a-zA-Z0-9] - alphanumeric
  • \w - word characters (letters, digits, underscore)
  • \d - digits
  • \a - alphabetic characters
  • \A - special characters

VirtualMachineTemplateRequest CRD

The VirtualMachineTemplateRequest custom resource allows you to create a VirtualMachineTemplate from an existing VirtualMachine. This is useful for a golden image scenario where you want to convert an existing VirtualMachine into a reusable template.

apiVersion: template.kubevirt.io/v1beta1
kind: VirtualMachineTemplateRequest
metadata:
  name: my-template-request
spec:
  templateName: my-template        # Optional: name for the created template
  ttlSecondsAfterFinished: 3600    # Optional: auto-delete after 1 hour
  virtualMachineRef:
    namespace: my-vm-namespace     # Namespace of the source VM
    name: my-vm                    # Name of the source VM
  templateLabels:                  # Optional: labels to apply to the created template
    example.com/os: linux
    example.com/workload: server

Once created, the controller will generate a VirtualMachineTemplate based on the referenced VirtualMachine in the namespace of the VirtualMachineTemplateRequest.

The optional ttlSecondsAfterFinished field limits the lifetime of a successfully completed request. After the specified number of seconds the request is automatically deleted. Failed requests are never cleaned up by the TTL controller so they remain available for debugging. If unset, the request is not automatically deleted.

Template Labels

The templateLabels field (available in v1beta1) allows you to apply custom labels to the created VirtualMachineTemplate. This is useful for organizing templates, adding metadata, or enabling label-based queries and filtering.

Note: Labels with the prefix template.kubevirt.io/ are reserved for system use. Any such labels specified in templateLabels will be rejected and filtered out, and the system-managed values will be used instead.

Authorization

When creating a VirtualMachineTemplateRequest that references a VirtualMachine in a different namespace (cross-namespace clone), the user must have create permission on the virtualmachinetemplaterequests/source subresource in the namespace of the source VirtualMachine. This is enforced by a ValidatingAdmissionPolicy and ensures that permission to use a VM as a source across namespaces is granted deliberately. Same-namespace clones do not require this permission.

A virtualmachinetemplaterequest-source-role ClusterRole is provided to simplify granting this permission. It is aggregated to the Kubernetes admin and edit roles by default and allows using all VMs in a namespace as a source. For finer-grained control, you can create custom roles that restrict the permission to specific VMs using resourceNames:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: allow-specific-vm-source
rules:
- apiGroups:
  - template.kubevirt.io
  resources:
  - virtualmachinetemplaterequests/source
  resourceNames:
  - my-vm
  verbs:
  - create

Wait for the template to be ready by running:

kubectl wait vmt my-template --for=condition=Ready

The created template can then be processed like any other VirtualMachineTemplate.

Template Subresources

The virtualmachinetemplate-admin-role and virtualmachinetemplate-editor-role ClusterRoles grant create on virtualmachinetemplates/process and virtualmachinetemplates/create (API group subresources.template.kubevirt.io). The /process subresource dry-runs template processing and does not persist a VirtualMachine. The /create subresource processes the template and creates a VirtualMachine in the namespace.

Authorization for these endpoints uses the subresource create verb. The VirtualMachine is created by the virt-template apiserver service account, so callers do not need direct kubevirt.io/virtualmachines create permission. Granting /create therefore allows users to create VMs via templates even when direct VM create RBAC is withheld. In default KubeVirt configurations the aggregated admin and edit roles already include VM management permissions; this distinction matters mainly when defining custom roles.

The virtualmachinetemplate-viewer-role grants /process only (dry-run), not /create.

Distribution

Build Installer Bundle

Generate a single YAML file with all resources:

For Kubernetes:

make build-installer IMG_REGISTRY=<registry> VERSION=<tag>

This creates dist/install.yaml which can be deployed with:

kubectl apply -f dist/install.yaml

For OpenShift:

make build-installer-openshift IMG_REGISTRY=<registry> VERSION=<tag>

This creates dist/install-openshift.yaml which can be deployed with:

kubectl apply -f dist/install-openshift.yaml

Development Tools

Run make help to see all available make targets.

Build tool versions (controller-gen, golangci-lint, gofumpt, etc.) are pinned in tools/go.mod and vendored in tools/vendor/. To upgrade a tool, update its version in tools/go.mod and run make vendor — the tool is rebuilt automatically on next use via go tool.

Kubevirtci workflows:

The project provides two kubevirtci-based development environments:

  • cluster-* targets: Test with a stable KubeVirt release
  • kubevirt-* targets: Test with KubeVirt from git main

Example workflow:

make cluster-up        # Start kubevirtci cluster
make cluster-sync      # Build, deploy, and test
make cluster-functest  # Run functional tests
make cluster-down      # Stop cluster

Contributing

Contributions are welcome! Please ensure:

  • All tests pass: make test functest
  • make all passes (runs formatting, vetting, linting, and code generation)

License

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Copyright The KubeVirt Authors.

About

A KubeVirt add-on providing native, user-friendly templating workflows for KubeVirt virtual machines.

Resources

Code of conduct

Contributing

Security policy

Stars

6 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages