I have been researching this in the last months and want to add my findings to @Jakob's answer:
First, there is an answer to the pros/cons of the different installation method, so I will not say anything about that:
https://istio.io/latest/faq/setup/#install-method-selection
Basically all of them can be done with terraform in a certain way.
- terraform + istioctl with terraform null_resource provider
This is basically the istioctl install -f <file>
command. You can create a template file and to the istictl install command with the null_resource provider.
resource "local_file" "setup_istio_config" {
content = templatefile("${path.module}/istio-operator.tmpl", {
enableHoldAppUntilProxyStarts = var.hold_app_until_proxy_starts
})
filename = "istio-operator.yaml"
}
resource "null_resource" "install_istio" {
provisioner "local-exec" {
command = "istioctl install -f \"istio-operator.yaml\" --kubeconfig ../${var.kubeconfig}"
}
depends_on = [local_file.setup_istio_config]
}
Pros:
Cons:
- How to upgrade using
istioctl upgrade -f <file
has to be solved somehow
- istioctl must be installed in different versions when handling multiple clusters with different istio versions
- Right istioctl version must be choosen on setup
I guess you can solve the upgrade process somehow, but the hole process is not really "infrastructure as code" enough. I didn't look into it further, because it doesn't seam to be good practice.
- terraform + istio operator with terraform null_resource provider and kubectl provider
Similar the istio operator setup initializes the operator pod and takes a istio-operator.yml to setup istio for you.
resource "null_resource" "init_operator" {
provisioner "local-exec" {
command = "istioctl operator init --kubeconfig ../${var.kubeconfig}"
}
}
resource "kubectl_manifest" "setup_istio" {
yaml_body = <<YAML
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
name: istio-setup
namespace: istio-system
spec:
profile: default
hub: gcr.io/istio-release
tag: 1.9.2
components:
ingressGateways:
- name: istio-ingressgateway
enabled: true
meshConfig:
defaultConfig:
holdApplicationUntilProxyStarts: ${var.hold_app_until_proxy_starts}"
YAML
depends_on = [null_resource.init_operator]
}
It would be a good idea to wait for some seconds between the init and applying the config.
Here is a good article about doing this with Azure's aks:
https://medium.com/@vipinagarwal18/install-istio-on-azure-kubernetes-cluster-using-terraform-214f6d3f611
Pros:
- Easy to setup
- Easy to upgrade istio using the kubectl provider
As long as helm is in alpha, this might be the best approach.
- terraform + helm with terraform helm provider
Istio provides some charts for the different componentes, when downloading istioctl. Those can be used for installing it with helm.
resource "helm_release" "istio_base" {
name = "istio-base"
chart = "./manifests/charts/base"
namespace = "istio-system"
}
Cons:
Bonus
- istio manifest + helm
Some time ago I've read an article on how to use istio manifest from istioctl manifest generate
in combination with helm to install and mange istio. This approach needs some custom code, but it could be done with terraform and the helm provider as well.
Please read: https://karlstoney.com/2021/03/04/ci-for-istio-mesh/index.html
Conclusion
Installing istio with terraform works but seams to be a bit dirty at the moment. Once the helm setup is stable, I guess this would be the best approach. And with the helm provider it can be composed with terraform creation of other resources. Terraform certainly misses an istio provider, but I don't think they will create one in the foreseeable future.