TerraformでBQデータセット作成時のアクセス権指定でのハマり("OWNER" -> nullという変更差分がplanで出続ける問題)

TerraformでBQデータセットを作った際に、applyは成功するのですが、その直後planをしても変更差分を永遠検出し続けてしまうというハマりがあったので備忘録しておきます。

# 発生した問題と再現手順
以下のようにデータセットを作成し、アクセス件として、「roles/bigquery.dataOwner」を同じくTerraformで作ったサービスアカウントへ付与する。
**ポイント：アクセス権を、`google_bigquery_dataset`の`access`項で指定している**
```terraform
resource "google_bigquery_dataset" "transfer_dest" {
  dataset_id  = "transfer_dest"
  location    = "US"

  access {
    role          = "roles/bigquery.dataOwner"
    user_by_email = google_service_account.bq_upload_account.email
  }
}

resource "google_service_account" "bq_upload_account" {
  account_id = "bq_upload_account"
  description = "xxxxxxxxxxxxxx"
}
```
planで見ると、以下の通り。特に違和感は無し。
```
Terraform will perform the following actions:

  # module.stg.google_bigquery_dataset.transfer_dest will be created
  + resource "google_bigquery_dataset" "transfer_dest" {
      + creation_time              = (known after apply)
      + dataset_id                 = "dataset-id"
      + delete_contents_on_destroy = false
      + etag                       = (known after apply)
      + id                         = (known after apply)
      + last_modified_time         = (known after apply)
      + location                   = "US"
      + project                    = (known after apply)
      + self_link                  = (known after apply)

      + access {
          + role          = "roles/bigquery.dataOwner"
          + user_by_email = "bq_upload_account@project-name.iam.gserviceaccount.com"
        }
    }

Plan: 1 to add, 0 to change, 0 to destroy.
```
applyしてデータセット作成に成功した直後にplanをしたところ、以下のような差分を検知！
**（これが当記事で言及している問題！）**

```
Terraform will perform the following actions:

  # module.stg.google_bigquery_dataset.transfer_dest will be updated in-place
  ~ resource "google_bigquery_dataset" "transfer_dest" {
        id                              = "projects/project-name/datasets/dataset_name"
        # (11 unchanged attributes hidden)

      - access {
          - role          = "OWNER" -> null
          - user_by_email = "bq_upload_account@project-name.iam.gserviceaccount.com" -> null
        }
      + access {
          + role          = "roles/bigquery.dataOwner"
          + user_by_email = "bq_upload_account@project-name.iam.gserviceaccount.com"
        }
    }

Plan: 0 to add, 1 to change, 0 to destroy.
```
この後、再度applyして成功するも、更にplanを表示しても同じ状況になる。
つまり、`"OWNER" -> null`の箇所が余分です。こんな指定は後にも先にも全くしていないのですが。
これは気持ち悪い・・・

# 解決方法
理屈はちゃんとわかっていませんが、以下のようにアクセス権付与を`google_bigquery_dataset_access`という別のリソースタイプでデータセットとは別個に指定してあげることで、当該事象は発生しなくなりました。

```terraform
resource "google_bigquery_dataset" "transfer_dest" {
  dataset_id  = "transfer_dest"
  location    = "US"
}

resource "google_bigquery_dataset_access" "access" {
  dataset_id    = google_bigquery_dataset.transfer_dest.dataset_id
  role          = "roles/bigquery.dataOwner"
  user_by_email = google_service_account.bq_upload_account.email
}

resource "google_service_account" "bq_upload_account" {
  account_id = "bq_upload_account"
  description = "xxxxxxxxxxxxxx"
}
```

# 原因の想像
BQのデータセットをGUIポチポチで作ったりすると、プロジェクトレベルのIAMから継承がされたしてきますが、`google_bigquery_dataset`の`access`項とかち合ってしまい、妙な状況になったりしているのかなと思いました。内部実装を見ていたりしていないので完全なる推測になります。

以上です！