Skip to content

Add multi-region support to listings and subscriptions#16021

Closed
okvidhi wants to merge 6 commits into
GoogleCloudPlatform:mainfrom
okvidhi:multiregion-support
Closed

Add multi-region support to listings and subscriptions#16021
okvidhi wants to merge 6 commits into
GoogleCloudPlatform:mainfrom
okvidhi:multiregion-support

Conversation

@okvidhi

@okvidhi okvidhi commented Dec 23, 2025

Copy link
Copy Markdown
Contributor

Description

This PR adds multi-region support to the BigQuery Analytics Hub listing and listing_subscription resources in the google-beta provider. This enhancement allows publishers to specify existing dataset replicas and allows subscribers to request replicas for their destination datasets.

This work takes over and finalizes the logic from the original PR #14481.

Key Changes

  • Feature Addition: Added replica_locations and effective_replicas fields to google_bigquery_analytics_hub_listing.
  • Feature Addition: Added replica_locations field to google_bigquery_analytics_hub_listing_subscription.
  • Beta Scoping: Used min_version: 'beta' in YAML and implemented version guards ({{- if ne ... }}) in renamed .go.tmpl test files to correctly restrict the feature to the beta provider.
  • Logic Improvements:
    • Applied tpgresource.CaseDiffSuppress to location fields to allow case-insensitive region input.
    • Implemented a custom CaseInsensitiveHash function in common_diff_suppress.go and configured set_hash_func in YAML to ensure the replica_locations Set handles case differences (e.g., "eu" vs "EU") without triggering a diff.
  • Build Fixes: Resolved "unused import" errors in the GA provider and correctly implemented ProtoV5ProviderBetaFactories for beta-specific acceptance tests.

Testing Performed

Manual verification in a test project confirmed:

  • Successful creation of listings and subscriptions with replicas.
  • Successful import of existing multi-region resources into Terraform state.
  • Proper handling of API constraints (blocking replica removal if it still exists in BigQuery).
  • Correct case-insensitive behavior for both string and set fields.
  • Correct scoping (feature is unavailable in the GA provider).

Bypass Note

BYPASS_BQUI_SCREENSHOT_BAN_PRESUBMIT=Updating existing screenshot goldens to reflect Terraform provider changes for the multi-region feature.

Additional attachments: https://docs.google.com/document/d/1V_377q8WQ2pNpvVjmRNSVQnOTzXIfBIJ4OjSIxrVVRU/edit?usp=sharing

bigqueryanalyticshub: added `replica_locations` and `effective_replicas` fields to `google_bigquery_analytics_hub_listing` and `replica_locations` field to `google_bigquery_analytics_hub_listing_subscription` (beta)

@google-cla

google-cla Bot commented Dec 23, 2025

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@modular-magician modular-magician added the awaiting-approval Pull requests that need reviewer's approval to run presubmit tests label Dec 23, 2025
@github-actions github-actions Bot requested a review from ScottSuarez December 23, 2025 11:31
@github-actions

Copy link
Copy Markdown

Hello! I am a robot. Tests will require approval from a repository maintainer to run.

Googlers: For automatic test runs see go/terraform-auto-test-runs.

@ScottSuarez, a repository maintainer, has been assigned to review your changes. If you have not received review feedback within 2 business days, please leave a comment on this PR asking them to take a look.

You can help make sure that review is quick by doing a self-review and by running impacted tests locally.

@okvidhi okvidhi force-pushed the multiregion-support branch 6 times, most recently from de76826 to aee82a3 Compare December 25, 2025 14:15
Comment thread mmv1/products/bigqueryanalyticshub/Listing.yaml
Comment thread mmv1/products/bigqueryanalyticshub/Listing.yaml
Comment thread mmv1/products/bigqueryanalyticshub/Listing.yaml
Comment thread mmv1/products/bigqueryanalyticshub/ListingSubscription.yaml
Comment thread mmv1/products/bigqueryanalyticshub/ListingSubscription.yaml Outdated
Comment thread mmv1/products/bigqueryanalyticshub/ListingSubscription.yaml
@github-actions

Copy link
Copy Markdown

@ScottSuarez This PR has been waiting for review for 3 weekdays. Please take a look! Use the label disable-review-reminders to disable these notifications.

@okvidhi okvidhi force-pushed the multiregion-support branch from aee82a3 to da1b37a Compare December 26, 2025 18:04
Comment thread mmv1/third_party/terraform/acctest/bootstrap_test_utils.go.tmpl
Comment thread mmv1/third_party/terraform/acctest/bootstrap_test_utils.go.tmpl
Comment thread mmv1/third_party/terraform/acctest/bootstrap_test_utils.go.tmpl
Comment thread mmv1/third_party/terraform/tpgresource/common_diff_suppress.go
@okvidhi okvidhi force-pushed the multiregion-support branch 2 times, most recently from 1cc0c01 to cd05f62 Compare December 29, 2025 11:28
@github-actions

Copy link
Copy Markdown

@GoogleCloudPlatform/terraform-team @ScottSuarez This PR has been waiting for review for 1 week. Please take a look! Use the label disable-review-reminders to disable these notifications.

@okvidhi okvidhi force-pushed the multiregion-support branch from cd05f62 to 58bab0e Compare December 30, 2025 18:02

@ScottSuarez ScottSuarez left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is quite a lot of changes and it is hard to follow. I would prefer for the test migrations and test file renaming to not be done within this change if possible. If needed or preferable could you let me know as to why?

method_name_separator: ':'
fetch_iam_policy_verb: 'POST'
parent_resource_attribute: 'listing_id'
example_config_body: 'templates/terraform/iam/iam_attributes.go.tmpl'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't be needed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, I have removed this line.

Comment on lines +2403 to +2499

func AddBigQueryDatasetReplica(projectID string,datasetID string,primaryLocation string,replicaLocation string) (string, error){
ctx := context.Background()

client, err := bigquery.NewClient(ctx, projectID)
if err != nil {
return "", fmt.Errorf("failed to create BigQuery client: %w", err)
}
defer client.Close()

log.Printf("INFO: Attempting to create dataset '%s' in project '%s' at location '%s'", datasetID, projectID, primaryLocation)
datasetRef := client.Dataset(datasetID)
datasetMetadata := &bigquery.DatasetMetadata{
Location: primaryLocation,
}

err = datasetRef.Create(ctx, datasetMetadata)
if err != nil {
log.Printf("failed to create BigQuery dataset '%s'.Dataset already exists.", datasetID)
} else {
log.Printf("INFO: Successfully created BigQuery dataset '%s' at location '%s'.", datasetID, primaryLocation)
}

sqlQuery := fmt.Sprintf(
"ALTER SCHEMA `%s` ADD REPLICA `%s` OPTIONS(location=`%s`)",
datasetID,
replicaLocation,
replicaLocation,
)

log.Printf("INFO: Executing BigQuery DDL query: %s", sqlQuery)

query := client.Query(sqlQuery)

job, err := query.Run(ctx)
if err != nil {
return "", fmt.Errorf("failed to submit BigQuery DDL job: %w", err)
}

status, err := job.Wait(ctx)
if err != nil {
log.Printf("failed to wait for BigQuery job completion: %v", err)
}

if status.Err() != nil {
log.Printf("BigQuery job completed with an error: %v", status.Err())
}

log.Println("Successfully added BigQuery dataset replica using the Go client library.")

fullDatasetLocation := fmt.Sprintf("projects/%s/datasets/%s", projectID, datasetID)
return fullDatasetLocation, nil
}

func CleanupBigQueryDatasetAndReplica(projectID, datasetID, replicaLocation string) {
log.Printf("[DEBUG] Cleanup: Starting cleanup for BigQuery dataset: projects/%s/datasets/%s", projectID, datasetID)
cleanupCtx := context.Background()

client, cerr := bigquery.NewClient(cleanupCtx, projectID)
if cerr != nil {
log.Printf("[ERROR] Cleanup: Failed to create BigQuery client for dataset %s: %v", datasetID, cerr)
return
}
defer client.Close()

// Attempt to remove the replica first
dropReplicaSQL := fmt.Sprintf(
"ALTER SCHEMA `%s` DROP REPLICA `%s`",
datasetID,
replicaLocation,
)
log.Printf("[DEBUG] Cleanup: Dropping replica with SQL: %s", dropReplicaSQL)
dropQuery := client.Query(dropReplicaSQL)
dropJob, dropErr := dropQuery.Run(cleanupCtx)
if dropErr != nil {
log.Printf("[ERROR] Cleanup: Failed to submit BigQuery DDL job for dropping replica %s of dataset %s: %v", replicaLocation, datasetID, dropErr)
} else {
dropStatus, dropWaitErr := dropJob.Wait(cleanupCtx)
if dropWaitErr != nil {
log.Printf("[ERROR] Cleanup: Failed to wait for BigQuery job completion for dropping replica %s of dataset %s: %v", replicaLocation, datasetID, dropWaitErr)
} else if dropStatus.Err() != nil {
log.Printf("[ERROR] Cleanup: BigQuery job for dropping replica %s of dataset %s completed with an error: %v", replicaLocation, datasetID, dropStatus.Err())
} else {
log.Printf("[INFO] Cleanup: Successfully dropped BigQuery dataset replica: %s for dataset %s", replicaLocation, datasetID)
}
}

//Delete the main dataset (including any remaining contents)
log.Printf("[DEBUG] Cleanup: Deleting main BigQuery dataset: %s", datasetID)
err := client.Dataset(datasetID).DeleteWithContents(cleanupCtx)
if err != nil {
// Cannot differentiate.
log.Printf("[ERROR] Cleanup: Failed to delete BigQuery dataset %s: %v", datasetID, err)
} else {
log.Printf("[INFO] Cleanup: Successfully deleted BigQuery dataset: %s", datasetID)
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are these functions added. They are not used anywhere. Can we remove them

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these functions are for bootstrapping the multi region acceptance tests. since terraform's google_bigquery_dataset cannot natively create replicas, we use these go client helpers to set up the required environment before the terraform tests run. i have restored the multiregion tests that explicitly call these functions

Comment thread mmv1/templates/terraform/pre_update/bigqueryanalyticshub_listing.go.tmpl Outdated
@okvidhi

okvidhi commented Dec 30, 2025

Copy link
Copy Markdown
Contributor Author

This is quite a lot of changes and it is hard to follow. I would prefer for the test migrations and test file renaming to not be done within this change if possible. If needed or preferable could you let me know as to why?

the test files were renamed to .go.tmpl to implement Beta-only scoping. Since the multi-region support is currently restricted to the google-beta provider, standard .go tests would cause the GA provider build to fail because the GA schema does not recognize the new replica_locations field.

@okvidhi okvidhi force-pushed the multiregion-support branch from 5c84a6b to 2476981 Compare December 30, 2025 19:21
@github-actions

github-actions Bot commented Jan 2, 2026

Copy link
Copy Markdown

@ScottSuarez This PR has been waiting for review for 3 weekdays. Please take a look! Use the label disable-review-reminders to disable these notifications.

@modular-magician modular-magician added service/bigquery and removed awaiting-approval Pull requests that need reviewer's approval to run presubmit tests labels Jan 2, 2026
@modular-magician

Copy link
Copy Markdown
Collaborator

Hi there, I'm the Modular magician. I've detected the following information about your changes:

Diff report

Your PR generated some diffs in downstreams - here they are.

google provider: Diff ( 12 files changed, 377 insertions(+), 738 deletions(-))
google-beta provider: Diff ( 15 files changed, 695 insertions(+), 776 deletions(-))
terraform-google-conversion: Diff ( 3 files changed, 88 insertions(+))

@modular-magician

Copy link
Copy Markdown
Collaborator

Tests analytics

Total tests: 5891
Passed tests: 5253
Skipped tests: 607
Affected tests: 31

Click here to see the affected service packages

All service packages are affected

Action taken

Found 31 affected test(s) by replaying old test recordings. Starting RECORDING based on the most recent commit. Click here to see the affected tests
  • TestAccAccessContextManager__gcp_user_access_binding
  • TestAccAccessContextManager__service_perimeter_dry_run_egress_policy
  • TestAccAccessContextManager__service_perimeter_dry_run_ingress_policy
  • TestAccBigqueryAnalyticsHubListingIamBindingGenerated
  • TestAccBigqueryAnalyticsHubListingIamMemberGenerated
  • TestAccBigqueryAnalyticsHubListingIamPolicyGenerated
  • TestAccBigqueryAnalyticsHubListingSubscription_bigqueryAnalyticshubListingSubscriptionBasicExample
  • TestAccBigqueryAnalyticsHubListingSubscription_differentProject
  • TestAccBigqueryAnalyticsHubListingSubscription_multiregion
  • TestAccBigqueryAnalyticsHubListing_bigqueryAnalyticshubListingBasicExample
  • TestAccBigqueryAnalyticsHubListing_bigqueryAnalyticshubListingDcrExample
  • TestAccBigqueryAnalyticsHubListing_bigqueryAnalyticshubListingDcrRoutineExample
  • TestAccBigqueryAnalyticsHubListing_bigqueryAnalyticshubListingLogLinkedDatasetQueryUserExample
  • TestAccBigqueryAnalyticsHubListing_bigqueryAnalyticshubListingMarketplaceExample
  • TestAccBigqueryAnalyticsHubListing_bigqueryAnalyticshubListingPubsubExample
  • TestAccBigqueryAnalyticsHubListing_bigqueryAnalyticshubListingRestrictedExample
  • TestAccBigqueryAnalyticsHubListing_bigqueryAnalyticshubListingUpdate
  • TestAccBigqueryAnalyticsHubListing_multiregion
  • TestAccComputeFutureReservation_futureReservationAggregateReservationExample
  • TestAccComputeFutureReservation_sharedFutureReservationExample
  • TestAccContainerCluster_networkPerformanceConfig
  • TestAccContainerCluster_withTPUConfig
  • TestAccContainerCluster_withTpu
  • TestAccContainerNodePool_secondaryBootDisks
  • TestAccDataFusionInstance_dataFusionInstanceCmekExample
  • TestAccDialogflowCXTestCase_dialogflowcxTestCaseFullExample
  • TestAccDialogflowCXTestCase_update
  • TestAccDiscoveryEngineCmekConfig_discoveryengineCmekconfigDefaultExample_update
  • TestAccGKEHubFeature_FleetDefaultMemberConfigPolicyController
  • TestAccHealthcarePipelineJob_healthcarePipelineJobBackfillExample
  • TestAccSqlDatabaseInstance_activationPolicy

Get to know how VCR tests work

@modular-magician

Copy link
Copy Markdown
Collaborator

🟢 Tests passed during RECORDING mode:
TestAccAccessContextManager__access_level [Debug log]
TestAccAccessContextManager__access_level_condition [Debug log]
TestAccAccessContextManager__access_level_custom [Debug log]
TestAccAccessContextManager__access_level_full [Debug log]
TestAccAccessContextManager__access_levels [Debug log]
TestAccAccessContextManager__access_policy [Debug log]
TestAccAccessContextManager__access_policy_scoped [Debug log]
TestAccAccessContextManager__authorized_orgs_desc [Debug log]
TestAccAccessContextManager__service_perimeter [Debug log]
TestAccAccessContextManager__service_perimeter_dry_run_egress_policy [Debug log]
TestAccAccessContextManager__service_perimeter_dry_run_ingress_policy [Debug log]
TestAccAccessContextManager__service_perimeter_update [Debug log]
TestAccAccessContextManager__service_perimeters [Debug log]
TestAccBigqueryAnalyticsHubListingSubscription_differentProject [Debug log]
TestAccBigqueryAnalyticsHubListingSubscription_multiregion [Debug log]
TestAccBigqueryAnalyticsHubListing_bigqueryAnalyticshubListingUpdate [Debug log]
TestAccBigqueryAnalyticsHubListing_multiregion [Debug log]

🟢 No issues found for passed tests after REPLAYING rerun.


🔴 Tests failed during RECORDING mode:
TestAccAccessContextManager__gcp_user_access_binding [Error message] [Debug log]
TestAccBigqueryAnalyticsHubListingIamBindingGenerated [Error message] [Debug log]
TestAccBigqueryAnalyticsHubListingIamMemberGenerated [Error message] [Debug log]
TestAccBigqueryAnalyticsHubListingIamPolicyGenerated [Error message] [Debug log]
TestAccBigqueryAnalyticsHubListingSubscription_bigqueryAnalyticshubListingSubscriptionBasicExample [Error message] [Debug log]
TestAccBigqueryAnalyticsHubListing_bigqueryAnalyticshubListingBasicExample [Error message] [Debug log]
TestAccBigqueryAnalyticsHubListing_bigqueryAnalyticshubListingDcrExample [Error message] [Debug log]
TestAccBigqueryAnalyticsHubListing_bigqueryAnalyticshubListingDcrRoutineExample [Error message] [Debug log]
TestAccBigqueryAnalyticsHubListing_bigqueryAnalyticshubListingLogLinkedDatasetQueryUserExample [Error message] [Debug log]
TestAccBigqueryAnalyticsHubListing_bigqueryAnalyticshubListingMarketplaceExample [Error message] [Debug log]
TestAccBigqueryAnalyticsHubListing_bigqueryAnalyticshubListingPubsubExample [Error message] [Debug log]
TestAccBigqueryAnalyticsHubListing_bigqueryAnalyticshubListingRestrictedExample [Error message] [Debug log]
TestAccComputeFutureReservation_futureReservationAggregateReservationExample [Error message] [Debug log]
TestAccComputeFutureReservation_sharedFutureReservationExample [Error message] [Debug log]
TestAccContainerCluster_networkPerformanceConfig [Error message] [Debug log]
TestAccContainerCluster_withTPUConfig [Error message] [Debug log]
TestAccContainerCluster_withTpu [Error message] [Debug log]
TestAccContainerNodePool_secondaryBootDisks [Error message] [Debug log]
TestAccDataFusionInstance_dataFusionInstanceCmekExample [Error message] [Debug log]
TestAccDialogflowCXTestCase_dialogflowcxTestCaseFullExample [Error message] [Debug log]
TestAccDialogflowCXTestCase_update [Error message] [Debug log]
TestAccDiscoveryEngineCmekConfig_discoveryengineCmekconfigDefaultExample_update [Error message] [Debug log]
TestAccGKEHubFeature_FleetDefaultMemberConfigPolicyController [Error message] [Debug log]
TestAccHealthcarePipelineJob_healthcarePipelineJobBackfillExample [Error message] [Debug log]
TestAccSqlDatabaseInstance_activationPolicy [Error message] [Debug log]

🔴 Errors occurred during RECORDING mode. Please fix them to complete your PR.

View the build log or the debug log for each test

Comment thread mmv1/products/bigqueryanalyticshub/Listing.yaml
}

{{- if ne $.TargetVersionName "ga" }}
func testAccBigqueryAnalyticsHubListingSubscription_multiregion(context map[string]interface{}) string {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need provider = google-beta for each resource, see https://googlecloudplatform.github.io/magic-modules/test/test/. Same for the other test file.

@github-actions

github-actions Bot commented Jan 6, 2026

Copy link
Copy Markdown

@GoogleCloudPlatform/terraform-team @ScottSuarez This PR has been waiting for review for 1 week. Please take a look! Use the label disable-review-reminders to disable these notifications.

@github-actions

Copy link
Copy Markdown

@GoogleCloudPlatform/terraform-team @ScottSuarez This PR has been waiting for review for 2 weeks. Please take a look! Use the label disable-review-reminders to disable these notifications.

@ScottSuarez ScottSuarez left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, apologies, wanted to check in on this. Could you pull the latest changes from main into your branch.

@okvidhi okvidhi force-pushed the multiregion-support branch from 2476981 to 2d42f69 Compare January 14, 2026 13:14
@modular-magician modular-magician added the awaiting-approval Pull requests that need reviewer's approval to run presubmit tests label Jan 14, 2026
@github-actions github-actions Bot requested a review from ScottSuarez January 14, 2026 13:15
@modular-magician modular-magician removed the awaiting-approval Pull requests that need reviewer's approval to run presubmit tests label Jan 14, 2026
@modular-magician

Copy link
Copy Markdown
Collaborator

Hi there, I'm the Modular magician. I've detected the following information about your changes:

Diff report

Your PR generated some diffs in downstreams - here they are.

google provider: Diff ( 12 files changed, 389 insertions(+), 738 deletions(-))
google-beta provider: Diff ( 15 files changed, 713 insertions(+), 777 deletions(-))
terraform-google-conversion: Diff ( 3 files changed, 88 insertions(+))

@ScottSuarez ScottSuarez left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

compilation errors downstream from the go mod file

@modular-magician

Copy link
Copy Markdown
Collaborator

Non-exercised tests

🔴 Tests were added that are skipped in VCR:

  • TestAccBigqueryAnalyticsHubListingSubscription_multiregion
  • TestAccBigqueryAnalyticsHubListing_multiregion

Tests analytics

Total tests: 0
Passed tests: 0
Skipped tests: 0
Affected tests: 0

Click here to see the affected service packages

All service packages are affected

🔴 Errors occurred during REPLAYING mode. Please fix them to complete your PR.

View the build log

listing_id: 'my_listing'
desc: 'example data exchange'
steps:
- name: 'basic'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the name for every test is now basic the documentation is changed in a negative direction. I would prefer we retain the names from the old examples which originated from the file names on the old system.

base := parts[0]
query := parts[1]

query = strings.ReplaceAll(query, "%2C", ",")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies if this was already covered in prior comments but why is this being removed?

if len(parts) == 2 {
base := parts[0]
query := parts[1]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not include replacement of "%2c" here?

@modular-magician modular-magician added the awaiting-approval Pull requests that need reviewer's approval to run presubmit tests label Jan 18, 2026
@github-actions github-actions Bot requested a review from ScottSuarez January 18, 2026 13:08
@okvidhi

okvidhi commented Jan 20, 2026

Copy link
Copy Markdown
Contributor Author

Hey, as this PR was getting a bit messy and hard to follow due to re-occuring conflicts, I am closing this PR. I have created a fresh PR where I have addressed all the comments received so far. Linking it below, I request all the reviewers to have a look. Thanks.
#16156

@okvidhi okvidhi closed this Jan 20, 2026
@okvidhi okvidhi requested a review from prashastia January 20, 2026 04:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting-approval Pull requests that need reviewer's approval to run presubmit tests service/bigquery

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants