OpenShift Virtualization on Azure: Bridging VMs and Containers
As a associate system administrator I worked on Redhat Linux servers, including user management, permissions, services, and performance monitoring Automated routine administrative tasks using Bash scripting and cron jobs, reducing manual effort by ~30% I am aws certified sysops administrator and Google Certified Cloud Engineer. Determined to transition my career into cloud architect /Cloud Support role
Virtualization has powered IT infrastructure for decades, but the emergence of cloud-native technologies and containerization has revealed the shortcomings of traditional hypervisor-based virtualization. IT teams often juggle disparate tools for managing virtual machines (VMs) and containers, resulting in inefficiencies and complexity.
OpenShift Virtualization, built on KubeVirt, solves this by enabling unified management of VMs and containers inside the same OpenShift cluster. On Microsoft Azure, this means you can run and scale both cloud-native applications and legacy VM-based workloads from one platform.
This guide covers the fundamentals of OpenShift Virtualization, its benefits, and how to deploy it on Azure Red Hat OpenShift (ARO).
Virtualization Options in Modern IT
1. Traditional Virtualization
Uses hypervisors like VMware vSphere, Microsoft Hyper-V, or KVM to abstract hardware resources into VMs. Benefits include consolidation, improved utilization, and workload isolation.
2. Cloud-Based Virtualization
Extends the concept with IaaS offerings such as Azure Virtual Machines, AWS EC2, or GCP Compute Engine. You gain elasticity, global scale, and pay-as-you-go economics.
3. OpenShift Virtualization
Adds VM lifecycle management into Kubernetes through KubeVirt. It unifies VM and container operations inside OpenShift, enabling organizations to:
Modernize legacy apps gradually
Simplify management with one toolset
Optimize resource usage
Benefits of OpenShift Virtualization on Azure
Efficiency: Manage VMs and containers in one OpenShift cluster.
Scalability: Leverage Kubernetes autoscaling for VM workloads.
Security: Built-in RBAC, network policies, and workload isolation.
Hybrid Cloud: Extend workloads across on-prem and Azure seamlessly.
Deploying OpenShift Virtualization on Azure
Prerequisites
An Azure Red Hat OpenShift (ARO) cluster.
Create it via Azure CLI:az aro create \ --resource-group myResourceGroup \ --name myAROCluster \ --vnet myVnet \ --master-subnet myMasterSubnet \ --worker-subnet myWorkerSubnet(Cluster provisioning may take ~30 minutes.)
Install oc (OpenShift CLI) and virtctl locally:
az aro list-credentials --name myAROCluster --resource-group myResourceGroup oc login https://api.<cluster_name>.<region>.aroapp.io:6443 -u kubeadmin -p <password>Enable OpenShift Virtualization Operator in your cluster via OperatorHub (web console) or CLI:
oc apply -f https://github.com/kubevirt/hyperconverged-cluster-operator/releases/latest/download/kubevirt-cr.yaml
Creating a Virtual Machine in OpenShift Virtualization
Step 1: Define the VM (YAML Manifest)
Save the following as rhel9-vm.yaml:
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: rhel9-vm
labels:
app: rhel9-vm
spec:
running: false
dataVolumeTemplates:
- metadata:
name: rhel9-vm-dv
spec:
sourceRef:
kind: DataSource
name: rhel9
namespace: openshift-virtualization-os-images
storage:
resources:
requests:
storage: 30Gi
template:
spec:
domain:
cpu:
cores: 2
resources:
requests:
memory: 8Gi
devices:
disks:
- name: rootdisk
disk:
bus: virtio
- name: cloudinitdisk
disk:
bus: virtio
interfaces:
- name: default
masquerade: {}
networks:
- name: default
pod: {}
volumes:
- name: rootdisk
dataVolume:
name: rhel9-vm-dv
- name: cloudinitdisk
cloudInitNoCloud:
userData: |
#cloud-config
user: cloud-user
password: "MySecurePass123"
chpasswd: { expire: False }
Step 2: Deploy the VM
oc create -f rhel9-vm.yaml
Step 3: Start the VM
virtctl start rhel9-vm
Accessing the VM
Web Console (VNC/Serial): OpenShift Console → Virtualization → VirtualMachines →
rhel9-vm→ "Console".virtctl (CLI):
virtctl console rhel9-vm virtctl vnc rhel9-vmSSH: If networking allows, SSH directly into the VM using the credentials defined in
cloud-init.
Real-World Use Cases
Application Modernization: Lift-and-shift legacy VMs to Azure OpenShift, then incrementally refactor into containers.
Hybrid Cloud: Standardize operations across on-prem OpenShift clusters and Azure ARO.
Dev/Test Environments: Spin up complex app stacks mixing VMs and containers in minutes.
VM-Only Clusters: Deploy dedicated OpenShift clusters for VMs as a VMware alternative.
Terraform Deployment of ARO with OpenShift Virtualization
1. Prerequisites
Terraform installed (
>= v1.4)Azure CLI logged in:
az login az account set --subscription "<your_subscription_id>"Resource group + networking prepared OR provisioned by Terraform
2. Terraform Configuration
Save the following as main.tf:
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~>3.95"
}
}
}
provider "azurerm" {
features {}
}
# ----------------------------
# Variables
# ----------------------------
variable "location" {
default = "eastus"
}
variable "resource_group_name" {
default = "aro-rg"
}
variable "cluster_name" {
default = "aro-cluster"
}
variable "vnet_name" {
default = "aro-vnet"
}
variable "master_subnet_name" {
default = "aro-master-subnet"
}
variable "worker_subnet_name" {
default = "aro-worker-subnet"
}
# ----------------------------
# Resource Group
# ----------------------------
resource "azurerm_resource_group" "aro" {
name = var.resource_group_name
location = var.location
}
# ----------------------------
# Networking
# ----------------------------
resource "azurerm_virtual_network" "aro_vnet" {
name = var.vnet_name
address_space = ["10.0.0.0/16"]
location = var.location
resource_group_name = azurerm_resource_group.aro.name
}
resource "azurerm_subnet" "master" {
name = var.master_subnet_name
resource_group_name = azurerm_resource_group.aro.name
virtual_network_name = azurerm_virtual_network.aro_vnet.name
address_prefixes = ["10.0.0.0/24"]
service_endpoints = ["Microsoft.ContainerRegistry"]
}
resource "azurerm_subnet" "worker" {
name = var.worker_subnet_name
resource_group_name = azurerm_resource_group.aro.name
virtual_network_name = azurerm_virtual_network.aro_vnet.name
address_prefixes = ["10.0.1.0/24"]
service_endpoints = ["Microsoft.ContainerRegistry"]
}
# ----------------------------
# Azure Red Hat OpenShift Cluster
# ----------------------------
resource "azurerm_redhat_openshift_cluster" "aro_cluster" {
name = var.cluster_name
resource_group_name = azurerm_resource_group.aro.name
location = var.location
cluster_profile {
domain = "aroexample"
version = "4.14.16"
resource_group_id = azurerm_resource_group.aro.id
}
master_profile {
vm_size = "Standard_D8s_v3"
subnet_id = azurerm_subnet.master.id
encryption_at_host_enabled = true
}
worker_profile {
vm_size = "Standard_D4s_v3"
subnet_id = azurerm_subnet.worker.id
disk_size_gb = 128
count = 3
}
network_profile {
pod_cidr = "10.128.0.0/14"
service_cidr = "172.30.0.0/16"
}
tags = {
Environment = "Dev"
Owner = "Terraform"
}
}
# ----------------------------
# Output login info
# ----------------------------
output "console_url" {
value = azurerm_redhat_openshift_cluster.aro_cluster.console_profile[0].url
}
output "api_server_url" {
value = azurerm_redhat_openshift_cluster.aro_cluster.apiserver_profile[0].url
}
3. Apply Terraform
terraform init
terraform plan
terraform apply -auto-approve
⏳ Cluster creation takes ~30–40 minutes.
4. Configure OpenShift Virtualization (Post-Provision)
Once the ARO cluster is ready:
Get login credentials:
az aro list-credentials \ --name aro-cluster \ --resource-group aro-rgLogin to OpenShift:
oc login https://api.<cluster_name>.<region>.aroapp.io:6443 \ -u kubeadmin -p <password>Enable OpenShift Virtualization Operator (via CRD):
Save as
hco-cr.yaml:apiVersion: hco.kubevirt.io/v1beta1 kind: HyperConverged metadata: name: kubevirt-hyperconverged namespace: openshift-cnv spec: infra: nodePlacement: {} workloads: nodePlacement: {}Apply it:
oc create namespace openshift-cnv oc apply -f hco-cr.yamlVerify the operator installation:
oc get pods -n openshift-cnv
You should see pods like virt-operator, virt-controller, and virt-handler running.
5. Deploy a VM (Optional)
You can now use the earlier RHEL9 VM manifest (rhel9-vm.yaml) and start it:
oc create -f rhel9-vm.yaml
virtctl start rhel9-vm
✅ With this setup:
Terraform provisions the ARO cluster on Azure.
OpenShift Virtualization is enabled via HyperConverged CR.
You can deploy and manage VMs + containers side-by-side.
Conclusion:
✅ With Azure Red Hat OpenShift + OpenShift Virtualization, enterprises can unify VM and container workloads, optimize resources, and accelerate digital transformation—without needing separate management stacks.