Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions content/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ and benefit from the expertise shared in this repository.

|Date|Headline|
|---|---|
|2026-07-30|[OpenShift Virtualization Terraform example](kubevirt/terraform/)|
|2026-07-30|[Update OpenShift Virtualization Ansible example](kubevirt/ansible/)|
|2026-07-30|[Audit Log Forwarding to Rsyslog](cluster-configuration/logging/forwarding-demo/)|
|2026-07-22|[Hosted Control Plane and Proxy](cluster-installation/hosted-control-plane/proxy/)|
Expand Down
159 changes: 159 additions & 0 deletions content/kubevirt/terraform/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
---
title: Terraform
linktitle: Terraform
description: OpenShift Virt & Terraform examples
tags: ['terraform','kubevirt','cnv','ocp-v']
icon: material/terraform
---

# Terraform

This page provides example Terraform configurations for managing virtual machines on OpenShift Virtualization using the [alekc/kubectl](https://registry.terraform.io/providers/alekc/kubectl/latest/docs) provider.

|Component|Version|
|---|---|
|OpenShift|v4.22.3|
|OpenShift Virt|v4.22.2|
|Terraform|v1.12.2|

## Prerequisites

```shell title="Install Terraform on macOS"
brew tap hashicorp/tap
brew install hashicorp/tap/terraform
```

## Deploy a VM

=== "Download: main.tf"

```shell
curl -L -O {{ page.canonical_url }}main.tf
```

=== "main.tf"

```hcl
--8<-- "content/kubevirt/terraform/main.tf"
```

```shell title="Initialize and apply"
cp -v $KUBECONFIG kubeconfig-terraform
terraform init
terraform apply
```

??? example "`terraform apply` output"

```shell hl_lines="95 108"
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated
with the following symbols:
+ create

Terraform will perform the following actions:

# kubectl_manifest.rhel9_vm will be created
+ resource "kubectl_manifest" "rhel9_vm" {
+ api_version = "kubevirt.io/v1"
+ apply_only = false
+ field_manager = "kubectl"
+ force_conflicts = false
+ force_new = false
+ id = (known after apply)
+ kind = "VirtualMachine"
+ live_manifest_incluster = (sensitive value)
+ live_uid = (known after apply)
+ name = "rhel9"
+ namespace = "rbohne-kubevirt-terraform"
+ server_side_apply = false
+ uid = (known after apply)
+ upgrade_api_version = false
+ validate_schema = true
+ wait_for_rollout = true
+ yaml_body = (sensitive value)
+ yaml_body_parsed = <<-EOT
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: rhel9
namespace: rbohne-kubevirt-terraform
spec:
dataVolumeTemplates:
- metadata:
name: rhel9-root
spec:
sourceRef:
kind: DataSource
name: rhel9
namespace: openshift-virtualization-os-images
storage:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 30Gi
runStrategy: Always
template:
metadata:
labels:
kubevirt.io/vm: rhel9
spec:
domain:
cpu:
cores: 2
devices:
disks:
- bootOrder: 1
disk:
bus: virtio
name: root
interfaces:
- bridge: {}
model: virtio
name: coe
memory:
guest: 4Gi
resources:
requests:
memory: 4Gi
networks:
- multus:
networkName: coe-bridge
name: coe
volumes:
- dataVolume:
name: rhel9-root
name: root
EOT
+ yaml_incluster = (sensitive value)

+ timeouts {
+ create = "20m"
}

+ wait_for {
+ field {
+ key = "status.printableStatus"
+ value = "Running"
+ value_type = "eq"
}
}
}

Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.

Enter a value: yes

kubectl_manifest.rhel9_vm: Creating...
kubectl_manifest.rhel9_vm: Still creating... [00m10s elapsed]
kubectl_manifest.rhel9_vm: Still creating... [00m20s elapsed]
kubectl_manifest.rhel9_vm: Creation complete after 22s [id=/apis/kubevirt.io/v1/namespaces/rbohne-kubevirt-terraform/virtualmachines/rhel9]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
```

<iframe width="560" height="315" src="https://www.youtube.com/embed/w9JF6eUKd5A?si=8eWWdinMfHLFZDE9" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
121 changes: 121 additions & 0 deletions content/kubevirt/terraform/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
terraform {
required_version = ">= 1.5.0"
required_providers {
kubectl = {
source = "alekc/kubectl"
version = "~> 2.1"
}
}
}

provider "kubectl" {
config_path = "kubeconfig-terraform"
insecure = true
}

variable "namespace" {
default = "rbohne-kubevirt-terraform"
}

resource "kubectl_manifest" "rhel9_vm" {
timeouts {
create = "20m"
}

wait_for {
field {
key = "status.printableStatus"
value = "Running"
}
}

yaml_body = yamlencode({
apiVersion = "kubevirt.io/v1"
kind = "VirtualMachine"
metadata = {
name = "rhel9"
namespace = var.namespace
}
spec = {
runStrategy = "Always"
dataVolumeTemplates = [
{
metadata = {
name = "rhel9-root"
}
spec = {
storage = {
accessModes = ["ReadWriteMany"]
resources = {
requests = {
storage = "30Gi"
}
}
}
sourceRef = {
kind = "DataSource"
name = "rhel9"
namespace = "openshift-virtualization-os-images"
}
}
}
]
template = {
metadata = {
labels = {
"kubevirt.io/vm" = "rhel9"
}
}
spec = {
domain = {
cpu = {
cores = 2
}
memory = {
guest = "4Gi"
}
resources = {
requests = {
memory = "4Gi"
}
}
devices = {
disks = [
{
name = "root"
bootOrder = 1
disk = {
bus = "virtio"
}
}
]
interfaces = [
{
name = "coe"
model = "virtio"
bridge = {}
}
]
}
}
networks = [
{
name = "coe"
multus = {
networkName = "coe-bridge"
}
}
]
volumes = [
{
name = "root"
dataVolume = {
name = "rhel9-root"
}
}
]
}
}
}
})
}
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ nav:
- Descheduler: kubevirt/descheduler/index.md
- Templates: kubevirt/template.md
- Ansible: kubevirt/ansible/README.md
- Terraform: kubevirt/terraform/index.md
- Networking: kubevirt/networking/index.md
- Storage: kubevirt/storage.md
- KubeVirt CSI Driver: kubevirt/kubevirt-csi-driver/index.md
Expand Down
Loading