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

Declaratively assigning DNS records to virtual machines

September 11, 2025
Raffaele Spazzoli
Related topics:
KubernetesVirtualization
Related products:
Red Hat OpenShift Virtualization

    Virtual machines often use friendly names rather than just IP addresses, which requires the creation of a DNS record. This is primarily because many virtual machines are treated as "pets" rather than "cattle," which requires that a unique identity, including a network identity, be assigned.

    Organizations operating a fleet of virtual machines (VMs) often establish a naming convention for virtual machines along with a process for assigning DNS records to new instances. These actions are typically one component of a broader VM lifecycle automation, encompassing both provisioning and decommissioning.

    Red Hat OpenShift Virtualization lets you manage virtual machines declaratively, often through GitOps. This article explores methods for declaratively assigning DNS records to these virtual machines.

    Requirements

    To manage DNS records that are associated with VMs in a declarative fashion, there are several items you must consider. These virtual machines are typically exposed to the network on VLANs. Aside from VLANs, externally addressable user defined networks (UDNs), which use BGP to announce routes, are another option for providing virtual machines access to the network. 

    The IPs that these virtual machines receive might or might not be known in advance, but this solution should work with either approach. 

    Finally, virtual machines can be exposed on multiple networks, and therefore be available at multiple IPs and consequently require multiple DNS records.

    So, in summary:

    • Virtual machines can be exposed on multiple networks.
    • IPs can be assigned statically or dynamically.
    • Some of the assigned IPs to a virtual machine might need to have associated DNS records.

    Design

    We want the user experience to be as simple as possible. Ideally, adding labels and annotations on the VirtualMachine custom resource should be enough to declaratively create DNS records. The following is an approach from the user experience point of view that can be applied to achieve the envisioned goal:

    A label, such as vm.redhat-cop.dns-name: "true", can be used to declare that DNS records should be assigned to the VM.

    Annotations can then be added to specify FQDNs that should be associated with this virtual machine. The annotations will take this form:

    vm.redhat-cop.dns-name/<interface-name>: <FQDN>

    In this case, interface-name is the name of the network interface whose IP needs to be associated with the specified FQDN. This combination allows for assigning distinct FQDNs to multiple network interfaces.

    Now that the user experience side of the design is defined, let’s focus on how the system will actually work. The diagram in Figure 1 depicts the steps and components involved.

    A flowchart shows how OpenShift Virtualization cluster components interact to create and update an Enterprise DNS endpoint.
    Figure 1: The workflow for updating an Enterprise DNS record using a policy controller within an OpenShift Virtualization cluster.

    First, a VirtualMachine with the previously described labels and annotations is created in the spec.template section of the custom resource. The instantiation of a VirtualMachine generates a VirtualMachineInstance custom resource with the same labels and annotations.

    Given the way the virtual machine API works, the actual values of the IPs configured on the network interfaces are known only at runtime within the status of the VirtualMachineInstance. This also requires the qemu-guest-agent to be correctly installed in the virtual machine OS.

    A policy controller monitors VirtualMachineInstance for certain attributes. When there is a match between the IP record on the status and the value of the annotation a DNSEndpoint Custom Resource is created.

    The DNSEnpoint itself is monitored by the ExternalDNS controller, which, if correctly configured (out of scope for this article), will update the DNS server with the desired DNS records.

    As an example, let’s suppose we have a VirtualMachine with this snippet:

    spec:
      template:
       metadata:
         annotations:
           vm.redhat-cop.dns-name/enp1s0: vm.example.com
         labels:
           vm.redhat-cop.dn-name: "true"

    Assuming that at runtime the VirtualMachineInstance receives an IP, this should generate the following DSNEndpoint:

    apiVersion: externaldns.k8s.io/v1alpha1
    kind: DNSEndpoint
    metadata:
     name: fedora-moccasin-tahr-60-enp1s0
     namespace: test-vm
    spec:
     endpoints:
     - dnsName: vm.example.com
       recordTTL: 180
       recordType: A
       targets:
       - 10.136.0.178

    The final decision left unanswered to this point is the specific policy controller that will be used. Two frameworks will be shown: Kyverno and Red Hat Advanced Cluster Management for Kubernetes, which in the end, will achieve the same result.

    Kyverno-based approach

    Kyverno is a cloud-native policy management framework that has been donated to the Cloud Native Computing Foundation (CNCF). It is lightweight and relatively easy to use. However, as of the time of this article, Kyverno is not supported by Red Hat.

    Our policy will need to react based on the existence of certain conditions (i.e., VirtualMachineInstance with certain labels and annotations) and when this situation occurs, one or more objects will be created in response (i.e., DNSEndpoints for this use case). Such a policy can be written similar to the following:

    apiVersion: kyverno.io/v1
    kind: ClusterPolicy
    metadata:
     name: create-vm-dns-endpoints
     annotations:
       policies.kyverno.io/title: DNS Entries for Virtual Machines
       policies.kyverno.io/category: external-dns, virtual-machines, dns
       policies.kyverno.io/subject: DNSEndpoints, VirtualMachinesInstance
       policies.kyverno.io/minversion: 1.6.0
       policies.kyverno.io/description: >-

    This policy creates DNSEndpoints for external-dns to manage DNS entries for virtual machines.

    spec:
     rules:
     - name: generate-dns-endpoints
       match:
         any:
         - resources:
             kinds:
             - kubevirt.io/v1/VirtualMachineInstance
             selector:
               matchLabels:
                 vm.redhat-cop.dns-name: "true"
       generate:
         generateExisting: true
         synchronize: true
         orphanDownstreamOnPolicyDelete: true
         foreach:
           - list: request.object.status.interfaces
             preconditions:
               any:
               - key: '{{ request.object.metadata.annotations."vm.redhat-cop.dns-name/{{ element.name }}" || "" }}'
                 operator: NotEquals
                 value: ""
             apiVersion: externaldns.k8s.io/v1alpha1
             kind: DNSEndpoint
             name: '{{request.object.metadata.name}}-{{element.name}}'
             namespace: "{{request.object.metadata.namespace}}"                   
             data:
               spec:
                 endpoints:
                 - dnsName: '{{ request.object.metadata.annotations."vm.redhat-cop.dns-name/{{ element.name }}" }}'
                   recordTTL: 180
                   recordType: A
                   targets:
                   - '{{element.ipAddress}}'

    This policy will generate a DNSEndpoint for each interface for which a DNS address has been requested.

    Red Hat Advanced Cluster Management policies-based approach

    Red Hat Advanced Cluster Management for Kubernetes is OpenShift's fleet management tool. It operates in a hub-and-spoke architecture, so it requires that a hub cluster be established in order to enforce policies on managed clusters. Advanced Cluster Management for Kubernetes contains a very expressive policy definition language primarily based on Golang templates.

    An Advanced Cluster Management policy to satisfy our use case is shown here (this is a raw policy; the full policy definition, Placement, and Placement bindings have been omitted for brevity):

    object-templates-raw: |-
     {{ range (lookup "kubevirt.io/v1" "VirtualMachineInstance" "" "" "vm.redhat-cop.dns-name=true").items }}
     {{ $vm := . -}}
     - complianceType: mustonlyhave
       objectDefinition:
         apiVersion: externaldns.k8s.io/v1alpha1
         kind: DNSEndpoint
         metadata:
           name: "{{ .metadata.name }}"
           namespace: "{{ .metadata.namespace }}"
         spec:
         {{- if $vm.status.interfaces }}
           endpoints:
           {{- range $vm.status.interfaces -}}
           {{ $annotationName := printf "%v%v" "vm.redhat-cop.dns-name/" .name  -}}
           {{ if get $vm.metadata.annotations $annotationName -}}
           - dnsName: "{{ get $vm.metadata.annotations $annotationName }}"
             recordTTL: 180
             recordType: A
             targets:
             - "{{.ipAddress}}"
           {{ end }}
           {{ end }}
         {{ else }}
           endpoints: []
         {{ end }}
     {{ end }}

    Conclusion

    This article explored several methods for how to declaratively assign FQDNs to virtual machine running in OpenShift Virtualization by using a combination of policy controllers and operators.

    We started off by providing details related to how many organizations apply naming conventions (FQDNs) to virtual machines. We have not implemented this logic in our solution, but you can easily write more policies to allow only virtual machines with well-formed FQDNs. Admission  policies are relatively easy to write. This exercise is left to the reader. 

    Related Posts

    • Automatic certificate provisioning with cert-manager and DNS challenge

    • Live migrating VMs with OpenShift Virtualization

    • Use Vagrant Landrush to add DNS features to your OpenShift CDK Machine

    • How OpenShift Virtualization supports VM live migration

    • How to back up and restore virtual machines with OpenShift

    • Why I switched from VMware to OpenShift Virtualization

    Recent Posts

    • MCP servers vs. skills: Choosing the right context for your AI

    • How to route external and local LLMs with Models-as-a-Service

    • Protect data offloaded to GPU-accelerated environments with OpenShift sandboxed containers

    • Case study: Measuring energy efficiency on the x64 platform

    • How to prevent AI inference stack silent failures

    What’s up next?

    Download the OpenShift Virtualization for VMware admins cheat sheet for a quick guide to managing virtual machines within the powerful OpenShift environment.

    Get the cheat sheet
    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.