Skip to content

Commit 3c25636

Browse files
[AlloyDB] Private Service Connect Support (#10783) (#18263)
[upstream:3963065a1e467a9482cee7e3ac5134dfd95fd558] Signed-off-by: Modular Magician <magic-modules@google.com>
1 parent 46c21e0 commit 3c25636

File tree

6 files changed

+349
-2
lines changed

6 files changed

+349
-2
lines changed

google/services/alloydb/resource_alloydb_cluster.go

Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ Please refer to the field 'effective_labels' for all of the labels present on th
392392
Description: `The relative resource name of the VPC network on which the instance can be accessed. It is specified in the following form:
393393
394394
"projects/{projectNumber}/global/networks/{network_id}".`,
395-
ExactlyOneOf: []string{"network", "network_config.0.network"},
395+
ExactlyOneOf: []string{"network", "network_config.0.network", "psc_config.0.psc_enabled"},
396396
},
397397
"network_config": {
398398
Type: schema.TypeList,
@@ -414,7 +414,22 @@ If set, the instance IPs for this cluster will be created in the allocated range
414414
DiffSuppressFunc: tpgresource.ProjectNumberDiffSuppress,
415415
Description: `The resource link for the VPC network in which cluster resources are created and from which they are accessible via Private IP. The network must belong to the same project as the cluster.
416416
It is specified in the form: "projects/{projectNumber}/global/networks/{network_id}".`,
417-
ExactlyOneOf: []string{"network", "network_config.0.network"},
417+
ExactlyOneOf: []string{"network", "network_config.0.network", "psc_config.0.psc_enabled"},
418+
},
419+
},
420+
},
421+
},
422+
"psc_config": {
423+
Type: schema.TypeList,
424+
Optional: true,
425+
Description: `Configuration for Private Service Connect (PSC) for the cluster.`,
426+
MaxItems: 1,
427+
Elem: &schema.Resource{
428+
Schema: map[string]*schema.Schema{
429+
"psc_enabled": {
430+
Type: schema.TypeBool,
431+
Optional: true,
432+
Description: `Create an instance that allows connections from Private Service Connect endpoints to the instance.`,
418433
},
419434
},
420435
},
@@ -690,6 +705,12 @@ func resourceAlloydbClusterCreate(d *schema.ResourceData, meta interface{}) erro
690705
} else if v, ok := d.GetOkExists("database_version"); !tpgresource.IsEmptyValue(reflect.ValueOf(databaseVersionProp)) && (ok || !reflect.DeepEqual(v, databaseVersionProp)) {
691706
obj["databaseVersion"] = databaseVersionProp
692707
}
708+
pscConfigProp, err := expandAlloydbClusterPscConfig(d.Get("psc_config"), d, config)
709+
if err != nil {
710+
return err
711+
} else if v, ok := d.GetOkExists("psc_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(pscConfigProp)) && (ok || !reflect.DeepEqual(v, pscConfigProp)) {
712+
obj["pscConfig"] = pscConfigProp
713+
}
693714
initialUserProp, err := expandAlloydbClusterInitialUser(d.Get("initial_user"), d, config)
694715
if err != nil {
695716
return err
@@ -961,6 +982,9 @@ func resourceAlloydbClusterRead(d *schema.ResourceData, meta interface{}) error
961982
if err := d.Set("database_version", flattenAlloydbClusterDatabaseVersion(res["databaseVersion"], d, config)); err != nil {
962983
return fmt.Errorf("Error reading Cluster: %s", err)
963984
}
985+
if err := d.Set("psc_config", flattenAlloydbClusterPscConfig(res["pscConfig"], d, config)); err != nil {
986+
return fmt.Errorf("Error reading Cluster: %s", err)
987+
}
964988
if err := d.Set("continuous_backup_config", flattenAlloydbClusterContinuousBackupConfig(res["continuousBackupConfig"], d, config)); err != nil {
965989
return fmt.Errorf("Error reading Cluster: %s", err)
966990
}
@@ -1047,6 +1071,12 @@ func resourceAlloydbClusterUpdate(d *schema.ResourceData, meta interface{}) erro
10471071
} else if v, ok := d.GetOkExists("database_version"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, databaseVersionProp)) {
10481072
obj["databaseVersion"] = databaseVersionProp
10491073
}
1074+
pscConfigProp, err := expandAlloydbClusterPscConfig(d.Get("psc_config"), d, config)
1075+
if err != nil {
1076+
return err
1077+
} else if v, ok := d.GetOkExists("psc_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, pscConfigProp)) {
1078+
obj["pscConfig"] = pscConfigProp
1079+
}
10501080
initialUserProp, err := expandAlloydbClusterInitialUser(d.Get("initial_user"), d, config)
10511081
if err != nil {
10521082
return err
@@ -1129,6 +1159,10 @@ func resourceAlloydbClusterUpdate(d *schema.ResourceData, meta interface{}) erro
11291159
updateMask = append(updateMask, "databaseVersion")
11301160
}
11311161

1162+
if d.HasChange("psc_config") {
1163+
updateMask = append(updateMask, "pscConfig")
1164+
}
1165+
11321166
if d.HasChange("initial_user") {
11331167
updateMask = append(updateMask, "initialUser")
11341168
}
@@ -1535,6 +1569,23 @@ func flattenAlloydbClusterDatabaseVersion(v interface{}, d *schema.ResourceData,
15351569
return v
15361570
}
15371571

1572+
func flattenAlloydbClusterPscConfig(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
1573+
if v == nil {
1574+
return nil
1575+
}
1576+
original := v.(map[string]interface{})
1577+
if len(original) == 0 {
1578+
return nil
1579+
}
1580+
transformed := make(map[string]interface{})
1581+
transformed["psc_enabled"] =
1582+
flattenAlloydbClusterPscConfigPscEnabled(original["pscEnabled"], d, config)
1583+
return []interface{}{transformed}
1584+
}
1585+
func flattenAlloydbClusterPscConfigPscEnabled(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
1586+
return v
1587+
}
1588+
15381589
func flattenAlloydbClusterContinuousBackupConfig(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
15391590
if v == nil {
15401591
return nil
@@ -2092,6 +2143,29 @@ func expandAlloydbClusterDatabaseVersion(v interface{}, d tpgresource.TerraformR
20922143
return v, nil
20932144
}
20942145

2146+
func expandAlloydbClusterPscConfig(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
2147+
l := v.([]interface{})
2148+
if len(l) == 0 || l[0] == nil {
2149+
return nil, nil
2150+
}
2151+
raw := l[0]
2152+
original := raw.(map[string]interface{})
2153+
transformed := make(map[string]interface{})
2154+
2155+
transformedPscEnabled, err := expandAlloydbClusterPscConfigPscEnabled(original["psc_enabled"], d, config)
2156+
if err != nil {
2157+
return nil, err
2158+
} else if val := reflect.ValueOf(transformedPscEnabled); val.IsValid() && !tpgresource.IsEmptyValue(val) {
2159+
transformed["pscEnabled"] = transformedPscEnabled
2160+
}
2161+
2162+
return transformed, nil
2163+
}
2164+
2165+
func expandAlloydbClusterPscConfigPscEnabled(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
2166+
return v, nil
2167+
}
2168+
20952169
func expandAlloydbClusterInitialUser(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
20962170
l := v.([]interface{})
20972171
if len(l) == 0 || l[0] == nil {

google/services/alloydb/resource_alloydb_cluster_test.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1297,3 +1297,39 @@ resource "google_compute_network" "default" {
12971297
data "google_project" "project" {}
12981298
`, context)
12991299
}
1300+
1301+
// Ensures cluster creation succeeds for a Private Service Connect enabled cluster.
1302+
func TestAccAlloydbCluster_withPrivateServiceConnect(t *testing.T) {
1303+
t.Parallel()
1304+
1305+
context := map[string]interface{}{
1306+
"random_suffix": acctest.RandString(t, 10),
1307+
}
1308+
1309+
acctest.VcrTest(t, resource.TestCase{
1310+
PreCheck: func() { acctest.AccTestPreCheck(t) },
1311+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
1312+
CheckDestroy: testAccCheckAlloydbClusterDestroyProducer(t),
1313+
Steps: []resource.TestStep{
1314+
{
1315+
Config: testAccAlloydbCluster_withPrivateServiceConnect(context),
1316+
Check: resource.ComposeTestCheckFunc(
1317+
resource.TestCheckResourceAttr("google_alloydb_cluster.default", "psc_config.0.psc_enabled", "true"),
1318+
),
1319+
},
1320+
},
1321+
})
1322+
}
1323+
1324+
func testAccAlloydbCluster_withPrivateServiceConnect(context map[string]interface{}) string {
1325+
return acctest.Nprintf(`
1326+
resource "google_alloydb_cluster" "default" {
1327+
cluster_id = "tf-test-alloydb-cluster%{random_suffix}"
1328+
location = "us-central1"
1329+
psc_config {
1330+
psc_enabled = true
1331+
}
1332+
}
1333+
data "google_project" "project" {}
1334+
`, context)
1335+
}

google/services/alloydb/resource_alloydb_instance.go

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,39 @@ the same instance.`,
215215
},
216216
},
217217
},
218+
"psc_instance_config": {
219+
Type: schema.TypeList,
220+
Optional: true,
221+
Description: `Configuration for Private Service Connect (PSC) for the instance.`,
222+
MaxItems: 1,
223+
Elem: &schema.Resource{
224+
Schema: map[string]*schema.Schema{
225+
"allowed_consumer_projects": {
226+
Type: schema.TypeList,
227+
Optional: true,
228+
Description: `List of consumer projects that are allowed to create PSC endpoints to service-attachments to this instance.
229+
These should be specified as project numbers only.`,
230+
Elem: &schema.Schema{
231+
Type: schema.TypeString,
232+
ValidateFunc: verify.ValidateRegexp(`^\d+$`),
233+
},
234+
},
235+
"psc_dns_name": {
236+
Type: schema.TypeString,
237+
Computed: true,
238+
Description: `The DNS name of the instance for PSC connectivity.
239+
Name convention: <uid>.<uid>.<region>.alloydb-psc.goog`,
240+
},
241+
"service_attachment_link": {
242+
Type: schema.TypeString,
243+
Computed: true,
244+
Description: `The service attachment created when Private Service Connect (PSC) is enabled for the instance.
245+
The name of the resource will be in the format of
246+
'projects/<alloydb-tenant-project-number>/regions/<region-name>/serviceAttachments/<service-attachment-name>'`,
247+
},
248+
},
249+
},
250+
},
218251
"query_insights_config": {
219252
Type: schema.TypeList,
220253
Computed: true,
@@ -390,6 +423,12 @@ func resourceAlloydbInstanceCreate(d *schema.ResourceData, meta interface{}) err
390423
} else if v, ok := d.GetOkExists("client_connection_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(clientConnectionConfigProp)) && (ok || !reflect.DeepEqual(v, clientConnectionConfigProp)) {
391424
obj["clientConnectionConfig"] = clientConnectionConfigProp
392425
}
426+
pscInstanceConfigProp, err := expandAlloydbInstancePscInstanceConfig(d.Get("psc_instance_config"), d, config)
427+
if err != nil {
428+
return err
429+
} else if v, ok := d.GetOkExists("psc_instance_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(pscInstanceConfigProp)) && (ok || !reflect.DeepEqual(v, pscInstanceConfigProp)) {
430+
obj["pscInstanceConfig"] = pscInstanceConfigProp
431+
}
393432
networkConfigProp, err := expandAlloydbInstanceNetworkConfig(d.Get("network_config"), d, config)
394433
if err != nil {
395434
return err
@@ -606,6 +645,9 @@ func resourceAlloydbInstanceRead(d *schema.ResourceData, meta interface{}) error
606645
if err := d.Set("client_connection_config", flattenAlloydbInstanceClientConnectionConfig(res["clientConnectionConfig"], d, config)); err != nil {
607646
return fmt.Errorf("Error reading Instance: %s", err)
608647
}
648+
if err := d.Set("psc_instance_config", flattenAlloydbInstancePscInstanceConfig(res["pscInstanceConfig"], d, config)); err != nil {
649+
return fmt.Errorf("Error reading Instance: %s", err)
650+
}
609651
if err := d.Set("network_config", flattenAlloydbInstanceNetworkConfig(res["networkConfig"], d, config)); err != nil {
610652
return fmt.Errorf("Error reading Instance: %s", err)
611653
}
@@ -684,6 +726,12 @@ func resourceAlloydbInstanceUpdate(d *schema.ResourceData, meta interface{}) err
684726
} else if v, ok := d.GetOkExists("client_connection_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, clientConnectionConfigProp)) {
685727
obj["clientConnectionConfig"] = clientConnectionConfigProp
686728
}
729+
pscInstanceConfigProp, err := expandAlloydbInstancePscInstanceConfig(d.Get("psc_instance_config"), d, config)
730+
if err != nil {
731+
return err
732+
} else if v, ok := d.GetOkExists("psc_instance_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, pscInstanceConfigProp)) {
733+
obj["pscInstanceConfig"] = pscInstanceConfigProp
734+
}
687735
networkConfigProp, err := expandAlloydbInstanceNetworkConfig(d.Get("network_config"), d, config)
688736
if err != nil {
689737
return err
@@ -744,6 +792,10 @@ func resourceAlloydbInstanceUpdate(d *schema.ResourceData, meta interface{}) err
744792
updateMask = append(updateMask, "clientConnectionConfig")
745793
}
746794

795+
if d.HasChange("psc_instance_config") {
796+
updateMask = append(updateMask, "pscInstanceConfig")
797+
}
798+
747799
if d.HasChange("network_config") {
748800
updateMask = append(updateMask, "networkConfig")
749801
}
@@ -1118,6 +1170,35 @@ func flattenAlloydbInstanceClientConnectionConfigSslConfigSslMode(v interface{},
11181170
return v
11191171
}
11201172

1173+
func flattenAlloydbInstancePscInstanceConfig(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
1174+
if v == nil {
1175+
return nil
1176+
}
1177+
original := v.(map[string]interface{})
1178+
if len(original) == 0 {
1179+
return nil
1180+
}
1181+
transformed := make(map[string]interface{})
1182+
transformed["service_attachment_link"] =
1183+
flattenAlloydbInstancePscInstanceConfigServiceAttachmentLink(original["serviceAttachmentLink"], d, config)
1184+
transformed["allowed_consumer_projects"] =
1185+
flattenAlloydbInstancePscInstanceConfigAllowedConsumerProjects(original["allowedConsumerProjects"], d, config)
1186+
transformed["psc_dns_name"] =
1187+
flattenAlloydbInstancePscInstanceConfigPscDnsName(original["pscDnsName"], d, config)
1188+
return []interface{}{transformed}
1189+
}
1190+
func flattenAlloydbInstancePscInstanceConfigServiceAttachmentLink(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
1191+
return v
1192+
}
1193+
1194+
func flattenAlloydbInstancePscInstanceConfigAllowedConsumerProjects(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
1195+
return v
1196+
}
1197+
1198+
func flattenAlloydbInstancePscInstanceConfigPscDnsName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
1199+
return v
1200+
}
1201+
11211202
func flattenAlloydbInstanceNetworkConfig(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
11221203
if v == nil {
11231204
return nil
@@ -1368,6 +1449,51 @@ func expandAlloydbInstanceClientConnectionConfigSslConfigSslMode(v interface{},
13681449
return v, nil
13691450
}
13701451

1452+
func expandAlloydbInstancePscInstanceConfig(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
1453+
l := v.([]interface{})
1454+
if len(l) == 0 || l[0] == nil {
1455+
return nil, nil
1456+
}
1457+
raw := l[0]
1458+
original := raw.(map[string]interface{})
1459+
transformed := make(map[string]interface{})
1460+
1461+
transformedServiceAttachmentLink, err := expandAlloydbInstancePscInstanceConfigServiceAttachmentLink(original["service_attachment_link"], d, config)
1462+
if err != nil {
1463+
return nil, err
1464+
} else if val := reflect.ValueOf(transformedServiceAttachmentLink); val.IsValid() && !tpgresource.IsEmptyValue(val) {
1465+
transformed["serviceAttachmentLink"] = transformedServiceAttachmentLink
1466+
}
1467+
1468+
transformedAllowedConsumerProjects, err := expandAlloydbInstancePscInstanceConfigAllowedConsumerProjects(original["allowed_consumer_projects"], d, config)
1469+
if err != nil {
1470+
return nil, err
1471+
} else if val := reflect.ValueOf(transformedAllowedConsumerProjects); val.IsValid() && !tpgresource.IsEmptyValue(val) {
1472+
transformed["allowedConsumerProjects"] = transformedAllowedConsumerProjects
1473+
}
1474+
1475+
transformedPscDnsName, err := expandAlloydbInstancePscInstanceConfigPscDnsName(original["psc_dns_name"], d, config)
1476+
if err != nil {
1477+
return nil, err
1478+
} else if val := reflect.ValueOf(transformedPscDnsName); val.IsValid() && !tpgresource.IsEmptyValue(val) {
1479+
transformed["pscDnsName"] = transformedPscDnsName
1480+
}
1481+
1482+
return transformed, nil
1483+
}
1484+
1485+
func expandAlloydbInstancePscInstanceConfigServiceAttachmentLink(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
1486+
return v, nil
1487+
}
1488+
1489+
func expandAlloydbInstancePscInstanceConfigAllowedConsumerProjects(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
1490+
return v, nil
1491+
}
1492+
1493+
func expandAlloydbInstancePscInstanceConfigPscDnsName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
1494+
return v, nil
1495+
}
1496+
13711497
func expandAlloydbInstanceNetworkConfig(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
13721498
l := v.([]interface{})
13731499
if len(l) == 0 || l[0] == nil {

0 commit comments

Comments
 (0)