I have the following resource in Terraform:
provider "docker" {
host = "tcp://${digitalocean_droplet.docker_server.ipv4_address}:2376/"
}
This relies on the value ipv4_address
to be known before it can connect to the docker machine. This value is not known until another resource is provisioned:
resource "digitalocean_droplet" "docker_server" {
image = "docker-18-04"
name = "docker_server"
region = "nyc2"
size = "512mb"
private_networking = true
ssh_keys = [
var.ssh_fingerprint
]
connection {
user = "root"
type = "ssh"
private_key = file(var.pvt_key)
timeout = "2m"
}
}
When I run terraform plan
, I get the following error:
Error: Error initializing Docker client: unable to parse docker host ``
on docker.tf line 1, in provider "docker": 1: provider "docker" {
It appears that ipv4_address
is empty because the docker plugin is trying to connect to the docker machine before it is provisioned. How do I tell it to wait for the machine to be provisioned before trying to connect to it?
One thing I tried:
provider "docker" {
host = "tcp://${digitalocean_droplet.docker_server.ipv4_address}:2376/"
depends_on = [
digitalocean_droplet.docker_server.ipv4_address,
]
}
When I do that, I get this error:
Error: Reserved argument name in provider block
on docker.tf line 4, in provider "docker": 4: depends_on = [
The provider argument name "depends_on" is reserved for use by Terraform in a future version.
But reading more into depends_on
, I don't think that's the solution anyway.
Unfortunately a provider block doesn't support expressions referring to a resource attribute.
This limitation is explained in the provider configuration documentation:
For example, this would work (but not solve your problem):
But there is a way out.
The solution is made of two steps:
In you are not already using a "real" remote backend such as S3 + DynamoDB, you can still experiment easily using the local backend as follows.
Directory layout:
The snippets below are using AWS, but it is trivial to adapt to DO.
File server/main.tf contains something similar to
File docker/main.tf contains something similar to
Finally:
Remember: you have to perform also separate
terraform destroy
, in LIFO order: first destroydocker
, then destroyserver
.