Use this model when your repositories already declare a backend that must keep working: the same state then serves Kumoss, your CI, and your engineers' laptops. Kumoss writes no backend configuration and reads the repository’s block as committed.
|
While Kumoss-managed state is on, which is the shipped default, the
repository’s backend block is ignored: the core’s
|
Prerequisites
-
Every repository Kumoss operates on declares a remote backend (
azurerm,s3,gcs, or any other the engine supports). Without one, the engine falls back to local state, which is lost with the workspace. -
An identity for the IaC sidecar that can read and write that state store.
-
IAC_BACKEND_CONFIGunset inservices/iac/.env. If it is set, you are in the Sidecar-supplied backend model instead.
Steps
-
Turn Kumoss-managed state off in
config.yamlwith an explicit empty string. Deleting the key does not turn it off (see Turn managed state off):storage: terraform_state_bucket: ""Rebuild the core so the baked-in configuration changes:
docker compose build core && docker compose up -d coreNo state bucket is created at boot, and no
backend_override.tfis written from now on. -
Make sure the repository declares its backend, and give the IaC sidecar the credentials to reach it in
services/iac/.env:terraform { backend "azurerm" { subscription_id = "_STATE_SUBSCRIPTION_ID_" resource_group_name = "tfstate-rg" storage_account_name = "acmetfstate" container_name = "tfstates" key = "platform.tfstate" use_azuread_auth = true } }# services/iac/.env ARM_TENANT_ID=_TENANT_ID_ ARM_CLIENT_ID=_CLIENT_ID_ ARM_CLIENT_SECRET=_CLIENT_SECRET_ ARM_USE_AZUREAD=trueGrant the service principal Storage Blob Data Contributor on the storage account or on the
tfstatescontainer.-
Keep
subscription_idin the block.initruns withARM_SUBSCRIPTION_IDset from the request’s cloud scope, so without it the backend looks for the storage account in the workload’s subscription and fails when the two differ. -
Without
use_azuread_auth, the backend fetches the account key through the management plane, which needslistKeys(Contributor, or Storage Account Key Operator) rather than a blob data role. -
To use the account key instead of RBAC, set
ARM_ACCESS_KEYto it and dropuse_azuread_auth.
terraform { backend "s3" { bucket = "acme-team-tfstate" key = "envs/prod/terraform.tfstate" region = "eu-west-1" use_lockfile = true } }# services/iac/.env AWS_ACCESS_KEY_ID=_ACCESS_KEY_ID_ AWS_SECRET_ACCESS_KEY=_SECRET_ACCESS_KEY_The identity needs
s3:ListBucketon the bucket ands3:GetObject,s3:PutObject, ands3:DeleteObjecton<bucket>/*. When the state bucket lives in another account, setAWS_PROFILEorAWS_ROLE_ARNto an identity in that account.terraform { backend "gcs" { bucket = "acme-team-tfstate" prefix = "envs/prod" } }# services/iac/.env GOOGLE_APPLICATION_CREDENTIALS=/etc/kumoss/gcp-sa.json # Optional, when state uses a different identity than the providers: # GOOGLE_BACKEND_CREDENTIALS=/etc/kumoss/gcp-state-sa.jsonThe identity needs Storage Object Admin on the bucket.
Per-authentication-method variable sets (OIDC, managed identity, profiles, and local CLI logins) are in Backend minimums.
-
-
Restart the sidecar so it reads the new variables:
docker compose up -d iac
Verify
To check all three layers in a deployed environment, see Find the active state.
-
Run a session against the repository, then confirm that the core wrote no override. This command must print nothing:
docker compose logs core | grep "Terraform state:" -
In the session’s
initoutput, check that the engine bound the repository’s backend, for exampleSuccessfully configured the backend "azurerm"!, and that the first plan shows your existing resources as unchanged rather than to be created.
Two sets of credentials on the sidecar
services/iac/.env must satisfy two different authentications. A setup
that only covers the first fails at init, before a single resource is
planned:
| What | Used by | Grants access to |
|---|---|---|
Provider credentials |
|
The cloud resources your modules create |
State-backend credentials |
|
The state store the repository’s backend block names |
Often the same variables serve both (an s3 backend and the aws
provider both read AWS_ACCESS_KEY_ID), but the identity behind them
must still be granted access to the state store, which commonly lives in
a different account, subscription, or project. Some backends read
variables the providers never look at, so the two identities can differ:
| Backend | Backend-only variables |
|---|---|
|
|
|
|
|
|
Kumoss-managed state can spare you the second set: where the core embeds static keys in the override, the sidecar needs nothing for state. See Credentials required.
Next steps
-
Change models safely: move state Kumoss already stored into your own backend.
-
Cloud credentials for the IaC engine: every variable the sidecar passes to the engine.