ExternalDNS for Kubernetes with AWS Route53

ExternalDNS synchronizes exposed Kubernetes Services, Ingresses, and Gateway API HTTPRoute resources with external DNS providers like AWS Route53.
This guide demonstrates how to configure ExternalDNS on Amazon EKS using EKS Pod Identity to automate Route53 DNS records dynamically.
📺 Video Walkthrough
Step 1. Configure IAM Policy & EKS Pod Identity
external-dns-iam.tf
# 1. Route53 IAM Policy
resource "aws_iam_policy" "external_dns" {
name = "ExternalDNSControllerPolicy-${module.eks.cluster_name}"
description = "Allows ExternalDNS to manage DNS records in Route53"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"route53:ChangeResourceRecordSets"
]
Resource = ["arn:aws:route53:::hostedzone/*"]
},
{
Effect = "Allow"
Action = [
"route53:ListHostedZones",
"route53:ListResourceRecordSets",
"route53:ListTagsForResources"
]
Resource = ["*"]
}
]
})
}
# 2. IAM Role with Pod Identity Trust
data "aws_iam_policy_document" "pod_id_trust" {
statement {
effect = "Allow"
principals {
type = "Service"
identifiers = ["pods.eks.amazonaws.com"]
}
actions = ["sts:AssumeRole", "sts:TagSession"]
}
}
resource "aws_iam_role" "external_dns" {
name = "external-dns-controller-${module.eks.cluster_name}"
assume_role_policy = data.aws_iam_policy_document.pod_id_trust.json
}
resource "aws_iam_role_policy_attachment" "external_dns" {
role = aws_iam_role.external_dns.name
policy_arn = aws_iam_policy.external_dns.arn
}
# 3. Pod Identity Association
resource "aws_eks_pod_identity_association" "external_dns" {
cluster_name = module.eks.cluster_name
namespace = "external-dns"
service_account = "external-dns-controller"
role_arn = aws_iam_role.external_dns.arn
}
Step 2. Install ExternalDNS via Helm
external-dns-values.yaml
serviceAccount:
create: true
name: external-dns-controller
provider:
name: aws
sources:
- ingress
- gateway-httproute
- service
domainFilters:
- vettom.online
txtOwnerId: "eks-demo-cluster"
policy: sync # or "upsert-only"
helm repo add external-dns https://kubernetes-sigs.github.io/external-dns/
helm repo update
helm install external-dns external-dns/external-dns \
--namespace external-dns \
--create-namespace \
--version 1.15.0 \
-f external-dns-values.yaml
Step 3. Expose an Application and Validate DNS Sync
When deploying an Ingress or HTTPRoute specifying hostnames: ["app.vettom.online"], ExternalDNS automatically creates the A record (alias to the ALB/NLB) and a tracking TXT record in Route53.