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

google_compute_target_pool is not idempotent when using URLs as values from google_compute_instance #9121

Closed
jsierles opened this issue Sep 29, 2016 · 7 comments

Comments

@jsierles
Copy link

jsierles commented Sep 29, 2016

Hi there,

Terraform v0.7.4
google_compute_target_pool

resource "google_compute_target_pool" "loadbalancer" {
  name = "target-pool-loadbalancer-${var.env}"
  instances = ["${google_compute_instance.loadbalancer.*.self_link}"]
  health_checks = ["${google_compute_http_health_check.loadbalancer.name}"]
}

Plan output

~ google_compute_target_pool.loadbalancer
    instances.0: "europe-west1-d/loadbalancer-0-staging" => "https://www.googleapis.com/compute/v1/projects/myproject-com/zones/europe-west1-d/instances/loadbalancer-0-staging"
    instances.1: "europe-west1-d/loadbalancer-1-staging" => "https://www.googleapis.com/compute/v1/projects/myproject-com/zones/europe-west1-d/instances/loadbalancer-1-staging"

Expected Behavior

This value should not be changed on every plan/apply run.

Actual Behavior

On every plan and apply, this resource is modified without makes changes to the configuration.

@jsierles
Copy link
Author

If this is a bug, I'd be happy to look at applying a fix if someone could clarify what the bug might be.

@danawillow
Copy link
Contributor

Sorry for the long delay! We're trying to get through some of our backlog of issues now, and I found this one. I'm not sure if you're still having the issue, but here's why it's happening.

The code is written so that an instance doesn't need to exist before it's added to the target pool. So instead of specifying the full URL, the author of the config can just specify the zone/name of the instance. After the resource is created, the state file stores that same zone/name key so that terraform doesn't think there's a diff. Unfortunately, this ends up meaning that if you specify the full URL, terraform will think there's a diff.

A solution would be to do a d.Get("instances") in the read method to check if the currently set values are URLs, and if so, don't do the conversion away from them. I'm not going to work on this now, but if anyone wants to take it I'm pretty sure that would work.

An easy workaround is to just convert to the zone/name syntax by doing something like:
instances = ["${formatlist("%s/%s", google_compute_instance.loadbalancer.*.zone, google_compute_instance.loadbalancer.*.name)}"]

Hope that helps!

@jsierles
Copy link
Author

Thanks, will try that.

@queeno
Copy link

queeno commented Feb 8, 2017

I've just been hit by this bug today, so it is still a problem in the latest terraform v0.8.4. it would be nice to have it fixed.

@danawillow
Copy link
Contributor

Thanks for chiming in, @queeno! Have you tried the workaround? If so, did it work?

@queeno
Copy link

queeno commented Feb 8, 2017

@danawillow Yes I have and it works 👍 Thanks for that!

What I have is an instance module which creates multiple Google cloud instances and outputs zones and names lists. These get passed to the load balancer module which joins them up using the formatlist function.

output "zones" {
    value = ["${google_compute_instance.myinstance.*.zone}"]
}

output "names" {
    value = ["${google_compute_instance.myinstance.*.name}"]
}
resource "google_compute_target_pool" "myloadbalancer" {
  name              = "lb-${var.name}"
  instances         = ["${formatlist("%s/%s", var.zones, var.instances)}"]
  health_checks     = ["${google_compute_http_health_check.myloadbalancer.name}"]
}

I would expect that the elements inzones and names lists match the the order they've been created.

For example, if I created an instance called myvm-1 in europe-west-1b and then myvm-2 in europe-west-1c, I would expect the two lists to look like this:

zones = ["europe-west-1b","europe-west-1c"]
names = ["myvm-1","myvm-2"]

I hope terraform is consistent with populating output lists in the same order they have been created when using the count parameter.

Testing has shown this seems to be the case and my terraform apply produced the expected result.

That said, I would rather use a self_link list, hence I would be more than happy if this issue could be resolved 😄

@paddycarver paddycarver self-assigned this Feb 24, 2017
gobengo pushed a commit to gobengo/terraform that referenced this issue Feb 26, 2017
* `google_compute_forwarding_rule.default.port_range = "80"` would save okay, but then would save to state file as "80-80", so it would always think a change was needed
* `google_compute_target_pool.default.instances` items would resolve to full URLs, but saved in state as just `{zone}/{instance.name}`.
  * This PR uses a [workaround](hashicorp#9121 (comment)) mentioned in hashicorp#9121
@ghost
Copy link

ghost commented Apr 10, 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.

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

No branches or pull requests

6 participants