# Akamai Edge DNS ## Prerequisites External-DNS v0.8.0 or greater. ### Zones External-DNS manages service endpoints in existing DNS zones. The Akamai provider does not add, remove or configure new zones. The [Akamai Control Center](https://control.akamai.com) or [Akamai DevOps Tools](https://developer.akamai.com/devops), [Akamai CLI](https://developer.akamai.com/cli) and [Akamai Terraform Provider](https://developer.akamai.com/tools/integrations/terraform) can create and manage Edge DNS zones. ### Akamai Edge DNS Authentication The Akamai Edge DNS provider requires valid Akamai Edgegrid API authentication credentials to access zones and manage DNS records. Either directly by key or indirectly via a file can set credentials for the provider. The Akamai credential keys and mappings to the Akamai provider utilizing different presentation methods are: | Edgegrid Auth Key | External-DNS Cmd Line Key | Environment/ConfigMap Key | Description | | ----------------- | ------------------------- | ------------------------- | ----------- | | host | akamai-serviceconsumerdomain | EXTERNAL_DNS_AKAMAI_SERVICECONSUMERDOMAIN | Akamai Edgegrid API server | | access_token | akamai-access-token | EXTERNAL_DNS_AKAMAI_ACCESS_TOKEN | Akamai Edgegrid API access token | | client_token | akamai-client-token | EXTERNAL_DNS_AKAMAI_CLIENT_TOKEN |Akamai Edgegrid API client token | | client-secret | akamai-client-secret | EXTERNAL_DNS_AKAMAI_CLIENT_SECRET |Akamai Edgegrid API client secret | In addition to specifying auth credentials individually, an Akamai Edgegrid .edgerc file convention can set credentials. | External-DNS Cmd Line | Environment/ConfigMap | Description | | --------------------- | --------------------- | ----------- | | akamai-edgerc-path | EXTERNAL_DNS_AKAMAI_EDGERC_PATH | Accessible path to Edgegrid credentials file, e.g /home/test/.edgerc | | akamai-edgerc-section | EXTERNAL_DNS_AKAMAI_EDGERC_SECTION | Section in Edgegrid credentials file containing credentials | [Akamai API Authentication](https://developer.akamai.com/getting-started/edgegrid) provides an overview and further information about authorization credentials for API base applications and tools. ## Deploy External-DNS An operational External-DNS deployment consists of an External-DNS container and service. The following sections demonstrate the ConfigMap objects that would make up an example functional external DNS kubernetes configuration utilizing NGINX as the service. Connect your `kubectl` client to the External-DNS cluster. Begin by creating a Kubernetes secret to securely store your Akamai Edge DNS Access Tokens. This key will enable ExternalDNS to authenticate with Akamai Edge DNS: ```shell kubectl create secret generic AKAMAI-DNS --from-literal=EXTERNAL_DNS_AKAMAI_SERVICECONSUMERDOMAIN=YOUR_SERVICECONSUMERDOMAIN --from-literal=EXTERNAL_DNS_AKAMAI_CLIENT_TOKEN=YOUR_CLIENT_TOKEN --from-literal=EXTERNAL_DNS_AKAMAI_CLIENT_SECRET=YOUR_CLIENT_SECRET --from-literal=EXTERNAL_DNS_AKAMAI_ACCESS_TOKEN=YOUR_ACCESS_TOKEN ``` Ensure to replace YOUR_SERVICECONSUMERDOMAIN, EXTERNAL_DNS_AKAMAI_CLIENT_TOKEN, YOUR_CLIENT_SECRET and YOUR_ACCESS_TOKEN with your actual Akamai Edge DNS API keys. Then apply one of the following manifests file to deploy ExternalDNS. ### Using Helm Create a values.yaml file to configure ExternalDNS to use Akamai Edge DNS as the DNS provider. This file should include the necessary environment variables: ```shell provider: name: akamai env: - name: EXTERNAL_DNS_AKAMAI_SERVICECONSUMERDOMAIN valueFrom: secretKeyRef: name: AKAMAI-DNS key: EXTERNAL_DNS_AKAMAI_SERVICECONSUMERDOMAIN - name: EXTERNAL_DNS_AKAMAI_CLIENT_TOKEN valueFrom: secretKeyRef: name: AKAMAI-DNS key: EXTERNAL_DNS_AKAMAI_CLIENT_TOKEN - name: EXTERNAL_DNS_AKAMAI_CLIENT_SECRET valueFrom: secretKeyRef: name: AKAMAI-DNS key: EXTERNAL_DNS_AKAMAI_CLIENT_SECRET - name: EXTERNAL_DNS_AKAMAI_ACCESS_TOKEN valueFrom: secretKeyRef: name: AKAMAI-DNS key: EXTERNAL_DNS_AKAMAI_ACCESS_TOKEN ``` Finally, install the ExternalDNS chart with Helm using the configuration specified in your values.yaml file: ```shell helm upgrade --install external-dns external-dns/external-dns --values values.yaml ``` ### Manifest (for clusters without RBAC enabled) ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: external-dns spec: strategy: type: Recreate selector: matchLabels: app: external-dns template: metadata: labels: app: external-dns spec: serviceAccountName: external-dns containers: - name: external-dns image: registry.k8s.io/external-dns/external-dns:v0.18.0 args: - --source=service # or ingress or both - --provider=akamai - --domain-filter=example.com # zone-id-filter may be specified as well to filter on contract ID - --registry=txt - --txt-owner-id={{ owner-id-for-this-external-dns }} - --txt-prefix={{ prefix label for TXT record }}. env: - name: EXTERNAL_DNS_AKAMAI_SERVICECONSUMERDOMAIN valueFrom: secretKeyRef: name: AKAMAI-DNS key: EXTERNAL_DNS_AKAMAI_SERVICECONSUMERDOMAIN - name: EXTERNAL_DNS_AKAMAI_CLIENT_TOKEN valueFrom: secretKeyRef: name: AKAMAI-DNS key: EXTERNAL_DNS_AKAMAI_CLIENT_TOKEN - name: EXTERNAL_DNS_AKAMAI_CLIENT_SECRET valueFrom: secretKeyRef: name: AKAMAI-DNS key: EXTERNAL_DNS_AKAMAI_CLIENT_SECRET - name: EXTERNAL_DNS_AKAMAI_ACCESS_TOKEN valueFrom: secretKeyRef: name: AKAMAI-DNS key: EXTERNAL_DNS_AKAMAI_ACCESS_TOKEN ``` ### Manifest (for clusters with RBAC enabled) ```yaml apiVersion: v1 kind: ServiceAccount metadata: name: external-dns --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: external-dns rules: - apiGroups: [""] resources: ["services","pods"] verbs: ["get","watch","list"] - apiGroups: ["discovery.k8s.io"] resources: ["endpointslices"] verbs: ["get","watch","list"] - apiGroups: ["extensions","networking.k8s.io"] resources: ["ingresses"] verbs: ["get","watch","list"] - apiGroups: [""] resources: ["nodes"] verbs: ["watch", "list"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: external-dns-viewer roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: external-dns subjects: - kind: ServiceAccount name: external-dns namespace: default --- apiVersion: apps/v1 kind: Deployment metadata: name: external-dns spec: strategy: type: Recreate selector: matchLabels: app: external-dns template: metadata: labels: app: external-dns spec: serviceAccountName: external-dns containers: - name: external-dns image: registry.k8s.io/external-dns/external-dns:v0.18.0 args: - --source=service # or ingress or both - --provider=akamai - --domain-filter=example.com # zone-id-filter may be specified as well to filter on contract ID - --registry=txt - --txt-owner-id={{ owner-id-for-this-external-dns }} - --txt-prefix={{ prefix label for TXT record }}. env: - name: EXTERNAL_DNS_AKAMAI_SERVICECONSUMERDOMAIN valueFrom: secretKeyRef: name: AKAMAI-DNS key: EXTERNAL_DNS_AKAMAI_SERVICECONSUMERDOMAIN - name: EXTERNAL_DNS_AKAMAI_CLIENT_TOKEN valueFrom: secretKeyRef: name: AKAMAI-DNS key: EXTERNAL_DNS_AKAMAI_CLIENT_TOKEN - name: EXTERNAL_DNS_AKAMAI_CLIENT_SECRET valueFrom: secretKeyRef: name: AKAMAI-DNS key: EXTERNAL_DNS_AKAMAI_CLIENT_SECRET - name: EXTERNAL_DNS_AKAMAI_ACCESS_TOKEN valueFrom: secretKeyRef: name: AKAMAI-DNS key: EXTERNAL_DNS_AKAMAI_ACCESS_TOKEN ``` Create the deployment for External-DNS: ```sh kubectl apply -f externaldns.yaml ``` ## Deploying an Nginx Service Create a service file called 'nginx.yaml' with the following contents: ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: nginx spec: selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - image: nginx name: nginx ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: nginx annotations: external-dns.alpha.kubernetes.io/hostname: nginx.example.com external-dns.alpha.kubernetes.io/ttl: "600" #optional spec: selector: app: nginx type: LoadBalancer ports: - protocol: TCP port: 80 targetPort: 80 ``` Create the deployment and service object: ```sh kubectl apply -f nginx.yaml ``` ## Verify Akamai Edge DNS Records Wait 3-5 minutes before validating the records to allow the record changes to propagate to all the Akamai name servers. Validate records using the [Akamai Control Center](http://control.akamai.com) or by executing a dig, nslookup or similar DNS command. ## Cleanup Once you successfully configure and verify record management via External-DNS, you can delete the tutorial's examples: ```sh kubectl delete -f nginx.yaml kubectl delete -f externaldns.yaml ``` ## Additional Information * The Akamai provider allows the administrative user to filter zones by both name (`domain-filter`) and contract Id (`zone-id-filter`). The Edge DNS API will return a '500 Internal Error' for invalid contract Ids. * The provider will substitute quotes in TXT records with a `` ` `` (back tick) when writing records with the API.