At the time of this writing, not all of the remote backends in Terraform have been updated to support state environments. For those that have, each backend has its own conventions for how to represent the now-multiple states in the data store.
As of version 0.9.2, the "consul", "s3" and "local" backends have been updated. The "gcs" backend has not yet, but once it has the procedure described here will apply to that too.
There's initially a "default" environment, but if you never run terraform apply
with this environment selected then you can ignore it and name your environments whatever you want.
To create a new environment called "production" and switch to it:
terraform env new production
This will establish an entirely separate state on the backend, so terraform plan
should show that all of the resources need to be created fresh.
You can switch between already-existing environments like this:
terraform env select production
Before 0.9, many teams (including yours, it sounds like) wrote wrapper scripts to simulate this behavior. It's likely that these scripts didn't follow exactly the same naming conventions in the storage backends, so some manual work will be required to migrate.
One way to do that migration is to start off using the "local" backend, which stores state in a local directory called terraform.state.d
. While working locally you can create the environments you want and then carefully overwrite the empty state files in the local directory with the existing state files from your previous scripted solution. Once all of the local environments have appropriate states in place you can then change the backend
block in the config to the appropriate remote backend and run terraform init
to trigger a migration of all of the local environments into the new backend.
After this, the terraform env select
command will begin switching between the remote environments rather than the local ones.
If your chosen remote backend doesn't yet support environments, it's best to continue with a scripted solution for the time being. This means replacing terraform remote config
in your existing wrapper script with a use of the partial configuration pattern to pass environment-specific configuration into terraform init
.