terraform-provider-docker
terraform-provider-docker copied to clipboard
Ports on stopped container force replacement
This issue was originally opened by @Temikus as https://github.com/hashicorp/terraform-provider-docker/issues/211. It was migrated here as a result of the community provider takeover from @kreuzwerker. The original body of the issue is below.
Looks like this may be a reoccurrence of https://github.com/hashicorp/terraform/issues/19294
λ terraform -v
Terraform v0.12.12
+ provider.docker v2.5.0
Starting with a recent upgrade of the provider (sadly I do not remember which one I've upgraded from) docker provider started forcing recreation of containers that have ports published.
Repro:
- Fire up this example container:
resource "docker_container" "btsync" {
image = "resilio/sync"
name = "btsync"
capabilities {
add = ["NET_ADMIN"]
}
ports {
internal = 8888
external = 8888
}
ports {
internal = 55555
}
log_driver = "json-file"
log_opts = {
max-size = "10m"
max-file = 3
}
volumes {
host_path = "/etc/localtime"
container_path = "/etc/localtime"
read_only = true
}
restart= "on-failure"
max_retry_count = 3
# Do not ensure that the container is running
must_run="false"
}
terraform apply- ssh onto the host
docker kill btsyncterraform planEXPECTED BEHAVIOUR:
- No changes need to be applied as
must_runis set to false ACTUAL BEHAVIOUR: - Container wants to be recreated:
+ ports { # forces replacement
+ external = 8888 # forces replacement
+ internal = 8888 # forces replacement
+ ip = "0.0.0.0" # forces replacement
+ protocol = "tcp" # forces replacement
}
+ ports { # forces replacement
+ external = (known after apply)
+ internal = 55555 # forces replacement
+ ip = "0.0.0.0" # forces replacement
+ protocol = "tcp" # forces replacement
}
Note that this doesn't happen with another container that's also stopped but doesn't have ports defined, here's the example config:
resource "docker_container" "speedtest_exporter" {
image = "nlamirault/speedtest_exporter"
name = "speedtest"
hostname = "speedtest"
networks_advanced {
name = docker_network.homelab.name
aliases = ["speedtest", "speedtest.docker"]
}
volumes {
host_path = "/etc/localtime"
container_path = "/etc/localtime"
read_only = true
}
restart= "on-failure"
max_retry_count = 3
# Do not ensure that the container needs to be running
must_run="false"
}
This issue is stale because it has been open 60 days with no activity.
Remove stale label or comment or this will be closed in 7 days.
If you don't want this issue to be closed, please set the label pinned.
This issue is stale because it has been open 60 days with no activity.
Remove stale label or comment or this will be closed in 7 days.
If you don't want this issue to be closed, please set the label pinned.
We are currently reading the ports data from the container.NetworkSettings.Ports, which is {} when the container has exited.
However, we can get the full port information from HostConfig.PortBindings, but we still have a problem:
The ports attribute of the docker_container resource is of type TypeList, which is a "ordered collection of items". We cannot map the order between the ports and the data from HostConfig.PortBindings
That could be solved, though, by changing the type of ports to TypeSet ("unordered collection of items").
This change is also mentioned inside https://github.com/kreuzwerker/terraform-provider-docker/issues/88
And the nice thing is: This is not a breaking change, because an ordered list is actually a subtype of an unordered list, so this should not create an issues when upgrading.
Hence, the next step is to change the ports type, then we can fix this issue