Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generating resources from a map then adding a new resource modifies unexpected resources #16210

Closed
gertjanmaas opened this issue Sep 28, 2017 · 4 comments

Comments

@gertjanmaas
Copy link

gertjanmaas commented Sep 28, 2017

Hi there,

I'm trying to generate a bunch of resources based upon a map. In this example I want to use the key of the map to name a resource, then supplying some data in the value part of the map. For this example (which is the simplest I could come up with) I'm creating some docker containers, but I also ran into this issue creating AWS EC2 instances and AWS ECR repositories.

Not sure if I'm using the map for a way it is not intended to be used or this is a bug.

Terraform Version

0.10.2

Terraform Configuration Files

provider "docker" {
  host = "unix:///var/run/docker.sock"
}

variable "containers" {
  type = "map"

  default = {
    test-container  = "test-data-1"
    test-container2 = "test-data-2"
    # test-a-error    = "test-data-3"
  }
}

resource "docker_container" "endpoint" {
  count = "${length(keys(var.containers))}"
  image = "gmaas/nginx_test"
  name = "${element(keys(var.containers), count.index)}"
  env = ["DATA=${element(values(var.containers), count.index)}"]
}

Steps to Reproduce

  1. terraform init
  2. terraform apply
  3. Uncomment the line that says test-a-error = "test-data-3"
  4. terraform plan

Expected Behavior

I expected one resource to be created and the other to be left intact.

Actual Behavior

-/+ docker_container.endpoint[0] (new resource required)
      bridge:           "" => "<computed>"
      env.#:            "1" => "1"
      env.1814979364:   "DATA=test-data-1" => "" (forces new resource)
      env.2183135752:   "" => "DATA=test-data-3" (forces new resource)
      gateway:          "172.17.0.1" => "<computed>"
      image:            "gmaas/nginx_test" => "gmaas/nginx_test"
      ip_address:       "172.17.0.5" => "<computed>"
      ip_prefix_length: "16" => "<computed>"
      log_driver:       "json-file" => "json-file"
      must_run:         "true" => "true"
      name:             "test-container" => "test-a-error" (forces new resource)
      restart:          "no" => "no"

-/+ docker_container.endpoint[1] (new resource required)
      bridge:           "" => "<computed>"
      env.#:            "1" => "1"
      env.1814979364:   "" => "DATA=test-data-1" (forces new resource)
      env.4112986782:   "DATA=test-data-2" => "" (forces new resource)
      gateway:          "172.17.0.1" => "<computed>"
      image:            "gmaas/nginx_test" => "gmaas/nginx_test"
      ip_address:       "172.17.0.4" => "<computed>"
      ip_prefix_length: "16" => "<computed>"
      log_driver:       "json-file" => "json-file"
      must_run:         "true" => "true"
      name:             "test-container2" => "test-container" (forces new resource)
      restart:          "no" => "no"

  + docker_container.endpoint[2]
      bridge:           "<computed>"
      env.#:            "1"
      env.4112986782:   "DATA=test-data-2"
      gateway:          "<computed>"
      image:            "gmaas/nginx_test"
      ip_address:       "<computed>"
      ip_prefix_length: "<computed>"
      log_driver:       "json-file"
      must_run:         "true"
      name:             "test-container2"
      restart:          "no"


Plan: 3 to add, 0 to change, 2 to destroy.

It seems the resources are linked to the order they are in the list (outputted from the keys() function). If instead you add a key in the containers map that alphabetically is in the end (keys() sorts by alphabet), everything works as expected.

References

Only reference I could find was #15678

@vladimirf7
Copy link

Hi. It seems like a well-known count bug in Terraform. You can find a good explanation and more info about it here: #15720 #14275. No solution for now unfortunately.

@apparentlymart
Copy link
Contributor

Hi @gertjanmaas,

As @vladimirf7 mentioned, this is indeed a known issue and one that we have a plan to resolve but need to complete other work first to create the foundation for it. The long-term plan is to have a new meta-attribute foreach that can be used instead of count, which then means that when a map is provided as the iteration value we can use the map keys as the discriminator for each instance rather than the list indices as you are forced to do today.

We are currently in the initial phase of a sequence of changes we need to make to be able to eventually support foreach, so unfortunately we won't have a solution to this in the very short term but it should arrive eventually.

In the mean time, I would suggest making your containers variable be a list rather than a map so that you can manage the order, and then at least you can ensure that new values only get appended to the end of the list. Not a complete solution by any means, but more predictable than using a map where the ordering is forced to be lexicographical by key.

@apparentlymart
Copy link
Contributor

Since #14275 is describing the same limitation, I'm going to close this just to consolidate the discussion over there. Thanks for pointing out this limitation!

@ghost
Copy link

ghost commented Apr 6, 2020

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@ghost ghost locked and limited conversation to collaborators Apr 6, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants