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.36k stars 1.75k forks source link

Can't import project_id with `google_pubsub_subscription_iam` #17684

Open antoinedeschenes opened 8 months ago

antoinedeschenes commented 8 months ago

Community Note

Terraform Version

Terraform v1.6.6
+ provider registry.terraform.io/hashicorp/google v5.21.0

Affected Resource(s)

google_pubsub_subscription_iam_*

Terraform Configuration

import {
  id = "projects/your-project/subscriptions/your-subscription-name roles/pubsub.subscriber serviceAccount:your-sa@your-project.iam.gserviceaccount.com"
  to = google_pubsub_subscription_iam_member.default
}

resource "google_pubsub_subscription_iam_member" "default" {
  subscription = "your-subscription-name"
  project      = "your-project"
  role         = "roles/pubsub.subscriber"
  member       = "serviceAccount:your-sa@your-project.iam.gserviceaccount.com"
}

Debug Output

No response

Expected Behavior

  # google_pubsub_subscription_iam_member.default will be imported
    resource "google_pubsub_subscription_iam_member" "default" {
        id           = "your-subscription-name/roles/pubsub.subscriber/serviceAccount:your-sa@your-project.iam.gserviceaccount.com"
        member       = "serviceAccount:your-sa@your-project.iam.gserviceaccount.com"
        project      = "your-project"
        role         = "roles/pubsub.subscriber"
        subscription = "your-subscription-name"
    }

Actual Behavior

Without CLOUDSDK_CORE_PROJECT environment variable

 Error: project: required field is not set

With CLOUDSDK_CORE_PROJECT set, the import ID isn't parsed properly, and the project is set in the subscription name instead:

  # google_pubsub_subscription_iam_member.default must be replaced
  # (imported from "projects/your-project/subscriptions/your-subscription-name roles/pubsub.subscriber serviceAccount:your-sa@your-project.iam.gserviceaccount.com")
  # Warning: this will destroy the imported resource
-/+ resource "google_pubsub_subscription_iam_member" "default" {
      ~ id           = "projects/your-project/subscriptions/your-subscription-name/roles/pubsub.subscriber/serviceAccount:your-sa@your-project.iam.gserviceaccount.com" -> (known after apply)
        member       = "serviceAccount:your-sa@your-project.iam.gserviceaccount.com"
      + project      = "your-project" # forces replacement
        role         = "roles/pubsub.subscriber"
      ~ subscription = "projects/your-project/subscriptions/your-subscription-name" -> "your-subscription-name"
    }

Steps to reproduce

  1. terraform plan

Important Factoids

No response

References

Import id parsing seems to look for the subscription name only, without parsing the project and subscription properly in the path.

https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/pubsub_subscription_iam#import

b/331832959

ggtisc commented 8 months ago

Hi @antoinedeschenes I can see that you are declaring you project here in the resource google_pubsub_subscription_iam_member:

resource "google_pubsub_subscription_iam_member" "default" {
  subscription = "your-subscription-name"
  **project      = "your-project"**
  role         = "roles/pubsub.subscriber"
  member       = "serviceAccount:your-sa@your-project.iam.gserviceaccount.com"
}

But at the same time, you are importing it here but never using or reference it:

import {
  id = "projects/your-project/subscriptions/your-subscription-name roles/pubsub.subscriber serviceAccount:your-sa@your-project.iam.gserviceaccount.com"
  to = google_pubsub_subscription_iam_member.default
}

If you want to use your imported project on the "google_pubsub_subscription_iam_member" "default" you just need to reference it:

resource "google_pubsub_subscription_iam_member" "default" {
  **project      = google_pubsub_subscription_iam_member.default.project**
  subscription = "your-subscription-name"
  role         = "roles/pubsub.subscriber"
  member       = "allUsers"
}
antoinedeschenes commented 8 months ago

@ggtisc why are you referring google_pubsub_subscription_iam_member.default to itself?

resource "google_pubsub_subscription_iam_member" "default" {
  **project      = google_pubsub_subscription_iam_member.default.project**

the import block is equivalent to running:

terraform import google_pubsub_subscription_iam_member.default "projects/your-project/subscriptions/your-subscription-name roles/pubsub.subscriber serviceAccount:your-sa@your-project.iam.gserviceaccount.com"

manually

roaks3 commented 8 months ago

Confirmed the issue, and agreed that the import ID parsing looks incorrect.

roy-work commented 7 months ago

I've been able to work around this by setting GOOGLE_PROJECT=garbage (literally). The value you supply in the environment variable doesn't seem to have any bearing except that it silences the error. But I have to do this on both the import, and on subsequent terraform plan runs, as well, so it is less than ideal.

I run into the same # forces replacement issue, too. That can then be worked around by editing the state, manually, though obviously, one must be careful here. In the state file, you will find that,

"project": null,

Tweak that to the project ID, and plan should be happy / converge on no changes.

After I resolved the issue with "project": null in the state file, and plan was happy again, it was no longer necessary to supply a garbage value for GOOGLE_PROJECT (i.e., that environment variable can just be unset, which is what it is normally for me).