Skip to main content
Redhat Developers  Logo
  • AI

    Get started with AI

    • Red Hat AI
      Accelerate the development and deployment of enterprise AI solutions.
    • AI learning hub
      Explore learning materials and tools, organized by task.
    • AI interactive demos
      Click through scenarios with Red Hat AI, including training LLMs and more.
    • AI/ML learning paths
      Expand your OpenShift AI knowledge using these learning resources.
    • AI quickstarts
      Focused AI use cases designed for fast deployment on Red Hat AI platforms.
    • No-cost AI training
      Foundational Red Hat AI training.

    Featured resources

    • OpenShift AI learning
    • Open source AI for developers
    • AI product application development
    • Open source-powered AI/ML for hybrid cloud
    • AI and Node.js cheat sheet

    Red Hat AI Factory with NVIDIA

    • Red Hat AI Factory with NVIDIA is a co-engineered, enterprise-grade AI solution for building, deploying, and managing AI at scale across hybrid cloud environments.
    • Explore the solution
  • Learn

    Self-guided

    • Documentation
      Find answers, get step-by-step guidance, and learn how to use Red Hat products.
    • Learning paths
      Explore curated walkthroughs for common development tasks.
    • Guided learning
      Receive custom learning paths powered by our AI assistant.
    • See all learning

    Hands-on

    • Developer Sandbox
      Spin up Red Hat's products and technologies without setup or configuration.
    • Interactive labs
      Learn by doing in these hands-on, browser-based experiences.
    • Interactive demos
      Click through product features in these guided tours.

    Browse by topic

    • AI/ML
    • Automation
    • Java
    • Kubernetes
    • Linux
    • See all topics

    Training & certifications

    • Courses and exams
    • Certifications
    • Skills assessments
    • Red Hat Academy
    • Learning subscription
    • Explore training
  • Build

    Get started

    • Red Hat build of Podman Desktop
      A downloadable, local development hub to experiment with our products and builds.
    • Developer Sandbox
      Spin up Red Hat's products and technologies without setup or configuration.

    Download products

    • Access product downloads to start building and testing right away.
    • Red Hat Enterprise Linux
    • Red Hat AI
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform
    • See all products

    Featured

    • Red Hat build of OpenJDK
    • Red Hat JBoss Enterprise Application Platform
    • Red Hat OpenShift Dev Spaces
    • Red Hat Developer Toolset

    References

    • E-books
    • Documentation
    • Cheat sheets
    • Architecture center
  • Community

    Get involved

    • Events
    • Live AI events
    • Red Hat Summit
    • Red Hat Accelerators
    • Community discussions

    Follow along

    • Articles & blogs
    • Developer newsletter
    • Videos
    • Github

    Get help

    • Customer service
    • Customer support
    • Regional contacts
    • Find a partner

    Join the Red Hat Developer program

    • Download Red Hat products and project builds, access support documentation, learning content, and more.
    • Explore the benefits

Creating and deploying an OVF Template to support image mode for RHEL at scale

July 15, 2024
Andrew Block
Related topics:
Developer productivityHybrid cloudLinuxVirtualization
Related products:
Image mode for Red Hat Enterprise LinuxRed Hat Enterprise Linux

    Repeatability and consistency -- These are tenants of cloud native infrastructure and just some of the many benefits that are inherently found within container images which led to the rapid adoption of the technology. Image mode for RHEL extends many of the benefits of running containers and applies them to building, deploying and managing traditional Operating System environments.

    In the preceding articles (Creating a VMDK using image mode for RHEL and Integrating an image mode for RHEL produced VMDK into vSphere), we described the process for producing a VMDK file with image mode for RHEL, publishing the resulting file to a VMware vSphere environment, and creating a new Virtual Machine using the VMDK as the primary disk drive for the machine. These steps illustrated just how easy it can be to use image mode for RHEL content within vSphere. However, where this implementation falls short in comparison to running traditional containers are those tenants that were highlighted earlier. There were quite a number of steps that went into achieving the end goal, and introducing one divergence from any of the expected steps could result in an error or failure to ultimately make use of the desired Virtual Machine. Yes, automation could be implemented to streamline the overall process, but there are features in VMware that can support deploying Virtual Machines in a repeatable manner at scale. 

    Open Virtualization Format (OVF) is an open standard for packaging and distributing Virtual Machines, and an OVF Template in vSphere encapsulates the disks and configurations associated with a Virtual Machine. By making use of an OVF Template, not only can Virtual Machines be deployed with ease in a repeatable fashion, but their content includes several optimizations, such as compression, to reduce the time that it takes to deploy Virtual Machine instances. In this article, we will describe the process for creating and deploying an OVF template within a vSphere environment to support managing image mode for RHEL at scale.

    Read more about image mode for RHEL

    Creating an OVF Template

    In the last article,  Integrating a VMDK produced with image mode for RHEL into vSphere, we created a Virtual Machine in a vSphere environment using a VMDK. To create an OVF template, an existing Virtual Machine needs to be available as it represents the content that will be used within the template. You can choose to make use of the existing Virtual Machine deployed previously or choose to deploy another Virtual Machine for the purpose of acting as the content for the OVF template. For the purposes of this article, we will make use of the existing Virtual Machine.

    Before we begin, ensure that you have the following prerequisites completed. The installation and configuration of these tools were described previously. Refer to the existing articles as needed:

    • Creating a VMDK using image mode for RHEL
    • Integrating a VMDK produced with image mode for RHEL into vSphere

    Prerequisites

    • Access to a vSphere environment
    • A Virtual Machine deployed within the vSphere environment with an image mode for RHEL based VMDK disk
    • govc CLI that has been authenticated to the vSphere environment
    • jq CLI
    • tee

    Recall that we established a directory structure containing our content

    Recall from the prior articles that all activities were performed within a directory called rhel-bootc-vmdk. Navigate to this directory, as it can be the start point to enable the creation and management of an OVF template from the existing Virtual Machine.

    The govc export.ovf subcommand can be used to facilitate the creation of an OVF template from an existing Virtual Machine. Before the template can be created, power off the Virtual machine if it is running. 

    govc vm.power \

        -dc="${DATACENTER}" \

        -off=true \

        ${VM_NAME}

    With the Virtual Machine powered off, create an OVF by exporting the Virtual Machine in a directory called ovf using the following command:

    govc export.ovf \

        -dc=${DATACENTER} \

        -vm=${VM_NAME} \

        -name=rhel-bootc \

        -sha=1 \

        ovf

    Once the export is complete, the contents will be located within a directory called rhel-bootc and enclosed with the ovf directory. Three following directory structures will be present:

    ovf/

    └── rhel-bootc

        ├── rhel-bootc-disk-0.vmdk

        ├── rhel-bootc.mf

        └── rhel-bootc.ovf

    The .ovf file contains the descriptor for the OVF template, while the .mf file contains a SHA1 hash of all of the files related within the OVF template.

    Creating a Virtual Machine from an OVF Template

    With the OVF template created, new Virtual Machines can be created in a repeatable manner. The govc import.ovf command can be used to deploy OVF templates from content on the local file system.  Another benefit of OVF templates is the ability to easily customize Virtual Machines from a known baseline at deploy time through the use of an options file. This JSON formatted file includes everything that one would want to configure as it relates to the Virtual Machine definition and simplifies how to deploy Virtual Machines in an automated way. 
    While an options file can be created from scratch, the starting point can be created from an existing OVF template file by using the govc import.spec command. Create an options file called options.json in the ovf directory from the previously created OVF template by using the following command.

    govc import.spec ovf/rhel-bootc/rhel-bootc.ovf  > ovf/options.json

    The options file can be customized, such as modifying the type of disk provisioning to be thin, by using the jq and tee CLI’s

    cat ovf/options.json | jq -r '.DiskProvisioning="thin"' | tee ovf/options.json

    Notice in the output and in the options.json file that the DiskProvisioning="thin" property has been populated.

    Create a new Virtual Machine called rhel-bootc-ovf by deploying the OVF Template along with the options file using the following command:

    govc import.ovf \

        -dc=${DATACENTER} \

        -ds=${DATASTORE} \

        --pool=${DATACENTER_POOL} \

        -options ovf/options.json \

        -name rhel-bootc-ovf \

        ovf/rhel-bootc/rhel-bootc.ovf

    Once complete, a new Virtual Machine called rhel-bootc-ovf will be created. Virtual Machines created from OVF templates are not started automatically by default. However, this behavior can be changed by specifying the PowerOn property within an options file (You may have noticed earlier that the PowerOn property currently defined within the options.json is set as false. Changing this value to true will automatically start the Virtual Machine

    However, if you recall from the prior article, cloud-init is used to inject configuration at an Operating System level at runtime. While it would have been ideal to define these properties within the options file, these values are used in the context of a Virtual Machine ExtraConfig, and these properties are not defined within an options file. As a result, applying the configurations must be made after a Virtual Machine has been deployed. Let’s demonstrate how to use cloud-init in combination with an OVF template.

    Prepare the cloud-init Metadata and User Data files by creating a metadata-ovf.yaml and user-data-ovf.yaml file within a directory called cloud-init with the following content (This directory should have been created from the previous article. However, if this directory does not currently exist, create one underneath the base rhel-bootc-vmdk directory for which all commands have been executed. 

    cloud-init/metadata-ovf.yaml:

    instance-id: rhel-bootc-ovf

    local-hostname: rhel-bootc-ovf

    cloud-init/user-data-ovf.yaml:

    #cloud-config

    users:

      - default

      - name: cloud-user

        sudo: ALL=(ALL) NOPASSWD:ALL

        groups: sudo, wheel

        lock_passwd: true

        ssh_authorized_keys:

          - ${SSH_PUB_KEY}

    The contents of the User Data file here is identical to the User Data file created in the previous article. Only the contents of the Metadata file differs with regards to the name of the machine. Update the value of the ${SSH_PUB_KEY} with an SSH public key that can be used to connect to the instance remotely once it is running.

    Modify the configuration of the rhel-bootc-ovf VirtualMachine to include the cloud-init configuration.

    govc vm.change \

        -dc="${DATACENTER}" \

        -vm="rhel-bootc-ovf" \

        -e guestinfo.metadata="$(gzip -c9 <cloud-init/metadata-ovf.yaml | { base64 -w0 2>/dev/null || base64; })" \

        -e guestinfo.metadata.encoding="gzip+base64" \

        -e guestinfo.userdata="$(gzip -c9 <cloud-init/user-data-ovf.yaml | { base64 -w0 2>/dev/null || base64; })" \

        -e guestinfo.userdata.encoding="gzip+base64"

    Power on the Virtual Machine and wait for the IP address to be allocated. 

    govc vm.power -on -dc=${DATACENTER} rhel-bootc-ovf

    govc vm.ip -v4 -dc=${DATACENTER} -wait=10m rhel-bootc-ovf

    Once an IP address has been returned, attempt to connect to the machine using SSH using the SSH private key associated with the SSH public key that was added to the cloud-init User Data.

    ssh cloud-user@<ip_address>

    If the connection to the rhel-bootc-ovf Virtual Machine was successful, the deployment of the OVF template and injecting template options and cloud-init configurations were a success.

    Deploying OVF Templates from a vSphere Content Library

    OVF templates greatly simplify what it takes to deploy Virtual Machines in a repeatable manner. One area that you might have noticed when deploying the OVF template in the prior section was the time that it took to complete the deployment. The majority of the time that it took to deploy the template was uploading the VMDK file to vSphere. Factoring in both the time that it takes to download the VMDK file from the source Virtual Machine when creating the OVF template and uploading the VMDK file when deploying the OVF template along with the connection speed between the local machine and the vSphere environment, the overall time that it takes to facilitate the management of Virtual Machines using OVF templates can be quite lengthy.

    Another option that provides a number of advantages compared to deploying OVF templates directly from a source on a local machine is to deploy OVF templates from content stored within the vSphere environment. By using this approach, the overall time that it takes to deploy OVF templates is greatly reduced.

    A Content Library is a feature that was introduced in VMware vSphere 6.7 Update 1 and enables the sharing and reuse of assets, including templates, and provides an ideal solution to the challenges discussed previously. An existing Content Library or a new Content Library can be created to facilitate the management of OVF templates associated with image mode for RHEL assets.

    Create a new Content Library within the vSphere environment called rhel-bootc-library that will contain assets related to image mode for RHEL:

    govc library.create \

        -dc="${DATACENTER}" \

        -ds="${DATASTORE}" \

        rhel-bootc-library

    Upload the OVF template from the local machine to the Content Library

    govc library.import \

        rhel-bootc-library \

        ovf/rhel-bootc/rhel-bootc.ovf

    Content stored within the Content Library can be listed by using the govc library.ls command. Running this command will confirm the OVF template imported previously is available for use.

    govc library.ls \

        rhel-bootc-library \

        rhel-bootc-library/*/

    /rhel-bootc-library

    /rhel-bootc-library/rhel-bootc/rhel-bootc.ovf

    /rhel-bootc-library/rhel-bootc/rhel-bootc-disk-0.vmdk

    With the OVF Template available within the Content Library, deploy the OVF Template using the govc library.deploy command. The process for deploying the template from the Content Library mirrors many of the same steps that are used when deploying from a local source. To use an options file when deploying an OVF template, the content should be generated from the OVF template so that it contains values associated with the template. While we already have a usable options file for the rhel-bootc OVF template, if there is a need to regenerate the options file again or use another template within the Content Library, the OVF template must be downloaded from the Content Library. Fortunately, only the .ovf specification file needs to be retrieved instead of all of the content related to the template, such as the VMDK file.

    If there was a need to download the OVF file again, the following command could be used:

    govc library.export \

        rhel-bootc-library/rhel-bootc/rhel-bootc.ovf \

        ${DESTINATION}

    The govc import.spec command could then be used to generate the options file.Since an options file is already available on the local machine, there is no need to generate a new one.

    Before deploying the OVF template from the Content Library, let’s remove the existing Virtual Machine created previously when deploying the OVF Template from the local machine.

    govc vm.destroy \

        -dc=${DATACENTER} \

        rhel-bootc-ovf

    Now, create a Virtual Machine called rhel-bootc-ovf by deploying the rhel-bootc OVF template from the Content Library referencing the options file, the location of the OVF template within the Content Library (name of the Content Library and path within the library), and the name of the Virtual Machine to create:

    govc library.deploy \

        -dc=${DATACENTER} \

        -ds=${DATASTORE} \

        --pool=${DATACENTER_POOL} \

        -options ovf/options.json \

        /rhel-bootc-library/rhel-bootc \

        rhel-bootc-ovf

    Since the template and its associated resources were all stored within the Content Library, the deployment will most likely have been faster than deploying from the local machine previously. And since the content is centrally located, there is additional assurance that the content does not differ regardless of who is executing the deployment process.

    The remainder of the steps for preparing the Virtual Machine for use continues to be the same. The Virtual Machine is injected with cloud-init configurations to enable Operating System level configurations and then the machine can be powered on. 

    govc vm.change \

        -dc="${DATACENTER}" \

        -vm="rhel-bootc-ovf" \

        -e guestinfo.metadata="$(gzip -c9 <cloud-init/metadata-ovf.yaml | { base64 -w0 2>/dev/null || base64; })" \

        -e guestinfo.metadata.encoding="gzip+base64" \

        -e guestinfo.userdata="$(gzip -c9 <cloud-init/user-data-ovf.yaml | { base64 -w0 2>/dev/null || base64; })" \

        -e guestinfo.userdata.encoding="gzip+base64"

    govc vm.power -on -dc=${DATACENTER} rhel-bootc-ovf

    Obtain an IP address for the machine and then connect via SSH to confirm the configurations were successful.

    govc vm.ip -v4 -dc=${DATACENTER} -wait=10m rhel-bootc-ovf

    ssh cloud-user@<ip_address>

    The use of OVF Templates greatly simplifies the process for deploying instances created with image mode for RHEL within a vSphere environment. By being able to leverage additional supporting components, like Content Libraries, managing content, and deploying Virtual Machines that originated from a VMDK disk created with image mode for RHEL is simplified. Each of these elements, working together, enables deploying a fleet of instances repeatedly, consistently, and most importantly, easily. 

    Last updated: July 24, 2024

    Recent Posts

    • Every layer counts: Defense in depth for AI agents with Red Hat AI

    • Fun in the RUN instruction: Why container builds with distroless images can surprise you

    • Trusted software factory: Building trust in the agentic AI era

    • Build a zero trust AI pipeline with OpenShift and RHEL CVMs

    • Red Hat Hardened Images: Top 5 benefits for software developers

    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Platforms

    • Red Hat AI
    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform
    • See all products

    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
    © 2026 Red Hat

    Red Hat legal and privacy links

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

    Chat Support

    Please log in with your Red Hat account to access chat support.