Skip to main content
Redhat Developers  Logo
  • Products

    Platforms

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat AI
      Red Hat AI
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • View All Red Hat Products

    Featured

    • Red Hat build of OpenJDK
    • Red Hat Developer Hub
    • Red Hat JBoss Enterprise Application Platform
    • Red Hat OpenShift Dev Spaces
    • Red Hat OpenShift Local
    • Red Hat Developer Sandbox

      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Openshift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • View All Technologies
    • Programming Languages & Frameworks

      • Java
      • Python
      • JavaScript
    • System Design & Architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer Productivity

      • Developer productivity
      • Developer Tools
      • GitOps
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Secure Development & Architectures

      • Security
      • Secure coding
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • AI/ML
      AI/ML Icon
    • View All Learning Resources

    E-Books

    • GitOps Cookbook
    • Podman in Action
    • Kubernetes Operators
    • The Path to GitOps
    • View All E-books

    Cheat Sheets

    • Linux Commands
    • Bash Commands
    • Git
    • systemd Commands
    • View All Cheat Sheets

    Documentation

    • Product Documentation
    • API Catalog
    • Legacy Documentation
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

Windows image-building service for OpenShift Virtualization

August 12, 2025
Karel Simon
Related topics:
CI/CDGitOpsVirtualizationWindows
Related products:
Red Hat OpenShift Virtualization

Share:

    Imagine managing virtual machines (VMs) in your continuous integration (CI) process as easily as you would any other piece of software. Red Hat OpenShift Pipelines makes this vision a reality by providing a robust framework for building CI/CD systems. This framework empowers developers to seamlessly build, test, and deploy applications in a truly cloud-native way.

    This article demonstrates how the integration of OpenShift Pipelines, Pipelines as Code, and Red Hat OpenShift Virtualization can automate the creation of standardized Windows golden images for efficient and consistent VM provisioning.

    How it works

    OpenShift Pipelines achieves this by managing pipelines, individual pipeline steps, and even pipeline runs as Kubernetes Custom Resources (CRs). The advantage of CRs lies in their ability to be stored as YAML code within files in a source control management (SCM) system like Git. This approach mirrors the principles of GitOps. By co-locating your pipeline definitions as code within the same SCM repository as your application code, you gain significant advantages. 

    It dramatically simplifies the versioning, reviewing, and collaborative aspects of pipeline changes, allowing them to evolve in lockstep with your application code. Furthermore, this integration provides a centralized vantage point, enabling you to monitor pipeline status and control execution directly from your SCM, eliminating the need to constantly switch between disparate systems.

    Red Hat OpenShift Virtualization stands as a powerful add-on to the OpenShift platform, seamlessly integrating the management of traditional VMs directly within your cloud-native environment. 

    OpenShift Virtualization, combined with the declarative power of OpenShift Pipelines and the "pipelines as code" paradigm, fundamentally transforms CI/CD. This synergy enables developers to manage and interact with VMs directly within their automated workflows, treating them as native objects. Consequently, this unified approach streamlines operations, accelerates application delivery, and bridges the gap between traditional virtualization and modern cloud-native practices. 

    The diagram in Figure 1 shows the high-level functionality of the Windows image-building service.

    diagram showing how the service works
    Figure 1: Windows image-building service diagram.

    The windows-image-builder repository includes multiple manifests of Pipeline, PipelineRuns, and ConfigMaps with answer files and PowerShell scripts. The connection between the repository and the cluster is managed by the Pipelines as Code (PAC) controller. When a user creates a pull request (PR), the repository webhook contacts the PAC controller running inside the cluster.

    Based on the configuration and the changes introduced in the PR, the PAC controller runs the appropriate Pipeline by creating a PipelineRun for it. Because the example PipelineRun references a Pipeline stored in the same repository, PAC controller also downloads and deploys the Pipeline.

    Once the PipelineRun completes successfully, PAC reports the results back to the PR. The full pipeline diagram is visible in Figure 2.

    pipeline diagram
    Figure 2: Pipeline diagram.

    The project uses a modified windows-efi-installer pipeline (the original pipeline is located here).

    The pipeline required modifications like original pipeline downloads ConfigMaps and creates Windows disk, which is available only in the cluster where the pipeline is triggered. The updated pipeline clones the windows-image-builder repository. From this cloned repository, it deploys ConfigMaps (needs to be located under the configmaps/autounattend/ path inside the repository) with answer files and PowerShell scripts.

    To be able to fully use the resulting image in different clusters, the pipeline contains a task for pushing the resulting Windows image to an external registry, so then you can use the image across multiple clusters. With an appropriate answers file, the pipeline can build golden images for Windows 10, 11, Server 2012, Server 2016, Server 2019, Server 2022, and Server 2025, all with UEFI mode enabled. Right now the example repository contains answers files for Windows 11 and Server 2025.

    The pipeline expects the Windows ISO to be already present in the cluster as a PVC.

    Prerequisites

    1. You will need a Red Hat OpenShift cluster running version 4.17 or newer.
    2. Install Red Hat OpenShift Pipelines and OpenShift Virtualization from the OperatorHub.
    3. Import Windows ISO file into a PVC (you can use a DataVolume for this).
    apiVersion: cdi.kubevirt.io/v1beta1
    kind: DataVolume
    metadata:
     name: windows-source
    spec:
     source:
       http:
         url: <URL>
     storage:
       volumeMode: Filesystem
       resources:
         requests:
           storage: 9Gi
    1. Install the command-line tools as documented here.
    2. Create a new OpenShift project. Connect the repo to the OpenShift cluster as documented here.
    3. Test the newly created webhook in GitHub (settings / Webhooks).
    4. Add all required files from the example repository to your repository and push it.
    git add .
    git commit -sm "initialize windows-image-builder repository"
    git push

    Example PipelineRun

    You run pipelines by creating PipelineRuns. You can find an example PipelineRun in windows-qe-virtio.yaml. 

    The example PipelineRun includes the parameter acceptEula. By setting this parameter, you are agreeing to the applicable Microsoft end user license agreement(s) for each deployment or installation for the Microsoft product(s). Set this parameter to true after reviewing the EULA. If you set it to false, the pipeline will exit in the first task.

    A PipelineRun consists of two key fields: metadata.annotations and spec.params. Fields spec.pipelineRef, spec.taskRunSpecs, and spec.workspaces are required to keep as-is.

    Annotations

    Use annotations to configure PAC (for example, which pipeline to use) on which PR comment it should trigger the PipelineRun.

    apiVersion: tekton.dev/v1
    kind: PipelineRun
    metadata:
     name: windows11-qe-virtio-installer-run
     annotations:
       pipelinesascode.tekton.dev/pipeline: "pipeline/windows-autounattend.yaml"
       pipelinesascode.tekton.dev/on-comment: "^/windows11-qe-virtio"
       pipelinesascode.tekton.dev/on-event: "[incoming,push]"
       pipelinesascode.tekton.dev/on-target-branch: "[main]"
       pipelinesascode.tekton.dev/on-cel-expression: >-
         (target_branch == "main") &&
         (files.all.exists(x, x.matches('.tekton/windows-qe-virtio.yaml|configmaps/autounattend/windows11-qe-virtio.yaml')))
    • pipelinesascode.tekton.dev/pipeline: "pipeline/windows-autounattend.yaml": Tells the PAC which local pipeline to use.
    • pipelinesascode.tekton.dev/on-comment: "^/windows11-qe-virtio": Triggers the PipelineRun if user comments the PR with /windows11-qe-virtio comment.
    • pipelinesascode.tekton.dev/on-event: "[incoming,push]": Triggers the PipelineRun if the event which triggers the PAC equals incoming (triggers PipelineRun via http webhook) or push (new code is pushed to PR).
    • pipelinesascode.tekton.dev/on-target-branch: "[main]": Triggers the PipelineRun only if  the PR is opened against the main branch.
    • pipelinesascode.tekton.dev/on-cel-expression: >-

            (files.all.exists(x, x.matches('.tekton/windows-qe-virtio.yaml|configmaps/autounattend/windows11-qe-virtio.yaml'))): Triggers the PipelineRun if the PR is opened against the main branch and contains any change to files .tekton/windows-qe-virtio.yaml or configmaps/autounattend/windows11-qe-virtio.yaml.

    Parameters

    This part contains all parameters the pipeline needs. Notice the result-registry-url and secret-name parameters. The result-registry-url parameter specifies the URL of the registry, where the resulting image will be pushed. You should use a full URL with a tag for this parameter. The secret-name parameter is the name of the secret that holds the registry credentials.

    apiVersion: tekton.dev/v1
    kind: PipelineRun
    metadata:
     name: windows11-qe-virtio-installer-run
    spec:
     params:
       - name: acceptEula
         value: false
       - name: secretName
         value: kubevirt-disk-uploader-credentials-quay
       - name: resultRegistryURL
         value: quay.io/<user>/<image-name>:<tag>

    The secret has to be in this format:

    apiVersion: v1
    stringData:
        accessKeyId: <ACCESS_KEY_ID>
        secretKey: <SECRET_KEY>
    kind: Secret
    metadata:
        name: disk-uploader-credentials
    type: Opaque

    You can adjust all other parameters based on which Windows version image you would like to build. The parameters revision and repository-url are populated by PAC and should not be changed. The parameters spec.pipelineRef, spec.taskRunSpecs, and spec.workspaces must be kept as they are.

    How to trigger the pipeline

    To create a new image, add a new PipelineRun with correct parameters in the .tekton folder in the repository and correct ConfigMap under configmaps/autounattend.

    Commit these files and open a PR in your repository connected to the cluster. The build should start within a few seconds. You can monitor the progress by navigating to the Pipelines tab in the left menu and selecting the PipelineRuns tab.

    Watch the entire automation process in action in this video:

    Results

    The example windows11-qe-virtio ConfigMap includes answer files that install Windows 11 with VirtIO drivers, Windows Subsystem for Linux (WSL), Python, and an enabled SSH server. The image then skips OOBE and shuts down. The resulting image is suitable for running Python test scripts or executing scripts within WSL. Alternatively, you can create a custom answer file to install your own software and configurations.

    If you need different Windows images with different configurations, just create a new PipelineRun and new ConfigMap in the windows-image-builder project. Then create a new PR and the automation will trigger a new PipelineRun in the cluster. When the PipelineRun finishes, your new Windows image will be waiting for you in the registry you defined.

    The newly created golden image can be imported into other clusters as described in the article Automate VM golden image management with OpenShift.

    Final thoughts

    This article provided a comprehensive guide on establishing your own automated pipeline for regularly building Windows golden images. This approach ensures that any modification you make to your autounattend.xml file, which dictates Windows setup and configuration, will automatically trigger the Windows image builder to produce a new, updated Windows image. This continuous process guarantees your golden images are always current, consistent, and reflect the latest desired configurations.

    Related Posts

    • Automate VM golden image management with OpenShift

    • First steps with the data virtualization Operator for Red Hat OpenShift

    • The new Tekton Pipelines extension for Visual Studio Code

    • Red Hat Open Innovation Labs: Automating CI/CD Deployment Pipelines

    Recent Posts

    • Staying ahead of artificial intelligence threats

    • Strengthen privacy and security with encrypted DNS in RHEL

    • How to enable Ansible Lightspeed intelligent assistant

    • Why some agentic AI developers are moving code from Python to Rust

    • Confidential VMs: The core of confidential containers

    What’s up next?

    The automated builds and deployments (CI/CD) of container-based applications can reduce mistakes, improve productivity, and promote more thorough testing. Try this sandbox activity to learn about OpenShift Pipelines for automated builds and deployment.

    Start the activity
    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Products

    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform

    Build

    • Developer Sandbox
    • Developer Tools
    • Interactive Tutorials
    • API Catalog

    Quicklinks

    • Learning Resources
    • E-books
    • Cheat Sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site Status Dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit
    © 2025 Red Hat

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Report a website issue