hashicorp / terraform-provider-google

Terraform Provider for Google Cloud Platform
https://registry.terraform.io/providers/hashicorp/google/latest/docs
Mozilla Public License 2.0
2.27k stars 1.72k forks source link

google_compute_instance update network_interface.network_ip with google_compute_address #16494

Closed florenp closed 1 week ago

florenp commented 9 months ago

I have an existing google_compute_instance and I want to switch to a fixed ip. I assign a google_compute_address of type "INTERNAL"

The plan show that the IP is going to change, but nothing is changed(the apply works fine). A 2nd plan still show the same change.

The IP should be changed or if not possible the google_compute_instance should be replaced

Community Note

Terraform Version

terraform -version Terraform v1.6.2 on linux_amd64

Affected Resource(s)

google_compute_instance

Debug Output

https://gist.github.com/florenp/2c02bd0d5328387d296d4485615dfecf

Expected Behavior

Update the google_compute_instance IP or if not possible replace the google_compute_instance

Actual Behavior

Nothing is changed. The apply is ok, but another plan just after want to make the same change

Steps to Reproduce

Create a google_compute_instance without any google_compute_address affected to it. Create a google_compute_address and try to affect it to your google_compute_instance

b/310337617

edwardmedia commented 9 months ago

@florenp do you plan to change a public ip and private one?

network_ip - (Optional) The private IP address to assign to the instance. If empty, the address will be automatically assigned.

To update the public ip, is this example helpful?

florenp commented 9 months ago

@edwardmedia

@florenp do you plan to change a public ip and private one?

network_ip - (Optional) The private IP address to assign to the instance. If empty, the address will be automatically assigned.

To update the public ip, is this example helpful?

I wanted to change my instance private IP(wanted to switch to a fixed one even if I destroy/recreate it). So I reserved a private one with google_compute_address and try to set it to my google_compute_instance. I got the result I pasted in the gist.

edwardmedia commented 9 months ago

Yeah, I do see this is a bug. Basically the plan shows the diff but there is no update for it in the apply

florenp commented 7 months ago

Hello @edwardmedia,

Any news on that?

LucaPrete commented 3 months ago

Hello all!

@florenp I'm afraid this is working as expected. The Google compute API doesn't allow you today to change the IP of a VM.

The process to promote it to static is described here. You will need to allocate (read create) a static IP, whose value is the one that the VM is already using.

I also successfully tried this in Terraform.

First, I created a test-vm with an ephemeral IP.

resource "google_compute_instance" "test_ip_update" {
  project      = "xxx"
  name         = "test-ip-update"
  machine_type = "e2-micro"
  zone         = "europe-west1-b"

  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-11"
    }
  }
  network_interface {
    subnetwork = "https://www.googleapis.com/compute/v1/projects/xxx/regions/europe-west1/subnetworks/test-subnet"
  }
}

Then, I used the google_compute_address resource to make the IP static:

resource "google_compute_address" "static_address" {
  name         = "my-internal-address"
  project      = "xxx"
  subnetwork   = "https://www.googleapis.com/compute/v1/projects/xxx/regions/europe-west1/subnetworks/test-subnet"
  address_type = "INTERNAL"
  address      = google_compute_instance.test_ip_update.network_interface[0].network_ip
  region       = "europe-west1"
}

From now on, the IP assigned to the VM is static.

On a side note, given the API doesn't even allow to change the network_ip value I'd remove the unnecessary code from the update method in the resource, I'd mark the field as "not updatable" and I'd possibly add a note in the documentation, thus avoiding further confusion. @edwardmedia I can take care of this if you want.

Finally, I'd close this bug and mark it as won't fix.

karolgorc commented 2 weeks ago

On a side note, given the API doesn't even allow to change the network_ip value I'd remove the unnecessary code from the update method in the resource, I'd mark the field as "not updatable"

Shouldn't we just make a change to the network_ip field force a replace of the instance? Unless there are some use cases of this i'm not aware of.

Because the succesful terraform apply even when just changing the network_ip by hand with different addresses is confusing to the user

karolgorc commented 2 weeks ago

Will also test if Instances.Update() supports the IP change instead of Instances.UpdateNetworkInterface()

Found this comment as well. // network_interface.[d].network_ip can only change when subnet/network // is also changing. Validate that if network_ip is changing this scenario // holds up to par. func forceNewIfNetworkIPNotUpdatable(ctx context.Context, d *schema.ResourceDiff, meta interface{}) error { // separate func to allow unit testing return forceNewIfNetworkIPNotUpdatableFunc(d) }

Seems like the force replace method is already in place but not working

ScottSuarez commented 1 week ago

@LucaPrete would you mind taking a look at https://github.com/GoogleCloudPlatform/magic-modules/pull/11395