
Cet article fait partie d’une série d’articles :
- Forger un cluster kubernetes dans son garage
- Préparation du déploiement des applications
- Déploiement Prometheus grafana dans Kubernetes
- Déploiement de notre première application
1. Notre application (Partie CI)
Il s’agit d’un bot discord créant un quiz. C’est une application écrite en golang.
Remarque : Cette application ne fait que se connecter à des APIS, et n’a donc pas besoin de recevoir des requètes de l’extérieur. Il n’y a donc pas besoin de créer un accès ingress depuis internet vers notre cluster, ce qui simplifie la gestion de la sécurité.

La compilation de l’application est assez simple :
go mod tidy
go build .
Ce qui se traduit pour le job suivant dans notre fichier de configuration de la CI/CD, le .gitlab-ci.yml par :
#.gitlab-ci.yml
buildgo:
stage: build
image: golang
script:
- go mod tidy
- go build .
cache:
policy: push
paths:
- quizzbot
Chaque job de CI s’exécute dans une conteneur docker différent, et donc le cache permet de sauvegarder des fichiers et de les partager entre les différents conteneurs, comme ici quizzbot, le binaire compilé de notre application.
Nous packageons notre application dans une image docker, qui sera notre livrable :
#.gitlab-ci.yml
builddocker:
stage: publish
services:
- name: docker:dind
command: ["dockerd", "--host=tcp://0.0.0.0:2375"]
alias: 'docker'
before_script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD"
script:
- docker build -t $CI_REGISTRY/discordquizbot .
- docker push $CI_REGISTRY/discordquizbot
cache:
policy: pull
paths:
- quizzbot
(Petit disclaimer : la méthode ici présentée est ancienne, mais je le sais, je n’ai pas eu trop le temps de peaufiner cette partie)
Note : Toute cette partie est exécutée sur les runner partagés de gitlab.com, car il n’y a aucun avantage à utiliser nos propres ressources pour celà.
2. Le déploiement terraform (Partie CD)

Chose à savoir : Je suis un grand adepte de terraform, donc je vais l’utiliser, et peut-être un peu plus que de raison.
Je vais par exemple utiliser directement le provider terraform pour kubernetes là où il aurait été plus “joli” d’utiliser des configurations helm puis de les exécuter avec le provider helm de terraform, laissant la possibilité à tout un chacun de choisir de déployer via terraform, ou non.
Ceci étant dit, retournons à notre déploiement :
Dans cette partie, nous déclarons les variables non déclarées dans nos projets gitlab, ou leurs groupe parent (voir le chapitre Préparation du déploiement des applications)
#.gitlab-ci.yml
variables:
TF_VAR_MINIKUBE_HOST: ${MINIKUBE_HOST}
TF_VAR_CI_PROJECT_ID: ${CI_PROJECT_ID}
TF_VAR_CI_REGISTRY: ${CI_REGISTRY}
Ici le préfixe TF_VAR_ est une façon de passer à terraform des variables.
Par exemple, la variable TF_VAR_CI_REGISTRY apparaîtra en tant que var.CI_REGISTRY dans notre code terraform.
Sur notre groupe gitlab, nous avons ajouté la variable
TF_VAR_KUBECONFIG_MKS8
qui contient le chemin de notre fichier de configuration au format lisible par kubectl (voir le chapitre Préparation du déploiement des applications)
Commençons par jouer la commande terraform init pour initialiser le dossier d’exécution puis terraform plan qui va valider en se connectant à kubernetes que tout est en place pour notre déploiement, sans pour autant le déclencher.
#.gitlab-ci.yml
terraform-plan:
stage: build
image:
name: hashicorp/terraform:latest
entrypoint:
- '/usr/bin/env'
- 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
tags:
- minikube
only:
- main
script:
- cd terraform
- apk update && apk add envsubst
- cat backend.tf.tpl | envsubst > backend.tf
- terraform init -input=false
- terraform plan -input=false -out=plan.cache
le terraform plan va s’exécuter sur notre cluster kubernetes grâce à ceci :
tags:
- minikube
minikube est le tag que j’ai donné à mon runner gitlab lors de sa création (voir le chapitre Préparation du déploiement des applications)
Tout va s’exécuter dans le dossier terraform de ce repo et terraform utilisera tous les fichier *.tf présents dans ce dossier
Je vous laisse étudier la documentation de terraform. Nous nous intéresserons surtout à la manière de déployer dans notre cluster.
Pour aller à l’essentiel, nous allons configurer le provider (driver) terraform pour kubernetes, dans le fichier provider.tf
# provider.tf
provider "kubernetes" {
config_path = var.KUBECONFIG_MKS8
}
(C’est ici que nous transmettons le chemin de notre fichier de configuration kubernetes à terraform)
Ensuite, nous instancions notre application via un appel de module dans le fichier main.tf:
module "french" {
source = "./app_instance"
MINIKUBE_NAMESPACE = data.kubernetes_namespace.botspace.id
CI_REGISTRY = var.CI_REGISTRY
DISCORD_TOKEN = var.DISCORD_TOKEN
}
Ce module exécute ce qui se trouve dans le dossier terraform/app_instance
et le fichier terraform/app_instance/application.tf contient le code de déploiement de notre application :
resource "kubernetes_deployment" "discordbot" {
metadata {
name = "discordbot"
namespace = var.MINIKUBE_NAMESPACE
labels = {
}
}
spec {
replicas = 1
selector {
match_labels = {
app = "discordbot"
}
}
template {
metadata {
labels = {
app = "discordbot"
}
}
spec {
container {
image = "${var.CI_REGISTRY}/discordquizbot"
name = "discordquizbot"
env {
name = "DISCORD_TOKEN"
value = "${var.DISCORD_TOKEN}"
}
}
}
}
}
}
Pour comprendre, je vous renvoie vers la documentation de l’objet kubernetes_deployment sur le site officiel
Une fois le terraform plan validé, notre pipeline gitlab exécutera le terrafom apply appliquera les modifications.
Voici à quoi ressemble notre pipeline gitlab :

Et notre conteneur sera démarré sur notre cluster kubernetes :
