terraform-provider-docker icon indicating copy to clipboard operation
terraform-provider-docker copied to clipboard

Ports on stopped container force replacement

Open mavogel opened this issue 4 years ago • 3 comments

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:

  1. 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"
}
  1. terraform apply
  2. ssh onto the host
  3. docker kill btsync
  4. terraform plan EXPECTED BEHAVIOUR:
  • No changes need to be applied as must_run is 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"
}

mavogel avatar Dec 25 '20 19:12 mavogel

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.

github-actions[bot] avatar Mar 29 '21 10:03 github-actions[bot]

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.

github-actions[bot] avatar Jun 06 '21 10:06 github-actions[bot]

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

Junkern avatar Feb 28 '23 13:02 Junkern