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"
}
})
}