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.34k stars 1.74k forks source link

Allow google_compute_network_peering to accept google_compute_network.id format in network field #10094

Open gdelaney opened 3 years ago

gdelaney commented 3 years ago

Community Note

Terraform Version

Terraform v1.0.7 on darwin_amd64

Affected Resource(s)

Terraform Configuration Files


resource "google_project" "service_project" {
  name                = "aproject"
  project_id          = "REDACTED"
  folder_id           = "REDACTED"
  billing_account     = "REDACTED"
  auto_create_network = "false"
  labels              = {
    platform      = "platform"
    environment   = "env"

  }

resource "google_compute_network" "vpc_network" {
  name                    = "mynetwork"
  auto_create_subnetworks = "false"
  routing_mode            = "GLOBAL"
  project                 = google_project.service_project.project_id
}

# Get the ID
output "network_id" {
value = google_compute_network.vpc_network.id
}

# Read back the network as a data source
data "google_compute_network" "vpc_netsrc" {
        project = google_project.service_project.project_id
        name = google_compute_network.vpc_network.name
}
output "readnet_id" {
value = data.google_compute_network.vpc_netsrc.id
}

# get the VPC from the other project to peer with
data "google_compute_network" "network-to-peer-with" {
  project = "parent-project"
  name = "peering-networkname"
}

# This fails here as the google_compute_network.vpc_network.id returns the vpc name and not 
# projects/aproject/global/networks/mynetwork which fails the regex
resource "google_compute_network_peering" "peering-setup" {
    name         = "peering-with-peering-anotherproject"
    network      = google_compute_network.vpc_network.id
    peer_network = data.google_compute_network.network-to-peer-with.id
    export_custom_routes = "false"
    import_custom_routes = "true"
    depends_on = [data.google_compute_network.network-to-peer-with, google_compute_network.vpc_network ]
  }

Debug Output

network_id   = "mynetwork"
readnet_id    = "projects/aproject/global/networks/mynetwork"
│ Error: "network" ("mynetwork") doesn't match regexp "projects/((?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?)))/global/networks/((?:[a-z](?:[-a-z0-9]*[a-z0-9])?))$"
│ 
│   with google_compute_network_peering.peering-setup,
│   on project.tf line 134, in resource "google_compute_network_peering" "peering-setup":
│  134:   network      = google_compute_network.vpc_network.id

Expected Behavior

I expect that the .id attribute to return the same values. The docs say the it should return "an identifier for the resource with format projects/{{project}}/global/networks/{{name}}"

Actual Behavior

Its returning only the vpc name and not projects/{{project}}/global/networks/{{name}}

Steps to Reproduce

  1. terraform plan
  2. check the output values, the resource and data sources return different values for the .id attribute.

Important Factoids

I use a service account json token to authenticate with GCP This is project that was built some time ago and we are trying to add peering between projects.

References

b/314111131

gdelaney commented 3 years ago

A work around for this was to remove the network from the state, then import it back. The ID field is now in the correct format.

terraform state rm google_compute_network.vpc_network
terraform import google_compute_network.vpc_network projects/aproject/global/networks/mynetwork
Klaitos commented 2 years ago

Same issue here, thanks for the workaround.

roaks3 commented 11 months ago

There appears to be different behavior now with google_compute_network.id: it does appear to be in the format projects/{{project}}/global/networks/{{name}}. However, while this format is accepted by the API behind google_compute_network_peering, it ends up creating a diff, because the format returned by the server is https://www.googleapis.com/compute/v1/projects/{{project}}/global/networks/{{name}}.

We could choose to support passing network.id (similar to https://github.com/GoogleCloudPlatform/magic-modules/pull/3621), but we would need to build in some custom logic. However, for now, the recommended solution is to use self_link, as mentioned in the examples.