Analytics Hub publisher
Decide the sharing mechanism first
Analytics Hub is not always the answer. Work down this table before designing an exchange.
| Situation | Use | Why not Analytics Hub |
|---|---|---|
| One team, same org, one dataset | dataset IAM grant | an exchange is overhead for one grant |
| Row or column restrictions per consumer | authorized view, or row-level security | listings share the whole dataset |
| Many consumers, stable product, cross-project | Analytics Hub | this is what it is for |
| External partner, different org | Analytics Hub | no data copy, no egress, revocable |
| Consumer needs to write | not sharing, a pipeline | linked datasets are read-only |
| One-off extract | authorized view or an export | a listing implies a commitment |
Say plainly that a listing is a product commitment. Publishing one means you have promised a schema, a freshness, and a deprecation path to people you may never meet. If the user is not ready for that, recommend an authorized view instead.
Structure
- Exchange: a container, scoped by audience.
internal-analytics,partner-suppliers,public-reference. Do not put internal and partner listings in the same exchange. - Listing: one per data product, backed by one dataset.
- Linked dataset: what the subscriber creates in their own project. It is read-only, queried on the subscriber's own slots, and reflects the source live.
Billing follows the query, so subscribers pay for their own scans. Storage stays with you. Say this explicitly when someone asks who pays.
Prepare the source dataset before listing it
A listing exposes the whole dataset, so the dataset must contain only what you intend to publish. Build a dedicated publication dataset rather than listing a working dataset.
- Create
pub_<domain>containing only the published surfaces. - Populate it with authorized views over the marts, so you keep control of the column list.
- Description and column descriptions on everything. This is the documentation the subscriber sees, and it is the only documentation they get.
- Partition filters required, so a subscriber cannot accidentally scan history.
- A schema contract on file for each table. See
bq-schema-contract.
Terraform
resource "google_bigquery_analytics_hub_data_exchange" "internal" {
project = var.project_id
location = var.location
data_exchange_id = "internal_analytics"
display_name = "Internal analytics"
description = "Governed data products published by the data platform team."
primary_contact = "data-platform@example.com"
}
resource "google_bigquery_analytics_hub_listing" "orders" {
project = var.project_id
location = var.location
data_exchange_id = google_bigquery_analytics_hub_data_exchange.internal.data_exchange_id
listing_id = "retail_orders_v1"
display_name = "Retail orders, v1"
description = "One row per order. Grain: order_id. Refreshed daily by 07:00 UTC."
primary_contact = "data-platform@example.com"
documentation = "https://internal.example.com/docs/data/retail-orders"
bigquery_dataset {
dataset = google_bigquery_dataset.pub_retail.id
}
restricted_export_config {
enabled = true
restrict_query_result = true
}
}
resource "google_bigquery_analytics_hub_listing_iam_member" "finance" {
project = var.project_id
location = var.location
data_exchange_id = google_bigquery_analytics_hub_data_exchange.internal.data_exchange_id
listing_id = google_bigquery_analytics_hub_listing.orders.listing_id
role = "roles/analyticshub.subscriber"
member = "group:finance-analytics@example.com"
}
Version in the listing id, not just the display name. retail_orders_v1 and
retail_orders_v2 can coexist while consumers migrate, which is the whole point
of versioning a published product.
Inspect before you publish
Read references/execution-model.md. A listing exposes an entire dataset, so
check what is actually in it before designing one. list_table_ids and
get_dataset_info tell you whether the working dataset has tables nobody
intended to publish, which is the usual reason a publication dataset is needed.
Creating the exchange, the listing, and the IAM bindings are writes. Emit the Terraform and the gcloud commands.
Governance
- Grant
roles/analyticshub.subscriberto groups, never to individuals. restricted_export_configon anything that leaves the org, so results cannot be exported wholesale.- Review subscribers quarterly. List them and ask each owner if they still need it:
gcloud bigquery analytics-hub listings list \
--data-exchange=internal_analytics --location=us
gcloud bigquery analytics-hub listings get-iam-policy LISTING_ID \
--data-exchange=internal_analytics --location=us
- Deprecating a listing: announce, keep the old version live for one full consumer cycle, then delete. Deleting a listing breaks every linked dataset immediately and without warning to the subscriber, so never do it quietly.
Output format
When designing a share, return: the mechanism chosen and why, the exchange and listing names, the publication dataset contents, the Terraform, the subscriber groups, and the deprecation policy in one sentence.