How to change an existing Terraform that is stored in a back end

I have inherited a Terraform implementation. The state is stored in a known Swift backend. I do not have the .tf files but I’m assuming there is a way to pull down the files from the back end so that I can then make a change and then apply. I have not been able to find anything in tutorials or documentation thus far on how to do this. Any tips on how this works and where I should look?

Hi @jaysonhurd,

Unfortunately, the contents of the backend alone will not be sufficient to apply a change. The backend only stores the state, which is like an index of bindings between resource names in the Terraform configuration and objects in the remote system. It doesn’t include the configuration that originally declared those bindings. As a weak analogy, you might say that this is like having the backend database of an application but not the application’s source code.

If there’s no way to get access to the original configuration (which typically lives in a standard version control system, separately from the system being deployed) then unfortunately I don’t think there’s an easy answer for how to proceed here. However, I can give you some ideas to retrieve the information about what you do have in order to decide what to do next.

If you have some way to infer how the backend had been configured in the original Terraform configuration then you could write a new configuration that only includes the backend configuration block, which will look something like this:

terraform {
  backend "swift" {
    # (backend-specific settings)

I’m not personally familiar with the swift backend in particular, so I can’t advise on what you might put inside that backend "swift" block, but hopefully you can refer to the swift backend documentation and infer how to populate that based on information you’ve already learned about the system.

Once you have a complete backend configuration, you’ll be able to carefully run a few Terraform commands that will should allow you to inspect the state even though your configuration is incomplete:

  • terraform init: this will connect to the backend using the settings configured above, retrieve the current state from the default workspace, and install any providers that are recorded as being responsible for resource instances in the state.
  • terraform workspace list: this will let you see if this backend has more than one workspace configured. Each workspace is a separate state established from the same configuration. If you only see default in this list then that’s the easy/common case where a configuration has only one workspace.
  • terraform show: this will show you all of the resource instances recorded in the state for the currently-selected workspace.
  • terraform workspace select: if you learned earlier that there is more than one workspace, you can use this command with a workspace name as an extra argument to switch contexts to one of the other workspaces, and then run terraform show again to see what objects exist there.

For the sake of familiarity to those who know the Terraform language, terraform show returns this data in a format that resembles the Terraform language, but it isn’t a complete representation of the source configuration (it records only the final values of each attribute, not the expressions that populated them) and, in some special cases, may not actually be entirely valid configuration syntax that Terraform could parse.

However, if you don’t have any configuration at all then the terraform show output could be a reasonable starting point for rebuilding a suitable replacement configuration. It won’t be an easy thing to do, because you’ll likely need to decompose the resources by which modules they belong to and reverse-engineer how the original configuration author had wired together all of the objects using Terraform language expressions, but it will hopefully make things easier than having no information at all.

Another outcome might be that you see terraform show report that there aren’t many resources in the state at all. In that case, you might be better served by just starting fresh with a new Terraform configuration and then using terraform import to bind those existing objects to the new configuration’s state. If you do that, you should discard the old state(s) once you’ve completed your work because a particular remote object should typically be bound only to one Terraform state at a time.

I hope that gives you some threads to pull on to get started here! Getting hold of the original source code would of course be the best option here, but if you cannot then hopefully this will at least allow you to reverse-engineer what’s already deployed and make a plan for what to do next.

1 Like

Wow thanks for the quick and detailed response. I just saw this but will take some good time tomorrow and go through this. I’ll have to ask and see if the .tf files are anywhere to be found, which I doubt…

Update - I managed to connect to the state and see what is going on there. I have the templates for the .tf files and many values are populated as variables from Consul. It may be a matter of rebuilding config each time and then just running the change required. I do have some code in the existing API that builds this for new provisions so hopefully I can find a way to recycle some of this and then do a change… This will take some time to sift through. Thanks again for the good help!