Hi,
Terraform version: v0.9.11
I have seen https://github.com/hashicorp/terraform/issues/15131 and found interpolation is not possible when performing terraform init. Is there any other way to accomplish the same? So that the state files are organised correctly for different projects. Ideally i would like to have the state files in seperate buckets as defined below.
tf-state-bucket-us-east-1/environment/non_immutable/terraform.state
tf-state-bucket-us-east-1/environment/
/environment/
tf-state-bucket-us-east-2/environment/non_immutable/terraform.state
tf-state-bucket-us-east-2/environment/
/environment/
The non_immutable will have state info about VPC.etc. In short resource which do not change once created.
Is this possible instead of configuring a single bucket in the config? Is yes can someone share the process on how to accomplish it cleanly.
Regards,
Kevin
Two things that might help you. For your "immutable" stuff, use Remote State Data Provider to reference another state in a read-only manner to be shared between other states.
If you want multiple "instances" of the same config without shared state, use workspaces (formerly env). They allow you use use the same configuration but deploy multiple times without sharing state. They do have to be in the same bucket, though.
By the way... if your concern is about availability of your state during a regional S3 outage, check out bucket mirroring. Has nothing to do with Terraform, but it would allow you to access your state info from another region during an outage. That's the only reason I can think of to use multiple buckets aside from segregating user access (which can also be done with IAM policies and bucket prefixes).
Hi @nbering
Thanks for the info. I have few comments
My requirements are as follows.
Regards,
Kevin
@linuxbsdfreak If you think switching environments is a pain now, keeping separate state in separate buckets is going to be even more work.
I had similar ideas when I first started working with Terraform, but realistically swimming against the current wasn't worth the effort. Terraform workspaces effectively provides the isolation you're looking for because it's a completely separate state file, just organized in a way that Terraform can use to provide some help in managing the multiple states.
I'm not a team member so I can't comment on whether multiple backend configurations in the same project will ever be supported, but at this point it is not. If it ever does arrive, I imagine it will be to support refactoring state with terraform mv. So, all I can suggest for your second requirement is writing your configuration as a submodule and then sharing it between multiple "root" projects.
./root1/main.tf
terraform {
backend "s3" {
bucket = "mybucket1"
key = "path/to/my/key"
region = "us-east-1"
}
}
module "project" {
source = "../shared"
somevar = "foo"
}
./root2/main.tf
terraform {
backend "s3" {
bucket = "mybucket2"
key = "path/to/my/key"
region = "us-east-2"
}
}
module "project" {
source = "../shared"
somevar = "bar"
}
./shared/main.tf
variable "somevar" {}
...
Use like this:
$ cd root1
$ terraform init
$ terraform plan
$ terraform apply
$ cd ../root2
$ terraform init
$ terraform plan
$ terraform apply
As I've said before though, doing this type of thing is a lot of work for something that is a mostly theoretical gain. One can rarely eliminate complexity with software, you just end up moving it around. If a feature were implemented to support multiple remote state buckets, the complexity would be handled by Terraform at the cost of maintaining another feature. If you do something like the above, you take on the complexity yourself. If you use workspaces, no new feature is written, but you compromise on not being able to use multiple buckets.
Hi @linuxbsdfreak, @nbering,
It is indeed true that right now the "smooth path" is to use the same backend configuration for all environments and allow Terraform to manage the different states via _workspaces_ (or "state environments", as they were called in 0.9).
Having multiple root modules that all just reference a shared child module is another path that allows more flexibility, at the expense of a slightly-tricker workflow since Terraform itself can't help switch between the environments.
One longer-term idea we've talked about is to have a special "multiplex backend" that acts as a wrapper around a number of different backends, making them behave as one. We don't have any immediate plans to implement that since it's got a lot of complexities to navigate around how it would manage credentials, etc, and so for the moment we're recommending either of the above strategies.
For more complex scenarios, it's possible to add additional arguments to the terraform init command to override certain elements of the backend configuration; we call this "partial configuration", since only part of the necessary config actually lives in the configuration files. This is not an ideal workflow since it requires careful management of which settings are currently active when running specific commands, but several users have reported success with this when running Terraform in automation such that it's easier to ensure that the right steps are always followed to keep things consistent.
As part of the 0.10 release we updated some documentation in this area that hopefully clarifies somewhat the different options here:
terraform init: Backend Initialization covers the init options for backend configuration, and links to some more detailed docs on the partial configuration idea.Neither of these resources specifically discusses @nbering's suggestion of multiple top-level configs and a shared child module, since of course that's not something that Terraform _itself_ manages, but based on this discussion here I would like to find somewhere to mention that in the documentation, since it _is_ a good pattern particularly when there are also some non-trivial structural differences between environments.
Hello again!
We didn't hear back from you, so I'm going to close this in the hope that a previous response gave you the information you needed. If not, please do feel free to re-open this and leave another comment with the information my human friends requested above. Thanks!
I'm going to lock this issue because it has been closed for _30 days_ โณ. This helps our maintainers find and focus on the active issues.
If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.
Most helpful comment
@linuxbsdfreak If you think switching environments is a pain now, keeping separate state in separate buckets is going to be even more work.
I had similar ideas when I first started working with Terraform, but realistically swimming against the current wasn't worth the effort. Terraform workspaces effectively provides the isolation you're looking for because it's a completely separate state file, just organized in a way that Terraform can use to provide some help in managing the multiple states.
I'm not a team member so I can't comment on whether multiple backend configurations in the same project will ever be supported, but at this point it is not. If it ever does arrive, I imagine it will be to support refactoring state with
terraform mv. So, all I can suggest for your second requirement is writing your configuration as a submodule and then sharing it between multiple "root" projects../root1/main.tf
./root2/main.tf
./shared/main.tf
Use like this:
As I've said before though, doing this type of thing is a lot of work for something that is a mostly theoretical gain. One can rarely eliminate complexity with software, you just end up moving it around. If a feature were implemented to support multiple remote state buckets, the complexity would be handled by Terraform at the cost of maintaining another feature. If you do something like the above, you take on the complexity yourself. If you use workspaces, no new feature is written, but you compromise on not being able to use multiple buckets.