-
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
Any benefit of using separate remote state files? #3838
Comments
@vasiliyb this is a great question but one that I think is rather subjective: what will work best for you will depend greatly on the scale and structure of what you're deploying. However, I can describe the pattern used by my team at work for managing a (somewhat-)complex infrastructure as a set of separate Terraform states. The Our architecture is such that there are many distinct applications, each of which controls most of its own infrastructure, and then these apps join "environments" (PROD and QA in this example) to gain access to shared infrastructure that allows them to communicate with one another, such as networks (VPC, subnets) and a Consul cluster. Each of the boxes in the diagram is a Terraform config and an associated remote state. The states for the top two ranks are stored in S3, and then the states for the bottom two ranks are stored within the Consul cluster within each environment (each of which is created by the configs on the second rank.) So we have many different distinct configs and Terraform states, but they all belong to one of the following categories:
This structure has been working well for us so far, and allows us to manage the lifecycles of different parts of the system separately. We deploy our apps a lot more often than we modify the different infrastructure configs, and we deploy them as a single unit so that the app gets updated everywhere in one action. The infrastructure configs are more separated because we tend to update them less often, with more care, one region at a time so that we can't break all of our infrastructure in a single step. However, our environment is relatively complex with many separately-maintained applications all interacting via shared infrastructure in multiple environments. I expect this would be overkill for a single, relatively-simple application where a standalone Terraform configuration could be more than sufficient. Ultimately you'll need to trade off the complexity of coordinating changes across many different configs against the flexibility of being able to evolve each subsystem separately. If you do decide to collapse all of your resources into a single Terraform config, you had the right idea about combining the state files together. You'll need to watch out for any collisions in the local identifiers of resources in different configs (e.g. if you have two configs that both declare You could also elect to create a wrapper module around your existing modules. In that case you'll have a new module whose entire contents are I'm sorry that this turned out to be a bit of an essay, but I hope some of it is useful. I'm curious to hear about what path you'll ultimately decide to take, and what characteristics of your problem led you to that decision. |
@apparentlymart best write up. Thank you! Question in the following scenario... A new deployment machine can only be configured with one remote terraform state file (either vpn or redis remote state), with this command:
or
Once this command is ran, it will download the state file from s3, and place it in .terraform directory locally, which will either have the vpn or redis state. BUT the problem I can not understand is, there are several terraform resources defined in our the codebase:
How does terraform decide where to stick the state into for the related playbook? Are the terraform_remote_state resources tied to a .tf file? |
@apparentlymart I would love to see this turned into a wiki article / blog post or something so that it can be added to - thoughts? |
Glad I stumbled upon this. The thing is, I am actually trying to use a single I found that I can do it by:
Would be nice to have a Then tooling can just switch to the remote state that it needs, pull it down, and be on its way. @vasiliyb from what I've seen, state is not a part of config, it's managed separate and remote state is a bit of a "state" itself (the As for |
@vasiliyb @stack72 writing up how we're using Terraform in my blog -- including the details above -- has been on my to-do list for a while but I probably won't get to it until next year now, since my schedule is packed over the holiday period. 😞 @vancluever we actually do what you're describing for the app-level configs (the bottom rank of my diagram above) to allow them to be separately deployed to each environment. We currently have some hacky wrapper scripts that do something like the |
Did this bug ever see the light of day in the form of a blog? Real world examples are always useful. |
Ran across this while I was refactoring my own state files, so here's a link to my blog post on managing multiple states / migrating to a tfstate file per environment. http://charity.wtf/2016/03/30/terraform-vpc-and-why-you-want-a-tfstate-file-per-env/ cc @shpsec-dennis |
@apparentlymart I'd love to read a more detailed description of your setup. Will you be writing a longer blog article? |
I'm sorry I never followed up with a full article on this. Things actually evolved a little since I wrote this, so I have some new stuff to share but my time is limited right now. What Charity described is largely the same, differing a little in the details. The only part not shown there is how apps get deployed with Terraform, and these days I think many folks are finding their use case is simple enough to just use Nomad (or similar) for that and not bring Terraform into play at that layer. Terraform can still be useful in this space if you have an environment where cloud services are wired up to apps running on computed resources, since it is good at connecting the dots to help these things talk together, but you can get a long way with Terraform writing resource attributes into Consul and Nomad reading Consul to configure job settings. |
I (finally) wrote some stuff about a more generalized pattern that is based on what I learned designing the architecture for the company I was at when I wrote the above. It's a bit wordy but is hopefully more useful than the specific details of that particular setup: I hope it's useful to others trying to model more complex systems in Terraform. |
@apparentlymart really appreciate your Terraform EA pattern document. I notice it was published about a month or so before Terraform 0.9 was released w/ overhauled remote state management. Does 0.9 cause you to rethink anything in that document or does it still pretty much hold up? Thanks again for the great work on this important topic. Cheers. |
The "State Environments" feature for 0.9 was in progress while I was writing that and so I was somewhat aware of the design of the new feature when I wrote it and watched out for anything that wouldn't work in the new model. I actually -- at the zeroth hour before publishing -- switched parts of it to use As far as I know, the high-level approach remains sound. One adjustment that could be made for 0.9 is to use One current limitation of Terraform's State Environments feature is that it requires that the state for all environments must live inside the same backend. This is contrary to the pattern that many users independently invented before there was first-class support, where perhaps each environment's states were kept in a separate S3 bucket or in a separate AWS account entirely. However, anyone building a fresh system should be able to design it around the current constraints -- for example, putting all the states in a single S3 bucket and using IAM policies to restrict access -- and get a working solution. |
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. |
Folks,
When initially implementing terraform, we have potentially made a mistake, and have setup several separate projects with terraform, which in turn manage the same AWS Account's infrastructure. What we have ended up with is an S3 bucket full of separate remote state files.
Now we face the dilemma of sharing things between these terraform setups. So this leads me to the questions:
1.) Combining JSON from all state files should probably give us a way out. Am I correct that after merging the code base of .tf files along with combining the remote state files into one should get us on to the same code base?
2.) Is there any benefit of keeping the current setup?
Thanks! Hope this is a good venue to ask such question, as I have not found much information regarding this anywhere in the docs. Would love to update with my findings!
The text was updated successfully, but these errors were encountered: