I'm setting up ephemeral review environments on GitLab MRs through Terraform and GitLab CI. I use Terraform Cloud as a backend. I want to create a workspace for each of the review env and do it dynamically based on some environment variables in GitLab CI.
My problem is that I cannot create a new Terraform Cloud workspace through the CLI without having an existing workspace first. It seems counterintuitive since I have no use of that workspace. If a workspace exist I can run terraform init
, then terraform workspace new
and the workspace is created in Terraform Cloud. If I don't create a workspace first init
doesn't work as no workspace exist and if I want to run terraform workspace new
before it yells because init
hasn't been run first. My configuration is:
terraform {
cloud {
organization = "my-org"
workspaces {
tags = ["review", "customer:test-frontend"]
}
}
}
I know I can create a workspace first through the API but that's cumbersome. I tried using TF_WORKSPACE
but it should point to an existing workspace which is not my case. My current solution is switching to:
terraform {
cloud {
organization = "my-org"
workspaces {
name = "<TF_WORKSPACE>"
}
}
}
Using sed
to replace that token with the dynamic name before calling terraform init
.
Is there a way to do it through the CLI? Am I missing something here?
Here is what I ended up doing. In my CI I do:
environments:
WORKSPACE: "${CI_PROJECT_NAME}_review_${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME}"
before_script:
- TF_WORKSPACE=empty-state-for-init terraform init -input=false
script:
- terraform workspace select $WORKSPACE || terraform workspace new $WORKSPACE
# then run terraform apply or whatever you want to do with your workspace
When I want to destroy my workspace and all associated infra, I do:
script:
- terraform workspace select $WORKSPACE
- terraform destroy -input=false -auto-approve
# We cannot delete a workspace if it's the current one
- terraform workspace select empty-state-for-init
- terraform workspace delete $WORKSPACE
In my projects, the Terraform configuration has:
terraform {
cloud {
organization = "my-org"
workspaces {
tags = ["review"]
}
}
}