Istio
EKS
Terraform
Helm
Kubernetes

Install Istio on EKS cluster using Terraform and Helm

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Installing Istio on EKS with Terraform usually means two separate concerns: Terraform manages access to the EKS cluster and drives the Helm releases, while Istio itself is installed as a set of Helm charts. The key is to wire the Kubernetes and Helm providers to the EKS API correctly, then install the Istio charts in the right order.

Start With EKS Provider Configuration

Assume the EKS cluster already exists or is created elsewhere in Terraform. The Kubernetes and Helm providers need the cluster endpoint, certificate authority data, and a token.

A common Terraform pattern looks like this:

hcl
1provider "aws" {
2  region = var.aws_region
3}
4
5data "aws_eks_cluster" "this" {
6  name = var.cluster_name
7}
8
9data "aws_eks_cluster_auth" "this" {
10  name = var.cluster_name
11}
12
13provider "kubernetes" {
14  host                   = data.aws_eks_cluster.this.endpoint
15  cluster_ca_certificate = base64decode(data.aws_eks_cluster.this.certificate_authority[0].data)
16  token                  = data.aws_eks_cluster_auth.this.token
17}
18
19provider "helm" {
20  kubernetes {
21    host                   = data.aws_eks_cluster.this.endpoint
22    cluster_ca_certificate = base64decode(data.aws_eks_cluster.this.certificate_authority[0].data)
23    token                  = data.aws_eks_cluster_auth.this.token
24  }
25}

This keeps Helm and Kubernetes talking directly to the EKS control plane rather than relying on an external kubeconfig file.

Install Istio Charts in the Right Order

Current Istio Helm installs are split into separate components. The official Helm-based flow installs the base chart before istiod, and optionally installs gateways after that.

A Terraform version of that flow can look like this:

hcl
1resource "helm_release" "istio_base" {
2  name             = "istio-base"
3  repository       = "https://istio-release.storage.googleapis.com/charts"
4  chart            = "base"
5  namespace        = "istio-system"
6  create_namespace = true
7}
8
9resource "helm_release" "istiod" {
10  name       = "istiod"
11  repository = "https://istio-release.storage.googleapis.com/charts"
12  chart      = "istiod"
13  namespace  = "istio-system"
14
15  set {
16    name  = "profile"
17    value = "default"
18  }
19
20  set {
21    name  = "global.platform"
22    value = "eks"
23  }
24
25  depends_on = [helm_release.istio_base]
26}
27
28resource "helm_release" "istio_ingress" {
29  name             = "istio-ingress"
30  repository       = "https://istio-release.storage.googleapis.com/charts"
31  chart            = "gateway"
32  namespace        = "istio-ingress"
33  create_namespace = true
34
35  depends_on = [helm_release.istiod]
36}

The depends_on chain matters because the base chart installs CRDs and cluster-scoped resources that istiod expects to find first.

Verify the Installation

After terraform apply, check the Helm releases and Kubernetes workloads:

bash
helm ls -n istio-system
kubectl get pods -n istio-system
kubectl get svc -n istio-ingress

If you plan to use sidecar injection, label a namespace and deploy a test workload:

bash
kubectl label namespace default istio-injection=enabled
kubectl get namespace default --show-labels

Then deploy an app and confirm the proxy sidecar is injected.

Why Terraform Plus Helm Is a Good Fit

This approach works well because:

  • Terraform manages cluster access and release dependencies
  • Helm manages chart lifecycle and upgrade state
  • Istio can still be customized with chart values instead of ad hoc kubectl patches

It also makes upgrades easier because the same Terraform resources can pin chart versions and set values consistently across environments.

Common Pitfalls

  • Installing istiod before the base chart and hitting missing-CRD or missing-resource errors.
  • Mixing kubeconfig-based local Helm usage with Terraform-managed provider configuration and then debugging the wrong cluster context.
  • Forgetting to create the namespaces or to express release ordering with depends_on.
  • Leaving chart versions unpinned in production and getting unexpected changes on later applies.
  • Assuming Istio is "done" after install, without verifying injection, gateways, and workload readiness.

Summary

  • Use Terraform to configure EKS access for both the Kubernetes and Helm providers.
  • Install Istio with Helm charts in order: base first, then istiod, then gateways as needed.
  • Express dependencies explicitly in Terraform so CRD installation happens before the control plane.
  • Use Istio chart values to adapt the install for EKS and for your chosen profile.
  • Verify the mesh after installation, because a successful apply is only the first step.

Course illustration
Course illustration

All Rights Reserved.