Cette page existe aussi en français
Terraform and OpenTofu apply against feint
with no cloud account, on two of the three emulated providers. You change one
configuration line, the rest is the code you will deploy in production, and a
full apply then destroy cycle passes without creating a single billed
resource. This page gives the exact provider blocks for Scaleway and
Outscale, explains why the Exoscale provider is refused, and covers the
root volume case that blocked Scaleway configurations for a long time.
What you will learn
- Redirect the Scaleway provider with a single setting,
api_url. - Drive Outscale with its
apiblock, whose full path is a trap. - Understand the Exoscale refusal, and what it protects.
- Write a
root_volumethe provider finally accepts.
Terraform on Scaleway
The Scaleway provider is redirected with a single setting, api_url. The
rest of the configuration stays what you would write for the real provider,
which is the whole point: you test the code you will deploy.
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_instance_server" "web" { name = "web-terraform" type = "DEV1-S" image = "ubuntu_jammy"}The apply needs no adaptation:
Apply 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"The returned identifiers carry the region or zone prefix, as Scaleway does.
A terraform destroy works symmetrically, which lets you validate a full
cycle in CI without creating a single billed resource.
The root volume, and the type that finally plans
Since 0.8.0, root_volume { volume_type = "sbs_volume" } is honoured, and
that unblocks a real problem. Before it, the field had no usable value at all:
the provider refuses b_ssd outright from 2.79 on, and sbs_volume planned for
ever without ever applying.
resource "scaleway_instance_server" "web" { name = "web-block" type = "DEV1-S" image = "ubuntu_jammy"
root_volume { volume_type = "sbs_volume" size_in_gb = 20 }}The disk is created in Block Storage, and the provider reads it back through
the fallback it always used: instance.GetVolume first, then block.GetVolume
on a typed 404. The apply completes and the output returns sbs_volume.
Terraform on Outscale
The official outscale/outscale provider drives the emulator end to end,
with an api block instead of Scaleway's api_url argument. The difference in
form matters: here the address carries the full API path, version segment
included.
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}The full cycle passes, including the empty second plan, which is the real test of a correct emulation: if the API returns its resources in a different shape than it accepted them, Terraform proposes a phantom change on every run.
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.Why the Exoscale Terraform provider is refused
feint refuses calls from the Exoscale Terraform provider, and answers 400 with the explanation. This is not a gap, it protects your invoice.
{"message":"the Exoscale Terraform provider only honours EXOSCALE_API_ENDPOINTfor half of its calls: the rest reach the real cloud and create billableresources. feint refuses rather than serve half an apply. SetFEINT_EXOSCALE_ALLOW_TERRAFORM=1 if you understand that and want the half it canserve. See docs/limits.md."}The cause is measured: that provider honours the endpoint for only part of its
calls, and the rest reach the real cloud with whatever credentials the
environment holds. An apply would therefore be split between the emulator and
a paying account, and a half success is indistinguishable from normal
operation until the invoice arrives. Refusing early and loudly is the only
honest behaviour.
The escape hatch exists, named rather than hidden, for anyone accepting that split knowingly:
FEINT_EXOSCALE_ALLOW_TERRAFORM=1 feint serveThe exo CLI is unaffected: detection matches the Exoscale-Terraform-Provider
user agent alone, so it refuses one client, not a provider.
Key points
- Scaleway is redirected with
api_url, Outscale with anapiblock whose path carries/api/v1. - The empty second plan is the real test: without it, emulation returns resources differently than it accepts them.
- The Exoscale provider is refused with a 400: it would split the apply between the emulator and a billed account.
root_volumeacceptssbs_volumesince 0.8.0, which unblocks configurations that declare it.- A full cycle costs nothing:
apply, empty plan,destroy, with no billed resource.