Hello and good day,
I am trying to understand how provider passing between root and child modules work in terraform.
This is my simple project structure:
./
├── docker
│ ├── main.tf
│ └── variables.tf
├── main.tf
└── variables.tf
I have my root/base module in ./main.tf
, and I am calling another module located in ./docker/main.tf
.
In my base module I try to create and provision a simple DigitalOcean droplet, and then from my child module I try to create a new docker network using the Docker provider.
Here is how my base module ./main.tf
looks like:
provider "docker" {
alias = "docker_config"
host = digitalocean_droplet.server.ipv4_address
ssh_opts = [
"-o StrictHostKeyChecking=no",
"-o UserKnownHostsFile=/dev/null",
"-o LogLevel=ERROR",
]
}
resource "digitalocean_droplet" "server" {
image = "ubuntu-20-04-x64"
name = "server"
region = "nyc3"
size = "s-1vcpu-1gb"
# Make sure docker is installed via user_data
user_data = "apt-get update && apt-get install -y docker.io"
}
resource "null_resource" "wait_for_droplet" {
depends_on = [digitalocean_droplet.server]
}
# call the docker module and pass the provider configuration with the droplet ip address as host
module "docker" {
source = "./docker"
depends_on = [digitalocean_droplet.server]
providers = {
docker = docker.docker_config
}
}
And here is how the child module ./docker/main.tf
looks like:
resource "docker_network" "test" {
name = "test"
}
The above code is valid via terraform validate
however when I try to apply the configuration, I get the following (expected) error:
╷
│ Error: Error initializing Docker client: unable to parse docker host ``
│
│ with provider["registry.terraform.io/kreuzwerker/docker"].docker_config,
│ on main.tf line 18, in provider "docker":
│ 18: provider "docker" {
│
╵
The provider configuration for docker fails as the host
IP address is not available just yet until I the configuration is applied and the DigitalOcean droplet is created.
I tried to remove the provider configuration from the base ./main.tf
module and tried to move all the provider configuration in the module
block as follows:
module "docker" {
source = "./docker"
depends_on = [digitalocean_droplet.server]
providers = {
docker = {
host = digitalocean_droplet.server.ipv4_address
ssh_opts = [
"-o StrictHostKeyChecking=no",
"-o UserKnownHostsFile=/dev/null",
"-o LogLevel=ERROR",
]
}
}
}
However then the code is no longer valid.
TL;DR, I would like to call the docker child module only after the DigitalOcean droplet is created, so I can pass the IP address of the droplet to the docker provider, so that terraform can communicate with the docker daemon on the server.
Any help is super appreciated.
Thanks.