Firstlume Docs firstlume.io ENPT PT Talk to us

State backend

Firstlume is the state backend of your stacks. It uses the http backend of Terraform and OpenTofu, with no plugin. Your code declares the backend, and Firstlume fills in the address and the credential on each run.

terraform {
  backend "http" {}
}

In every run, the executor exports TF_HTTP_ADDRESS, TF_HTTP_LOCK_ADDRESS, TF_HTTP_UNLOCK_ADDRESS, TF_HTTP_USERNAME and TF_HTTP_PASSWORD, so nothing about the backend appears in your code.

With Terragrunt

In Terragrunt, each unit has its own state. The root.hcl builds each unit's address from FIRSTLUME_STATE_URL:

remote_state {
  backend  = "http"
  generate = { path = "backend.tf", if_exists = "overwrite_terragrunt" }
  config = {
    address        = "${get_env("FIRSTLUME_STATE_URL")}/${path_relative_to_include()}"
    lock_address   = "${get_env("FIRSTLUME_STATE_URL")}/${path_relative_to_include()}"
    unlock_address = "${get_env("FIRSTLUME_STATE_URL")}/${path_relative_to_include()}"
  }
}

A unit's key is its relative path, such as net or zone-a/node01. A plain Terraform stack has a single state at the root.

How it behaves

  • Lock per unit. In a run --all, each unit writes its state when its own apply finishes. If one unit fails, the others stay saved.
  • Plan doesn't write. The credential of the plan phase, and of drift, can only read and lock the state. Only the apply writes.
  • Versions. Each write becomes an immutable version, encrypted with a key of its own. Writes that would lose state (a lower serial, or the lineage of another infrastructure) are refused.
  • A run's locks are released when the phase ends, however it ends.
  • A stack with resources in its state can't be deleted. Run a destroy or delete the state first, with DELETE /api/v1/orgs/{org}/stacks/{id}/state and the stack's name in the body as {"confirm": "<name>"}. Deleted state is kept for 30 days.

Code with no backend fails at Init. Its state would stay on the runner's disk and be lost. With run --all, where Terragrunt initializes units during the plan, it fails at the end of the Plan step. The message names the unit.

Code with another backend keeps working. With s3, for example, Firstlume's variables are ignored and the state stays where your code puts it.

More on state

The State tab in the UI, with versions, diff, rollback and forced unlock, is planned. Today the run page shows the backend each unit used, and the stack's Resources tab lists what is in the current state, with no attribute values.