Terraform を用いて Analytics Hub を設定してみた

## はじめに
本記事は、[BigQuery Advent Calendar 2023](https://qiita.com/advent-calendar/2023/bigquery) 13日目の記事です。


私自身、普段の業務で Analytics Hub を利用しています。
Analytics Hub に関する記事も増えてきていて、個人的にもたくさん参考にさせていただいています。

ですが、私が調べた限りでは、
Terraform を用いての Analytics Hub を設定している記事は見当たりませんでした。
<font color="DarkGray">(公式ドキュメントがあるのでは？という声が聞こえてきそうですが、温かい目で見守ってください)</font>

実は、私自身がデータエンジニアとして働き始めてまだ半年弱です。
多くの調べ物をする中で、公式ドキュメントと併せて、皆さんの記事をたくさん読むことで自分の勉強になりました。

そんな思いから、少しでも、どなたかのお役に立てばと思い、書いていきます。

## 前提
本記事の趣旨から外れてしまうこともあり、一部、基礎知識は割愛させていただきます。
公式ドキュメントや既にたくさんのわかりやすい記事が存在しています。そちらをご確認ください。

少しだけ記載します。
- Terraform とは、HashiCorp 社が提供する IaC (Infrastructure as Code) の一つです。
- Analytics Hubは、異なる組織間において、Bigqueryデータセットを効率よく安全に共有することができるサービスです。

加えて、今回の環境において、以下は Terraform 管理外、もしくは割愛しています。
- 共有するデータセット
- 各プロジェクトの Analytics Hub API 有効化
- Google Cloud プロジェクトと Terraform の接続方法

## 本題
それでは、Terraform を用いて、Analytics Hub の設定を行っていきます。
Analytics Hub の設定手順は大きく分けて、以下の3つです。
### 手順
1. データエクスチェンジ を作成
2. リスティング を作成
3. ユーザーにサブスクライバー権限を付与


### １．データエクスチェンジを作成
まずは、データエクスチェンジを作成する必要があります。
Terraform のコードは以下の通りです。


```terraform:main.tf
resource "google_bigquery_analytics_hub_data_exchange" "test" {
  
  #Required
    location         = "US"
    data_exchange_id = "test_analytics_hub"
    display_name     = "test_analytics_hub"
  
  #Optional
    primary_contact  = "XXXXX@gmail.com"
    description      = "テストデータです"
    
}
```
コンソールで確認すると、以下のようにデータエクスチェンジが作成されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2785991/92312394-0408-d4c1-c9f4-d47e26df8050.png)

<img width="450" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2785991/caaa5435-715c-9a2b-f86a-65a567076b45.png">

その名の通りですが、
`primary_contact` が「メインの連絡先」、`description` が「説明」として設定されています。
※特に設定をしなかった場合は「値なし」と表示されます。

また、プロジェクトはコード内で定義していないため、provider のプロジェクトが自動的に指定されています。（今回の場合だと、publisher-XXXXXX）

その他、詳細は[公式ドキュメント](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/bigquery_analytics_hub_data_exchange)をご確認ください。

### 2．リスティングを作成
続いて、リスティングを作成します。Tearraform のコードは以下の通りです。
```terraform:main.tf
resource "google_bigquery_analytics_hub_listing" "test" {

  #Required
    location         = "US"
    data_exchange_id = google_bigquery_analytics_hub_data_exchange.test.data_exchange_id
    listing_id       = "test_listing"
    display_name     = "test_listing"

    bigquery_dataset {
      dataset = "projects/publisher-XXXXXX/datasets/test_dataset"
    }

  #Optional
    description      = "テストデータです"
    documentation    = "このデータは、テストデータです"
    
}
```
ここで作成するリスティングは、先ほど作成したデータエクスチェンジと関連付ける必要があるため、`data_exchange_id` で 引用しています。


コンソールで確認すると、以下のようにリスティングが作成されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2785991/c934b99e-753b-92b5-5bd5-79ca9321a3cb.png)

`description` と `documentation` が記載される位置も確認できるかと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2785991/d5573251-6c98-d1ad-c625-85b2b71f092f.png)


#### 補足
今回共有するデータセットは、以下の Terraform 管理外のものを指定しています。

<img width="200" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2785991/74fe3d49-1bc6-33d6-989b-fb146ae773b8.png">

この時、`dataset` は、`projects/プロジェクトid/datasets/データセットid`で指定することができます。
（[公式ドキュメント](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/bigquery_analytics_hub_listing#nested_bigquery_dataset)だと、Terraform 管理のデータセットを設定しているので、異なるパターンにしました）


### 3．ユーザーにサブスクライバー権限を付与
最後に、データセットの共有相手にサブスクライバー権限を付与します。
Tearraform のコードは以下の通りです。
```terraform:main.tf
data "google_iam_policy" "admin" {
  binding {
    role = "roles/analyticshub.subscriber"
    members = [
      "user:xxxxxx@gmail.com",
    ]
  }
}

resource "google_bigquery_analytics_hub_data_exchange_iam_policy" "policy" {
  project          = google_bigquery_analytics_hub_data_exchange.test.project
  location         = google_bigquery_analytics_hub_data_exchange.test.location
  data_exchange_id = google_bigquery_analytics_hub_data_exchange.test.data_exchange_id
  policy_data      = data.google_iam_policy.admin.policy_data
}
```


基本的に、権限付与に関連しない引数は、既に作成済であるデータエクスチェンジの情報を引用すれば問題ありません。


コンソールで確認すると、サブスクライバーとしてユーザーに権限が付与されていることが確認できます。

<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2785991/ece80edf-c6b2-a64b-442e-359f8100c53c.png">

:::note info
今回は、メールアドレスを用いて特定のユーザーのみに権限を付与しています。
しかしながら、グループ単位での権限付与や一般公開設定も可能です。
是非、[公式ドキュメント](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/bigquery_analytics_hub_data_exchange_iam)をご確認ください。
:::

以上で、Analytics Hub の設定は完了です。

#### 念のため
無事にサブスクライバーのプロジェクトにデータセットを登録することが出来ています。

<img width="200" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2785991/69b7be1a-2a6e-e490-341b-7af6609ab0d5.png">


### 最後に
今回は、Terraform を用いて Analytics Hub を設定してみました。
そこまで複雑な内容ではなく、比較的簡単に実装できることを感じていただけたのではないでしょうか？
Analytics Hub は、このように簡単にデータシェアリングを実現してくれます。
データクリーンルームもサポートされていることから、今後より一層、データシェアリングを行う上で有効的な手段の一つとして選択されていくのではないでしょうか？
皆さんも是非、色々な場面で Analytics Hub を利用してみていただけますと幸いです。