-
Notifications
You must be signed in to change notification settings - Fork 9.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make Terraform workspaces explicit #17185
Comments
Hi @marco-m! Thanks for this feature request. The current usage model for workspaces was modeled after git branches, with We're generally cautious about adding more variants and options to the core workflow, since it increases the surface area of things to learn when new users come to Terraform, and hurts people's ability to transfer their Terraform skills from project to project, and company to company. However, I do see the use-case here and would like to think for a while about whether there's a different way we could meet this need without adding a new option, or changing the primary workflow. In the mean time, you may be able to achieve something like what you want here by creating a Terraform wrapper script. A number of teams use this to impose additional constraints on workflow, and it's often a good stepping-stone towards running Terraform inside a CI system or other automation. Terraform supports a export TF_WORKSPACE=determine_workspace_from_args_somehow()
terraform apply I understand that this doesn't fully meet your goals here, since there is nothing stopping a user from directly running Teams that need to create a reliable audit trail around Terraform changes often create a more regimented workflow with VCS commits triggering Terraform to run in a CI or other automation system. That way, all actions are serialized and tracked in a central location (in the CI system) rather than across potentially many personal shell histories, and each change can be easily mapped back to the git commit for the configuration that triggered it. This also has other benefits for a production environment, such as managing any necessary credentials centrally within the CI system where it's more straightforward to implement best-practices such as time-limited, restricted-role credentials. It's also possible, with some additional configuration, to run Building such a thing in-house is cost-prohibitive for many smaller teams, but there are building blocks available such as Hootsuite's Atlantis. HashiCorp's own Terraform Enterprise is also an option, designed specifically to meet enterprise requirements such as change tracking and credentials management. With all of that said, we'll keep this issue open to remind us to think more about audit-ability of direct Terraform CLI actions; the above is intended just as some ideas of how teams with this sort of need might be able to meet them in the mean time. |
Hello @apparentlymart, thanks for the detailed answer, I appreciate the explanation and the suggestions. I agree that at the end terraform should be invoked from a CI system, and this is my final goal. On the other hand, I am using terraform to bootstrap also the CI system, so I have a chicken and egg problem until I arrive there :-) |
Using Terraform to deploy your automation for Terraform is definitely an interesting challenge! It's true that this means there's always at least one Terraform configuration that isn't managed in your CI. In my own experience doing this (in a previous role, before I joined HashiCorp) we just accepted that this one configuration was managed outside of our usual process, and took steps to make sure that mistakes here couldn't possibly affect our "real" production systems, such as deploying it on completely isolated AWS resources. On occasions where operator error led to a CI system outage, this was annoying but at least impacted only our internal workflow and not any customer-facing systems. The CI system also changed infrequently enough that we were able to justify a higher level of risk for updates to it, compared to the "real" system. Different organizations have different constraints of course, and so I understand that this tradeoff isn't for everyone. As noted before, I would like to find a suitable answer here eventually, but unfortunately for the moment our focus is elsewhere (on configuration language usability, at the time of writing) and so I have to ask for patience on this particular problem. |
Yes I understand perfectly, don't worry, you gave me plenty of good suggestions / workarounds. |
Here's my workaround based on #15469 (comment) : http://blog.ampli.fi/explicit-workspaces-terraform/ TL;DR: main.tf:
dev.tfvars:
prod.tfvars:
|
My big problem was visual feedback of which workspace was the active one. I come up with this small bash helper function for my PS1: __tf_ps1 () {
local workspace=""
local print_format=${1:-(%s)}
if [[ -z ${TF_WORKSPACE+x} ]]; then
if [[ -f .terraform/environment ]]; then
workspace=`cat .terraform/environment`
else
workspace=""
fi
else
workspace=${TF_WORKSPACE}
fi
if [[ $workspace != "" ]]; then
printf "$print_format" "$workspace"
fi
unset workspace print_format
return 0
} Here is a snapshot of my prompt. In this example "default" is the current workspace. I hope this helps! |
Thanks for sharing that snippet, @nbetm! On the subject of making the currently-selected workspace more visible, we also recently merged a change (#18253) that includes the workspace name in the |
Terraform, in the spirit of its legacy in describing infra as code, should also support "Workspace as code". Hear me out. Example: # main.tf
terraform {
workspace {
dev {
// Define workspace-specific variables.
ec2_instance_type = "t2.micro"
}
prod {
ec2_instance_type = "t2.large"
}
}
} Running To deploy a workspace, run |
The problem I am facing
I use and love Tf workspaces, but the problem I see is that they are implicit: the behavior of terraform depends on the last
terraform workspace select
.Consider the following. In the same directory, the effects of the
terraform apply
depends on the current, implicit workspace:If something went wrong and I want to reconstruct the steps, I cannot simply look at the shell history and look at a single line, I have to find the latest
terraform workspace select
. Now, imagine I worked in multiple consoles: I could have done the workspace selection in one console and the actual apply in another.Doing a
terraform show
might not be enough, because in the meantime I could have done anotherselect
(maybe a runaway script ...)To limit the potential for confusion or errors, we modify the shell prompt to always show the current workspace (like you can modify the shell prompt to show the git status of the current directory). But also in this case, the shell prompt is not recorded in the shell history and requires the developer to prepare the prompt beforehand.
An humble proposal
This proposal comes from the
fly
command-line utility of Concourse CI, where you could replace the concept of "fly target" with "terraform workspace".In order to apply (or do any command that requires to know the current workspace):
or, if this is more uniform to current subcommands structure
Backwards compatibility / optionality
If backwards compatibility is needed or if in any case you want this feature to be optional, then maybe the terraform configuration could have an optional key similar to:
that, if present, would require the workspace to be always passed on the command-line.
Hope you find this idea valid :-) and really thanks for Terraform!
The text was updated successfully, but these errors were encountered: