Terraform: Remove ephemeral External IP from google_compute_instance under network_interface > access_config > nat_id

Created on 16 Mar 2017  路  20Comments  路  Source: hashicorp/terraform

In Google Cloud Platform, when launching a new google_compute_instance, it auto assigns an External ephemeral IP unless a nat_id is specified.

At the moment, I am having to launch the instance(s) and then manually remove the external ephemeral IP in the console.

I would like the option rather than manually removing or 'hiding' it behind some firewall rules.

enhancement providegoogle-cloud

Most helpful comment

Fwiw, I landed here thinking that there is equivalent to AWS' associate_public_ip_address, but after reading the documentation more carefully, I realize that it actually says what the solution is. Just remove the entire access_config block from the network_interface block, and no ephemeral public IP will be assigned.

All 20 comments

+1

Hey @mbrucker, can you help me understand this a bit better? It sounds like what you want is to provision an instance without setting nat_id and without it having an ephemeral external IP address. Is that correct? But at the moment, you get an ephemeral external IP address by default, and the only way around it you've found is to set nat_id. Is that correct?

Hi @paddyforan

I'm trying to create instances with only an internal IP. When they are launched, they are assigned an External IP and I have to manually go into the console, edit the instances, and remove the Ephemeral (external) IP address. Once that is done they have internal only.

Using Terraform with AWS, I accomplish this by launching instances with associate_public_ip_address = false flag. Really, I am looking for this option when launching instances in Google.

Does that provide enough clarity?

Matt

That does, thanks! I need to investigate whether this is intended-to-be-helpful behaviour the API is providing, or if it's something Terraform is doing, but it sounds like a reasonable ask either way. One way or another, we'll find a workaround. It will probably, as you noted, be a flag you have to set--we avoid backwards incompatible changes where possible, so I'd hate to just disable the behaviour under people.

For what it's worth, here's a way to accomplish this without having to do stuff in the console, though I agree having it as a flag would be nicer looking: https://github.com/hashicorp/terraform/commit/0bd27f068d02ccb839bdeeb0d858c243979a7371

I feel like I'm missing something on this issue; I can't seem to reproduce it, or am misunderstanding what you're doing.

The following config works for me, and does not assign an external IP address:

resource "google_compute_instance" "default" {
  name         = "paddy-test-12747"
  machine_type = "n1-standard-1"
  zone         = "us-central1-a"

  disk {
    image = "debian-cloud/debian-8"
  }

  network_interface {
    network = "default"
  }
}

Could you post a config that does generate an external IP address that should not?

(I should also note, the API does not assign an ephemeral IP automatically--I checked with the API explorer, and created an instance without an external IP).

So here's the issue I'm running into. If I set the network_interface as default then the ideal result occurs (only an internal IP is assigned.)

network_interface {
network = "default"
}
}

However, when defining a customer subnetwork:

network_interface {
network = "custom-network"
}
}

Then the instance/resource is assigned a Public IP. Not sure where I'm going wrong or if it's a bug. Will continue to investigate from my end.

Hm. That's useful to know, but I'm still having trouble reproducing.

Can you edit this configuration to make it reproduce the issue you're having?

resource "google_compute_instance" "default" {
  name         = "paddy-test-12747"
  machine_type = "n1-standard-1"
  zone         = "us-central1-a"

  disk {
    image = "debian-cloud/debian-8"
  }

  network_interface {
    network = "${google_compute_network.default.name}"
  }
}

resource "google_compute_network" "default" {
  name                    = "paddy-test-12747"
  auto_create_subnetworks = "true"
}

Ok, so running your config generates the expected results. It creates multiple /20 subnets spanning multiple regions and places the instance with no Ephemeral IP in the correct zone.

Taking your methodology and running with it I think I have got the solution which generates the expected instance in the correct subnet with only an internal IP assigned...

resource "google_compute_instance" "test" {
  name         = "${var.env_name}-test"
  machine_type = "n1-standard-1"
  zone         = "${var.zones}"

  disk {
    image = "debian-cloud/debian-8"
  }

  network_interface {
    subnetwork = "${google_compute_subnetwork.test-subnet-1.name}"
  }
}

resource "google_compute_network" "default" {
  name                    = "paddy-test-12747"
  auto_create_subnetworks = "false"
}

resource "google_compute_subnetwork" "test-subnet-1" {
  name          = "test-subnet-1"
  ip_cidr_range = "10.2.0.0/24"
  network       = "${google_compute_network.default.self_link}"
  region        = "us-west1"
}

I haven't had a chance to refactor this into my other instances, just yet, but should get to it tonight or tomorrow, but I think this is going to get me 99% of the way or solve the issue.

Thanks for working through this with me @paddycarver

My pleasure! If you can figure out a config or anything that helps us reproduce this minimally, I'd love to figure out what's going on and get it fixed.

Hey @mbrucker, because it's been about a week and it sounds like we solved your issue, I'm going to go ahead and close this out so it's easier for us to find issues that require our attention. If you can get a reproduction, I'd love to see it, so don't hesitate to comment on this issue and we'll reopen it. Thanks!

I am facing same issue can any one help me on this
on nat_ip list which address i have to mention @paddycarver

Hi @vutukuribharat! Sorry you're having the issue!

We've actually moved the Google provider to github.com/terraform-providers/terraform-provider-google. Would you mind opening an issue there and we can work on this? If at all possible, please provide a reproduction in the new issue, so we have some way to debug it.

Hi @Brucker,

you said

"--I'm trying to create instances with only an internal IP. When they are launched, they are assigned an External IP and I have to manually go into the console, edit the instances, and remove the Ephemeral (external) IP address. Once that is done they have internal only.---"

Could you tell me how do you manually remove the external IP into the console? what commands do you use? gcloud or other commands? thanks.

I'm not sure if people are still looking for this information, but here are a few options based on different scenarios.

GUI when creating a VM:

  • Select New VM instance
  • Expand Management, security, disks, networking, sole tenancy
  • Select Networking
  • select the edit "pencil" below "Network interfaces"
  • Select none from the External IP drop down.

gcloud command when creating a VM:
Use --network-interface=no-address in the create command.

gcloud command after VM has been created:
Use "gcloud compute instances delete-access-config [INSTANCE_NAME] --access-config-name external-nat". Note that "external-nat" may be different with you VM and you should use the "describe" command to capture the network interface name.

References:
https://cloud.google.com/sdk/gcloud/reference/compute/instances/describe
https://cloud.google.com/compute/docs/ip-addresses/reserve-static-external-ip-address

Hope this helps.

Any updates or options added in latest version to specify to skip adding ephemeral Public IP in Terraform ?

Fwiw, I landed here thinking that there is equivalent to AWS' associate_public_ip_address, but after reading the documentation more carefully, I realize that it actually says what the solution is. Just remove the entire access_config block from the network_interface block, and no ephemeral public IP will be assigned.

I have the case where i have a single instance module which called from main.tf with params and create various instances. Some of these instances need to created with internal ip's only.

The question how it is possible to conditionally remove access_config {} from google_compute_instance resource?

Here is a part of the module.

  network_interface {                                                           
    network    = "${var.vpc.self_link}"                                         
    subnetwork = "${var.snet0.self_link}"                                       
    access_config {                                                             
      nat_ip       = "${var.nat_ip ? element(google_compute_address.default.*.address, count.index) : ""}"
      network_tier = "${var.network_tier}"                                      
    }                                                                           
  } 

PLEASE NOTE:

  • making empty access_config will create Ephemeral IP by default.
  • any value (null, NONE, ...) assigned to network_tier will create Ephemeral IP.
    The only way to force creation with internal ip is to delete whole access_config block...

Any help appreciated.

Hi folks,
This issue is closed, and the relevant code has changed since then, and moved out of terraform core.
If you are experiencing a bug in the google cloud provider, please open a new issue in the provider repository.

If you have a question, it's better to use the community forum where there are more people ready to help. The GitHub issues here are monitored only by our few core maintainers.

Based on the age of this issue, and the fact that any new questions or issues should be opened in the provider repository, I am going to lock this. Thank you!

Was this page helpful?
0 / 5 - 0 ratings