Skip to content

Commit af50b9a

Browse files
google_datastream_stream: Add support for projectID field in SourceHierarchyDatasets (#14858) (#10704)
[upstream:9b1a11e9d9d58895df0acf835427cd7e23a56abc] Signed-off-by: Modular Magician <[email protected]>
1 parent 9a9cbe3 commit af50b9a

File tree

5 files changed

+387
-0
lines changed

5 files changed

+387
-0
lines changed

.changelog/14858.txt

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
```release-note:enhancement
2+
datastream: added `destination_config.bigquery_destination_config.source_hierarchy_datasets.project_id` field to `google_datastream_stream` resource
3+
```
4+
5+
google_datastream_stream: Add support for projectID field in SourceHierarchyDatasets.
6+
7+
Also added a new test in [`mmv1/templates/terraform/examples/datastream_stream_bigquery_cross_project_source_hierachy.tf.tmpl`](https://github.com/benjamin-maynard/magic-modules/blob/c1aaf45e21117e93ccbd5c25461efc2170b7b49e/mmv1/templates/terraform/examples/datastream_stream_bigquery_cross_project_source_hierachy.tf.tmpl).
8+
9+
I also had to add `default_from_api: true` to `binaryLogPosition` (the default) as **all** of the BigQuery tests were failing with a diff-after-apply. Unrelated to my changes¹.
10+
11+
I believe this is safe and all of the tests pass² (although the [blmt test is skipped](https://github.com/benjamin-maynard/magic-modules/blob/c1aaf45e21117e93ccbd5c25461efc2170b7b49e/mmv1/products/datastream/Stream.yaml#L234-L235)), but please let me know if any concerns.
12+
13+
14+
[1]
15+
```
16+
Step 1/2 error: After applying this test step, the plan was not empty.
17+
        stdout:
18+
        Terraform used the selected providers to generate the following execution
19+
        plan. Resource actions are indicated with the following symbols:
20+
          ~ update in-place
21+
        Terraform will perform the following actions:   
22+
          # google_datastream_stream.default will be updated in-place
23+
          ~ resource "google_datastream_stream" "default" {
24+
                id                              = "projects/platform-dev-8bvnw/locations/us-central1/streams/tf-test-my-streammpuoq3q4ky"
25+
                name                            = "projects/platform-dev-8bvnw/locations/us-central1/streams/tf-test-my-streammpuoq3q4ky"
26+
                # (10 unchanged attributes hidden)
27+
              ~ source_config {
28+
                    # (1 unchanged attribute hidden)
29+
                  ~ mysql_source_config {
30+
                        # (2 unchanged attributes hidden)
31+
                      - binary_log_position {}
32+
                    }
33+
                # (2 unchanged blocks hidden)
34+
            }      
35+
        Plan: 0 to add, 1 to change, 0 to destroy.
36+
```
37+
38+
[2]
39+
```
40+
benmaynard$ make testacc TEST=./google/services/datastream TESTARGS='-run=TestAccDatastreamStream_datastreamStreamBigquery'
41+
TF_ACC=1 TF_SCHEMA_PANIC_ON_ERROR=1 go test ./google/services/datastream -v -run=TestAccDatastreamStream_datastreamStreamBigquery -timeout 240m -ldflags="-X=github.com/hashicorp/terraform-provider-google/version.ProviderVersion=acc"
42+
=== RUN TestAccDatastreamStream_datastreamStreamBigqueryExample
43+
=== PAUSE TestAccDatastreamStream_datastreamStreamBigqueryExample
44+
=== RUN TestAccDatastreamStream_datastreamStreamBigqueryCrossProjectSourceHierachyExample
45+
=== PAUSE TestAccDatastreamStream_datastreamStreamBigqueryCrossProjectSourceHierachyExample
46+
=== RUN TestAccDatastreamStream_datastreamStreamBigqueryAppendOnlyExample
47+
=== PAUSE TestAccDatastreamStream_datastreamStreamBigqueryAppendOnlyExample
48+
=== CONT TestAccDatastreamStream_datastreamStreamBigqueryExample
49+
=== CONT TestAccDatastreamStream_datastreamStreamBigqueryAppendOnlyExample
50+
=== CONT TestAccDatastreamStream_datastreamStreamBigqueryCrossProjectSourceHierachyExample
51+
2025/08/14 14:48:16 [INFO] Authenticating using DefaultClient...
52+
2025/08/14 14:48:16 [INFO] -- Scopes: [https://www.googleapis.com/auth/cloud-platform https://www.googleapis.com/auth/userinfo.email]
53+
--- PASS: TestAccDatastreamStream_datastreamStreamBigqueryAppendOnlyExample (1369.56s)
54+
--- PASS: TestAccDatastreamStream_datastreamStreamBigqueryExample (1420.77s)
55+
--- PASS: TestAccDatastreamStream_datastreamStreamBigqueryCrossProjectSourceHierachyExample (1503.81s)
56+
PASS
57+
ok github.com/hashicorp/terraform-provider-google/google/services/datastream 1505.460s
58+
```

google-beta/services/datastream/resource_datastream_stream.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,11 @@ See https://cloud.google.com/bigquery/docs/customer-managed-encryption for more
274274
},
275275
},
276276
},
277+
"project_id": {
278+
Type: schema.TypeString,
279+
Optional: true,
280+
Description: `Optional. The project id of the BigQuery dataset. If not specified, the project will be inferred from the stream resource.`,
281+
},
277282
},
278283
},
279284
ExactlyOneOf: []string{"destination_config.0.bigquery_destination_config.0.single_target_dataset", "destination_config.0.bigquery_destination_config.0.source_hierarchy_datasets"},
@@ -4199,6 +4204,8 @@ func flattenDatastreamStreamDestinationConfigBigqueryDestinationConfigSourceHier
41994204
transformed := make(map[string]interface{})
42004205
transformed["dataset_template"] =
42014206
flattenDatastreamStreamDestinationConfigBigqueryDestinationConfigSourceHierarchyDatasetsDatasetTemplate(original["datasetTemplate"], d, config)
4207+
transformed["project_id"] =
4208+
flattenDatastreamStreamDestinationConfigBigqueryDestinationConfigSourceHierarchyDatasetsProjectId(original["projectId"], d, config)
42024209
return []interface{}{transformed}
42034210
}
42044211
func flattenDatastreamStreamDestinationConfigBigqueryDestinationConfigSourceHierarchyDatasetsDatasetTemplate(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
@@ -4230,6 +4237,10 @@ func flattenDatastreamStreamDestinationConfigBigqueryDestinationConfigSourceHier
42304237
return v
42314238
}
42324239

4240+
func flattenDatastreamStreamDestinationConfigBigqueryDestinationConfigSourceHierarchyDatasetsProjectId(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
4241+
return v
4242+
}
4243+
42334244
func flattenDatastreamStreamDestinationConfigBigqueryDestinationConfigBlmtConfig(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
42344245
if v == nil {
42354246
return nil
@@ -7414,6 +7425,13 @@ func expandDatastreamStreamDestinationConfigBigqueryDestinationConfigSourceHiera
74147425
transformed["datasetTemplate"] = transformedDatasetTemplate
74157426
}
74167427

7428+
transformedProjectId, err := expandDatastreamStreamDestinationConfigBigqueryDestinationConfigSourceHierarchyDatasetsProjectId(original["project_id"], d, config)
7429+
if err != nil {
7430+
return nil, err
7431+
} else if val := reflect.ValueOf(transformedProjectId); val.IsValid() && !tpgresource.IsEmptyValue(val) {
7432+
transformed["projectId"] = transformedProjectId
7433+
}
7434+
74177435
return transformed, nil
74187436
}
74197437

@@ -7462,6 +7480,10 @@ func expandDatastreamStreamDestinationConfigBigqueryDestinationConfigSourceHiera
74627480
return v, nil
74637481
}
74647482

7483+
func expandDatastreamStreamDestinationConfigBigqueryDestinationConfigSourceHierarchyDatasetsProjectId(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
7484+
return v, nil
7485+
}
7486+
74657487
func expandDatastreamStreamDestinationConfigBigqueryDestinationConfigBlmtConfig(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
74667488
l := v.([]interface{})
74677489
if len(l) == 0 || l[0] == nil {

google-beta/services/datastream/resource_datastream_stream_generated_meta.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ fields:
6565
- field: 'destination_config.bigquery_destination_config.source_hierarchy_datasets.dataset_template.dataset_id_prefix'
6666
- field: 'destination_config.bigquery_destination_config.source_hierarchy_datasets.dataset_template.kms_key_name'
6767
- field: 'destination_config.bigquery_destination_config.source_hierarchy_datasets.dataset_template.location'
68+
- field: 'destination_config.bigquery_destination_config.source_hierarchy_datasets.project_id'
6869
- field: 'destination_config.destination_connection_profile'
6970
- field: 'destination_config.gcs_destination_config.avro_file_format'
7071
- field: 'destination_config.gcs_destination_config.file_rotation_interval'

google-beta/services/datastream/resource_datastream_stream_generated_test.go

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"github.com/hashicorp/terraform-plugin-testing/terraform"
2727

2828
"github.com/hashicorp/terraform-provider-google-beta/google-beta/acctest"
29+
"github.com/hashicorp/terraform-provider-google-beta/google-beta/envvar"
2930
"github.com/hashicorp/terraform-provider-google-beta/google-beta/tpgresource"
3031
transport_tpg "github.com/hashicorp/terraform-provider-google-beta/google-beta/transport"
3132
)
@@ -719,6 +720,173 @@ resource "google_datastream_stream" "default" {
719720
`, context)
720721
}
721722

723+
func TestAccDatastreamStream_datastreamStreamBigqueryCrossProjectSourceHierachyExample(t *testing.T) {
724+
acctest.SkipIfVcr(t)
725+
t.Parallel()
726+
727+
context := map[string]interface{}{
728+
"billing_account": envvar.GetTestBillingAccountFromEnv(t),
729+
"org_id": envvar.GetTestOrgFromEnv(t),
730+
"deletion_protection": false,
731+
"random_suffix": acctest.RandString(t, 10),
732+
}
733+
734+
acctest.VcrTest(t, resource.TestCase{
735+
PreCheck: func() { acctest.AccTestPreCheck(t) },
736+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
737+
ExternalProviders: map[string]resource.ExternalProvider{
738+
"random": {},
739+
"time": {},
740+
},
741+
CheckDestroy: testAccCheckDatastreamStreamDestroyProducer(t),
742+
Steps: []resource.TestStep{
743+
{
744+
Config: testAccDatastreamStream_datastreamStreamBigqueryCrossProjectSourceHierachyExample(context),
745+
},
746+
{
747+
ResourceName: "google_datastream_stream.default",
748+
ImportState: true,
749+
ImportStateVerify: true,
750+
ImportStateVerifyIgnore: []string{"create_without_validation", "labels", "location", "stream_id", "terraform_labels"},
751+
},
752+
},
753+
})
754+
}
755+
756+
func testAccDatastreamStream_datastreamStreamBigqueryCrossProjectSourceHierachyExample(context map[string]interface{}) string {
757+
return acctest.Nprintf(`
758+
data "google_project" "project" {
759+
}
760+
761+
resource "google_project" "cross-project-dataset" {
762+
project_id = "tf-test%{random_suffix}"
763+
name = "tf-test%{random_suffix}"
764+
org_id = "%{org_id}"
765+
billing_account = "%{billing_account}"
766+
deletion_policy = "DELETE"
767+
}
768+
769+
resource "time_sleep" "wait_60_seconds" {
770+
create_duration = "60s"
771+
depends_on = [google_project.cross-project-dataset]
772+
}
773+
774+
resource "google_project_service" "bigquery" {
775+
project = google_project.cross-project-dataset.project_id
776+
service = "bigquery.googleapis.com"
777+
disable_on_destroy = false
778+
depends_on = [time_sleep.wait_60_seconds]
779+
}
780+
781+
resource "google_project_iam_member" "datastream_bigquery_admin" {
782+
project = google_project.cross-project-dataset.project_id
783+
role = "roles/bigquery.admin"
784+
member = "serviceAccount:service-${data.google_project.project.number}@gcp-sa-datastream.iam.gserviceaccount.com"
785+
depends_on = [time_sleep.wait_60_seconds]
786+
}
787+
788+
resource "google_sql_database_instance" "instance" {
789+
name = "tf-test-my-instance%{random_suffix}"
790+
database_version = "MYSQL_8_0"
791+
region = "us-central1"
792+
settings {
793+
tier = "db-f1-micro"
794+
backup_configuration {
795+
enabled = true
796+
binary_log_enabled = true
797+
}
798+
799+
ip_configuration {
800+
801+
// Datastream IPs will vary by region.
802+
authorized_networks {
803+
value = "34.71.242.81"
804+
}
805+
806+
authorized_networks {
807+
value = "34.72.28.29"
808+
}
809+
810+
authorized_networks {
811+
value = "34.67.6.157"
812+
}
813+
814+
authorized_networks {
815+
value = "34.67.234.134"
816+
}
817+
818+
authorized_networks {
819+
value = "34.72.239.218"
820+
}
821+
}
822+
}
823+
824+
deletion_protection = %{deletion_protection}
825+
}
826+
827+
resource "google_sql_database" "db" {
828+
instance = google_sql_database_instance.instance.name
829+
name = "db"
830+
}
831+
832+
resource "random_password" "pwd" {
833+
length = 16
834+
special = false
835+
}
836+
837+
resource "google_sql_user" "user" {
838+
name = "user"
839+
instance = google_sql_database_instance.instance.name
840+
host = "%"
841+
password = random_password.pwd.result
842+
}
843+
844+
resource "google_datastream_connection_profile" "source_connection_profile" {
845+
display_name = "Source connection profile"
846+
location = "us-central1"
847+
connection_profile_id = "tf-test-source-profile%{random_suffix}"
848+
849+
mysql_profile {
850+
hostname = google_sql_database_instance.instance.public_ip_address
851+
username = google_sql_user.user.name
852+
password = google_sql_user.user.password
853+
}
854+
}
855+
856+
resource "google_datastream_connection_profile" "destination_connection_profile" {
857+
display_name = "Connection profile"
858+
location = "us-central1"
859+
connection_profile_id = "tf-test-destination-profile%{random_suffix}"
860+
861+
bigquery_profile {}
862+
}
863+
864+
resource "google_datastream_stream" "default" {
865+
stream_id = "tf-test-my-stream%{random_suffix}"
866+
location = "us-central1"
867+
display_name = "my stream"
868+
source_config {
869+
source_connection_profile = google_datastream_connection_profile.source_connection_profile.id
870+
mysql_source_config {}
871+
}
872+
destination_config {
873+
destination_connection_profile = google_datastream_connection_profile.destination_connection_profile.id
874+
bigquery_destination_config {
875+
source_hierarchy_datasets {
876+
dataset_template {
877+
location = "us-central1"
878+
}
879+
project_id = google_project.cross-project-dataset.project_id
880+
}
881+
}
882+
}
883+
884+
backfill_none {
885+
}
886+
}
887+
`, context)
888+
}
889+
722890
func TestAccDatastreamStream_datastreamStreamBigqueryAppendOnlyExample(t *testing.T) {
723891
acctest.SkipIfVcr(t)
724892
t.Parallel()

0 commit comments

Comments
 (0)