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

docker_registry_image : Provider produced inconsistent final plan

Open stephenlacy opened this issue 4 years ago • 14 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

Terraform v1.0.5 kreuzwerker/docker v2.15.0

Affected Resource(s)

  • docker_registry_image

Terraform Configuration Files

resource "docker_registry_image" "this" {
  name = "image:${var.REV}"
  build {
    context = "./"
    build_args = {
      REV     = var.REV
      PORT    = var.PORT
    }
  }
}

Debug Output

https://gist.github.com/stevelacy/b807abca095f59486e4587097ab24025

Actual Behaviour

│ Error: Provider produced inconsistent final plan
│
│ When expanding the plan for module.backend.docker_registry_image.this to
│ include new values learned so far during apply, provider
│ "registry.terraform.io/kreuzwerker/docker" produced an invalid new value
│ for .build[0].context: was
│ cty.StringVal("./:d0bf0244333d694ac286b5de97ead1d28344bae08ff63ddb7e9e50fa87d4cff0"),
│ but now
│ cty.StringVal("./:0765d42dc5f3cc826c5702ec60ec5e09b47b6c5395edb0f65b55ad6f38d76ec8").
│
│ This is a bug in the provider, which should be reported in the provider's
│ own issue tracker.

Steps to Reproduce

  1. terraform apply

This error goes away on a subsequent build assuming the image hash is the same.

References

Seems releated to #192 except this time the context folder name is ./

  • https://github.com/kreuzwerker/terraform-provider-docker/issues/192

stephenlacy avatar Sep 15 '21 00:09 stephenlacy

This looks related to the issue I made ( #290 ) but I think I've found the cause of the problem, which I've put in the 'Actual Behaviour' section.

KanchiMoe avatar Sep 26 '21 06:09 KanchiMoe

So, I found a quick fix for 2.15.0 . It looks like if tfstate does not exist, then it would fail. Just run terraform apply -auto-approve || terraform apply -auto-approve, which should fix it.

I have not tested any issues in setting the build context path so far, so I cannot commit to that.

da-moon avatar Sep 30 '21 17:09 da-moon

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 Dec 15 '21 10:12 github-actions[bot]

Still happening

stephenlacy avatar Dec 15 '21 15:12 stephenlacy

Happening for me. What's interesting to note is that the documentation states that you must use an absolute path but you seemingly don't in that docker_registry_image object up above? Is there any reason for that?

explaingarlic avatar Dec 17 '21 13:12 explaingarlic

Issue confirmed on a windows machine using aws s3 as a back-end.

martijnvanderkamp avatar Dec 28 '21 10:12 martijnvanderkamp

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 Feb 27 '22 10:02 github-actions[bot]

Issue is still happening and not resolved.

KanchiMoe avatar Feb 28 '22 00:02 KanchiMoe

Yes, still happens.

joanmarccarbo avatar May 19 '22 11:05 joanmarccarbo

Looking at the code, it appends a hash of the context directory's contents. This bit me because I was referencing the directory containing terraform's state file, which changed every time I tried to terraform apply. Even worse, I was dynamically generating the Dockerfile so even after working around this, the very first apply fails because there's no Dockerfile yet to hash.

Workarounds:

  • Put your Dockerfile in a directory without any other files that change when you run terraform.
  • If you need to change/template your Dockerfile at build time, use Docker build args.

jonohill avatar May 27 '22 22:05 jonohill

Thanks for all the comments! In short: The calculation of the internal state value for build.context is, nicely put, not optimal. It is definitely one of my highest priorities to fix. As I am new to the whole "terraform provider" world, I still need some time digging into the provider code and also learning about the plan/state/resource mapping inside a provider.

My gut feeling tells me that in order to properly fix the "Provider produced inconsistent final plan" issue we would need a major version bump because of breaking changes. But let's see.

Possible workarounds:

  • Please refer to the comment above.
  • https://github.com/kreuzwerker/terraform-provider-docker/issues/290#issuecomment-1091428236

With the version to be released (v2.19.0) it will also finally be possible to have a Dockerfile outside the build context (https://github.com/kreuzwerker/terraform-provider-docker/pull/402) maybe that will help some of you out there.

Junkern avatar Jul 13 '22 11:07 Junkern

@stevelacy I assume this issue is still happening for you? What contents are in your ./ context?

Junkern avatar Jul 13 '22 15:07 Junkern

As close as I could make it to the original:

resource "docker_registry_image" "this" {
  name = "name_here"
  build {
    context = "./server"
  }
}

contents of ./server/

Dockerfile
main.go

Pretty sure it was erroring out with the context as ./ or ./server

I "fixed" it by moving the Dockerfile from ./ to ./server and also renamed the context from ./server to server without the leading ./

stephenlacy avatar Jul 13 '22 16:07 stephenlacy

Thanks a lot! That is very interesting information and could be enough to build a nice reproducible case.

In general, I think one of the main problems is that the provider does not enforce the "absolute path" of the context (https://registry.terraform.io/providers/kreuzwerker/docker/latest/docs/resources/registry_image#context), such as in your case. But maybe that can be fixed with some additional code and path-handling. Because now enforcing the absolute path will lead to a breaking change 🤔

Junkern avatar Jul 13 '22 18:07 Junkern

Looking at the code, it appends a hash of the context directory's contents. This bit me because I was referencing the directory containing terraform's state file, which changed every time I tried to terraform apply. Even worse, I was dynamically generating the Dockerfile so even after working around this, the very first apply fails because there's no Dockerfile yet to hash.

Workarounds:

  • Put your Dockerfile in a directory without any other files that change when you run terraform.
  • If you need to change/template your Dockerfile at build time, use Docker build args.

In my case, any changes to build context would result such failure. Even I have the changes being a dependency of docker_registry_image, it does not help.

joesonw avatar Dec 23 '22 14:12 joesonw

The build block of docker_registry_image is now deprecated and will be removed with the next major version. Please migrate to using the build block of the docker_image. There were many fixes done to the context attribute which should fix most of the problems. There will also be a guide for migrating from v2.x to v3.x.

Please open a new issue in case you encounter any bugs and issues!

Junkern avatar Jan 05 '23 14:01 Junkern