Is anyone aware of how to instantiate dynamic providers

I have a case where I need to create multiple namespaces in the vault and I have to write down separate providers for each namespace. Is there any workaround available for this?

Provider configurations in Terraform must be statically-defined because they are one object in Terraform which is needed for essentially all operations, including planning and destroying resources. In particular, a provider configuration must always outlive all of the resource instances that belong to it, and so must survive for at least one additional terraform apply than the associated resource configurations do.

However, you can use a shared module called multiple times as a way to factor out everything except the provider configuration so it can be maintained in a central location.

For example, you could create a module in ./modules/vault-namespace (just for example) and call it once for each namespace, each one coupled with its own provider configuration, like this:

provider "vault" {
  alias = "a"

  # ...
}

module "a" {
  source = "./modules/vault-namespace"

  # (any required settings)

  providers = {
    vault = vault.a
  }
}

provider "vault" {
  alias = "b"

  # ...
}

module "b" {
  source = "./modules/vault-namespace"

  # (any required settings)

  providers = {
    vault = vault.b
  }
}

The providers argument inside a module block tells Terraform to give the called module a different “view” of the available provider configurations than the caller had. In this case, the first module call says that the default vault provider configuration in the child module maps to the “a”-aliased configuration from the root module, whereas the second one uses the “b”-aliased configuration.

In order to meet the requirement I mentioned above about resource instances always outliving their provider configurations, if you ever want to remove one of your namespaces that would require a two step process. For example, to remove the “b” namespace:

  • Remove the module "b" block, and apply that change to destroy all of the objects it declared.
  • Now remove the provider "vault" block that has alias = "b", which no longer has any resource instances associated with it. You can run terraform plan to confirm that there are no remaining references to that provider configuration.

The addition of a new namespace can typically happen in only a single step though, because when you first add the new module block and associated provider "vault" block the provider configuration will be available to support the initial creation of the objects declared in that module.

1 Like