Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BigQuery Authorized Datasets gets overwritten when any new changes to BigQuery Dataset IAM are applied during tf apply #11218

Closed
archeanlokinindi05 opened this issue Mar 4, 2022 · 22 comments

Comments

@archeanlokinindi05
Copy link

archeanlokinindi05 commented Mar 4, 2022

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request.
  • Please do not leave +1 or me too comments, they generate extra noise for issue followers and do not help prioritize the request.
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment.
  • If an issue is assigned to the modular-magician user, it is either in the process of being autogenerated, or is planned to be autogenerated soon. If an issue is assigned to a user, that user is claiming responsibility for the issue. If an issue is assigned to hashibot, a community member has claimed the issue already.

Terraform Version

1.0.11

Affected Resource(s)

  • google_bigquery_dataset

Panic Output

There is no error output, the authorized datasets are getting removed.

Expected Behavior

Authorized Datasets shouldnt have been reset.

Actual Behavior

Authorized datasets are getting reset on Dataset IAM terraform apply

Steps to Reproduce

  1. Create two BigQuery Datasets, add one as the authorized dataset to another.
  2. Add a new user as a dataViewer and run the terraform apply, you will

b/300616992

@archeanlokinindi05
Copy link
Author

The above bug with the provider is related to this issue here #11091. We noticed it when we tested it against the latest provider release.

@c2thorn
Copy link
Collaborator

c2thorn commented Mar 9, 2022

Hi @archeanlokinindi05,

Looking for some clarification here. Can you provide some more logging of the terraform apply?

Is the Terraform plan output stating the the resource will be replaced when adding the new user? Or does it state it will be updated in-place and then remove the resource later?

@MeuXX74
Copy link

MeuXX74 commented Apr 27, 2022

Hello,

We are facing the same issues.
Here is an example of a plan, which is adding one user to the dataset, but as we can see it tries to remove all (after that user) and re-add them, but those have actually no changes.

`
google_bigquery_dataset.income_tracking_live will be updated in-place
~ resource "google_bigquery_dataset" "income_tracking_live" {
id = "projects/bigquery-prod/datasets/income_tracking_live"
# (13 unchanged attributes hidden)

  - access {
    }
  - access {
      - role          = "OWNER" -> null
      - special_group = "projectOwners" -> null
    }
  - access {
      - role          = "READER" -> null
      - special_group = "projectReaders" -> null
    }
  - access {
      - role          = "WRITER" -> null
      - special_group = "projectWriters" -> null
    }
  - access {
      - group_by_email = "[email protected]" -> null
      - role           = "READER" -> null
    }
  - access {
      - group_by_email = "[email protected]" -> null
      - role           = "READER" -> null
    }
  - access {
      - group_by_email = "[email protected]" -> null
      - role           = "WRITER" -> null
    }
  - access {
      - group_by_email = "[email protected]" -> null
      - role           = "READER" -> null
    }
  + access {
      + group_by_email = "[email protected]"
      + role           = "READER"
    }
  + access {
      + group_by_email = "[email protected]"
      + role           = "READER"
    }
  + access {
      + group_by_email = "[email protected]"
      + role           = "WRITER"
    }
  + access {
      + group_by_email = "[email protected]"
      + role           = "READER"
    }
  + access {
      + role          = "OWNER"
      + special_group = "projectOwners"
    }
  + access {
      + role          = "READER"
      + special_group = "projectReaders"
    }
  + access {
      + role          = "WRITER"
      + special_group = "projectWriters"
    }

    # (1 unchanged block hidden)
}`

@ghost
Copy link

ghost commented Jun 14, 2022

What is the update on this issue.

@RenardTheFox
Copy link

We're seeing the same problem across our projects and this has been going on for quite some time.

We've explored other options, including restructuring our resources to use "google_bigquery_dataset_access" or, even better (since it actually allows us to use the Google recommended BQ roles and not the BQ dataset level legacy basic roles they discourage people from using, especially in production) the "google_bigquery_dataset_iam_binding" resource. Unfortunately, neither of these will work for a variety of reasons, not the least of which is that they cannot be used together and the "google_bigquery_dataset_iam_binding" resource cannot be used with Authorized Views.

@dalekseevs
Copy link

Using "google_bigquery_dataset" resource worked for us. It is authoritative, so acts as a combination google_bigquery_dataset_iam_binding and google_bigquery_dataset_access. It is also more performant, as it is only a single resource per dataset + all access definitions. However, we encountered another issue, that it recreates access blocks even if they are the same sometimes. This is an unrelated bug however.

@nolan-jardine
Copy link

I outlined the issues with all 5 BigQuery dataset access control options here: #11461 (comment)

There doesn't seem to be an authoritative way to manage BigQuery dataset access that supports authorized datasets/views and does not generate horrendous plans when a single change to access is made.

@github-actions github-actions bot added service/bigquery forward/review In review; remove label to forward labels Aug 17, 2023
@edwardmedia edwardmedia removed the forward/review In review; remove label to forward label Sep 14, 2023
@Roman-Mekicki
Copy link

Hey, what is status of this bug?

@bakuljajan
Copy link

Hi @c2thorn @edwardmedia, It seems that the resource does not support VIEWS destructively if using google_bigquery_dataset_iam_member (in our case). Granting access (or removal) for a user to a dataset that has any Authorized View makes it delete the authorized dataset.

Looking in the debug log when applying,

[DEBUG] provider.terraform-provider-google_v4.84.0_x5: -----------------------------------------------------
[DEBUG] provider.terraform-provider-google_v4.84.0_x5: 2023/11/02 15:44:23 [DEBUG] Google API Response Details:
[DEBUG] provider.terraform-provider-google_v4.84.0_x5: ---[ RESPONSE ]--------------------------------------
[DEBUG] provider.terraform-provider-google_v4.84.0_x5: HTTP/2.0 200 OK
[DEBUG] provider.terraform-provider-google_v4.84.0_x5: Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
[DEBUG] provider.terraform-provider-google_v4.84.0_x5: Cache-Control: private
[DEBUG] provider.terraform-provider-google_v4.84.0_x5: Content-Type: application/json; charset=UTF-8
[DEBUG] provider.terraform-provider-google_v4.84.0_x5: Date: Thu, 02 Nov 2023 08:44:26 GMT
[DEBUG] provider.terraform-provider-google_v4.84.0_x5: Etag: b8O1zg0u6PWM+tPoL9W6Sg==
[DEBUG] provider.terraform-provider-google_v4.84.0_x5: Server: ESF
[DEBUG] provider.terraform-provider-google_v4.84.0_x5: Vary: Origin
[DEBUG] provider.terraform-provider-google_v4.84.0_x5: Vary: X-Origin
[DEBUG] provider.terraform-provider-google_v4.84.0_x5: Vary: Referer
[DEBUG] provider.terraform-provider-google_v4.84.0_x5: X-Content-Type-Options: nosniff
[DEBUG] provider.terraform-provider-google_v4.84.0_x5: X-Frame-Options: SAMEORIGIN
[DEBUG] provider.terraform-provider-google_v4.84.0_x5: X-Xss-Protection: 0
[DEBUG] provider.terraform-provider-google_v4.84.0_x5: 
[DEBUG] provider.terraform-provider-google_v4.84.0_x5: {
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:   "kind": "bigquery#dataset",
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:   "etag": "b8O1zg0u6PWM+tPoL9W6Sg==",
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:   "id": "<redacted>:test_terraform",
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:   "selfLink": "https://bigquery.googleapis.com/bigquery/v2/projects/<redacted>/datasets/test_terraform",
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:   "datasetReference": {
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:     "datasetId": "test_terraform",
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:     "projectId": "<redacted>"
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:   },
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:   "access": [
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:     {
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:       "role": "WRITER",
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:       "specialGroup": "projectWriters"
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:     },
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:     {
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:       "role": "OWNER",
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:       "specialGroup": "projectOwners"
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:     },
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:     {
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:       "role": "OWNER",
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:       "userByEmail": "brian.lie@<redacted>"
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:     },
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:     {
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:       "role": "READER",
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:       "specialGroup": "projectReaders"
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:     },
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:     {
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:       "dataset": {
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:         "dataset": {
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:           "datasetId": "test_terraform",
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:           "projectId": "<redacted>"
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:         },
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:         "targetTypes": [
[DEBUG] provider.terraform-provider-google_v4.84.0_x5: "VIEWS"
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:         ]
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:       }
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:     }
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:   ],
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:   "creationTime": "1698913473636",
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:   "lastModifiedTime": "1698913533730",
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:   "location": "asia-southeast2",
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:   "type": "DEFAULT",
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:   "isCaseInsensitive": false,
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:   "maxTimeTravelHours": "168",
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:   "storageBillingModel": "LOGICAL"
[DEBUG] provider.terraform-provider-google_v4.84.0_x5: }

the provider got the correct access from the dataset but when we try to apply, we observe that the dataset part is missing

[DEBUG] provider.terraform-provider-google_v4.84.0_x5: ---[ REQUEST ]---------------------------------------
[DEBUG] provider.terraform-provider-google_v4.84.0_x5: PATCH /bigquery/v2/projects/<redacted>/datasets/test_terraform?alt=json HTTP/1.1
[DEBUG] provider.terraform-provider-google_v4.84.0_x5: Host: bigquery.googleapis.com
[DEBUG] provider.terraform-provider-google_v4.84.0_x5: User-Agent: Terraform/1.3.10 (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google/4.84.0
[DEBUG] provider.terraform-provider-google_v4.84.0_x5: Content-Length: 375
[DEBUG] provider.terraform-provider-google_v4.84.0_x5: Content-Type: application/json
[DEBUG] provider.terraform-provider-google_v4.84.0_x5: Accept-Encoding: gzip
[DEBUG] provider.terraform-provider-google_v4.84.0_x5: 
[DEBUG] provider.terraform-provider-google_v4.84.0_x5: {
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:  "access": [
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:   {
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:    "role": "roles/bigquery.dataEditor",
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:    "specialGroup": "projectWriters"
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:   },
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:   {
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:    "role": "roles/bigquery.dataOwner",
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:    "specialGroup": "projectOwners"
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:   },
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:   {
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:    "role": "roles/bigquery.dataOwner",
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:    "userByEmail": "brian.lie@<redacted>"
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:   },
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:   {
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:    "role": "roles/bigquery.dataViewer",
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:    "specialGroup": "projectReaders"
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:   },
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:   {
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:    "role": "roles/bigquery.metadataViewer",
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:    "userByEmail": "thomas.wangsa@<redacted>"
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:   }
[DEBUG] provider.terraform-provider-google_v4.84.0_x5:  ]
[DEBUG] provider.terraform-provider-google_v4.84.0_x5: }

As you can see, the part for configuring the Authorized Dataset is missing.

{
    "dataset": {
        "dataset": {
            "datasetId": "test_terraform",
            "projectId": "<redacted>"
        },
        "targetTypes": [
            "VIEWS"
        ]
    }
}

This makes the terraform accidentally delete the access.
image

@wj-chen
Copy link

wj-chen commented Nov 4, 2023

I'm from the BigQuery Terraform team. Thank you all for your reports. Let's continue to use this issue to track problems related to the behavior of authorized datasets getting removed unexpectedly. For concerns about the access blocks causing permadiffs, please create a separate issue. Our team has seen similar complications with other BigQuery Terraform resource fields and we will address them together.

Meanwhile I wasn't able to reproduce this issue with the google_bigquery_dataset resource. I see some people might be using google_bigquery_dataset_access instead. Can anyone share some example configs, both the baseline config and a change that would trigger an Update?

@bakuljajan
Copy link

Hi @wj-chen, you can try using this example

resource "google_bigquery_dataset" "this" {
  dataset_id    = "bq_test_tf"
  friendly_name = "bq_test_tf"
  labels = {
    "created_by"  = "eka"
    "environment" = "staging"
  }
  location = "US"
  project  = "my-gcp-project"

  access {
    dataset {
      dataset {
        project_id = "my-gcp-project"
        dataset_id = "bq_ds_test1"
      }
      target_types = ["VIEWS"]
    }
  }
}

resource "google_bigquery_dataset_iam_member" "this" {
  dataset_id = google_bigquery_dataset.this.dataset_id
  project    = google_bigquery_dataset.this.project
  role       = "roles/bigquery.dataEditor"
  member     = "user:[email protected]"
}

The first apply will succeed but when you replan, it will re add the authorized dataset

  # google_bigquery_dataset.this will be updated in-place
  ~ resource "google_bigquery_dataset" "this" {
        id                              = "projects/my-gcp-project/datasets/bq_test_tf"
        # (13 unchanged attributes hidden)

      + access {
          + dataset {
              + target_types = [
                  + "VIEWS",
                ]

              + dataset {
                  + dataset_id = "bq_ds_test1"
                  + project_id = "my-gcp-project"
                }
            }
        }
      - access {
          - role          = "OWNER" -> null
          - special_group = "projectOwners" -> null
        }
      - access {
          - role          = "READER" -> null
          - special_group = "projectReaders" -> null
        }
      - access {
          - role          = "WRITER" -> null
          - user_by_email = "[email protected]" -> null
        }
      - access {
          - role          = "WRITER" -> null
          - special_group = "projectWriters" -> null
        }
    }

@wj-chen
Copy link

wj-chen commented Nov 7, 2023

Thank you @bakuljajan. I can see that in this case the google_bigquery_dataset_iam_member config overrode google_bigquery_dataset.access. In https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/bigquery_dataset_iam, there are several Notes that call out potential conflicts like this. Is there a reason you are unable to define all IAM configs in google_bigquery_dataset.access or google_bigquery_dataset + google_bigquery_dataset_access?

@bakuljajan
Copy link

bakuljajan commented Nov 7, 2023

Is there a reason you are unable to define all IAM configs in google_bigquery_dataset.access or google_bigquery_dataset + google_bigquery_dataset_access?

@wj-chen it just feels unnatural to manage access using a dataset resource, access to bigquery can be granted in project, dataset, and table. For the project and table, we need to use terraform iam_member/iam_binding resources but not the dataset. Isn't that weird?

To be honest, we already implemented user/service account access using iam_member/iam_binding for a long time now and we just noticed this behavior recently since we only recently explored access using authorized view/dataset. For us, the effort to migrate the whole dataset access from iam_member/iam_binding to dataset_access is really big.

@bakuljajan
Copy link

I've also tried using the suggested google_bigquery_dataset and got permadiffs problem mentioned in #7755 #7142 #3929

I can't use the google_bigquery_dataset_access since it does not support import yet, as mentioned in #7486 #7659

@wj-chen
Copy link

wj-chen commented Nov 8, 2023

@bakuljajan Thank you for sharing your use cases. Dataset permissions work slightly differently from permissions for projects/tables/jobs etc. and the complication happens upstream at the API level. There is work underway to improve that but won't be available in the near future.

I've also tried using the suggested google_bigquery_dataset and got permadiffs problem mentioned in #7755 #7142 #3929

This appears to be a framework-level issue. I added a comment to check on the latest state in hashicorp/terraform#21901.

I can't use the google_bigquery_dataset_access since it does not support import yet, as mentioned in #7486 #7659

Acknowleged.

To mitigate the issue with authorized dataset/view specifically, we will explore if it's feasible to update the behavior of google_bigquery_dataset_iam_member to modify only role bindings and not authorized dataset/view settings, which should work for your case.

Meanwhile I'd like to see if that'd also work for the other users here. If anyone is using a combination different from google_bigquery_dataset + google_bigquery_dataset_iam_member, please also share sample configs and the actual behavior of the configs.

@fpopic
Copy link
Contributor

fpopic commented Nov 18, 2023

Might help (a bit hard to read)

https://www.cloud-computing-koeln.de/bigquery-authorized-views-permissions-via-terraform-avoiding-the-chicken-egg-problem

google_bigquery_dataset_iam_policy: Authoritative.
Sets the IAM policy for the dataset and replaces any existing policy already attached.

google_bigquery_dataset_iam_binding: Authoritative for a given role.
Updates the IAM policy to grant a role to a list of members. Other roles within the IAM policy for the dataset are preserved.

google_bigquery_dataset_iam_member: Non-authoritative. Updates the IAM policy to grant a role to a new member. Other members for the role for the dataset are preserved.

Using any of these resources together with an authorized view will remove the permissions from the dataset. If any of these resources are used in conjunction with the google_bigquery_dataset_access resource or the access field on the google_bigquery_dataset resource, we will end up in a race condition where these resources will fight over which permissions take precedence.

So, this essentially means that if we try to create and assign permissions to authorized views simultaneously as dataset creation from within the Terraform code, we will end up with a chicken & egg problem where there will be a dispute between the dataset and authorized views policy, causing the authorized views permissions to be wiped out as a result.

@wj-chen
Copy link

wj-chen commented Feb 5, 2024

This work is still pending engineering capacity from our team. Will add exploration of any potential quick fixes into our Q1 planning .

@dmitri-lerko
Copy link

This is a huge pain-point for our usage of Terraform + BigQuery where we need a lot of focus from engineers to analyse plans or risk missing out a drift in permissions or accidental removal of permissions. We train people to expect noisy plans which create perma-plan fatigue.

@husseyd
Copy link

husseyd commented Mar 19, 2024

It seems that applying any google_bigquery_dataset_iam_member to a dataset will also erase dataset authorization config that has been made outside of Terraform.

EG,

  1. via console I authorise access to dataset A ('data' dataset) from dataset B ('view' dataset)
  2. In Terraform I grant a role like roles/bigquery.dataViewer to a group on dataset A using google_bigquery_dataset_iam_member

Then the dataset authorization I configured in step 1 is gone!

sachinpro added a commit to sachinpro/magic-modules that referenced this issue Apr 30, 2024
…ng current and new binding for google_bigquery_dataset_iam_member
sachinpro added a commit to sachinpro/magic-modules that referenced this issue Apr 30, 2024
…ng current and new binding for google_bigquery_dataset_iam_member
@sachinpro
Copy link

Draft PR-10560 aims to fix this.

sachinpro added a commit to sachinpro/magic-modules that referenced this issue Aug 5, 2024
…ng current and new binding for google_bigquery_dataset_iam_member
sachinpro added a commit to sachinpro/magic-modules that referenced this issue Aug 13, 2024
…ng current and new binding for google_bigquery_dataset_iam_member
sachinpro added a commit to sachinpro/magic-modules that referenced this issue Aug 13, 2024
…ng current and new binding for google_bigquery_dataset_iam_member
c2thorn pushed a commit to GoogleCloudPlatform/magic-modules that referenced this issue Aug 13, 2024
modular-magician added a commit to modular-magician/terraform-provider-google-beta that referenced this issue Aug 13, 2024
…… (#11352)

[upstream:649cb8b86339253af356ad48f0b523b2acfb099f]

Signed-off-by: Modular Magician <[email protected]>
modular-magician added a commit to modular-magician/terraform-provider-google that referenced this issue Aug 13, 2024
[upstream:649cb8b86339253af356ad48f0b523b2acfb099f]

Signed-off-by: Modular Magician <[email protected]>
modular-magician added a commit to hashicorp/terraform-provider-google-beta that referenced this issue Aug 13, 2024
…… (#11352) (#7960)

[upstream:649cb8b86339253af356ad48f0b523b2acfb099f]

Signed-off-by: Modular Magician <[email protected]>
modular-magician added a commit that referenced this issue Aug 13, 2024
[upstream:649cb8b86339253af356ad48f0b523b2acfb099f]

Signed-off-by: Modular Magician <[email protected]>
@sachinpro
Copy link

GoogleCloudPlatform/magic-modules#11352 should fix this.

Copy link

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.
If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 14, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests