Terraform and variables in resource names


I have some config has a variable id which represents a tenant in my future product. I niavely was planning on doing something like this:
terraform apply -var=“tenant=1”
terraform apply -var=“tenant=2”

However, obviously the 2nd run assumes that im just renaming resources and so wants to delete tenant 1s resources!

How can I achieve what I want - which is it to be able to parameterise the creation of different tenants infrastructure?

Do I need to have a “Terraform” environment per tenant?


Hi @listentorick,

There are two main options for this. What the two options have in common is that they cause Terraform to use a separate state for each tenant. Where they differ is in how the differences between the tenants (in your case, it sounds like that’s just the tenant number) are represented.

The most general solution is to consider the configuration you’ve written so far as a shared Terraform module and then write a new configuration for each tenant that calls that module. You can then put the values that differ between tenants inside the module block when calling the shared module:

module "tenant" {
  source = "../../modules/tenant"

  tenant = 1

The above approach is the most flexible in that you can use a variety of variables to allow for configuration differences between tenants and then put those differences under version control with a separate little configuration per tenant.

If only an identifier differs between tenants though, a lower-overhead way to accomplish this is via multiple workspaces, named using a predictable naming scheme. Terraform makes the current namespace name available as terraform.workspace, so you can use that to automatically populate a suitable tenant identifier for use elsewhere in the configuration:

locals {
  tenant = tonumber(regex("^tenant(\d+)", terraform.workspace)[0])

The above expects workspace names that are the literal prefix tenant followed by the tenant id digits. You can create such workspaces like this:

terraform workspace new tenant1
terraform workspace new tenant2

Use local.tenant in your configuration anywhere you need to distinguish something by tenant either for tagging or namespaceing reasons.

Now you can switch between them using terraform workspace select:

terraform workspace select tenant1

Other commands like terraform apply will then act on the currently-selected workspace. At a high level, a Terraform workspace is a bit like a git branch in that you can switch your local working directory between workspaces without affecting anyone else’s selected workspace. Whereas each git branch refers to its latest commit, each Terraform workspace refers to its latest state snapshot.

Unlike git branches, Terraform Workspaces do not have a common history up to some divergence point: instead, each new workspace starts with an empty state snapshot and so the first terraform apply in a new workspace will plan to create all of the objects described in the configuration.

1 Like