hashicorp / terraform

Terraform enables you to safely and predictably create, change, and improve infrastructure. It is a source-available tool that codifies APIs into declarative configuration files that can be shared amongst team members, treated as code, edited, reviewed, and versioned.
https://www.terraform.io/
Other
41.66k stars 9.41k forks source link

PG Backend: Allow customizing name of created table or allow setting an index pre-/suffix #35320

Open deepbrook opened 3 weeks ago

deepbrook commented 3 weeks ago

Terraform Version

✦ 🐟 ❯ terraform version
Terraform v1.8.4
on linux_amd64

Use Cases

I want to store my terraform state files - from different configuration repositories - in a single PostgresDB instance, instead of having to create one database per configuration repo.

I cannot currently do this, as the created table by the pg backend is always named identically (states) and the statefiles always keyed using the terraform workspace; this leads to clashes when two configurations use the same workspace name - which is always the case, as all configurations start with a default workspace out of the box.

Attempted Solutions

The only viable solution at the moment is to never use the default workspace and make sure all other workspaces are prefixed with the configuration they belong to.

For example, repo-a and repo-b cannot both use the workspace prod - they must each name it repo-a-prod and repo-b-prod.

Proposal

The following solutions come to mind:

  1. Allow customizing the created table's name (currently it's always states), via attribute and environment variable (e.g. PG_CREATED_TABLE_NAME )
  2. Allowing the setting of an key prefix, which is pre-prended to the index key value used to store a statefile, via attribute or environment variable (e.g. PG_KEY_PREFIX)

Solution 1 is preferable imo, as it does not result in a single, potentially very cluttered table.

Example Config

Solution 1: Create a new table for the config's statefiles named a-custom-table-name and key the values using ${workspace} as the index key as before:

terraform {
  backend "pg" {
    table = "a-custom-table-name", // default to "state" if absent
  }
}

Solution 2: Add the statefile to the states table, adding statefiles using the key ${key_prefix}-${workspace}, e.g. config-name-default for the default workspace:

terraform {
  backend "pg" {
    key_prefix = "config-name", // default to "" if absent
  }
}

References

No response

crw commented 3 weeks ago

Thanks for the request! As an FYI, @remilapeyre is the code owner for the PG backend.