
Déployer un cluster Kubernetes Talos sur NumSpot avec Terraform : quand minimalisme et souveraineté riment avec modernité
Motivation
Chez de nombreux Cloud Providers, la tentation est grande d’utiliser les services managés Kubernetes (KaaS) : maintenance simplifiée, upgrades automatisés, intégration avec la console cloud... NumSpot n’échappe pas à la règle et propose sa propre offre Kubernetes managée, très séduisante pour qui veut déployer vite et sans douleur.
Mais que faire lorsqu'on souhaite garder un contrôle total sur son OS, sa couche Kubernetes, tout en s’appuyant sur l’infrastructure robuste d’un cloud souverain ? C’est là que Talos de SideroLabs entre en scène. Minimaliste, sécurisé et taillé pour le Cloud Native, Talos OS s’impose comme un choix sérieux pour déployer Kubernetes en toute maîtrise.
Dans cet article, je vous guide sur la création d’un cluster Talos sur NumSpot, orchestré par Terraform. Une alternative sérieuse pour ceux qui veulent conjuguer automatisation, sobriété et souveraineté.
Pourquoi Talos et pas un service managé ?
Avant de plonger dans le code, posons le décor.
Talos est un OS Linux immuable et minimaliste conçu exclusivement pour exécuter Kubernetes. Pas de package manager, pas de SSH, une surface d’attaque réduite au strict nécessaire, et une approche API-first pour l'administration.
NumSpot, de son côté, est un cloud souverain basé sur OutScale (Xen), robuste et compatible avec les standards du cloud public. Il propose déjà un Kubernetes managé, mais dans notre cas :
Contrainte de sécurité élevée : Talos réduit les vecteurs d'attaque.
Volonté d’expérimenter : maîtriser les mises à jour, le bootstrap, la gestion du cycle de vie.
Homogénéité multi-cloud / on-prem : même OS partout, même comportement.
Pré-requis
Avant de commencer :
-
Un projet actif sur NumSpot avec quota suffisant.
-
Un compte de service numspot avec des droits suffisants pour créer tous les éléments de l'infrastructure Numspot.
-
Sous la forme d'un ID (SA_idKey) et d'un Secret (SA_KeyPass)
-
Une infrastructure réseau existante (Vpc, Subnet, Nat Gateway). Très facile à créer en utilisant terraform.
-
Une vm de service avec :
- Terraform installé (>=1.6.x).
- talosctl installé.
- curl pour accéder à l'API de numspot car tou n'est pas encore disponible dans le provider terraform pour Numspot.
- Prévoyez sur cette VM un volume supplémentaire de 20G monté sur la VM (/dev/sda).
1. Création d'une Image dans le catalogue privé du compte Numspot
L'image Talos n'est pas disponible dans le catalogue public de Numspot.
1.1 Téléchargement du raw disk Talos Linux
Nous allons devoir télécharger une image sur Talos Linux Image Factory
C'est un service proposé par Sidero Labs qui permet de générer des images machine personnalisées pour Talos Linux.
- Choisir la version de Talos Linux, ex: 1.9.5
- Cliquer sur "Next"
- Choisir "Nocloud" comme type de distribution
- Cliquer sur "Next"
- Choisir amd64 comme architecture de machine, ne pas cocher SecureBoot
- Cliquer sur "Next"
- Vous pouvez choisir des extensions système si besoin (moi j'en ai choisi aucune)
- Cliquer sur "Next"
- Laisser le champ Customization vide
- Cliquer sur "Next"
- Télécharger le Disk Image (ex: https://factory.talos.dev/image/
/v1.9.5/nocloud-amd64.raw.xz) sur la VM de service
1.1.2 Copie du raw disk sur /dev/sda
- Décompresser le raw disk
xz -d nocloud-amd64.raw.xz
mv talos-1.9.5-nocloud-amd64.raw
- Nettoyage du disk avant copie
Vérifiez où est monté votre volume dans la vm (sudo fdisk -l). (Moi /dev/sda)
Disk /dev/vda: 10 GiB, 10737418240 bytes, 20971520 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: C7AE58FB-33FF-47AD-B0B0-C5494AA4C12B
Device Start End Sectors Size Type
/dev/vda1 2099200 20971486 18872287 9G Linux filesystem
/dev/vda14 2048 10239 8192 4M BIOS boot
/dev/vda15 10240 227327 217088 106M EFI System
/dev/vda16 227328 2097152 1869825 913M Linux extended boot
Partition table entries are not in disk order.
Disk /dev/sda: 20 GiB, 21474836480 bytes, 41943040 sectors
Disk model: QEMU HARDDISK
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Commande à lancer
sudo wipefs -a /dev/sda
- Copie avec la commande dd du raw disk sur /dev/sda
sudo dd if=talos-1.9.5-nocloud-amd64.raw of=/dev/sda bs=32M status=progress
1241513984 bytes (1.2 GB, 1.2 GiB) copied, 1 s, 1.1 GB/s ...
38+1 records in
38+1 records out
1306525696 bytes (1.3 GB, 1.2 GiB) copied, 123.819 s, 10.6 MB/s
Soyez patient !
Ça peut prendre un certain temps avant d'avoir la 🫲.
Si on repasse un fdisk -l
on voit que le disk a maintenant une structure
Disk /dev/sda: 20 GiB, 21474836480 bytes, 41943040 sectors
Disk model: QEMU HARDDISK
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 1C07C588-7E7B-4245-BF46-C54B8BCBDEEE
Device Start End Sectors Size Type
/dev/sda1 2048 206847 204800 100M EFI System
/dev/sda2 206848 208895 2048 1M BIOS boot
/dev/sda3 208896 2256895 2048000 1000M Linux filesystem
/dev/sda4 2256896 2258943 2048 1M Linux filesystem
1.1.3 Snapshot du volume pour en faire un ... Snapshot 😏
Sur numspot on peut convertir un snapshot en une image numspot utilisable pour booter une vm.
Je pense qu'on peut faire cette partie par l'api de numspot, mais je vais au plus simple et je vais le faire par le portail.
- Allez dans Stockage >> Volumes
- Identifiez le volume que vous avez ajouté à votre VM
- Dans
Actions
Choissisez "Créer un Snapshot depuis ce Volume" - Donnez un nom à votre snapshot pour facilement l'identifier (ex: talos-nocloud-1.9.5)
- Puis allez dans snapshot, Vérifiez que votre snapshot est généré et disponible
- notez l'ID du snapshot dans notre exemple
snap-88153838
1.1.4 Transformation du Snapshot en Image privée Numspot
C'est à ce moment-là que les choses se compliquent car cette fonctionnalité n'existe pas encore dans le portail.
On va donc utiliser l'API de numspot pour faire ça !
-
Il faut nous connecter à l'API pour récupérer un TOKEN d'authentification qui sera utilisé dans les commandes curl suivantes.
-
Créer un script
auth.sh
avec le code suivant :
Adapter simplement REGION
, SA_idKey
et SA_KeyPass
# auth.sh
export REGION="cloudgouv-eu-west-1"
SA_idKey="zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz"
SA_KeyPass="omygodthisisasecretkey"
export ACCESS_TOKEN=$(curl -s -X POST https://api.$REGION.numspot.com/iam/token \
-H 'Accept: */*' \
-u "${SA_idKey}":"${SA_KeyPass}" \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=client_credentials&scope=openid+offline_access' | jq -r '.access_token')
# pour Debug seulement
#echo $ACCESS_TOKEN
- Nous avons notre
TOKEN
. Nous allons donc transformer notre snapshot en image privée.
Créer le script suivant ou la commande :
#!/bin/bash
source auth.sh
curl 'https://api.cloudgouv-eu-west-1.numspot.com/compute/spaces/xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx/images' \
--request POST \
--header 'Content-Type: application/json' \
--header "Authorization: Bearer ${ACCESS_TOKEN}" \
--data '{
"architecture": "x86_64",
"blockDeviceMappings": [
{
"bsu": {
"deleteOnVmDeletion": true,
"snapshotId": "snap-88153838",
"volumeSize": 20,
"volumeType": "standard"
},
"deviceName": "/dev/sda1"
}
],
"productCodes": [
"0001"
],
"name": "talos1.9.5-img",
"rootDeviceName": "/dev/sda1"
}'
- Adaptez les champs :
- snapshotId
- name
-
volumeType (si besoin)
-
Gardez les champs :
- /dev/sda1 de deviceName et rootDeviceName
- architecture
Je ne sais pas trop ce qu'est productCodes
Note :
- Comment trouver https://api.cloudgouv-eu-west-1.numspot.com/compute/spaces/xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx ?
-
Allez dans IAM >> Espaces : Prenez l'ID de votre Espace
-
Lancez le script
Si tout se passe bien, allez dans Compute >> Images et tapez Talos dans le champ de recherche. Vous devriez avoir quelque chose d'approchant à ça
Notez l'ID de votre image (chez moi ami-4a8eaf5a
)
Voilà nous avons une image disponible nous allons pouvoir créer des VM à partir de cette image.
Vous pouvez déjà créer une vm de test pour vous assurer qu'elle boot correctement
Note :
Le boot est, je ne sais pas trop pourquoi, la première fois très lent.
Si vous ouvrez la console de la VM créée vous aurez quelque chose comme ça d'approchant :
2. Création des configurations terraform pour Talos sur Numspot
Structure du répertoire :
.
├── files
├── numspot-talos
└── templates
Répertoire :
files
: contient 1 fichiercp-scheduling.yaml
qui permet de configurer les nœuds Talos avec des données fixes.templates
: contient 1 fichier de configurationnode-configuration.yaml.tmpl
qui permet de configurer les différents nœuds en fonction de leurs rôles ou autres paramètres.numspot-talos
: répertoire généré avec le nom du cluster, contiendra les fichiers permettant d'administrer le cluster avec la CLI talosctl et le kubeconfig permettant l'accès à l'API kubernetes
2.1 fichiers Providers
- Créez un fichier
providers.tf
avec le code suivant :
terraform {
required_providers {
numspot = {
source = "numspot/numspot"
version = ">= 1.0"
}
talos = {
source = "siderolabs/talos"
version = ">= 0.6.0"
}
}
}
provider "numspot" {
numspot_host = "https://api.cloudgouv-eu-west-1.numspot.com"
client_id = "ID du SA"
client_secret = "Secret du SA"
space_id = "Votre Space ID"
numspot_host_os = "https://objectstorage.eu-west-2.numspot.com"
}
Adaptez les informations de numspot
Le rôle principal du fichier providers.tf
est de :
-
Déclarer les fournisseurs (Providers) requis : Indiquer à Terraform quels plugins (fournisseurs) sont nécessaires pour interagir avec les différentes API des services que vous souhaitez gérer (ici, NumSpot et Talos).
-
Configurer les fournisseurs : Fournir les informations d'authentification et les paramètres spécifiques (comme les points de terminaison d'API ou les régions) pour que Terraform puisse communiquer correctement avec ces services.
-
Bloc terraform {}
- C'est un bloc spécial pour les configurations globales de Terraform lui-même.
- required_providers {} : Ce sous-bloc est crucial. Il liste les fournisseurs externes dont dépend votre code Terraform.
- numspot = { ... } :
- Déclare que le fournisseur numspot est nécessaire.
- source = "numspot/numspot" : Indique à Terraform où trouver le code de ce fournisseur dans le Registre Terraform (ici, il s'agit du fournisseur officiel maintenu par ou pour NumSpot).
- version = ">= 1.0" : Spécifie que n'importe quelle version du fournisseur numspot égale ou supérieure à 1.0 est acceptable. Terraform téléchargera la version la plus récente correspondante lors de l'exécution de terraform init.
- talos = { ... } :
- Déclare que le fournisseur talos est nécessaire.
- source = "siderolabs/talos" : Indique que ce fournisseur provient de l'organisation siderolabs (les créateurs de Talos OS).
- version = ">= 0.6.0" : Spécifie que n'importe quelle version du fournisseur Talos égale ou supérieure à 0.6.0 est acceptable.
- numspot = { ... } :
- Bloc provider "numspot" {}
- Ce bloc configure le fournisseur numspot qui a été déclaré dans required_providers. C'est ici que vous donnez à Terraform les "clés" pour accéder à votre compte NumSpot.
- numspot_host = "https://api.cloudgouv-eu-west-1.numspot.com" : Définit l'URL du point de terminaison (endpoint) de l'API principale de NumSpot pour la région eu-west-1. C'est l'adresse que Terraform utilisera pour envoyer ses requêtes de gestion d'infrastructure.
- client_id = "ID du SA" : C'est l'identifiant de votre Compte de Service (SA) NumSpot. Vous devez remplacer "ID du SA" par votre véritable identifiant. Ce compte doit avoir les permissions nécessaires pour créer/modifier/supprimer les ressources définies dans votre code Terraform.
- client_secret = "Secret du SA" : C'est le secret associé à votre client_id. Vous devez remplacer "Secret du SA" par votre véritable secret. ATTENTION : Il est fortement déconseillé de stocker des secrets en clair directement dans les fichiers .tf. Utilisez plutôt des variables d'environnement (ex: NUMSPOT_CLIENT_SECRET) ou un fichier terraform.tfvars (ajouté au .gitignore) pour plus de sécurité.
- space_id = "Votre Space ID" : C'est l'identifiant de votre "Espace" (Space) NumSpot, qui correspond souvent à un projet ou un périmètre d'isolation logique au sein de votre organisation. Vous devez remplacer "Votre Space ID" par votre ID d'espace réel.
- numspot_host_os = "https://objectstorage.eu-west-2.numspot.com" : Définit l'URL du point de terminaison spécifique pour le service de Stockage Objet (Object Storage) de NumSpot, ici dans la région eu-west-2. Le fournisseur peut avoir besoin de cette information pour certaines opérations liées au stockage (par exemple, si vous gérez des buckets S3 ou téléchargez des images via ce service).
2.2 variables et fichiers de configuration statiques ou templates
Nous allons avoir besoin de quelques variables.
Ce fichier (vars.tf ou variables.tf) regroupe les paramètres que j'ai rendus configurables pour ce projet de déploiement de Talos sur NumSpot.
L'idée est que vous puissiez adapter facilement le déploiement à vos besoins (nom du cluster, IPs, configuration des nœuds) sans toucher au cœur logique du code Terraform.
Il faudra adapter les adresses IP en fonction des subnets que vous avez définis.
Un des gros avantages de Talos c'est de pouvoir définir une vip
pour le control plane.
- Créez un fichier
vars.tf
avec le code suivant :
variable "cluster_name" {
description = "A name to provide for the Talos cluster"
type = string
default = "numspot-talos"
}
variable "vip" {
description = "vip of k8s Talos cluster"
type = string
default = "10.0.1.230"
}
variable "node_data" {
description = "A map of node data"
type = object({
controlplanes = map(object({
install_disk = string
hostname = optional(string)
}))
workers = map(object({
install_disk = string
hostname = optional(string)
}))
})
default = {
controlplanes = {
"10.0.1.234" = {
install_disk = "/dev/sda"
},
"10.0.1.235" = {
install_disk = "/dev/sda"
},
"10.0.1.236" = {
install_disk = "/dev/sda"
}
}
workers = {
"10.0.1.240" = {
install_disk = "/dev/sda"
hostname = "worker-1"
},
"10.0.1.241" = {
install_disk = "/dev/sda"
hostname = "worker-2"
}
}
}
}
Voici le détail des variables que j'ai définies :
-
variable "cluster_name"
- Ce que ça fait : Ici, vous définissez le nom que portera le cluster Talos que nous allons créer. Ce nom sera utilisé pour taguer certaines ressources ou dans la configuration Talos elle-même.
- Type attendu : Une simple chaîne de caractères (
string
). - Valeur par défaut : Si vous ne fournissez pas de nom spécifique, j'utiliserai
"numspot-Talos"
par défaut.
-
variable "vip"
- Ce que ça fait : Cette variable sert à définir l'adresse IP virtuelle (VIP) que j'utiliserai comme point d'accès stable pour le control plane Kubernetes (l'API Server). C'est l'adresse que vous utiliserez généralement dans votre
kubeconfig
. - Type attendu : Une chaîne de caractères (
string
) représentant une adresse IP valide. - Valeur par défaut : J'ai mis
"10.0.1.230"
par défaut, ce qui correspond à mon réseau de test. Adaptez-la à votre plan d'adressage réseau.
- Ce que ça fait : Cette variable sert à définir l'adresse IP virtuelle (VIP) que j'utiliserai comme point d'accès stable pour le control plane Kubernetes (l'API Server). C'est l'adresse que vous utiliserez généralement dans votre
-
variable "node_data"
- Ce que ça fait : C'est la variable la plus structurée. Elle me permet de savoir exactement quels nœuds (control planes et workers) vous voulez dans votre cluster et quelques détails à leur sujet. Pour chaque nœud, je m'attends à trouver son adresse IP (qui sert de clé dans la map), le disque sur lequel je dois installer Talos (
install_disk
), et éventuellement un nom d'hôte (hostname
) que vous souhaitez lui assigner. - Type attendu : Un objet complexe (
object
) contenant deux maps :controlplanes
etworkers
. Chaque map associe une adresse IP (cléstring
) à un objet contenant au moinsinstall_disk
(string
) et optionnellementhostname
(string
). - Valeur par défaut : J'ai fourni une configuration par défaut assez complète pour vous montrer la structure attendue et permettre un démarrage rapide. Elle configure :
- Trois control planes aux IPs
10.0.1.234
,10.0.1.235
,10.0.1.236
. - Deux workers aux IPs
10.0.1.240
(nomméworker-1
) et10.0.1.241
(nomméworker-2
). - Pour tous ces nœuds par défaut, j'installerai Talos sur le disque
/dev/sda
(assurez-vous que c'est bien le disque que vous avez préparé sur vos VM NumSpot comme indiqué dans les prérequis !).
- Trois control planes aux IPs
- Ce que ça fait : C'est la variable la plus structurée. Elle me permet de savoir exactement quels nœuds (control planes et workers) vous voulez dans votre cluster et quelques détails à leur sujet. Pour chaque nœud, je m'attends à trouver son adresse IP (qui sert de clé dans la map), le disque sur lequel je dois installer Talos (
-
fichier
files/cp-scheduling.yaml
Contenu :
cluster:
allowSchedulingOnControlPlanes: true
Permet de déployer des workloads utilisateur sur les control-plane (vous pouvez mettre false
)
- fichier
templates/node-configuration.yaml.tmpl
Contenu :
machine:
certSANs:
- ${ dns_name }
%{ if vip != "" }
- ${vip}
%{ endif }
install:
disk: ${install_disk}
network:
hostname: ${hostname}
interfaces:
- interface: eth0
dhcp: true
%{ if vip != "" }
vip:
ip: ${vip}
%{ endif }
cluster:
apiServer:
certSANs:
- ${ dns_name }
Permet de configurer des install disk différents, de mettre des hostname parlant et d'ajouter les SANs pour la vip et le fqdn du loadbalancer
2.3 les data (ressources externes numspot)
Mon infrastructure Numspot possède déjà des composants déployés (ex: VPC, Subnets, IPs ...).
Plutôt que de recréer un réseau à chaque fois, je pars du principe que vous avez déjà un VPC, un sous-réseau (subnet), et un groupe de sécurité (security group) prêts à l'emploi.
Ce fichier sert à les "retrouver" pour que Terraform puisse les utiliser.
Créez un fichier data.tf
avec le code suivant :
data "numspot_vpcs" "ds-vpc" {
ids = ["vpc-xxxxxxx"]
}
data "numspot_subnets" "ds-subnet" {
vpc_ids = [data.numspot_vpcs.ds-vpc.items.0.id]
}
data "numspot_security_groups" "ds-sg" {
security_group_ids = ["sg-xxxxxxx"]
}
resource "null_resource" "print-ds-vpc-id" {
provisioner "local-exec" {
command = "echo data.numspot_vpcs.ds-vpc.items.0.id"
}
}
resource "null_resource" "print-ds-subnet-id" {
provisioner "local-exec" {
command = "echo data.numspot_subnets.ds-subnet.items.0.id"
}
}
resource "null_resource" "print-ds-sg-id" {
provisioner "local-exec" {
command = "echo data.numspot_security_groups.ds-sg.items.0.id"
}
}
-
data "numspot_vpcs" "ds-vpc"
- Ce que ça fait : Ce bloc utilise une source de données (
data
) Terraform pour rechercher des informations sur un VPC spécifique dans NumSpot. - Comment : Je lui demande de chercher le VPC dont l'identifiant est
vpc-xxxxxxxx
. Le nom que je lui donne dans Terraform estds-vpc
(pour "data source VPC"). - Pourquoi : J'ai besoin de l'identifiant et potentiellement d'autres détails de ce VPC pour configurer le reste de l'infrastructure, notamment pour trouver le bon sous-réseau.
- Important : Vous devez remplacer
vpc-xxxxxxxx
par l'ID du VPC que vous souhaitez réellement utiliser dans votre environnement NumSpot.
- Ce que ça fait : Ce bloc utilise une source de données (
-
data "numspot_subnets" "ds-subnet"
- Ce que ça fait : De la même manière, je recherche ici un ou plusieurs sous-réseaux.
- Comment : Au lieu de chercher par ID de sous-réseau, je filtre en demandant les sous-réseaux qui appartiennent au VPC que j'ai trouvé juste avant (
data.numspot_vpcs.ds-vpc.items.0.id
). J'utilise.items.0.id
car la source de donnéesnumspot_vpcs
renvoie une liste (même s'il n'y a qu'un seul VPC correspondant à l'ID), et je prends le premier élément (0
) de cette liste. - Pourquoi : Les machines virtuelles de notre cluster Talos devront être placées dans un sous-réseau spécifique. Ce bloc me permet d'obtenir l'ID de ce sous-réseau.
- Note : Ce code suppose qu'il y a au moins un sous-réseau dans le VPC spécifié. Si vous en avez plusieurs, le code Terraform qui utilise
data.numspot_subnets.ds-subnet.items.0.id
ciblera le premier sous-réseau retourné par l'API NumSpot. Assurez-vous que c'est bien celui que vous visez.
-
data "numspot_security_groups" "ds-sg"
- Ce que ça fait : Je récupère ici les informations d'un groupe de sécurité existant.
- Comment : Comme pour le VPC, je le cible directement par son ID :
sg-xxxxxxxx
. - Pourquoi : Les machines virtuelles auront besoin d'être associées à un groupe de sécurité pour contrôler le trafic entrant et sortant. Ce groupe doit déjà être configuré avec les règles nécessaires pour Talos et Kubernetes (par exemple, ouvrir les ports 6443, 50000, 50001, etc.).
- Important : Vous devez remplacer
sg-xxxxxxxx
par l'ID du groupe de sécurité que vous avez préparé pour ce cluster.
-
resource "null_resource" "print-..."
- Ce que ça fait : Ces trois blocs (
print-ds-vpc-id
,print-ds-subnet-id
,print-ds-sg-id
) sont un peu différents. Ils utilisent une ressourcenull_resource
, qui ne crée rien dans NumSpot. Associée àprovisioner "local-exec"
, elle me permet simplement d'exécuter une commande sur la machine où vous lancez Terraform. - Comment : J'exécute une commande
echo
qui affiche littéralement la chaîne de caractères correspondant au chemin d'accès Terraform vers l'ID de la ressource (par exemple,echo data.numspot_vpcs.ds-vpc.items.0.id
). - Pourquoi : Je les ai ajoutés principalement à des fins de débogage ou de vérification rapide. Lorsque vous lancez
terraform apply
, ces commandes s'exécuteront et afficheront les chemins d'accès dans la sortie. Cela ne montre pas la valeur de l'ID, mais confirme que Terraform tente d'utiliser ces références. C'est une petite aide pour s'assurer que les data sources sont bien lues, même si pour voir les vraies valeurs, il faudrait utiliser desoutput
ou une interpolation${...}
dans leecho
. - Note : Ces ressources
null_resource
n'ont aucun impact sur l'infrastructure créée et peuvent être retirées si vous les trouvez inutiles.
- Ce que ça fait : Ces trois blocs (
2.4 Les VMs et autres composants de l'infrastructure
Ce fichier contient les définitions des ressources principales que Terraform va créer et gérer sur NumSpot pour notre cluster Talos. On y trouve la création des VMs (Control Plane et Workers) et du Load Balancer nécessaire pour la haute disponibilité et l'accès externe à l'API Kubernetes.
- Créez un fichier infra.tf avec le code suivant :
# Création des VMs Controlplane
resource "numspot_vm" "talos-cp" {
for_each = var.node_data.controlplanes
image_id = "ami-4a8eaf5a"
type = "ns-eco6-2c8r"
keypair_name = "talos-keypair"
subnet_id = data.numspot_subnets.ds-subnet.items.0.id
security_group_ids = [data.numspot_security_groups.ds-sg.items.0.id]
private_ips = [each.key]
tags = [
{
key = "name"
value = "talos-cp-${each.key}"
}
]
}
# Création des VMs Worker
resource "numspot_vm" "talos-worker" {
for_each = var.node_data.workers
image_id = "ami-4a8eaf5a"
type = "ns-eco6-2c8r"
keypair_name = "talos-keypair"
subnet_id = data.numspot_subnets.ds-subnet.items.0.id
security_group_ids = [data.numspot_security_groups.ds-sg.items.0.id]
private_ips = [each.key]
tags = [
{
key = "name"
value = "talos-worker-${each.value.hostname}"
}
]
}
resource "numspot_load_balancer" "load-balancer" {
name = "nlb001"
listeners = [{
load_balancer_port = 6443
backend_port = 6443
backend_protocol = "TCP"
load_balancer_protocol = "TCP"
}]
subnets = [data.numspot_subnets.ds-subnet.items.0.id]
security_groups = [data.numspot_security_groups.ds-sg.items.0.id]
backend_vm_ids = [for ip, data in var.node_data.controlplanes : numspot_vm.talos-cp[ip].id]
// invalide à l'heure actuelle - public_ip = numspot_public_ip.lb-public-ip.public_ip
type = "internet-facing"
health_check = {
healthy_threshold = 3
check_interval = 10
port = 6443
protocol = "HTTPS"
path = "/api/v1/namespaces/kube-public/configmaps/cluster-info"
timeout = 5
unhealthy_threshold = 5
}
}
data "numspot_load_balancers" "load-balancer" {
load_balancer_names = [numspot_load_balancer.load-balancer.name]
depends_on = [numspot_load_balancer.load-balancer]
}
Note :
Pour le Health check je mets ça mais en fait ça ne peut pas marcher car tous les accès à l'API sont authentifiés. même la partie publique.
Le problème c'est que je ne peux pas utiliser actuellement (bug ? ) un check TCP sur le port 6443 avec le provider numspot.
Je patcherai plus tard le healthcheck via un call API pour le mettre à jour.
Ce fichier contient les définitions des ressources principales que Terraform va créer et gérer sur NumSpot pour notre cluster Talos. On y trouve la création des VMs (Control Plane et Workers) et du Load Balancer nécessaire pour la haute disponibilité et l'accès externe à l'API Kubernetes.
-
resource "numspot_vm" "talos-cp"
- Ce que ça fait : Ici, je définis les machines virtuelles qui serviront de nœuds Control Plane pour notre cluster Kubernetes.
- Comment : J'utilise une boucle
for_each
qui s'appuie sur la mapcontrolplanes
de notre variablevar.node_data
(définie dansvars.tf
). Pour chaque entrée dans cette map (chaque IP de control plane), Terraform créera une VM. - Configuration clé :
image_id = "ami-3b18dcca"
: J'utilise une image spécifique de NumSpot. Attention, cet ID (ami-3b18dcca
) est l'ID de l'image Talos que nous avons créée manuellement dans la première étape du tuto. Vous devrez remplacer cet ID par celui de votre image Talos perso dans votre catalogue privé NumSpot.type = "ns-eco6-2c8r"
: Je choisis ce type d'instance (taille/puissance). Vous pouvez l'adapter selon vos besoins.keypair_name = "talos-keypair"
: J'associe une paire de clés SSH préexistante nomméetalos-keypair
à la VM. Même si Talos n'utilise pas SSH, NumSpot peut le requérir ou cela peut être utile pour certaines opérations de bas niveau (très rare avec Talos). Assurez-vous que cette keypair existe dans votre compte NumSpot.subnet_id
etsecurity_group_ids
: J'utilise les informations du VPC/Subnet/Groupe de Sécurité que nous avons récupérées dansdata.tf
.private_ips = [each.key]
: C'est ici que j'attribue l'adresse IP privée fixe à chaque VM control plane. L'adresse IP provient directement de la clé de la mapvar.node_data.controlplanes
.tags
: Je mets un tag "name" sur chaque VM pour l'identifier facilement (ex:talos-cp-10.0.1.234
).
-
resource "numspot_vm" "talos-worker"
- Ce que ça fait : Très similaire au bloc précédent, mais celui-ci crée les machines virtuelles pour les nœuds Worker de notre cluster.
- Comment : Utilise aussi une boucle
for_each
, mais cette fois sur la mapworkers
devar.node_data
. - Configuration clé : Globalement identique aux control planes (même image, type, keypair, réseau), mais :
private_ips = [each.key]
: Attribue l'IP privée fixe venant de la clé de la mapvar.node_data.workers
.tags
: Le tag "name" utilise ici lehostname
défini dans la valeur de la map (ex:talos-worker-worker-1
).
-
resource "numspot_load_balancer" "load-balancer"
- Ce que ça fait : Crée un Load Balancer réseau (NLB) sur NumSpot.
- Pourquoi : Il va répartir le trafic entrant destiné à l'API Kubernetes (sur le port 6443) entre les différentes VMs Control Plane que nous avons créées. C'est essentiel pour la haute disponibilité et pour avoir un point d'entrée unique (
vip
) pour le cluster. - Configuration clé :
name = "nlb001"
: Je donne un nom fixe au Load Balancer.listeners
: Je configure l'écouteur pour recevoir du trafic TCP sur le port 6443 et le transférer vers les backends (nos control planes) sur le port 6443 également.subnets
&security_groups
: Je place le LB dans notre sous-réseau et lui associe notre groupe de sécurité (il faut que ce groupe autorise le trafic sur le port 6443).backend_vm_ids
: C'est ici que je connecte le LB aux VMs control plane. J'utilise une expressionfor
pour récupérer dynamiquement les IDs de toutes les VMs créées par le blocnumspot_vm.talos-cp
.public_ip
: Note importante : J'ai commenté cette ligne (// invalide à l'heure actuelle - public_ip = ...
). Cela suggère qu'au moment où j'ai écrit ce code, l'assignation directe d'une IP publique via cet attribut n'était pas fonctionnelle ou supportée par le provider NumSpot pour ce type de LB. Le LB sera donc probablement accessible via une IP publique assignée automatiquement ou nécessitera une étape manuelle/supplémentaire pour l'exposition sur Internet sitype = "internet-facing"
fonctionne comme attendu.type = "internet-facing"
: Indique que je veux que ce LB soit potentiellement accessible depuis Internet (même si l'IP publique n'est pas explicitement définie ici).health_check
: Je définis comment le LB vérifie si les control planes sont opérationnels. Il essaie de contacter un endpoint spécifique de l'API Kubernetes (/api/v1/.../cluster-info
) sur le port 6443 en HTTPS.
-
data "numspot_load_balancers" "load-balancer"
- Ce que ça fait : Ce bloc ne crée rien, il lit des informations sur le Load Balancer que nous venons juste de définir dans le bloc
resource
précédent. - Comment : Il recherche un LB ayant le nom
nlb001
. - Pourquoi : Souvent, on utilise une source de données comme celle-ci juste après avoir créé une ressource pour récupérer des attributs qui ne sont connus qu'après la création (comme un DNS Name généré automatiquement par NumSpot pour le LB). Le
depends_on = [numspot_load_balancer.load-balancer]
est crucial : il garantit que Terraform essaiera de lire ces informations seulement après que la création du LB soit terminée. Cela évite les erreurs si on essayait de lire trop tôt. Dans ce code précis, les informations lues ne semblent pas être utilisées immédiatement, mais c'est une bonne pratique de l'avoir si on prévoit d'utiliser des attributs dynamiques du LB plus tard (par exemple dans un fichier d'output).
- Ce que ça fait : Ce bloc ne crée rien, il lit des informations sur le Load Balancer que nous venons juste de définir dans le bloc
2.5 La configuration du cluster Talos
- Créez un fichier talos-cluster.tf avec le code suivant :
resource "talos_machine_secrets" "this" {}
data "talos_machine_configuration" "controlplane" {
depends_on = [numspot_load_balancer.load-balancer]
cluster_name = var.cluster_name
cluster_endpoint = "https://10.0.1.230:6443"
machine_type = "controlplane"
machine_secrets = talos_machine_secrets.this.machine_secrets
}
data "talos_machine_configuration" "worker" {
depends_on = [numspot_load_balancer.load-balancer]
cluster_name = var.cluster_name
cluster_endpoint = "https://10.0.1.230:6443"
machine_type = "worker"
machine_secrets = talos_machine_secrets.this.machine_secrets
}
data "talos_client_configuration" "this" {
cluster_name = var.cluster_name
client_configuration = talos_machine_secrets.this.client_configuration
endpoints = [for k, v in var.node_data.controlplanes : k]
}
resource "talos_machine_configuration_apply" "controlplane" {
client_configuration = talos_machine_secrets.this.client_configuration
machine_configuration_input = data.talos_machine_configuration.controlplane.machine_configuration
for_each = var.node_data.controlplanes
node = each.key
config_patches = [
templatefile("${path.module}/templates/node-configuration.yaml.tmpl", {
hostname = each.value.hostname == null ? format("%s-cp-%s", var.cluster_name, index(keys(var.node_data.controlplanes), each.key)) : each.value.hostname
install_disk = each.value.install_disk
vip = var.vip
public_ip = data.numspot_load_balancers.load-balancer.items.0.public_ip
dns_name = data.numspot_load_balancers.load-balancer.items.0.dns_name
}),
file("${path.module}/files/cp-scheduling.yaml"),
]
}
resource "talos_machine_configuration_apply" "worker" {
client_configuration = talos_machine_secrets.this.client_configuration
machine_configuration_input = data.talos_machine_configuration.worker.machine_configuration
for_each = var.node_data.workers
node = each.key
config_patches = [
templatefile("${path.module}/templates/node-configuration.yaml.tmpl", {
hostname = each.value.hostname == null ? format("%s-worker-%s", var.cluster_name, index(keys(var.node_data.workers), each.key)) : each.value.hostname
install_disk = each.value.install_disk
vip = ""
public_ip = data.numspot_load_balancers.load-balancer.items.0.public_ip
dns_name = data.numspot_load_balancers.load-balancer.items.0.dns_name
})
]
}
resource "talos_machine_bootstrap" "this" {
depends_on = [talos_machine_configuration_apply.controlplane]
client_configuration = talos_machine_secrets.this.client_configuration
node = [for k, v in var.node_data.controlplanes : k][0]
}
resource "talos_cluster_kubeconfig" "this" {
depends_on = [talos_machine_bootstrap.this]
client_configuration = talos_machine_secrets.this.client_configuration
node = [for k, v in var.node_data.controlplanes : k][0]
}
resource "local_file" "talosconfig" {
content = data.talos_client_configuration.this.talos_config
filename = "${path.module}/${var.cluster_name}/talosconfig"
}
resource "local_file" "kubeconfig" {
content = talos_cluster_kubeconfig.this.kubeconfig_raw
filename = "${path.module}/${var.cluster_name}/kubeconfig"
}
Ce fichier est entièrement dédié à l'interaction avec Talos lui-même, une fois que les VMs de base sont (ou sont en train d'être) créées par infra.tf. J'utilise ici le provider Terraform siderolabs/talos pour générer les configurations spécifiques à Talos, les appliquer aux nœuds, et finalement bootstrapper le cluster Kubernetes. C'est ici que la "magie" Talos opère.
-
resource "talos_machine_secrets" "this"
- Ce que ça fait : C'est la première étape essentielle pour Talos. Je demande au provider de générer tous les secrets cryptographiques nécessaires (certificats PKI, clés) pour sécuriser le cluster et les communications entre les nœuds et avec le client (
talosctl
). - Pourquoi : Talos est sécurisé par défaut et repose sur mTLS. Cette ressource gère toute la complexité de la génération de cette PKI.
- Ce que ça fait : C'est la première étape essentielle pour Talos. Je demande au provider de générer tous les secrets cryptographiques nécessaires (certificats PKI, clés) pour sécuriser le cluster et les communications entre les nœuds et avec le client (
-
data "talos_machine_configuration" "controlplane"
etdata "talos_machine_configuration" "worker"
- Ce que ça fait : Ces blocs ne créent rien sur les machines, ils utilisent des data sources du provider Talos pour générer les fichiers de configuration de base pour les control planes et les workers, mais en mémoire. C'est l'équivalent de ce que
talosctl gen config
ferait, mais intégré à Terraform. - Pourquoi : J'ai besoin d'une configuration standard pour chaque type de nœud, basée sur le nom du cluster (
var.cluster_name
), l'endpoint (j'utilise ici directement la VIP10.0.1.230
définie dansvars.tf
– assurez-vous qu'elle correspond à votrevar.vip
!), le type de machine (controlplane
ouworker
) et les secrets générés juste avant. - Dépendance : J'ai mis
depends_on = [numspot_load_balancer.load-balancer]
pour m'assurer que la génération de cette config (même si elle n'utilise pas directement le LB ici) n'ait lieu qu'après la création du LB, car les étapes suivantes vont utiliser les informations du LB.
- Ce que ça fait : Ces blocs ne créent rien sur les machines, ils utilisent des data sources du provider Talos pour générer les fichiers de configuration de base pour les control planes et les workers, mais en mémoire. C'est l'équivalent de ce que
-
data "talos_client_configuration" "this"
- Ce que ça fait : Génère, toujours en mémoire, la configuration client (
talosconfig
) nécessaire pour quetalosctl
(et le provider Terraform lui-même) puisse communiquer avec les nœuds Talos. - Pourquoi : Pour appliquer les configurations et lancer le bootstrap, le provider a besoin de savoir comment s'authentifier auprès des nœuds Talos.
- Comment : J'utilise le nom du cluster, la partie "client" des secrets générés, et je lui fournis la liste des IPs des control planes comme points d'accès initiaux (
endpoints
).
- Ce que ça fait : Génère, toujours en mémoire, la configuration client (
-
resource "talos_machine_configuration_apply" "controlplane"
etresource "talos_machine_configuration_apply" "worker"
- Ce que ça fait : C'est l'étape où j'applique effectivement la configuration sur chaque nœud (VM). Le provider Terraform se connecte à l'API Talos de chaque machine (sur le port 50000) en utilisant la configuration client générée, et lui envoie sa configuration.
- Comment : J'utilise
for_each
pour boucler sur les IPs définies dansvar.node_data
(comme pour la création des VMs). Pour chaque nœud (node = each.key
), je prends la configuration de base générée (machine_configuration_input
) et j'y ajoute des patchs (config_patches
). - Les Patchs (
config_patches
) : C'est là que je personnalise la configuration pour chaque nœud spécifique :- J'utilise
templatefile
pour lire un fichier modèle (templates/node-configuration.yaml.tmpl
) et y injecter des valeurs dynamiques :- Le
hostname
: soit celui défini dansvar.node_data
, soit un nom généré automatiquement (ex:numspot-talos-cp-0
). - Le disque d'installation (
install_disk
) pris depuisvar.node_data
. - La VIP (
var.vip
) pour les control planes (vide pour les workers). - L'IP publique (
public_ip
) et le nom DNS (dns_name
) récupérés depuis le Load Balancer NumSpot (via la source de donnéesdata.numspot_load_balancers.load-balancer
que j'avais définie dansinfra.tf
- c'est pour ça que la dépendance et la data source étaient importantes !).
- Le
- Pour les control planes, j'ajoute aussi un patch statique (
files/cp-scheduling.yaml
), qui contient probablement des configurations spécifiques aux CPs (peut-être pour autoriser l'exécution de pods dessus, ou définir des taints/labels).
- J'utilise
- Important : Ces blocs nécessitent que les fichiers
templates/node-configuration.yaml.tmpl
etfiles/cp-scheduling.yaml
existent aux chemins indiqués.
-
resource "talos_machine_bootstrap" "this"
- Ce que ça fait : Une fois que tous les control planes ont leur configuration appliquée, je déclenche le processus de bootstrap sur un seul des control planes. C'est l'équivalent de la commande
talosctl bootstrap
. - Pourquoi : Cette étape initialise le cluster etcd et démarre réellement le control plane Kubernetes.
- Comment : Je cible le premier control plane de ma liste (
[for k, v in var.node_data.controlplanes : k][0]
). - Dépendance :
depends_on = [talos_machine_configuration_apply.controlplane]
garantit que je n'essaie pas de bootstrapper avant que les CPs soient configurés.
- Ce que ça fait : Une fois que tous les control planes ont leur configuration appliquée, je déclenche le processus de bootstrap sur un seul des control planes. C'est l'équivalent de la commande
-
resource "talos_cluster_kubeconfig" "this"
- Ce que ça fait : Une fois le cluster bootstrappé, je demande à Talos (via le provider et en me connectant au premier control plane) de générer le fichier
kubeconfig
pour pouvoir interagir avec le cluster Kubernetes viakubectl
. - Pourquoi : C'est le sésame pour utiliser notre nouveau cluster !
- Dépendance :
depends_on = [talos_machine_bootstrap.this]
assure que le bootstrap est terminé.
- Ce que ça fait : Une fois le cluster bootstrappé, je demande à Talos (via le provider et en me connectant au premier control plane) de générer le fichier
-
resource "local_file" "talosconfig"
etresource "local_file" "kubeconfig"
- Ce que ça fait : Je prends les configurations client Talos (
talosconfig
) et Kubernetes (kubeconfig
) qui ont été générées par les ressources précédentes, et je les écris dans des fichiers locaux sur la machine où Terraform est exécuté. - Pourquoi : Pour que vous puissiez facilement utiliser
talosctl --talosconfig=./numspot-talos/talosconfig ...
etkubectl --kubeconfig=./numspot-talos/kubeconfig ...
après l'exécution de Terraform. - Comment : Je les sauvegarde dans un sous-dossier portant le nom du cluster (ex:
./numspot-talos/
).
- Ce que ça fait : Je prends les configurations client Talos (
3. Let's GO !
3.1 Terraform init
Lancez la commande :
terraform init
La commande terraform init
est la première étape fondamentale que vous devez exécuter lorsque vous commencez à travailler avec une nouvelle configuration Terraform ou lorsque vous modifiez certains aspects fondamentaux d'une configuration existante (comme les fournisseurs, les modules ou le backend).
Son rôle principal est de préparer ton répertoire de travail pour que Terraform puisse exécuter les autres commandes (plan
, apply
, destroy
, etc.).
Voici ce que terraform init
fait exactement :
-
Initialisation du Backend :
- Terraform lit le bloc
backend
(s'il existe) dans ta configuration (généralement dans un fichierterraform.tf
ouproviders.tf
). - Il configure la manière dont Terraform va stocker et accéder au fichier d'état (
terraform.tfstate
). Ce fichier est crucial car il contient la correspondance entre tes ressources Terraform et l'infrastructure réelle. - Si aucun backend n'est spécifié, il utilise le backend local par défaut (le fichier
terraform.tfstate
est stocké dans le même répertoire). - Si un backend distant est configuré (comme S3, Azure Blob Storage, Terraform Cloud, etc.),
init
vérifie la configuration et établit la connexion.
- Terraform lit le bloc
-
Téléchargement des Fournisseurs (Providers) :
- Terraform analyse tes fichiers de configuration (
.tf
) pour identifier tous les fournisseurs requis, déclarés dans les blocsrequired_providers
(commenumspot/numspot
ousiderolabs/talos
dans tes exemples). - Il se connecte au Registre Terraform (ou à une autre source spécifiée) pour trouver et télécharger le code exécutable (le plugin) de chaque fournisseur nécessaire, en respectant les contraintes de version que vous avez spécifiées (
version = ">= 1.0"
). - Ces plugins sont stockés localement dans un sous-répertoire caché nommé
.terraform/providers
. C'est ce code qui permet à Terraform de communiquer avec les API des différents services (NumSpot, Talos, AWS, etc.).
- Terraform analyse tes fichiers de configuration (
-
Installation des Modules :
- Si ta configuration utilise des modules (référencés via des blocs
module
),terraform init
va les télécharger ou les copier. - Les modules peuvent provenir de différentes sources :
- Registre Terraform
- Dépôts Git (comme GitHub)
- Chemins locaux sur ton disque dur
- Archives HTTP
- Buckets S3, GCS...
- Les modules téléchargés sont également stockés dans le répertoire
.terraform/modules
.
- Si ta configuration utilise des modules (référencés via des blocs
-
Initialisation des Modules Enfants :
- Si les modules que vous utilisez contiennent eux-mêmes des blocs
required_providers
ou référencent d'autres modules,terraform init
s'occupe de ces dépendances de manière récursive.
- Si les modules que vous utilisez contiennent eux-mêmes des blocs
Quand faut-il exécuter terraform init
?
- La première fois que vous clonez ou crées une configuration Terraform.
- Chaque fois que vous ajoutez ou supprimes un fournisseur.
- Chaque fois que vous ajoutez ou supprimes un module.
- Chaque fois que vous modifiez la configuration du backend.
- Il est souvent sûr et recommandé de l'exécuter si vous n'êtes pas sûr de l'état de ton répertoire de travail.
C'est une commande idempotente, ce qui signifie que vous ouvez l'exécuter plusieurs fois sans effet négatif ; elle ne refera que ce qui est nécessaire.
3.2 Terraform apply
lancez la commande
terraform apply
La commande terraform apply
est l'étape où vous concrétisez les changements décrits dans ta configuration Terraform. Après avoir potentiellement vérifié ce qui allait se passer avec terraform plan
, terraform apply
est la commande qui applique réellement ces changements à ton infrastructure réelle (sur NumSpot, Talos, etc.).
Voici ce que terraform apply
fait en détail :
-
Lecture de la Configuration : Comme
plan
, il lit tous tes fichiers.tf
dans le répertoire courant pour comprendre l'état désiré de ton infrastructure. -
Lecture de l'État Existant : Il lit le fichier d'état (
terraform.tfstate
, qu'il soit local ou distant via un backend) pour savoir quelles ressources Terraform gère déjà et comment elles sont configurées selon la dernière exécution réussie. -
Génération d'un Plan d'Exécution : Il compare l'état désiré (issu de ta configuration) avec l'état actuel (issu du fichier d'état et potentiellement en interrogeant les fournisseurs pour vérifier l'état réel des ressources). Sur la base de cette comparaison, il détermine les actions nécessaires :
- Créer de nouvelles ressources qui sont dans ta configuration mais pas dans l'état.
- Mettre à jour des ressources existantes dont la configuration a changé.
- Détruire des ressources qui sont dans l'état mais ne sont plus dans ta configuration.
-
Affichage du Plan et Demande de Confirmation :
- Terraform te montre le plan d'exécution qu'il vient de générer (exactement comme le ferait
terraform plan
). Il liste toutes les ressources qui seront créées, modifiées ou détruites, avec les détails des changements. - Ensuite, il te demande explicitement de confirmer que vous souhaitez appliquer ce plan en tapant
yes
. C'est une étape de sécurité cruciale pour éviter des modifications accidentelles.
- Terraform te montre le plan d'exécution qu'il vient de générer (exactement comme le ferait
-
Exécution des Actions (si confirmé) :
- Si vous tapez
yes
, Terraform commence à exécuter les actions listées dans le plan, dans l'ordre correct en respectant les dépendances entre les ressources. - Il communique avec les fournisseurs (NumSpot, Talos, etc.) via leurs API pour leur demander de créer, modifier ou supprimer les ressources réelles.
- Il affiche la progression de ces opérations en temps réel.
- Si vous tapez
-
Mise à Jour du Fichier d'État :
- Au fur et à mesure que les opérations réussissent, Terraform met à jour le fichier d'état (
terraform.tfstate
) pour refléter le nouvel état de l'infrastructure. Par exemple, si une nouvelle VM est créée, son ID unique fourni par NumSpot sera enregistré dans le fichier d'état. Cette mise à jour est essentielle pour que les prochaines exécutions de Terraform sachent ce qui existe réellement.
- Au fur et à mesure que les opérations réussissent, Terraform met à jour le fichier d'état (
-
Affichage des Sorties (Outputs) :
- Une fois toutes les actions terminées avec succès, Terraform affiche les valeurs des éventuelles sorties (
output
) que vous avez définies dans ta configuration (comme le chemin dukubeconfig
ou l'IP du load balancer dans tes exemples).
- Une fois toutes les actions terminées avec succès, Terraform affiche les valeurs des éventuelles sorties (
C'est la commande principale pour gérer le cycle de vie de ton infrastructure avec Terraform.
Option importante :
* terraform apply -auto-approve
: Permet de sauter l'étape de confirmation manuelle (yes
). À utiliser avec prudence, principalement dans des scripts d'automatisation (CI/CD) où un terraform plan
a déjà été validé au préalable.
3.3 Utilisation du cluster
L'apply est très rapide, par contre, la configuration sous-jacente de Talos peut être assez longue.
Donc comment contrôler que tout va bien !
- Dashboard Talos
Dans le répertoire numspot-talos
vous avez ces fichiers
- kubeconfig
- talosconfig
Exécutez la commande :
talosctl --talosconfig numspot-talos/talosconfig dashboard -n 10.0.1.234 -e 10.0.1.234
Vous pouvez faire cela sur l'ensemble des nœuds du cluster
- Accès à kubernetes
Rien de plus simple !
Exécutez la commande :
export KUBECONFIG=numspot-talos/kubeconfig
kubectl get nodes
kubectl get nodes
NAME STATUS ROLES AGE VERSION
numspot-talos-cp-0 Ready control-plane 3d1h v1.32.0
numspot-talos-cp-1 Ready control-plane 3d1h v1.32.0
numspot-talos-cp-2 Ready control-plane 3d1h v1.32.0
worker-1 Ready <none> 3d1h v1.32.0
worker-2 Ready <none> 3d1h v1.32.0
Si vous souhaitez utiliser le cluster avec l'API publique de votre loadbalancer
Modifiez dans le kubeconfig server: https://10.0.1.230:6443
en server: https://nlb001-CXXXX.cloudgouv-eu-west-1.lbu.outscale.com:6443
Retrouvez l'URL dans le portail Numspot
Pour que ça fonctionne il faut patcher le healthcheck du loadbalancer pour faire un ping TCP sur le port 6443.
Créez un script update-lb.sh avec le contenu suivant :
#!/bin/bash
# Il faudra adapter si vous avez plusieurs LB
source auth.sh
LBID=$(curl -s 'https://api.cloudgouv-eu-west-1.numspot.com/compute/spaces/A MODIFIER/loadBalancers' \
--request GET \
--header 'Content-Type: application/json' \
--header "Authorization: Bearer ${ACCESS_TOKEN}" | jq -r '.items[0].name')
curl -s "https://api.cloudgouv-eu-west-1.numspot.com/compute/spaces/A MODIFIER/$LBID" \
--request PUT \
--header 'Content-Type: application/json' \
--header "Authorization: Bearer ${ACCESS_TOKEN}" \
--data '{
"healthCheck": {
"checkInterval": 10,
"healthyThreshold": 3,
"port": 6443,
"protocol": "TCP",
"timeout": 5,
"unhealthyThreshold": 5
}
}'
4. Améliorations
Plein de choses à prévoir !
Ce POC est un quick and dirty pour montrer qu'il est tout à fait possible de créer son propre cluster Talos sur Numspot.
Il faudrait retravailler les configurations Terraform pour variabiliser les différents ID passés "en dur" !
5. Conclusions
NumSpot continue de gagner en maturité, offrant des solutions cloud souveraines de plus en plus robustes et adaptées aux besoins des entreprises. La plateforme propose une interface web intuitive, le portail, qui permet de gérer les ressources cloud de manière centralisée et sécurisée.
Ce portail est conçu pour évoluer progressivement, intégrant de nouvelles fonctionnalités d'observabilité et de gestion des opérations afin de fournir une vue unifiée des services déployés.
Par ailleurs, NumSpot adopte une approche « Infrastructure as Code » (IaC), offrant des interfaces standardisées compatibles avec des outils du marché tels que Terraform.
Cette compatibilité permet aux ingénieurs de définir et de gérer l'infrastructure informatique à l'aide de fichiers de script ou de code, facilitant ainsi l'automatisation des actions sur le cloud
Cependant, bien que ces avancées soient prometteuses, il est important de noter que le portail et le provider Terraform de NumSpot nécessitent encore des enrichissements pour exploiter pleinement toutes les fonctionnalités de l'API.
Découvrez les derniers articles d'alter way