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

Destruction of `google_bigquery_dataset_iam_member` does not remove the underlying IAM membership from the dataset policy #19343

Closed najose closed 4 hours ago

najose commented 2 months ago

Community Note

Terraform Version & Provider Version(s)

Terraform v1.7.5 on linux_amd64

Affected Resource(s)

google_bigquery_dataset_iam_member

Terraform Configuration

terraform {
  required_version = ">= 1.7.2"
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "~> 6.0"
    }
    google-beta = {
      source  = "hashicorp/google-beta"
      version = "~> 6.0"
    }
  }
}

resource "google_service_account" "test_sa" {
  project      = "my-test-project"
  account_id   = "test-sa-todel"
  display_name = "SA to test big query IAM bug."
}

resource "google_bigquery_dataset_iam_member" "test-bq-dataset-policy" {
  project    = "my-test-project"
  dataset_id = "dataset_id"
  role       = "roles/bigquery.dataEditor"
  member     = google_service_account.test_sa.member
}

Debug Output

No response

Expected Behavior

On destroying the resources (the google_service_account and google_bigquery_dataset_iam_member) are destroyed and the underlying IAM membership for the service account is removed from the BigQuery dataset IAM policy.

Actual Behavior

On destroying the resources (the google_service_account and google_bigquery_dataset_iam_member) are destroyed and the underlying IAM membership for the deleted service account is not removed from the BigQuery dataset IAM policy.

Steps to reproduce

  1. terraform apply

Important Factoids

No response

References

No response

b/365168686

melinath commented 2 months ago

I am able to reproduce this with the following steps:

  1. Apply this configuration:
resource "google_service_account" "test-account" {
  account_id   = "tf-test-bq-iam-kajwerhr"
  display_name = "Bigquery Dataset IAM Testing Account"
}

resource "google_bigquery_dataset_iam_member" "member" {
  dataset_id = google_bigquery_dataset.dataset.dataset_id
  role     = "roles/bigquery.dataViewer"
  member   = "serviceAccount:${google_service_account.test-account.email}"
}

resource "google_bigquery_dataset" "dataset" {
  dataset_id = "example_dataset"
}
  1. In BigQuery Explorer, expand your project and click on example_dataset in the sidebar. Click on "Sharing > Permissions" and expand the BigQuery Data Viewer section. Confirm that the tf-test-bq-iam-kajwerhr is there.
  2. Comment out the iam member resource & reapply.
  3. Reload the BigQuery permissions and confirm that the tf-test-bq-iam-kajwerhr account is still there.

I waited five minutes to be sure this wasn't somehow a propagation issue.

melinath commented 2 months ago

It looks like this may have been an intentional change as part of https://github.com/GoogleCloudPlatform/magic-modules/pull/11352 based on the release note:

bigquery: made `google_bigquery_dataset_iam_member` non-authoritative. To remove a bigquery dataset iam member, use an authoritative resource like `google_bigquery_dataset_iam_policy`

However, I agree that this is potentially a dangerous behavior (since it could silently leave permissions in place that a user thought were removed.) Forwarding to engineering for consideration.

melinath commented 2 months ago

Additional context: IAM member resources are generally considered "non-authoritative" in that they don't remove other parts of the IAM policy. However, they still remove the access described in the resource when deleted.

If this new behavior is intentional, it could be worth reconsidering the documentation to make it more clear that this is a different "non-authoritative" than other IAM member resources.

bardsleysdgr commented 2 months ago

@melinath thank you for examing this issue. I appreciate and understand your comments, however...

resource "google_bigquery_dataset_iam_member" "member" {
  dataset_id = google_bigquery_dataset.dataset.dataset_id
  role     = "roles/bigquery.dataViewer"
  member   = "serviceAccount:${google_service_account.test-account.email}"
}

Declaring this resource creates the IAM binding, it doesn't do anything else, that is all it does. Why would removing this resource not remove the binding?

Forcing people to "To remove a bigquery dataset iam member, use an authoritative resource like google_bigquery_dataset_iam_policy" creates an entirely new paradigm of the relationship between a resource declaration in HCL and the actual object. Where objects are created in one resource block but removed by creating an entirely new and different resource block that exists to define the absence of something that has been deleted.

This is a significant change in how both terraform and the google provider work, and effectively deprecates "IAM member" as a concept and forces everyone to use "iam binding" or "iam policy".

oprudkyi commented 1 month ago

we used next approach

now we have huge security issue because deleting google_bigquery_dataset_iam_member doesn't remove real iam

fpopic commented 11 hours ago

Is this issue resolved? can it be closed?

melinath commented 4 hours ago

It looks like this was resolved by https://github.com/GoogleCloudPlatform/magic-modules/pull/11853