Programically change out backend providers

Is there a way to programmatically disable a backend state? Looking to control whether or not a backend is enabled using a variable. Count or For_each would work but not supported from what i can tell.

terraform {

backend "azurerm" {

 container_name = "main"

 key            = "terraform.tfstate"

}

}

Maybe best way today is to just pass them in via init and not in a tf file? Although it seems you can’t edit the backend type that way.

-backend-config=path This can be either a path to an HCL file with key/value
assignments (same format as terraform.tfvars) or a
‘key=value’ format. This is merged with what is in the
configuration file. This can be specified multiple
times. The backend type must be in the configuration
itself.

Hi @rohrerb,

The backend is expected to be fixed for a particular configuration, and isn’t something you can select dynamically via configuration. You can potentially override parts of it using -backend-config for special situations where the values need to change based on where Terraform is running, though I’d recommend trying to avoid that if possible because it increases the risk of mistakes if the backend settings are incorrectly provided. (That risk can be mitigated by running Terraform in automation so that the -backend-config arguments are being set systematically rather than manually.)

It’s not common workflow for the entire backend configuration to need to change between runs. If you are running into that, it might suggest that your use-case is better met by writing a shared module and calling that module from several different root configurations with different backend settings, so that the configuration of what is to be created is separated from the configuration of the backend used for a particular instance of that infrastructure, with both still under version control but separated.

In an unusual situation where you really do need the backend to be fully dynamic for each execution, I think the best approach would be to write an automation wrapper around Terraform which can generate a new configuration file just in time before running terraform init, containing the backend configuration appropriate for this particular run. That would not be a conventional Terraform workflow, but should work.

There was another question today about dynamically creating new infrastructure per client which is an example of a situation where fully-dynamic backend configuration can be useful. Over there I’d proposed something similar to the above of generating a root module configuration on the fly that refers to a shared module published elsewhere, which is a sort of combination of my two ideas above.

Thank you for guidance. I use a wrapper script to invoke terraform which allows me to manipulate certain things prior to an action.

Below is my hack…

Ended up moving all config items to command line, example

backend_configs.append('-backend-config=storage_account_name={}'.format(os.environ.get("STORAGE_ACCOUNT")))
backend_configs.append('-backend-config=container_name={}'.format(ARGS.section))
backend_configs.append('-backend-config=key={}'.format('terraform.tfstate'))

And then depending on backend i dynamically change the file.

def switch_backend_type(backend_type):
    """Dynamically updates backend.tf in the correct section to use configured backend."""
    # Yes i know this is a hack but its our option if you want to have different backends.
    for line in fileinput.input([BACKEND_PATH], inplace=True):
        print(re.sub('"(.*?)"', '"' + backend_type + '"', line.strip()))

The backend starts off as

terraform {
backend "" {
}
}

then dynamically changes to the target which is local or azurerm

terraform {
backend "azurerm" {
}
}