Deploy Istio and Kiali on Kubernetes using Terraform

In this post, we will deploy Istio and Kiali on Kubernetes using Terraform. We will use the official Helm charts for Istio and Kiali. This post isn’t intended to be a deep dive into Istio or Kiali, but rather a quick guide to get you started with Istio and Kiali on Kubernetes using Terraform.

Prerequisites

  • A Kubernetes cluster
  • Helm v3
  • Terraform >v1.0.0
  • kubectl
  • A working instance of Prometheus and Grafana

Setup

Create a namespace for Istio

resource "kubernetes_namespace" "istio-system" {
  metadata {
    name = var.namespace
    labels = {
      istio-injection = "enabled"
    }
  }
}

First chart: istio-base

This first chart can be deployed as is. It will install the base components of Istio.

resource "helm_release" "istio-base" {
  name             = "istio-base"
  namespace        = var.namespace
  create_namespace = false
  repository       = "https://istio-release.storage.googleapis.com/charts"
  chart            = "base"
  version          = "1.22.2"

  depends_on = [kubernetes_namespace.istio-system]
}

Second chart: istiod

This chart requires some configuration:

  • We need to set the futur uri of the zipkin endpoint of our Jaeger instance.
  • If needed, we can define the number of proxies before the traffic will reach our istio gateway.
  • We can configure some extra options to the sidecar that will intercept our Pods traffic.
  • We can configure the behavior of traffic aimed at external resources.
  • And more.
locals {
  istiod_values_yaml = <<EOF
meshConfig:
  defaultConfig:
    tracing:
      zipkin:
        address: "jaeger-collector.istio-system:9411"
        # address: "zipkin.istio-system:9411"
      sampling: 100.0
    gatewayTopology:
      proxyProtocol: {}
      numTrustedProxies: 2
    proxyMetadata:
      # Enable basic DNS proxying
      ISTIO_META_DNS_CAPTURE: "true"
      # Enable automatic address allocation, optional
      ISTIO_META_DNS_AUTO_ALLOCATE: "true"
  outboundTrafficPolicy:
    mode: REGISTRY_ONLY
EOF
}

resource "helm_release" "istio-istiod" {
  name             = "istio-istiod"
  namespace        = var.namespace
  create_namespace = false
  repository       = "https://istio-release.storage.googleapis.com/charts"
  chart            = "istiod"
  version          = "1.22.2"

  values = [local.istiod_values_yaml]

  depends_on = [helm_release.istio-base]
}

Third chart: istio-ingress

This chart will deploy the Istio Ingress Gateway. We can configure the annotations that will be applied to our LoadBalancer resources, the Pods annotations (for monitoring by example) as well as the protocol to use (PROXY2 in my case). Labels are also set: they will be used by Istio and Kiali later to find our resources.

locals {
  istio_ingress_values_yaml = <<EOF
name: istio-ingressgateway
service:
  annotations:
    service.beta.kubernetes.io/scw-loadbalancer-use-hostname: "true"
    service.beta.kubernetes.io/scw-loadbalancer-proxy-protocol-v2: "true"
podAnnotations:
  # Keep original labels
  prometheus.io/port: "15020"
  prometheus.io/scrape: "true"
  prometheus.io/path: "/stats/prometheus"
  inject.istio.io/templates: "gateway"
  sidecar.istio.io/inject: "true"
  # Needed for PROXY v2 protocol
  proxy.istio.io/config: '{"gatewayTopology" : { "proxyProtocol": {} }}'
labels:
  app: istio-ingressgateway
  istio: ingressgateway
EOF
}

resource "helm_release" "istio-ingress" {
  name             = "istio-ingress"
  namespace        = var.namespace
  create_namespace = false
  repository       = "https://istio-release.storage.googleapis.com/charts"
  chart            = "gateway"
  version          = "1.22.2"

  values = [local.istio_ingress_values_yaml]

  depends_on = [helm_release.istio-base, helm_release.istio-istiod]
}

Fourth chart: jaeger to coller network traces

locals {
  jaeger_values_yaml = <<EOF
provisionDataStore:
  cassandra: false
allInOne:
  enabled: true
storage:
  type: memory
agent:
  enabled: false
collector:
  enabled: false
query:
  enabled: false
EOF
}

resource "helm_release" "jaeger" {
  name             = "jaeger"
  namespace        = var.namespace
  create_namespace = true
  repository       = "https://jaegertracing.github.io/helm-charts"
  chart            = "jaeger"
  version          = "3.1.0"

  values = [local.jaeger_values_yaml]
}

Last chart: kiali

resource "helm_release" "istio-kiali" {
  name             = "kiali-server"
  namespace        = var.namespace
  create_namespace = true
  repository       = "https://kiali.org/helm-charts"
  chart            = "kiali-server"
  version          = "1.85.0"

  # set {
  #   name  = "auth.strategy"
  #   value = "anonymous"
  # }

  # set {
  #   name  = "deployment.view_only_mode"
  #   value = true
  # }

  set {
    name  = "external_services.istio.root_namespace"
    value = "istio-system"
  }

  # Prometheus

  set {
    name  = "external_services.prometheus.url"
    value = "http://prometheus-operated.prometheus:9090"
  }

  # Grafana
  set {
    name  = "external_services.grafana.enabled"
    value = true
  }
 
  set {
    name  = "external_services.grafana.in_cluster_url"
    value = "http://prometheus-grafana.prometheus"
  }

  set {
    name  = "external_services.grafana.url"
    value = "https://metrics.delta.home-labs.fr/"
  }

  # Tracing w/ Jaeger
  set {
    name  = "external_services.tracing.enabled"
    value = true
  }

  set {
    name  = "external_services.tracing.in_cluster_url"
    value = "http://jaeger-query.istio-system.svc.cluster.local:16685/jaeger"
  }

  set {
    name  = "external_services.tracing.use_grpc"
    value = true
  }

  # Labels
  set {
    name  = "istio_labels.app_label_name"
    value = "app.kubernetes.io/instance"
  }

  set {
    name  = "istio_labels.version_label_name"
    value = "app.kubernetes.io/version"
  }

  depends_on = [helm_release.istio-base, helm_release.istio-istiod]
}

Conclusion

This is a simple way to deploy Istio and Kiali on Kubernetes using Terraform and a good starting point to get you up and running with Istio and Kiali on Kubernetes for testing and validation. You can now explore the features of Istio and Kiali and start using them in your projects.