How to use multiple Terraform Providers sequentially

Maybe you can use a provider instance within your resources/module to set up various resources with various providers.

https://www.terraform.io/docs/configuration/providers.html#multiple-provider-instances

The doc talks about multiple instances of same provider but I believe the same should be doable with distinct providers as well.


Terraform's current design struggles with creating "multi-layer" architectures in a single configuration, due to the need to pass dynamic settings from one provider to another:

resource "digitalocean_droplet" "example" {
  # (settings for a machine running docker)
}

provider "docker" {
  host = "tcp://${digitalocean_droplet.example.ipv4_address_private}:2376/"
}

As you saw in the documentation, passing dynamic values into provider configuration doesn't fully work. It does actually partially work if you use it with care, so one way to get this done is to use a config like the above and then solve the "chicken-and-egg" problem by forcing Terraform to create the droplet first:

$ terraform plan -out=tfplan -target=digitalocean_droplet.example

The above will create a plan that only deals with the droplet and any of its dependencies, ignoring the docker resources. Once the Docker droplet is up and running, you can then re-run Terraform as normal to complete the setup, which should then work as expected because the Droplet's ipv4_address_private attribute will then be known. As long as the droplet is never replaced, Terraform can be used as normal after this.

Using -target is fiddly, and so the current recommendation is to split such systems up into multiple configurations, with one for each conceptual "layer". This does, however, require initializing two separate working directories, which you indicated in your question that you didn't want to do. This -target trick allows you to get it done within a single configuration, at the expense of an unconventional workflow to get it initially bootstrapped.

Tags:

Terraform