Terraform et OpenTofu s'appliquent contre feint
sans compte cloud, sur les trois fournisseurs émulés. Vous changez une
ligne de configuration, le reste est le code que vous déploierez en production,
et un cycle apply puis destroy complet passe sans créer la moindre ressource
facturée. Cette page donne les blocs provider exacts pour Scaleway,
Outscale et Exoscale, et traite le cas du volume racine qui a
longtemps bloqué les configurations Scaleway.
Ce que vous allez obtenir
Section intitulée « Ce que vous allez obtenir »À la fin de cette page, un apply aura créé vos ressources sur les trois
fournisseurs, un second plan sera vide partout, et un destroy aura
tout nettoyé, sans qu'aucun compte cloud ne soit sollicité.
- Détourner le provider Scaleway avec un seul réglage,
api_url. - Piloter Outscale avec son bloc
api, dont le chemin complet est un piège. - Brancher Exoscale par variable d'environnement, avec un provider 0.71.0 ou plus récent.
- Écrire un
root_volumeque le provider accepte enfin.
Les trois fournisseurs se pilotent désormais par Terraform contre l'émulateur. Exoscale a rejoint les deux autres avec la version 0.71.0 de son provider ; les configurations écrites pour une version antérieure demandent une seule ligne de plus, et la section Exoscale explique laquelle. Chaque cas est traité ci-dessous.
Terraform sur Scaleway
Section intitulée « Terraform sur Scaleway »Le provider Scaleway se détourne avec un seul réglage, api_url. Le reste
de la configuration reste celle que vous écririez pour le vrai fournisseur, ce
qui est tout l'intérêt : vous testez le code que vous déploierez.
terraform { required_providers { scaleway = { source = "scaleway/scaleway" version = "~> 2.79" } }}
provider "scaleway" { access_key = "SCWXXXXXXXXXXXXXXXXX" secret_key = "11111111-1111-1111-1111-111111111111" project_id = "11111111-1111-1111-1111-111111111111" organization_id = "99999999-9999-4999-8999-999999999999" region = "fr-par" zone = "fr-par-1"
api_url = "http://127.0.0.1:4599"}
resource "scaleway_vpc" "lab" { name = "lab-feint"}
resource "scaleway_vpc_private_network" "lab" { name = "reseau-interne" vpc_id = scaleway_vpc.lab.id}
resource "scaleway_instance_server" "web" { name = "web-terraform" type = "DEV1-S" image = "ubuntu_jammy"}L'application se déroule sans adaptation particulière :
terraform initterraform apply -auto-approveApply complete! Resources: 3 added, 0 changed, 0 destroyed.
Outputs:
private_network_id = "fr-par/a0fa6f82-2aad-4f82-985a-2abeb65f05f7"server_id = "fr-par-1/d2303f04-8ab3-4e71-a682-ad91c81286b7"Les identifiants renvoyés portent le préfixe de région ou de zone, comme
chez Scaleway. Un terraform destroy fonctionne symétriquement, ce qui
permet de valider un cycle complet dans une CI sans créer la moindre
ressource facturée. Pour la construction des configurations elles-mêmes, la
section Terraform du site
couvre le sujet en profondeur.
Le volume racine, et le type qui planifie enfin
Section intitulée « Le volume racine, et le type qui planifie enfin »Le bloc root_volume accepte volume_type = "sbs_volume", et cela débloque
un vrai problème. Ce champ n'avait longtemps aucune valeur utilisable : le
provider refuse b_ssd d'emblée à partir de la 2.79, et sbs_volume planifiait
indéfiniment sans jamais s'appliquer.
resource "scaleway_instance_server" "web" { name = "web-block" type = "DEV1-S" image = "ubuntu_jammy"
root_volume { volume_type = "sbs_volume" size_in_gb = 20 }}Le disque est créé dans Block Storage, et le provider le relit par le
repli qu'il a toujours utilisé : instance.GetVolume d'abord, puis
block.GetVolume sur un 404 typé. L'apply aboutit et la sortie
renvoie bien sbs_volume.
Terraform sur Outscale
Section intitulée « Terraform sur Outscale »Le provider officiel outscale/outscale pilote l'émulateur de bout en bout,
avec un bloc api au lieu de l'argument api_url de Scaleway. La différence de
forme compte : ici l'adresse porte le chemin complet de l'API, segment de
version inclus.
terraform { required_providers { outscale = { source = "outscale/outscale" version = "~> 1.7" } }}
provider "outscale" { access_key_id = "AAAAAAAAAAAAAAAAAAAA" secret_key_id = "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
api { endpoint = "http://127.0.0.1:4599/api/v1" region = "eu-west-2" }}
resource "outscale_net" "lab" { ip_range = "10.70.0.0/16"
tags { key = "name" value = "lab-feint" }}
resource "outscale_subnet" "lab" { net_id = outscale_net.lab.net_id ip_range = "10.70.1.0/24"}
resource "outscale_vm" "web" { image_id = "ami-12345678" vm_type = "tinav4.c2r2p1" subnet_id = outscale_subnet.lab.subnet_id}Le cycle complet passe, y compris le second plan vide qui est le vrai révélateur d'une émulation correcte : si l'API renvoie ses ressources autrement qu'elle ne les a acceptées, Terraform propose une modification fantôme à chaque exécution.
outscale_net.lab: Creation complete after 0s [id=vpc-4e93695a]outscale_subnet.lab: Creation complete after 1s [id=subnet-348a9987]outscale_vm.web: Creation complete after 0s [id=i-ef8f6fe1]
Apply complete! Resources: 3 added, 0 changed, 0 destroyed.No changes. Your infrastructure matches the configuration.Terraform sur Exoscale
Section intitulée « Terraform sur Exoscale »Le provider officiel exoscale/exoscale pilote l'émulateur depuis sa version
0.71.0. Ce n'a pas toujours été le cas, et l'histoire vaut d'être connue parce
qu'elle explique le garde-fou qui subsiste. Jusqu'à cette version, le provider
construisait deux clients et un seul honorait EXOSCALE_API_ENDPOINT : la
moitié des appels partait vers le vrai cloud avec les identifiants trouvés
dans l'environnement, et un apply se retrouvait partagé entre l'émulateur et
un compte facturé. Un feint down lancé dans ce répertoire a ainsi envoyé
cinq requêtes signées vers les serveurs d'Exoscale. Le correctif est venu d'en
haut, dans la version 0.71.0 du
provider.
L'adresse voyage ici dans une variable d'environnement, jamais dans un
argument du bloc provider : Exoscale n'en déclare aucun. Le segment /v2
fait partie de la valeur, et l'oublier est l'erreur qui coûte le plus de temps.
export EXOSCALE_API_ENDPOINT='http://127.0.0.1:4599/v2'export EXOSCALE_API_KEY='EXOxxxxxxxxxxxxxxxxxxxx'export EXOSCALE_API_SECRET='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'export EXOSCALE_ZONE='ch-dk-2'Ces quatre lignes sont exactement ce que produit feint env exoscale, qui vous
évite de les écrire.
terraform { required_providers { exoscale = { source = "exoscale/exoscale" version = ">= 0.71.0" } }}Le plancher de version est appliqué, pas seulement recommandé. Un provider
antérieur à 0.71.0 est reconnu à son agent utilisateur et refusé par un 400
qui nomme la version à épingler, plutôt que de servir la moitié d'un apply.
{"message":"the Exoscale Terraform provider 0.62.0 only honours EXOSCALE_API_ENDPOINTfor half of its calls: the rest reach the real cloud and create billable resources.Upstream fixed that in v0.71.0; pin at least that version. feint refuses rather thanserve half an apply. See docs/limits.md."}Le refus porte donc sur une version, non plus sur un client, et deux choses
ont disparu avec l'ancien comportement. feint up ne s'arrête plus au seuil
quand une déclaration demande Terraform pour Exoscale : il n'y a plus de veto à
rencontrer. Et la variable d'échappement FEINT_EXOSCALE_ALLOW_TERRAFORM
n'existe plus, puisqu'elle n'a plus rien à lever.
À retenir
Section intitulée « À retenir »- Scaleway se détourne avec
api_url, Outscale avec un blocapidont le chemin porte/api/v1. - Le second plan vide est le vrai test : sans lui, l'émulation renvoie ses ressources autrement qu'elle ne les accepte.
- Exoscale se branche par
EXOSCALE_API_ENDPOINT, segment/v2compris, et exige un provider 0.71.0 ou plus récent : les versions antérieures sont refusées par agent utilisateur, parce qu'elles partageaient l'apply entre l'émulateur et un compte facturé. root_volumeacceptesbs_volume, ce qui débloque les configurations qui le déclarent.- Un cycle complet ne coûte rien :
apply, plan vide,destroy, sans ressource facturée.