Problem
When performing a run in Terraform Enterprise using the remote backend, Terraform workspaces may be active in the local context. However, when the run occurs remotely in Terraform Enterprise, the name of the local Terraform workspace is not currently preserved. Therefore, attempts to interpolate ${terraform.workspace}
in Terraform Enterprise will always yield default
.
Cause
The terraform.workspace
interpolation has different values depending on where terraform is run and how the remote
backend is configured.
When the remote
backend is configured using the name
option rather than the prefix
option, Terraform CLI workspaces are effectively unsupported and disabled. This can be seen locally by configuring remote
with name
and then attempting to create a workspace with terraform workspace new foo
. Since workspaces are unsupported, the terraform.workspace
interpolation is always the value default
.
When the remote
backend is configured with the prefix
option instead, workspaces are supported. With a prefix foo-
, a new Terraform CLI workspace bar
will be created with terraform workspace new bar
. In this case the TFE workspace name will be foo-bar
, and locally the terraform.workspace
interpolation will produce bar
- the workspace name without the prefix
value.
In TFE, the backend configuration is always overridden. This ensures that the TFE remote state storage backend for that workspace is always used regardless as to any other backend present in the configuration. The backend override is the remote backend with the name
option, therefore the value of terraform.workspace
is always default
.
Unfortunately it’s possible to have a configuration locally with a workspace bar
, a TFE workspace name of foo-bar
, and the terraform.workspace
produce the value default
.
Solution
There are some alternative approaches to consider.
- By creating a variable named
workspace
and set it on the Variables page per workspace. - Alternatively, by using an environment variable that is present in the Terraform worker container and having it set locally to match in, the event that a local-only run (not using the remote backend) is needed.
There is a variable available in TFE that will work for this purpose. At times it is informative to check the container used in TFE to see what is set and what the container layout is like. Here is the output of env
run from a null_resource
in a local-exec
provisioner (and trimmed for readability):
Executing: ["/bin/sh" "-c" "env"]
ATLAS_RUN_ID=run-nsYMgVXgwWDeZazK
TF_VAR_ATLAS_CONFIGURATION_SLUG=randomalias/tfe_demo
MAIL=/var/mail/terraform
SSH_CLIENT=192.168.126.1 54920 22
USER=terraform
LANGUAGE=en_US:
TF_INPUT=0
SHLVL=1
ATLAS_WORKSPACE_NAME=tfe_demo
HOME=/home/terraform
OLDPWD=/home/terraform
TF_X_SHADOW=0
TF_VAR_ATLAS_CONFIGURATION_NAME=tfe_demo
LOGNAME=terraform
TF_VAR_ATLAS_WORKSPACE_SLUG=randomalias/tfe_demo
_=/usr/bin/envdir
ATLAS_CONFIGURATION_SLUG=randomalias/tfe_demo
XDG_SESSION_ID=2
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
TF_VAR_ATLAS_ADDRESS=https://app.terraform.io
ATLAS_TOKEN=<redacted>
XDG_RUNTIME_DIR=/run/user/500
TF_VAR_ATLAS_RUN_ID=run-nsYMgVXgwWDeZazK
TF_APPEND_USER_AGENT=TFE/abcd623
LANG=en_US
cccf35992f8f3cd8d1d28f0109dd953e26664531=7c28215aca87789f95b406b8dd91aa5198406750
SHELL=/bin/bash
TF_VAR_ATLAS_WORKSPACE_NAME=tfe_demo
TF_VAR_TFE_RUN_ID=run-nsYMgVXgwWDeZazK
ATLAS_CONFIGURATION_NAME=tfe_demo
PLUGIN_MIN_PORT=10000
ATLAS_WORKSPACE_SLUG=randomalias/tfe_demo
PLUGIN_MAX_PORT=25000
CHECKPOINT_DISABLE=1
TERRAFORM_CONFIG=/tmp/cli.tfrc
PWD=/terraform
SSH_CONNECTION=192.168.126.1 54920 192.168.126.163 22
TF_IN_AUTOMATION=1
TF_FORCE_LOCAL_BACKEND=1
ATLAS_ADDRESS=https://app.terraform.io
TFE_RUN_ID=run-nsYMgVXgwWDeZazK
TF_PLUGIN_MAGIC_COOKIE=<redacted>
The Environment Variable is called TF_VAR_ATLAS_WORKSPACE_NAME=tfe_demo
. This naming follows the convention needed for setting Terraform variables via environment variables:
https://www.terraform.io/docs/configuration/environment-variables.html#tf_var_name
To make this variable available in your Terraform configuration, declare it as:
variable "ATLAS_WORKSPACE_NAME" {}
Then it should be possible to use it in the configuration:
variable "ATLAS_WORKSPACE_NAME" {}
resource "null_resource" "n" {}
output "workspace" { value = "${var.ATLAS_WORKSPACE_NAME}" }
...
Outputs:
workspace = tfe_demo
Additional Information
Please note that this is an implementation detail of TFE and is likely to change, if for no other reason, due to the use of the term ATLAS
.