Skip to main content
Source

This page is generated from skills/eks-build/references/addon-catalog.md. Edit the source, not this page.

Addon Catalog

All addons supported by this framework, organized by category. Each addon is toggled via YAML configuration -- no Terraform code changes required.

Addon Summary Table​

CategoryAddonConfig KeyPattern 1Pattern 2DefaultAuth
EKS ManagedVPC CNIeks_addons.vpc-cniTerraformTerraformOnNode role
CoreDNSeks_addons.corednsTerraformTerraformOnNode role
kube-proxyeks_addons.kube-proxyTerraformTerraformOnNode role
EBS CSI Drivereks_addons.aws-ebs-csi-driverTerraformTerraformOnPod Identity
EFS CSI Drivereks_addons.aws-efs-csi-driverTerraformTerraformOffPod Identity
Pod Identity Agenteks_addons.eks-pod-identity-agentTerraformTerraformOnNode role
NetworkingAWS LB Controlleraws_load_balancer_controllerTerraformArgoCDOnIRSA
ingress-nginxingress_nginxTerraformArgoCDOff--
External DNSexternal_dnsTerraformArgoCDOffIRSA
Gateway API Controlleraws_gateway_api_controllerTerraformArgoCDOffIRSA
AutoscalingCluster Autoscalercluster_autoscalerTerraformArgoCDOnIRSA
Karpenterkarpenter (dedicated submodule)TerraformArgoCDOffPod Identity
Metrics Servermetrics_serverTerraformArgoCDOn--
Securitycert-managercert_managerTerraformArgoCDOff--
External Secretsexternal_secretsTerraformArgoCDOffIRSA
GatekeepergatekeeperTerraformArgoCDOff--
KyvernokyvernoTerraformArgoCDOff--
ObservabilityCloudWatch Metricscloudwatch_metricsTerraform--OffIRSA
Fluent BitfluentbitTerraform--OffIRSA
PrometheusprometheusTerraform--Off--
StorageFSx CSI Driverfsx_csiTerraform--OffPod Identity
BackupVeleroveleroTerraformArgoCDOffIRSA/PodId
CapabilitiesACKcapabilities.ackTerraformTerraformOffIAM role
KROcapabilities.kroTerraformTerraformOff--
CustomPrisma Cloudcustom_addons.prisma_defenderTerraformArgoCD*Off--
New Reliccustom_addons.new_relicTerraformArgoCD*Off--
Flux CDcustom_addons.fluxTerraformArgoCD*Off--
Multus CNIcustom_addons.multusTerraformArgoCD*Off--
AWS PCA Issuercustom_addons.pca_issuerTerraformArgoCD*OffIRSA

* In Pattern 2, custom addons deploy via gitops/custom-addons/ directory-based ApplicationSet.

EKS Managed Addons​

Deployed through the EKS API (not Helm), managed identically in both patterns. Configure under eks_addons in addons.yaml:

eks_addons:
vpc-cni:
most_recent: true
before_compute: true # MANDATORY -- prevents NodeCreationFailure
coredns:
most_recent: true
kube-proxy:
most_recent: true
aws-ebs-csi-driver:
most_recent: true
aws-efs-csi-driver:
most_recent: true
eks-pod-identity-agent:
most_recent: true
before_compute: true # MANDATORY -- for Pod Identity workloads

before_compute Requirements​

AddonNeeds before_computeReason
vpc-cniYesNodes need CNI for Pod IPs and health checks
eks-pod-identity-agentYesPods need agent DaemonSet for Pod Identity
corednsNoDNS runs as Deployment; nodes work without it initially
kube-proxyNoIptables rules set up on node join
aws-ebs-csi-driverNoStorage driver only needed when PVCs are created

Pod Identity for EKS Managed Addons​

EKS managed addons (EBS CSI, EFS CSI, FSx CSI, Mountpoint S3 CSI, CloudWatch) use Pod Identity instead of IRSA. IAM roles are created by terraform-aws-modules/eks-pod-identity/aws modules. Associations are separate aws_eks_pod_identity_association resources -- not inline in addon config.

Why separate resources (not inline pod_identity_association):

  1. Terraform v1.14's strict for_each rejects unknown module outputs in the upstream EKS module's filter expression
  2. Separate resources create correct destroy ordering -- associations destroyed before IAM roles
# IAM role (no association -- created separately)
module "ebs_csi_pod_identity" {
source = "terraform-aws-modules/eks-pod-identity/aws"
version = "<LOOK_UP>" # Look up latest from Terraform Registry
name = "${local.cluster_config.name}-ebs-csi"
use_name_prefix = false
attach_aws_ebs_csi_policy = true
aws_ebs_csi_policy_name = "${local.cluster_config.name}-EBS_CSI" # Avoid cross-project collision
tags = local.tags
}

# Separate association (depends on both cluster and IAM role)
resource "aws_eks_pod_identity_association" "ebs_csi" {
cluster_name = module.eks_cluster.cluster_name
namespace = "kube-system"
service_account = "ebs-csi-controller-sa"
role_arn = module.ebs_csi_pod_identity[0].iam_role_arn
}

Blueprints Addons (Pattern 1)​

The aws-ia/eks-blueprints-addons module deploys these as Helm releases. Each addon has an enabled flag and optional config block:

aws_load_balancer_controller:
enabled: true
config:
wait: true # Required for Phase 1 webhook ordering
chart_version: "<LOOK_UP>" # Always override module default
set:
- name: vpcId
value: "vpc-0abc123" # Explicit -- IMDS fallback can fail
- name: replicaCount
value: "2"

Critical: Two-Phase Module Architecture​

LBC and Gatekeeper must deploy in Phase 1 (with wait: true) before all other addons in Phase 2. See lessons-learned.md for details.

ArgoCD-Managed Addons (Pattern 2)​

Addon enable flags pass to ArgoCD via the GitOps Bridge metadata secret. ArgoCD reads enable_<addon_name> annotations and conditionally creates Helm Applications.

Karpenter in Pattern 2 (validated): Terraform creates the IAM roles and Pod Identity associations via the dedicated submodule. The Helm chart deploys via ArgoCD Application (OCI chart: oci://public.ecr.aws/karpenter/karpenter). NodePool/EC2NodeClass CRDs can be deployed via a custom-addons chart. Discovery tags must be applied by Terraform before ArgoCD syncs.

addons:
aws_load_balancer_controller:
enabled: true
metrics_server:
enabled: true
cluster_autoscaler:
enabled: true

Tenant Workloads (Pattern 2)​

Tenants use a Kustomize-based ApplicationSet with a Git Directory Generator that auto-discovers tenant overlay directories (gitops/tenants/*/overlays/*). Each tenant gets its own AppProject for RBAC isolation.

Custom Addons​

Prisma Cloud Defender​

Runtime container security agent from Palo Alto Networks.

custom_addons:
prisma_defender:
enabled: true
chart: twistlock-defender
chart_version: "<LOOK_UP>"
repository: "https://<REGISTRY_URL>"
namespace: twistlock

New Relic​

Infrastructure monitoring bundle (K8s integration, Prometheus agent, logging).

custom_addons:
new_relic:
enabled: true
chart: nri-bundle
chart_version: "<LOOK_UP>" # Look up from https://artifacthub.io/packages/helm/newrelic/nri-bundle
repository: https://helm-charts.newrelic.com
namespace: newrelic
set:
- name: global.licenseKey
value: "<YOUR_LICENSE_KEY>"

Flux CD​

GitOps toolkit. Installs Flux controllers; configure GitRepository and Kustomization CRDs separately.

custom_addons:
flux:
enabled: true
chart: flux2
chart_version: "<LOOK_UP>" # Look up from https://artifacthub.io/packages/helm/fluxcd-community/flux2
repository: https://fluxcd-community.github.io/helm-charts
namespace: flux-system

Multus CNI -- BROKEN​

Do NOT enable. Thick-plugin has a pod-lookup race condition that blocks ALL new pod creation.

custom_addons:
multus:
enabled: false # BROKEN: thick-plugin pod-lookup race

AWS PCA Issuer​

Bridges cert-manager with AWS Private Certificate Authority for org-trusted TLS.

custom_addons:
pca_issuer:
enabled: true
chart: aws-privateca-issuer
chart_version: "<LOOK_UP>" # Look up from https://artifacthub.io/packages/helm/cert-manager/aws-privateca-issuer
repository: https://cert-manager.github.io/aws-privateca-issuer
namespace: cert-manager
service_account_role_arn: "arn:aws:iam::<ACCOUNT_ID>:role/pca-issuer-role"
cluster_issuer_arn: "arn:aws:acm-pca:<REGION>:<ACCOUNT_ID>:certificate-authority/<CA_ID>"
cluster_issuer_name: pca-cluster-issuer

Adding a New Custom Addon​

Pattern 1 (Terraform)​

  1. Add a module block in modules/custom-addons/main.tf:
module "my_addon" {
count = try(var.custom_addons_config.my_addon.enabled, false) ? 1 : 0
source = "aws-ia/eks-blueprints-addon/aws"
version = "<LOOK_UP>" # Look up from Terraform Registry

chart = try(var.custom_addons_config.my_addon.chart, "my-addon")
chart_version = try(var.custom_addons_config.my_addon.chart_version, "<LOOK_UP>")
repository = try(var.custom_addons_config.my_addon.repository, "https://charts.example.com")
namespace = try(var.custom_addons_config.my_addon.namespace, "my-addon")
create_namespace = true

values = try(var.custom_addons_config.my_addon.values, [])
set = try(var.custom_addons_config.my_addon.set, [])
tags = var.tags
}
  1. Add config in addons.yaml:
custom_addons:
my_addon:
enabled: true
chart: my-addon
chart_version: "<LOOK_UP>"
repository: "https://charts.example.com"
namespace: my-addon

Pattern 2 (ArgoCD)​

  1. Create gitops/custom-addons/charts/my-addon/ with Chart.yaml + values.yaml.
  2. The directory-based ApplicationSet auto-discovers and deploys it.