Skip to main content

Getting Started

Prerequisites

RequirementMinimum version
Terraform≥ 1.0.0
AWS provider (hashicorp/aws)≥ 3.72
Helm provider (hashicorp/helm)≥ 2.0
Kubernetes provider (hashicorp/kubernetes)≥ 2.0
An existing EKS cluster

Provider Configuration

The module requires AWS, Helm, and Kubernetes providers configured against your EKS cluster:

# versions.tf
terraform {
required_version = ">= 1.0.0"

required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 3.72"
}
helm = {
source = "hashicorp/helm"
version = ">= 2.0"
}
kubernetes = {
source = "hashicorp/kubernetes"
version = ">= 2.0"
}
}
}

# Configure Helm and Kubernetes providers against your EKS cluster
data "aws_eks_cluster" "cluster" {
name = var.cluster_name
}

data "aws_eks_cluster_auth" "cluster" {
name = var.cluster_name
}

provider "helm" {
kubernetes {
host = data.aws_eks_cluster.cluster.endpoint
cluster_ca_certificate = base64decode(data.aws_eks_cluster.cluster.certificate_authority[0].data)
token = data.aws_eks_cluster_auth.cluster.token
}
}

provider "kubernetes" {
host = data.aws_eks_cluster.cluster.endpoint
cluster_ca_certificate = base64decode(data.aws_eks_cluster.cluster.certificate_authority[0].data)
token = data.aws_eks_cluster_auth.cluster.token
}

Basic Usage

module "eks_addons" {
source = "git::https://github.com/clouddrove/terraform-aws-eks-addons.git?ref=0.0.7"

# Required inputs
eks_cluster_name = module.eks.cluster_name
data_plane_wait_arn = module.eks.data_plane_wait_arn

# Tags applied to all IRSA IAM resources
tags = {
Environment = "production"
ManagedBy = "terraform"
}

# Enable add-ons
metrics_server = true
cluster_autoscaler = true
aws_load_balancer_controller = true
certification_manager = true
external_secrets = true
external_dns = true
}

data_plane_wait_arn is an output from the CloudDrove EKS module that signals when the node group is ready. If using the AWS EKS module directly, set it to the node group ARN or leave it empty ("").


The Add-on Variable Pattern

Every add-on follows the same three-variable pattern:

# 1. Enable the add-on (bool, default = false)
metrics_server = true

# 2. Override Helm values (any, default = null — uses bundled defaults)
metrics_server_helm_config = {
version = "3.12.0"
values = [file("${path.module}/helm-values/metrics-server.yaml")]
}

# 3. Override the helm_release Terraform resource attributes (any, default = {})
metrics_server_extra_configs = {
timeout = 600
cleanup_on_fail = true
recreate_pods = false
}

When <addon>_helm_config is null, the module uses its own bundled default values. You only need to set it when overriding chart version or values files.


Helm Value Overrides

To pin a chart version or supply a custom values.yaml:

# Pin version only
cluster_autoscaler_helm_config = {
version = "9.29.0"
}

# Full values file override
ingress_nginx_helm_config = {
version = "4.9.0"
values = [
<<-EOT
controller:
replicaCount: 3
service:
type: LoadBalancer
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: nlb
defaultBackend:
enabled: true
EOT
]
}

IRSA — IAM Roles for Service Accounts

Add-ons that call AWS APIs (Cluster Autoscaler, External Secrets, FluentBit, etc.) use IRSA — each add-on gets its own IAM role bound to its Kubernetes service account via an OIDC trust policy. The module creates this role automatically.

No extra IAM configuration is needed unless you want a custom policy.

To use a custom IAM policy instead of the built-in one:

# Custom IAM policy for External Secrets (e.g., restrict to specific secret paths)
external_secrets_iampolicy_json_content = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = ["secretsmanager:GetSecretValue", "secretsmanager:DescribeSecret"]
Resource = "arn:aws:secretsmanager:us-east-1:123456789012:secret:prod/*"
},
{
Effect = "Allow"
Action = ["ssm:GetParameter", "ssm:GetParameters"]
Resource = "arn:aws:ssm:us-east-1:123456789012:parameter/prod/*"
}
]
})

Add-ons that support custom IRSA policies: cluster_autoscaler, aws_load_balancer_controller, aws_efs_csi_driver, aws_ebs_csi_driver, karpenter, external_secrets, fluent_bit, velero, external_dns, aws_xray, prometheus_cloudwatch_exporter.


Add-on Dependencies

Some add-ons depend on others being installed first. The module handles this internally, but you must enable the prerequisite when enabling the dependent:

Add-onRequires
kiali_serveristio_ingress = true
grafanaaws_load_balancer_controller = true
istio_ingressaws_load_balancer_controller = true
actions_runner_controllercertification_manager = true

GitOps Mode

Set manage_via_gitops = true to skip Helm chart installation — the module will only create IRSA roles and output configuration, leaving the actual chart deployment to Flux or ArgoCD.

module "eks_addons" {
source = "git::https://github.com/clouddrove/terraform-aws-eks-addons.git?ref=0.0.7"

eks_cluster_name = module.eks.cluster_name
data_plane_wait_arn = module.eks.data_plane_wait_arn
manage_via_gitops = true # ← skip Helm installs

# These will create IRSA roles but not install charts
cluster_autoscaler = true
aws_load_balancer_controller = true
external_secrets = true
}

Common Variables

VariableTypeDescription
eks_cluster_namestringName of the EKS cluster
data_plane_wait_arnstringARN to wait on before installing add-ons
tagsmap(string)Tags applied to all IAM resources
irsa_iam_role_pathstringIAM role path for IRSA roles (default /)
irsa_iam_permissions_boundarystringPermissions boundary ARN for IRSA roles
manage_via_gitopsboolSkip Helm installs; create IRSA only

Outputs

Each installed add-on exposes:

# Namespace the add-on was installed into
output "metrics_server_namespace" {}

# Helm chart version installed
output "metrics_server_chart_version" {}

# Helm chart repository URL
output "metrics_server_repository" {}

IRSA-enabled add-ons additionally expose:

# Kubernetes service account name
output "cluster_autoscaler_service_account" {}

# IAM policy name created for IRSA
output "cluster_autoscaler_iam_policy" {}

Reference: terraform-aws-eks-addons on GitHub →