OpenMCF logoOpenMCF

Loading...

Kubernetes External DNS

Deploys ExternalDNS on Kubernetes using the official Helm chart (external-dns v1.19.0) from kubernetes-sigs, with support for Google Cloud DNS (GKE), AWS Route53 (EKS), Azure DNS (AKS), and Cloudflare as DNS providers, automatic ServiceAccount creation with workload-identity annotations, optional namespace creation, and configurable ExternalDNS and Helm chart versions.

What Gets Created

When you deploy a KubernetesExternalDns resource, OpenMCF provisions:

  • Namespace — created only when createNamespace is true
  • ServiceAccount — a dedicated Kubernetes ServiceAccount annotated with workload-identity bindings for the selected DNS provider (GKE Workload Identity, EKS IRSA, AKS Workload Identity, or no annotation for Cloudflare)
  • Helm Release (ExternalDNS) — deploys ExternalDNS from the external-dns chart at https://kubernetes-sigs.github.io/external-dns/, pinned to version 1.19.0 by default, with atomic rollback enabled, cleanup-on-fail, and a 3-minute timeout
  • Cloudflare API Token Secret — when using the Cloudflare provider, a Kubernetes Secret named {name}-cloudflare-api-token is created in the target namespace and mounted as the CF_API_TOKEN environment variable

Prerequisites

  • Kubernetes credentials configured via environment variables or OpenMCF provider config
  • A Kubernetes namespace that already exists, or set createNamespace to true
  • DNS provider access — one of the following depending on your provider:
    • GKE: a GCP project with Cloud DNS enabled and a Google Service Account with dns.admin role; Workload Identity must be configured on the GKE cluster
    • EKS: an AWS Route53 hosted zone and either an existing IRSA role ARN or IAM permissions for auto-creation
    • AKS: an Azure DNS zone and optionally a Managed Identity client ID for workload identity
    • Cloudflare: an API token with Zone:Zone:Read and Zone:DNS:Edit permissions

Quick Start

Create a file external-dns.yaml:

apiVersion: kubernetes.openmcf.org/v1
kind: KubernetesExternalDns
metadata:
  name: my-external-dns
  labels:
    openmcf.org/provisioner: pulumi
    pulumi.openmcf.org/organization: my-org
    pulumi.openmcf.org/project: my-project
    pulumi.openmcf.org/stack.name: dev.KubernetesExternalDns.my-external-dns
spec:
  namespace: external-dns
  createNamespace: true
  cloudflare:
    apiToken: cf-api-token-value
    dnsZoneId: zone-id-value

Deploy:

openmcf apply -f external-dns.yaml

This creates an ExternalDNS instance in the external-dns namespace configured to manage DNS records in Cloudflare, using ExternalDNS v0.19.0 and Helm chart version 1.19.0.

Configuration Reference

Required Fields

FieldTypeDescriptionValidation
namespacestringKubernetes namespace for the ExternalDNS deployment. Can reference a KubernetesNamespace resource via valueFrom.Required
Provider config (one of)objectExactly one of gke, eks, aks, or cloudflare must be set.Required

Optional Fields

FieldTypeDefaultDescription
targetCluster.clusterKindenum—Kubernetes cluster kind. Valid values: AwsEksCluster, GcpGkeCluster, AzureAksCluster, DigitalOceanKubernetesCluster, CivoKubernetesCluster.
targetCluster.clusterNamestring—Name of the target Kubernetes cluster in the same environment.
createNamespaceboolfalseWhen true, creates the namespace before deploying resources.
externalDnsVersionstringv0.19.0ExternalDNS container image tag.
helmChartVersionstring1.19.0Helm chart version for the external-dns chart.

GKE Provider (gke):

FieldTypeDescriptionValidation
gke.projectIdstringGCP project hosting the DNS zone and GKE cluster. Can reference a GcpProject resource via valueFrom.Required
gke.dnsZoneIdstringGCP Cloud DNS zone ID for ExternalDNS to manage. Can reference a GcpDnsZone resource via valueFrom.Required

EKS Provider (eks):

FieldTypeDescriptionValidation
eks.route53ZoneIdstringAWS Route53 hosted zone ID for ExternalDNS to manage. Can reference an AwsRoute53Zone resource via valueFrom.Required
eks.irsaRoleArnOverridestringExisting IAM role ARN for IRSA. If blank, the role is expected to be auto-created externally.Optional

AKS Provider (aks):

FieldTypeDescriptionValidation
aks.dnsZoneIdstringAzure DNS zone ID for ExternalDNS to manage. Can reference an AzureDnsZone resource via valueFrom.Required
aks.managedIdentityClientIdstringAzure Managed Identity client ID for workload identity authentication.Optional

Cloudflare Provider (cloudflare):

FieldTypeDescriptionValidation
cloudflare.apiTokenstringCloudflare API token with Zone:Zone:Read and Zone:DNS:Edit permissions. Stored as a Kubernetes Secret.Required
cloudflare.dnsZoneIdstringCloudflare DNS zone ID to manage. Can reference a CloudflareDnsZone resource via valueFrom.Required
cloudflare.isProxiedboolEnable Cloudflare proxy (orange cloud) for managed DNS records, routing traffic through Cloudflare's edge network for DDoS protection, WAF, and CDN. Default: false.Optional

Note on valueFrom: Fields marked "Can reference ... via valueFrom" are StringValueOrRef types. You can provide a literal string value directly, or use valueFrom to reference the output of another OpenMCF resource. See the foreign key reference example below.

Examples

GKE with Google Cloud DNS

Deploy ExternalDNS on a GKE cluster to manage records in a Google Cloud DNS zone:

apiVersion: kubernetes.openmcf.org/v1
kind: KubernetesExternalDns
metadata:
  name: gke-external-dns
  labels:
    openmcf.org/provisioner: pulumi
    pulumi.openmcf.org/organization: my-org
    pulumi.openmcf.org/project: my-project
    pulumi.openmcf.org/stack.name: dev.KubernetesExternalDns.gke-external-dns
spec:
  namespace: external-dns
  createNamespace: true
  gke:
    projectId: my-gcp-project
    dnsZoneId: my-dns-zone

The module creates a ServiceAccount annotated with iam.gke.io/gcp-service-account: gke-external-dns@my-gcp-project.iam.gserviceaccount.com and configures ExternalDNS to use the google provider scoped to the specified zone.

EKS with AWS Route53

Deploy ExternalDNS on an EKS cluster with an existing IRSA role:

apiVersion: kubernetes.openmcf.org/v1
kind: KubernetesExternalDns
metadata:
  name: eks-external-dns
  labels:
    openmcf.org/provisioner: pulumi
    pulumi.openmcf.org/organization: my-org
    pulumi.openmcf.org/project: my-project
    pulumi.openmcf.org/stack.name: prod.KubernetesExternalDns.eks-external-dns
spec:
  namespace: external-dns
  createNamespace: true
  externalDnsVersion: "v0.15.1"
  helmChartVersion: "1.15.0"
  eks:
    route53ZoneId: Z0123456789ABCDEF
    irsaRoleArnOverride: arn:aws:iam::123456789012:role/external-dns-irsa

This pins ExternalDNS to v0.15.1 and the Helm chart to 1.15.0. The ServiceAccount is annotated with eks.amazonaws.com/role-arn for IRSA authentication.

Cloudflare with Proxy Enabled

Deploy ExternalDNS to manage Cloudflare DNS records with the proxy (orange cloud) enabled:

apiVersion: kubernetes.openmcf.org/v1
kind: KubernetesExternalDns
metadata:
  name: cf-external-dns
  labels:
    openmcf.org/provisioner: pulumi
    pulumi.openmcf.org/organization: my-org
    pulumi.openmcf.org/project: my-project
    pulumi.openmcf.org/stack.name: prod.KubernetesExternalDns.cf-external-dns
spec:
  namespace: external-dns
  createNamespace: true
  cloudflare:
    apiToken: my-cloudflare-api-token
    dnsZoneId: abc123def456
    isProxied: true

The module creates a Kubernetes Secret for the API token, configures ExternalDNS to watch Services, Ingress, Gateway API HTTPRoutes, and Istio Gateways, and enables the --cloudflare-proxied flag so all managed records are proxied through Cloudflare's edge network.

Using Foreign Key References

Reference OpenMCF-managed resources instead of hardcoding values:

apiVersion: kubernetes.openmcf.org/v1
kind: KubernetesExternalDns
metadata:
  name: platform-external-dns
  labels:
    openmcf.org/provisioner: pulumi
    pulumi.openmcf.org/organization: my-org
    pulumi.openmcf.org/project: my-project
    pulumi.openmcf.org/stack.name: prod.KubernetesExternalDns.platform-external-dns
spec:
  namespace:
    valueFrom:
      kind: KubernetesNamespace
      name: dns-namespace
      field: spec.name
  createNamespace: false
  gke:
    projectId:
      valueFrom:
        kind: GcpProject
        name: platform-project
        field: status.outputs.project_id
    dnsZoneId:
      valueFrom:
        kind: GcpDnsZone
        name: platform-zone
        field: status.outputs.zone_id

This example references an OpenMCF-managed namespace, GCP project, and DNS zone rather than embedding literal values.

Stack Outputs

After deployment, the following outputs are available in status.outputs:

OutputTypeDescription
namespacestringKubernetes namespace where ExternalDNS is deployed
releaseNamestringHelm release name for the ExternalDNS deployment
solverSastringKubernetes ServiceAccount name used by ExternalDNS

Related Components

  • KubernetesNamespace — provides the target namespace via valueFrom reference
  • KubernetesHelmRelease — alternative for deploying Helm charts with custom configurations
  • KubernetesDeployment — application deployments that ExternalDNS can create DNS records for
  • KubernetesService — services annotated with ExternalDNS hostname annotations to trigger DNS record creation

Next article

Kubernetes External Secrets

Kubernetes External Secrets Deploys the External Secrets Operator (ESO) onto any Kubernetes cluster using its official Helm chart. ESO synchronizes secrets from cloud provider secret stores (Google Cloud Secret Manager, AWS Secrets Manager, Azure Key Vault) into native Kubernetes Secrets, keeping application pods decoupled from provider-specific APIs. The module creates a dedicated ServiceAccount wired to the correct cloud identity mechanism (GKE Workload Identity, EKS IRSA, or AKS Managed...
Read next article
Presets
4 ready-to-deploy configurationsView presets →