Skip to content

Amazon EKS Add-ons

The Amazon EKS add-on implementation is generic and can be used to deploy any add-on supported by the EKS API; either native EKS addons or third party add-ons supplied via the AWS Marketplace.

See the EKS documentation for more details on EKS addon-ons, including the list of Amazon EKS add-ons from Amazon EKS, as well as Additional Amazon EKS add-ons from independent software vendors.

Architecture Support

The Amazon EKS provided add-ons listed below support both x86_64/amd64 and arm64 architectures. Third party add-ons that are available via the AWS Marketplace will vary based on the support provided by the add-on vendor. No additional changes are required to add-on configurations when switching between x86_64/amd64 and arm64 architectures; Amazon EKS add-ons utilize multi-architecture container images to support this functionality.

Add-on x86_64/amd64 arm64
vpc-cni
aws-ebs-csi-driver
coredns
kube-proxy
adot
aws-guardduty-agent

Usage

The Amazon EKS add-ons are provisioned via a generic interface behind the eks_addons argument which accepts a map of add-on configurations. The generic interface for an add-on is defined below for reference:

module "eks_blueprints_addons" {
  source = "aws-ia/eks-blueprints-addons/aws"

  # ... truncated for brevity

  eks_addons = {
    <key> = {
      name = string # Optional - <key> is used if `name` is not set

      most_recent          = bool
      addon_version        = string # overrides `most_recent` if set
      configuration_values = string # JSON string

      preserve                    = bool # defaults to `true`
      resolve_conflicts_on_create = string # defaults to `OVERWRITE`
      resolve_conflicts_on_update = string # defaults to `OVERWRITE`

      timeouts = {
        create = string # optional
        update = string # optional
        delete = string # optional
      }

      tags = map(string)
    }
  }
}

Example

module "eks_blueprints_addons" {
  source = "aws-ia/eks-blueprints-addons/aws"

  # ... truncated for brevity

  eks_addons = {
    # Amazon EKS add-ons
    aws-ebs-csi-driver = {
      most_recent              = true
      service_account_role_arn = module.ebs_csi_driver_irsa.iam_role_arn
    }

    coredns = {
      most_recent = true

      timeouts = {
        create = "25m"
        delete = "10m"
      }
    }

    vpc-cni = {
      most_recent              = true
      service_account_role_arn = module.vpc_cni_irsa.iam_role_arn
    }

    kube-proxy = {}

    # Third party add-ons via AWS Marketplace
    kubecost_kubecost = {
      most_recent = true
    }

    teleport_teleport = {
      most_recent = true
    }
  }
}

Configuration Values

You can supply custom configuration values to each addon via the configuration_values argument of the add-on definition. The value provided must be a JSON encoded string and adhere to the JSON scheme provided by the version of the add-on. You can view this schema using the awscli by supplying the add-on name and version to the describe-addon-configuration command:

aws eks describe-addon-configuration \
--addon-name coredns \
--addon-version v1.10.1-eksbuild.2 \
--query 'configurationSchema' \
--output text | jq

Which returns the formatted JSON schema like below:

{
  "$ref": "#/definitions/Coredns",
  "$schema": "http://json-schema.org/draft-06/schema#",
  "definitions": {
    "Coredns": {
      "additionalProperties": false,
      "properties": {
        "affinity": {
          "default": {
            "affinity": {
              "nodeAffinity": {
                "requiredDuringSchedulingIgnoredDuringExecution": {
                  "nodeSelectorTerms": [
                    {
                      "matchExpressions": [
                        {
                          "key": "kubernetes.io/os",
                          "operator": "In",
                          "values": [
                            "linux"
                          ]
                        },
                        {
                          "key": "kubernetes.io/arch",
                          "operator": "In",
                          "values": [
                            "amd64",
                            "arm64"
                          ]
                        }
                      ]
                    }
                  ]
                }
              },
              "podAntiAffinity": {
                "preferredDuringSchedulingIgnoredDuringExecution": [
                  {
                    "podAffinityTerm": {
                      "labelSelector": {
                        "matchExpressions": [
                          {
                            "key": "k8s-app",
                            "operator": "In",
                            "values": [
                              "kube-dns"
                            ]
                          }
                        ]
                      },
                      "topologyKey": "kubernetes.io/hostname"
                    },
                    "weight": 100
                  }
                ]
              }
            }
          },
          "description": "Affinity of the coredns pods",
          "type": [
            "object",
            "null"
          ]
        },
        "computeType": {
          "type": "string"
        },
        "corefile": {
          "description": "Entire corefile contents to use with installation",
          "type": "string"
        },
        "nodeSelector": {
          "additionalProperties": {
            "type": "string"
          },
          "type": "object"
        },
        "replicaCount": {
          "type": "integer"
        },
        "resources": {
          "$ref": "#/definitions/Resources"
        },
        "tolerations": {
          "default": [
            {
              "key": "CriticalAddonsOnly",
              "operator": "Exists"
            },
            {
              "key": "node-role.kubernetes.io/master",
              "operator": "NoSchedule"
            }
          ],
          "description": "Tolerations of the coredns pod",
          "items": {
            "type": "object"
          },
          "type": "array"
        },
        "topologySpreadConstraints": {
          "description": "The coredns pod topology spread constraints",
          "type": "array"
        }
      },
      "title": "Coredns",
      "type": "object"
    },
    "Limits": {
      "additionalProperties": false,
      "properties": {
        "cpu": {
          "type": "string"
        },
        "memory": {
          "type": "string"
        }
      },
      "title": "Limits",
      "type": "object"
    },
    "Resources": {
      "additionalProperties": false,
      "properties": {
        "limits": {
          "$ref": "#/definitions/Limits"
        },
        "requests": {
          "$ref": "#/definitions/Limits"
        }
      },
      "title": "Resources",
      "type": "object"
    }
  }
}

You can supply the configuration values to the add-on by passing a map of the values wrapped in the jsonencode() function as shown below:

module "eks_blueprints_addons" {
  source = "aws-ia/eks-blueprints-addons/aws"

  # ... truncated for brevity

  eks_addons = {
     coredns = {
      most_recent = true
      configuration_values = jsonencode({
        replicaCount = 4
        tolerations = [
        {
          key      = "dedicated",
          operator = "Equal",
          effect   = "NoSchedule",
          value    = "orchestration-seb"
        }
        ]

        topologySpreadConstraints = [
          {
            maxSkew = 1
            topologyKey = "topology.kubernetes.io/zone"
            whenUnsatisfiable = "ScheduleAnyway"
            labelSelector = {
              matchLabels = {
                k8s-app: "kube-dns"
              }
            }
          }
        ]

        affinity = {
          nodeAffinity = {
            requiredDuringSchedulingIgnoredDuringExecution = {
              nodeSelectorTerms = [
              {
                matchExpressions = [
                  {
                    key = "kubernetes.io/os"
                    operator = "In"
                    values = ["linux"]
                  },
                  {
                    key = "kubernetes.io/arch"
                    operator = "In"
                    values = ["amd64"]
                  }
                ]
              }]
            }
          }

          podAffinity = {
            requiredDuringSchedulingIgnoredDuringExecution = [{
                labelSelector = {
                  matchExpressions = [
                    {
                      key = "k8s-app"
                      operator = "NotIn"
                      values = ["kube-dns"]
                    }
                  ]
                }
                topologyKey = "kubernetes.io/hostname"
            }
            ]
          }

          podAntiAffinity = {
            preferredDuringSchedulingIgnoredDuringExecution = [{
              podAffinityTerm = {
                labelSelector = {
                  matchExpressions = [
                    {
                      key = "k8s-app"
                      operator = "In"
                      values = ["kube-dns"]
                    }
                  ]
                }
                topologyKey = "kubernetes.io/hostname"
              }
              weight = 100
              }
            ]

            requiredDuringSchedulingIgnoredDuringExecution = [{
                labelSelector = {
                  matchExpressions = [
                    {
                      key = "k8s-app"
                      operator = "In"
                      values = ["kube-dns"]
                    }
                  ]
                }
                topologyKey = "kubernetes.io/hostname"
              }
            ]
          }

        }

        resources = {
          limits = {
            cpu    = "100m"
            memory = "150Mi"
          }
          requests = {
            cpu    = "100m"
            memory = "150Mi"
        }
      })
    }