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

`docker_tag` does not detect changes when the `docker_image` referenced by `source_image` changes

Open labmonkey42 opened this issue 2 years ago • 2 comments

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Terraform (and docker Provider) Version

1.3.9

Affected Resource(s)

  • docker_tag

Terraform Configuration Files

provider "docker" {
  registry_auth {
    address = "registry1.example.org"
  }
  registry_auth {
    address = "registry2.example.org"
  }
}

data "docker_registry_image" "upstream" {
  name = "registry1.example.org/ns/foo:latest"
}

resource "docker_image" "local" {
  name          = data.docker_registry_image.upstream.name
  pull_triggers = [data.docker_registry_image.upstream.sha256_digest]
}

resource "docker_tag" "server" {
  source_image = docker_image.local.name
  target_image = "registry2.example.org/ns/foo:success"
}

resource "docker_registry_image" "push" {
  keep_remotely = true
  name          = docker_tag.server.target_image

  depends_on = [
    docker_image.local
  ]
}

Expected Behaviour

Any change to the upstream image at registry1.example.org/ns/foo:latest should ultimately result in a copy at registry2.example.org/ns/foo:success.

Actual Behaviour

A change to the upstream image at registry1.example.org/ns/foo:latest is detected by the upstream data source and successfully triggers the local image resource to pull the image to the local docker instance. In my case, this is an ephemeral build server instance which disappears after the build pipeline regardless of success for failure, so this is seen as a new resource at every plan.

However, because the values of the docker_tag's source_image and target_image technically never change, the docker_tag resource never detects source image change and thus the image is never published to registry2....

labmonkey42 avatar Jun 21 '23 22:06 labmonkey42

Would be very nice to add a triggers property like docker_registry_image so it is revalidated against the sha, for example.
My workaround is to taint the tag but that of course is manual 🤮

avbenavides avatar Oct 20 '23 10:10 avbenavides

@labmonkey42 I fully agree that it would be nice for the docker_tag resource to have a triggers parameter that mimics the functionality of other resources like docker_image and docker_registry_image.

In the meantime, I managed to implement a workaround using Terraform's replace_triggered_by. If you're on Terraform >= 1.2 this might work for you too:

data "docker_registry_image" "upstream" {
  name = "registry1.example.org/ns/foo:latest"
}

resource "docker_image" "local" {
  name          = data.docker_registry_image.upstream.name
  pull_triggers = [data.docker_registry_image.upstream.sha256_digest]
}

resource "docker_tag" "server" {
  source_image = docker_image.local.name
  target_image = "registry2.example.org/ns/foo:success"

  lifecycle {
    replace_triggered_by = [
      docker_image.local.repo_digest
    ]
  }
}

resource "docker_registry_image" "push" {
  keep_remotely = true
  name          = docker_tag.server.target_image

  triggers = {
    source_image_hash = docker_tag.server.source_image_id
  }
}

Hope this helps!

carchi1a avatar Oct 31 '23 16:10 carchi1a