Install and configure external-DNS on AWS EKS

3 min read | by Jordi Prats

With external DNS the DNS records for the ingress objects we have will be created automatically. We can choose between several cloud providers but we can even configure it to use the standard dynamic zone manipulation defined in RFC-2136. Let's see how to configure it on AWS EKS with Route53

First we will have to create a IRSA role with a policy to be able to list and modify any hosted zone as follows:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "route53:ChangeResourceRecordSets"
      ],
      "Resource": [
        "arn:aws:route53:::hostedzone/*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "route53:ListHostedZones",
        "route53:ListResourceRecordSets"
      ],
      "Resource": [
        "*"
      ]
    }
  ]
}

Then we will have to make sure the serviceAccount is created the appropriate annotation. To do so we can check the values.yaml on the external-dns helm chart. We will have to make sure the annotations are set wiht the IRSA role that we have created:

serviceAccount:
  create: true
  annotations:
    "eks.amazonaws.com/role-arn": "arn:..."
  name: "externaldns"

Once the helm chart is deployed like so, it will check all the Ingress objects checking for the configured hosts, if there's a DNS record missing it will add it automatically. If there's any existing record it won't update it, to identify which records are managed by external-dns it will create a TXT with the same name.

It can also use the external-dns.alpha.kubernetes.io/hostname annotation for Ingress and Service objects, for example:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    external-dns.alpha.kubernetes.io/hostname: external-ampa.pet2cattle.com
(...)

We can check the controller's logs to see what is modifying:

time="2021-08-28T21:25:18Z" level=info msg="Applying provider record filter for domains: [pet2cattle.com.]"
time="2021-08-28T21:25:18Z" level=info msg="Desired change: CREATE external-ampa.pet2cattle.com A [Id: /hostedzone/Z1234567890123456789O]"
time="2021-08-28T21:25:18Z" level=info msg="Desired change: CREATE external-ampa.pet2cattle.com TXT [Id: /hostedzone/Z1234567890123456789O]"
time="2021-08-28T21:25:18Z" level=info msg="2 record(s) in zone pet2cattle.com. [Id: /hostedzone/Z1234567890123456789O] were successfully updated"

On the external-dns helm chart we can also configure a list of extraArgs that will be used on the controller, we can check the list of options like this:

$ kubectl exec externaldns-external-dns-5c7b969558-7644r -n external-dns -- /bin/external-dns --help
usage: external-dns --source=source --provider=provider [<flags>]

ExternalDNS synchronizes exposed Kubernetes Services and Ingresses with DNS
providers.

(...)

Among them we can also define if there's some of the sources that we want to disable:

  --ignore-hostname-annotation   Ignore hostname annotation when generating DNS
  --ignore-ingress-tls-spec      Ignore tls spec section in ingresses resources,
  --ignore-ingress-rules-spec    Ignore rules spec section in ingresses

Posted on 09/11/2021