Guide Terraform
Découvrez comment utiliser les providers Terraform OpenStack et AWS sur SNC Cloud Platform, de l'authentification par clouds.yaml au stockage compatible S3
Objectif
Guide pratique pour utiliser le provider terraform-provider-openstack/openstack (et le provider aws reconfiguré pour l'Object Storage compatible S31) sur cette plateforme. Public cible : DevOps/SRE déjà familiers de Terraform.
Vue d'ensemble
La plateforme expose une API OpenStack standard (Keystone, Nova, Neutron, Cinder, Glance, Placement) accessible via le provider Terraform officiel terraform-provider-openstack/openstack, plus un endpoint Object Storage compatible S3 (Ceph RGW ou équivalent) qui se pilote via le provider hashicorp/aws reconfiguré sur un endpoint personnalisé. Il n'existe pas de provider Terraform dédié compatible S3 : c'est le modèle standard pour ce type de plateforme.
Prérequis
- Disposer de Terraform
>= 1.5(>= 1.10pour le backend distant avec verrou S3 natif, reportez-vous à la section « Workflow recommandé »). - Disposer d'un fichier
clouds.yamlavec un application credential (pas d'identifiant/mot de passe classique). - Pour l'Object Storage : disposer d'un couple clé d'accès / clé secrète compatible S3, distinct du
clouds.yaml.
L'application credential se récupère dans le manager, via le lien Get your Application Credentials de la section API Access & Documentation du tableau de bord :

Puis dans API access > Application credentials, où vous pouvez télécharger directement un clouds.yaml prêt à l'emploi ou créer un nouvel application credential :

En pratique
Authentification & configuration des providers
OpenStack
Le provider lit clouds.yaml via les variables d'environnement standard openstacksdk — aucun secret en dur dans les fichiers .tf :
OS_CLIENT_CONFIG_FILE est nécessaire si clouds.yaml ne se trouve pas dans le répertoire courant, ~/.config/openstack/ ou /etc/openstack/ — c'est le cas la plupart du temps dans un dépôt versionné, où le fichier est stocké à un emplacement dédié pour pouvoir être facilement exclu du contrôle de version.
Object Storage compatible S3
Les 3 skip_* sont indispensables : le provider aws tente par défaut de valider la région et le compte auprès d'IAM/STS AWS, qui n'existent pas ici. Sans ces paramètres, terraform plan échoue avant même de toucher au bucket.
s3_access_key, s3_secret_key et s3_endpoint_url se récupèrent dans le manager, sur la page Object Storage > Connect :

La clé secrète n'est affichée qu'une seule fois, à la création de la clé d'accès — si elle est perdue, supprimez la clé d'accès et créez-en une nouvelle.
Spécificités de la plateforme à connaître avant de commencer
Ces points ne figurent pas dans la documentation générique du provider — ils sont propres à cette plateforme.
1. Pas de floating IP / routeur Neutron
Le service floating IP sera disponible à partir de la version majeure n° 2 de la plateforme. En attendant, les instances exposées publiquement obtiennent leur IP via une deuxième interface réseau attachée directement au réseau externe partagé Ext-Net, qui leur fournit une IP publique fixe :
access_network = true indique explicitement au provider quelle interface doit alimenter l'attribut calculé access_ip_v4 — sans lui, le choix entre plusieurs interfaces n'est pas garanti.
Cette interface Ext-Net, ici créée implicitement par le provider, a un comportement à connaître : le port Neutron sous-jacent est supprimé automatiquement si l'instance est détruite, ce qui libère l'IP publique dans le pool (rien ne garantit qu'elle soit réattribuée à la prochaine instance). Le guide « Gestion des IP publiques » détaille comment créer ce port indépendamment de l'instance pour pouvoir conserver la même adresse publique d'une instance à l'autre.
2. Tous les flavors ont un disque racine de 0 Go
Conséquence directe : démarrer une instance avec uniquement image_id échoue avec Only volume-backed servers are allowed for flavors with zero disk. Il faut systématiquement un block_device avec destination_type = "volume", qui crée un volume Cinder de démarrage à partir de l'image :
volume_size doit être strictement supérieur à la taille virtuelle de l'image (virtual_size côté Glance), pas à sa taille compressée sur disque. Une image annoncée à quelques centaines de Mo peut avoir une taille virtuelle de 15-20 Go une fois décompressée — sous-dimensionner le volume produit l'erreur Image virtual size is XGB and doesn't fit in a volume of size YGB.
3. Réutiliser les ressources existantes via des data sources
Les images système (Debian 13, AlmaLinux 10, etc.) et le réseau externe sont déjà présents sur le projet — ne les recréez pas :
Modèles de ressources
Groupe de sécurité à accès restreint
Modèle recommandé pour limiter l'exposition à des plages d'IP connues (réseau interne, VPN) plutôt qu'à 0.0.0.0/0, sans dupliquer une règle par port × CIDR à la main :
setproduct() génère le produit cartésien port × CIDR ; la clé de for_each ("${port}-${cidr}") garantit un state Terraform stable même si l'ordre des listes change — indispensable pour éviter des destroy/create en cascade sur un simple réordonnancement.
Compute : clé SSH générée par Terraform
Pas besoin de gérer une paire de clés séparément — le provider tls en génère une, stockée dans le state (à protéger comme un secret) :
Object Storage compatible S3
Une fois le provider aws reconfiguré (voir plus haut), les ressources standard fonctionnent normalement :
Secrets et données sensibles
- Déclarez toute variable portant un secret (application credential, clé S3, mot de passe) avec
sensitive = true— Terraform masque sa valeur dans les logs deplan/apply, mais elle reste en clair dans le state. Un backend distant chiffré (ou a minima un state local exclu du contrôle de version) est indispensable dès que le projet dépasse l'usage individuel. terraform.tfvarscontenant les valeurs réelles doit être exclu du contrôle de version (.gitignore), tout commeclouds.yaml.
Piège avec bcrypt() : la fonction native Terraform bcrypt(string) génère un sel aléatoire à chaque évaluation. Si vous l'appelez directement dans une ressource (ex. un Caddyfile généré via templatefile() et embarqué dans un user_data), le hash change à chaque plan, ce qui force un remplacement de l'instance à chaque exécution — même sans aucun changement réel. Précalculez le hash une fois (en dehors de Terraform, ou via un script d'implémentation) et passez-le comme valeur statique d'une variable sensitive pour éviter ce problème.
Bootstrap applicatif via user_data / cloud-init
Modèle pour embarquer une application complète (code, configuration, service systemd) de façon déclarative, sans provisioner SSH séparé :
Le template cloud-init utilise write_files (avec encoding: b64 pour le contenu binaire/encodé) et runcmd pour installer et démarrer les services.
Piège d'ordonnancement : si un fichier de configuration personnalisé écrase un conffile d'un paquet APT pas encore installé (ex. écrire /etc/caddy/Caddyfile avant apt-get install caddy), dpkg détecte un conflit et affiche une invite interactive. Sous cloud-init, il n'y a pas de TTY : dpkg échoue donc silencieusement, ce qui peut empêcher le postinst du paquet de s'exécuter correctement (ex. un utilisateur système n'est jamais créé). Installez toujours le paquet avant d'écraser ses fichiers de configuration, en copiant le fichier personnalisé dans un runcmd après l'installation plutôt que via write_files directement à l'emplacement final.
Workflow recommandé
terraform validatene fait aucun appel réseau : lancez-le systématiquement avantplan.- Relisez toujours un
planavantapply, en particulier le nombre de ressources détruites — un changement anodin dans untemplatefile()(ex. le contenu deuser_data) force le remplacement complet de l'instance. - Un state local (
terraform.tfstate) est adapté à un usage individuel/exploratoire. Pour un usage en équipe, migrez vers un backend distant sur ce même endpoint compatible S3, comme décrit dans le guide « Utiliser OVHcloud Object Storage comme Backend Terraform pour stocker votre état (state) Terraform », avec le verrou natif activé :
Pièges connus (dépannage)
Aller plus loin
Documentation officielle : terraform-provider-openstack, provider AWS, provider TLS.
Pour une formation ou une assistance technique sur la mise en œuvre de nos solutions, contactez votre commercial ou consultez la page Professional Services pour obtenir un devis et faire analyser votre projet par nos experts.
Échangez avec notre communauté d'utilisateurs.
1 : S3 est une marque déposée appartenant à Amazon Technologies, Inc. Les services OVHcloud ne sont pas sponsorisés, approuvés, ou affiliés de quelque manière que ce soit.