"Variables may not be used here" during terraform init

Viewed 20832

I am using Terraform snowflake plugins. I want to use ${terraform.workspace} variable in terraform scope.

terraform {
  required_providers {
    snowflake = {
      source  = "chanzuckerberg/snowflake"
      version = "0.20.0"
    }
  }
  backend "s3" {
    bucket         = "data-pf-terraform-backend-${terraform.workspace}"
    key            = "backend/singlife/landing"
    region         = "ap-southeast-1"
    dynamodb_table = "data-pf-snowflake-terraform-state-lock-${terraform.workspace}"
  }
}

But I got this error. Variables are not available in this scope?

Error: Variables not allowed

  on provider.tf line 9, in terraform:
   9:     bucket         = "data-pf-terraform-backend-${terraform.workspace}"

Variables may not be used here.


Error: Variables not allowed

  on provider.tf line 12, in terraform:
  12:     dynamodb_table = "data-pf-snowflake-terraform-state-lock-${terraform.workspace}"

Variables may not be used here.
5 Answers
  • Set backend.tf

    terraform {
      backend "azurerm" {}
    }
    
  • Create a file backend.conf

    storage_account_name = "deploymanager"
    container_name       = "terraform"
    key                  = "production.terraform.tfstate"
    
  • Run:

    terraform init -backend-config=backend.conf
    

The terraform backend docs state:

A backend block cannot refer to named values (like input variables, locals, or data source attributes).

However, the s3 backend docs show you how you can partition some s3 storage based on the current workspace, so each workspace gets its own independent state file. You just can't specify a distinct bucket for each workspace. You can only specify one bucket for all workspaces, but the s3 backend will add the workspace prefix to the path:

When using a non-default workspace, the state path will be /workspace_key_prefix/workspace_name/key (see also the workspace_key_prefix configuration).

And one dynamo table will suffice for all workspaces. So just use:

  backend "s3" {
    bucket         = "data-pf-terraform-backend"
    key            = "terraform.tfstate"
    region         = "ap-southeast-1"
    dynamodb_table = "data-pf-snowflake-terraform-state-lock"
  }

And switch workspaces as appropriate before deployments.

But how is Jhonny's answer any different? You still cannot put variables in backend.conf, which was the initial question.

Initializing the backend...
╷
│ Error: Variables not allowed
│
│   on backend.conf line 1:
│    1: bucket  = "server-${var.account_id}"
│
│ Variables may not be used here.

The only way for now is to use a wrapper script that provides env variables, unfortunately.

Check Jhonny's solution first:

(keeping this one for historical reference)


Seems like a specific instance of a more common problem in Terraform: Concatenating variables.

Using locals to concatenate should fix it. See https://www.terraform.io/docs/configuration/locals.html

An example from https://stackoverflow.com/a/61506549/132438:

locals {
  BUCKET_NAME = [
    "bh.${var.TENANT_NAME}.o365.attachments",
    "bh.${var.TENANT_NAME}.o365.eml"
  ]
}

resource "aws_s3_bucket" "b" {
  bucket = "${element(local.BUCKET_NAME, 2)}"
  acl    = "private"
}
Related