Kumoss

Sidecar-supplied backend

Hand the IaC sidecar a mounted backend configuration file so the deployment owns the backend decision centrally.

Use this model when the platform team, not each repository, decides where state goes. The IaC sidecar passes a backend configuration file to every init as -backend-config=<file>, and its values override the repository’s backend block key by key.

Prerequisites

  • Kumoss-managed state turned off with storage.terraform_state_bucket: "" (see Turn managed state off). Combined with managed state, the file merges into the core’s override and produces a backend neither side fully describes (see Which value wins).

  • Every repository declares the backend type, even with an empty body, for example terraform { backend "azurerm" {} }. A file holds values only and cannot introduce a backend where none is declared.

  • An identity for the IaC sidecar that can read and write the state store. The file carries no credentials; see the two credential grants.

Steps

  1. Write the backend values as a .hcl or .tfbackend partial configuration:

    # backend.hcl
    subscription_id      = "_STATE_SUBSCRIPTION_ID_"
    resource_group_name  = "tfstate-rg"
    storage_account_name = "acmecentraltfstate"
    container_name       = "tfstates"
    use_azuread_auth     = true
    # backend.hcl
    bucket       = "acme-central-tfstate"
    region       = "eu-west-1"
    use_lockfile = true

    Leave key out of a file every repository shares. key is a single value, so a shared file that sets it makes every project share one state object. Let each repository declare its own key in its backend block; per-project keys are only automatic under Kumoss-managed state.

  2. Mount the file into the sidecar and point IAC_BACKEND_CONFIG at it:

    # docker-compose.override.yml
    services:
      iac:
        volumes:
          - ./backend.hcl:/etc/kumoss/backend.hcl:ro
    # services/iac/.env
    IAC_BACKEND_CONFIG=/etc/kumoss/backend.hcl

    An absolute path resolves inside the sidecar container. A relative path resolves against the workspace, which is how a file carried by the target repository is reached. The file must be readable by uid 10001 (kumoss), the user the image runs as. An empty or whitespace-only value counts as unset.

  3. Restart the sidecar:

    docker compose up -d iac

    The sidecar does not check the path at startup: a workspace-relative file exists only after the clone. A wrong path surfaces as an init failure on the first job, in that job’s stderr rather than in the container’s startup log.

Verify

To check all three layers in a deployed environment, see Find the active state.

  1. Run a session, then confirm that the core wrote no override. This command must print nothing:

    docker compose logs core | grep "Terraform state:"
  2. In the session’s init output, check that the engine bound the backend from the file, for example Successfully configured the backend "azurerm"!, and that the state object appears under the key the repository declares.

Next steps