Comment j’utilise Terraform et Helm pour déployer le tableau de bord Kubernetes

Lorsque je travaille sur des projets qui nécessitent le provisionnement d’une infrastructure cloud, mon flux de travail comporte deux composants disparates : l’un est l’orchestration de l’infrastructure, qui inclut Terraform pour mettre en place l’infrastructure (par exemple, de nouveaux clusters EKS), et le second est le composant de provisionnement, qui inclut des scripts Ansible ou Bash pour instancier et initialiser cette infrastructure pour accepter de nouveaux déploiements (par exemple, l’installation de Cluster Autoscaler, kube-state-metrics, etc.)
La raison en est simple : très peu d’outils peuvent se croiser et gérer à la fois l’orchestration et le provisionnement. Lorsque je suis tombé sur le fournisseur Helm pour Terraform, je voulais explorer la possibilité d’utiliser un seul outil pour gérer les deux côtés : utiliser Terraform pour faire apparaître un nouveau cluster EKS et le provisionner avec Prometheus, Loki, Grafana, Cluster Autoscaler et autres, le tout dans un déploiement soigné et propre. Mais cela ne se produit pas tant que je n’ai pas compris comment utiliser cette chose. Voici donc mon expérience avec Terraform et Helm pour quelque chose de simple : déployer le tableau de bord Kubernetes.
Contents
Le fournisseur de Helm
Le fournisseur Helm fonctionne comme les autres fournisseurs de cloud. Vous pouvez spécifier le chemin du KUBECONFIG
ou d’autres informations d’identification, exécutez terraform init
, et le fournisseur Helm est initialisé.
Déployer le tableau de bord Kubernetes
Je vais utiliser Minikube pour ce test.
Mon main.tf
fichier contient les éléments suivants :
provider "helm" {
kubernetes {
config_path = "~/.kube/config"
}
}resource "helm_release" "my-kubernetes-dashboard" {
name = "my-kubernetes-dashboard"
repository = "https://kubernetes.github.io/dashboard/"
chart = "kubernetes-dashboard"
namespace = "default"set {
name = "service.type"
value = "LoadBalancer"
}set {
name = "protocolHttp"
value = "true"
}set {
name = "service.externalPort"
value = 80
}set {
name = "replicaCount"
value = 2
}set {
name = "rbac.clusterReadOnlyRole"
value = "true"
}
}
Dans le Terraform ci-dessus, je déploie le kubernetes-dashboard
Graphique de https://kubernetes.github.io/dashboard/
dans l’espace de noms default
. j’utilise aussi le set
variable pour remplacer les valeurs par défaut du graphique :
service.type
: je change cela enLoadBalancer
pour revoir mes modifications localement. N’oubliez pas de courirminikube tunnel
dans une fenêtre séparée, ou cela ne fonctionnera pas.protocolHttp
: je déploie la version non sécurisée pour supprimer les avertissements HTTPS surlocalhost
.service.externalPort
: ce doit être 80 pour non-sécurisé.replicaCount
: je change cela en 2 pour voir si ces changements fonctionnent même 🙂rbac.clusterReadOnlyRole
: Ce devrait êtretrue
pour que le tableau de bord dispose des autorisations appropriées.
Exécuter notre Terraform
Commençons par initialiser Terraform avec terraform init
:
Initializing the backend...Initializing provider plugins...
- Finding latest version of hashicorp/helm...
- Installing hashicorp/helm v2.2.0...
- Installed hashicorp/helm v2.2.0 (signed by HashiCorp)Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
Jusqu’ici tout va bien. Terraform a initialisé avec succès le fournisseur Helm. Et maintenant pour terraform apply
:
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ createTerraform will perform the following actions:
# helm_release.my-kubernetes-dashboard will be created
+ resource "helm_release" "my-kubernetes-dashboard" {
+ atomic = false
+ chart = "kubernetes-dashboard"
+ cleanup_on_fail = false
[...]
+ set {
+ name = "service.type"
+ value = "LoadBalancer"
}
}Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.Enter a value: yes
helm_release.my-kubernetes-dashboard: Creating...
helm_release.my-kubernetes-dashboard: Still creating... [10s elapsed]
helm_release.my-kubernetes-dashboard: Creation complete after 14s [id=my-kubernetes-dashboard]
(N’oubliez pas de courir minikube tunnel
dans une autre fenêtre de terminal, sinon le apply
ne fonctionnera pas).
Vérification de nos modifications
Vérifions si nos pods sont en cours d’utilisation kubectl get po
et kubectl get svc
:
~ kubectl get po
NAME READY STATUS RESTARTS AGE
my-kubernetes-dashboard-7bc7ccfbd9-56w56 1/1 Running 0 18m
my-kubernetes-dashboard-7bc7ccfbd9-f6jc4 1/1 Running 0 18m~ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 20m
my-kubernetes-dashboard LoadBalancer 10.104.144.125 10.104.144.125 80:32066/TCP 19m
Nos pods sont déployés et l’équilibreur de charge fonctionne. Vérifiez maintenant l’interface utilisateur :
Conclusion
Vous pouvez retrouvez les exemples de cet article dans mon repo Gitlab.
Avec l’approvisionnement de Helm désormais intégré à Terraform, ma vie professionnelle est d’autant plus facile. Je me rends compte que la séparation entre l’infrastructure et l’approvisionnement avait un objectif différent : les changements d’infrastructure étaient généralement ponctuels ou ne nécessitaient pas de mises à jour fréquentes, peut-être à quelques reprises lorsque les règles de gouvernance ou de sécurité de mon organisation ont changé. D’un autre côté, les modifications de provisionnement se produisaient fréquemment, parfois à chaque version. Il était donc logique d’avoir Terraform (Infrastructure) et Helm Charts (Provisioning) dans deux dépôts différents avec deux outils différents et deux workflows de révision différents. Je ne suis pas sûr que les fusionner à l’aide d’un seul outil soit la meilleure idée, mais un outil de moins dans la chaîne d’outils est toujours une énorme victoire. Je pense que le pour et le contre varient d’un projet à l’autre et d’une équipe à l’autre.