Skip to content

Commit 87b1f51

Browse files
Add "consumerAcceptList" and "serviceAttachment" to ApigeeInstance. (#5862) (#11595)
* Add support IAM policy for the Environment of Apigee X * Add support IAM policy for the Environment of Apigee X * Add support IAM policy for the Environment of Apigee X * Add support IAM policy for the Environment of Apigee X * Revert all changes to test files. * Revert all changes to test files. * Revert all changes to test files. * Add primary_resource_name to fix tests. * Update iam_attributes.tf.erb to honor skip_test. * Don't reject skip_tests when example is nil. * Update mmv1/products/apigee/api.yaml Co-authored-by: Stephen Lewis (Burrows) <[email protected]> * Fix primary_resource_name for apigee organization name. * Add "consumerAcceptList" and "serviceAttachment" to ApigeeInstance. * Fix new test * Add tests Co-authored-by: Stephen Lewis (Burrows) <[email protected]> Signed-off-by: Modular Magician <[email protected]> Co-authored-by: Stephen Lewis (Burrows) <[email protected]>
1 parent e0f4316 commit 87b1f51

File tree

4 files changed

+252
-0
lines changed

4 files changed

+252
-0
lines changed

.changelog/5862.txt

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:enhancement
2+
Add "consumerAcceptList" and "serviceAttachment" to ApigeeInstance.
3+
```

google/resource_apigee_instance.go

+44
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,19 @@ func resourceApigeeInstance() *schema.Resource {
5959
Description: `The Apigee Organization associated with the Apigee instance,
6060
in the format 'organizations/{{org_name}}'.`,
6161
},
62+
"consumer_accept_list": {
63+
Type: schema.TypeList,
64+
Computed: true,
65+
Optional: true,
66+
ForceNew: true,
67+
Description: `Optional. Customer accept list represents the list of projects (id/number) on customer
68+
side that can privately connect to the service attachment. It is an optional field
69+
which the customers can provide during the instance creation. By default, the customer
70+
project associated with the Apigee organization will be included to the list.`,
71+
Elem: &schema.Schema{
72+
Type: schema.TypeString,
73+
},
74+
},
6275
"description": {
6376
Type: schema.TypeString,
6477
Optional: true,
@@ -108,6 +121,13 @@ see [CidrRange](https://cloud.google.com/apigee/docs/reference/apis/apigee/rest/
108121
Computed: true,
109122
Description: `Output only. Port number of the exposed Apigee endpoint.`,
110123
},
124+
"service_attachment": {
125+
Type: schema.TypeString,
126+
Computed: true,
127+
Description: `Output only. Resource name of the service attachment created for the instance in
128+
the format: projects/*/regions/*/serviceAttachments/* Apigee customers can privately
129+
forward traffic to this service attachment using the PSC endpoints.`,
130+
},
111131
},
112132
UseJSONNumber: true,
113133
}
@@ -163,6 +183,12 @@ func resourceApigeeInstanceCreate(d *schema.ResourceData, meta interface{}) erro
163183
} else if v, ok := d.GetOkExists("disk_encryption_key_name"); !isEmptyValue(reflect.ValueOf(diskEncryptionKeyNameProp)) && (ok || !reflect.DeepEqual(v, diskEncryptionKeyNameProp)) {
164184
obj["diskEncryptionKeyName"] = diskEncryptionKeyNameProp
165185
}
186+
consumerAcceptListProp, err := expandApigeeInstanceConsumerAcceptList(d.Get("consumer_accept_list"), d, config)
187+
if err != nil {
188+
return err
189+
} else if v, ok := d.GetOkExists("consumer_accept_list"); !isEmptyValue(reflect.ValueOf(consumerAcceptListProp)) && (ok || !reflect.DeepEqual(v, consumerAcceptListProp)) {
190+
obj["consumerAcceptList"] = consumerAcceptListProp
191+
}
166192

167193
lockName, err := replaceVars(d, config, "{{org_id}}/apigeeInstances")
168194
if err != nil {
@@ -272,6 +298,12 @@ func resourceApigeeInstanceRead(d *schema.ResourceData, meta interface{}) error
272298
if err := d.Set("port", flattenApigeeInstancePort(res["port"], d, config)); err != nil {
273299
return fmt.Errorf("Error reading Instance: %s", err)
274300
}
301+
if err := d.Set("consumer_accept_list", flattenApigeeInstanceConsumerAcceptList(res["consumerAcceptList"], d, config)); err != nil {
302+
return fmt.Errorf("Error reading Instance: %s", err)
303+
}
304+
if err := d.Set("service_attachment", flattenApigeeInstanceServiceAttachment(res["serviceAttachment"], d, config)); err != nil {
305+
return fmt.Errorf("Error reading Instance: %s", err)
306+
}
275307

276308
return nil
277309
}
@@ -399,6 +431,14 @@ func flattenApigeeInstancePort(v interface{}, d *schema.ResourceData, config *Co
399431
return v
400432
}
401433

434+
func flattenApigeeInstanceConsumerAcceptList(v interface{}, d *schema.ResourceData, config *Config) interface{} {
435+
return v
436+
}
437+
438+
func flattenApigeeInstanceServiceAttachment(v interface{}, d *schema.ResourceData, config *Config) interface{} {
439+
return v
440+
}
441+
402442
func expandApigeeInstanceName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
403443
return v, nil
404444
}
@@ -426,3 +466,7 @@ func expandApigeeInstanceDisplayName(v interface{}, d TerraformResourceData, con
426466
func expandApigeeInstanceDiskEncryptionKeyName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
427467
return v, nil
428468
}
469+
470+
func expandApigeeInstanceConsumerAcceptList(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
471+
return v, nil
472+
}

google/resource_apigee_instance_generated_test.go

+193
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,199 @@ resource "google_apigee_instance" "apigee_instance" {
301301
`, context)
302302
}
303303

304+
func TestAccApigeeInstance_apigeeInstanceServiceAttachmentBasicTestExample(t *testing.T) {
305+
skipIfVcr(t)
306+
t.Parallel()
307+
308+
context := map[string]interface{}{
309+
"org_id": getTestOrgFromEnv(t),
310+
"billing_account": getTestBillingAccountFromEnv(t),
311+
"random_suffix": randString(t, 10),
312+
}
313+
314+
vcrTest(t, resource.TestCase{
315+
PreCheck: func() { testAccPreCheck(t) },
316+
Providers: testAccProviders,
317+
CheckDestroy: testAccCheckApigeeInstanceDestroyProducer(t),
318+
Steps: []resource.TestStep{
319+
{
320+
Config: testAccApigeeInstance_apigeeInstanceServiceAttachmentBasicTestExample(context),
321+
},
322+
{
323+
ResourceName: "google_apigee_instance.apigee_instance",
324+
ImportState: true,
325+
ImportStateVerify: true,
326+
ImportStateVerifyIgnore: []string{"ip_range", "org_id"},
327+
},
328+
},
329+
})
330+
}
331+
332+
func testAccApigeeInstance_apigeeInstanceServiceAttachmentBasicTestExample(context map[string]interface{}) string {
333+
return Nprintf(`
334+
resource "google_project" "project" {
335+
project_id = "tf-test%{random_suffix}"
336+
name = "tf-test%{random_suffix}"
337+
org_id = "%{org_id}"
338+
billing_account = "%{billing_account}"
339+
}
340+
341+
resource "google_project_service" "apigee" {
342+
project = google_project.project.project_id
343+
service = "apigee.googleapis.com"
344+
}
345+
346+
resource "google_project_service" "compute" {
347+
project = google_project.project.project_id
348+
service = "compute.googleapis.com"
349+
}
350+
351+
resource "google_project_service" "servicenetworking" {
352+
project = google_project.project.project_id
353+
service = "servicenetworking.googleapis.com"
354+
}
355+
356+
resource "google_compute_network" "apigee_network" {
357+
name = "apigee-network"
358+
project = google_project.project.project_id
359+
depends_on = [google_project_service.compute]
360+
}
361+
362+
resource "google_compute_global_address" "apigee_range" {
363+
name = "apigee-range"
364+
purpose = "VPC_PEERING"
365+
address_type = "INTERNAL"
366+
prefix_length = 16
367+
network = google_compute_network.apigee_network.id
368+
project = google_project.project.project_id
369+
}
370+
371+
resource "google_service_networking_connection" "apigee_vpc_connection" {
372+
network = google_compute_network.apigee_network.id
373+
service = "servicenetworking.googleapis.com"
374+
reserved_peering_ranges = [google_compute_global_address.apigee_range.name]
375+
depends_on = [google_project_service.servicenetworking]
376+
}
377+
378+
resource "google_compute_address" "psc_ilb_consumer_address" {
379+
name = "psc-ilb-consumer-address"
380+
region = "us-west2"
381+
382+
subnetwork = "default"
383+
address_type = "INTERNAL"
384+
385+
project = google_project.project.project_id
386+
depends_on = [google_project_service.compute]
387+
}
388+
389+
resource "google_compute_forwarding_rule" "psc_ilb_consumer" {
390+
name = "psc-ilb-consumer-forwarding-rule"
391+
region = "us-west2"
392+
393+
target = google_compute_service_attachment.psc_ilb_service_attachment.id
394+
load_balancing_scheme = "" # need to override EXTERNAL default when target is a service attachment
395+
network = "default"
396+
ip_address = google_compute_address.psc_ilb_consumer_address.id
397+
398+
project = google_project.project.project_id
399+
}
400+
401+
resource "google_compute_forwarding_rule" "psc_ilb_target_service" {
402+
name = "producer-forwarding-rule"
403+
region = "us-west2"
404+
405+
load_balancing_scheme = "INTERNAL"
406+
backend_service = google_compute_region_backend_service.producer_service_backend.id
407+
all_ports = true
408+
network = google_compute_network.psc_ilb_network.name
409+
subnetwork = google_compute_subnetwork.psc_ilb_producer_subnetwork.name
410+
411+
project = google_project.project.project_id
412+
}
413+
414+
resource "google_compute_region_backend_service" "producer_service_backend" {
415+
name = "producer-service"
416+
region = "us-west2"
417+
418+
health_checks = [google_compute_health_check.producer_service_health_check.id]
419+
420+
project = google_project.project.project_id
421+
}
422+
423+
resource "google_compute_health_check" "producer_service_health_check" {
424+
name = "producer-service-health-check"
425+
426+
check_interval_sec = 1
427+
timeout_sec = 1
428+
tcp_health_check {
429+
port = "80"
430+
}
431+
432+
project = google_project.project.project_id
433+
depends_on = [google_project_service.compute]
434+
}
435+
436+
resource "google_compute_network" "psc_ilb_network" {
437+
name = "psc-ilb-network"
438+
auto_create_subnetworks = false
439+
440+
project = google_project.project.project_id
441+
depends_on = [google_project_service.compute]
442+
}
443+
444+
resource "google_compute_subnetwork" "psc_ilb_producer_subnetwork" {
445+
name = "psc-ilb-producer-subnetwork"
446+
region = "us-west2"
447+
448+
network = google_compute_network.psc_ilb_network.id
449+
ip_cidr_range = "10.0.0.0/16"
450+
451+
project = google_project.project.project_id
452+
}
453+
454+
resource "google_compute_subnetwork" "psc_ilb_nat" {
455+
name = "psc-ilb-nat"
456+
region = "us-west2"
457+
458+
network = google_compute_network.psc_ilb_network.id
459+
purpose = "PRIVATE_SERVICE_CONNECT"
460+
ip_cidr_range = "10.1.0.0/16"
461+
462+
project = google_project.project.project_id
463+
}
464+
465+
resource "google_compute_service_attachment" "psc_ilb_service_attachment" {
466+
name = "my-psc-ilb"
467+
region = "us-west2"
468+
description = "A service attachment configured with Terraform"
469+
470+
enable_proxy_protocol = true
471+
connection_preference = "ACCEPT_AUTOMATIC"
472+
nat_subnets = [google_compute_subnetwork.psc_ilb_nat.id]
473+
target_service = google_compute_forwarding_rule.psc_ilb_target_service.id
474+
475+
project = google_project.project.project_id
476+
}
477+
478+
resource "google_apigee_organization" "apigee_org" {
479+
analytics_region = "us-central1"
480+
project_id = google_project.project.project_id
481+
authorized_network = google_compute_network.apigee_network.id
482+
depends_on = [
483+
google_service_networking_connection.apigee_vpc_connection,
484+
google_project_service.apigee,
485+
]
486+
}
487+
488+
resource "google_apigee_instance" "apigee_instance" {
489+
name = "tf-test%{random_suffix}"
490+
location = "us-central1"
491+
org_id = google_apigee_organization.apigee_org.id
492+
consumer_accept_list = [123456, google_project.project.number]
493+
}
494+
`, context)
495+
}
496+
304497
func testAccCheckApigeeInstanceDestroyProducer(t *testing.T) func(s *terraform.State) error {
305498
return func(s *terraform.State) error {
306499
for name, rs := range s.RootModule().Resources {

website/docs/r/apigee_instance.html.markdown

+12
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,13 @@ The following arguments are supported:
271271
Customer Managed Encryption Key (CMEK) used for disk and volume encryption. Required for Apigee paid subscriptions only.
272272
Use the following format: `projects/([^/]+)/locations/([^/]+)/keyRings/([^/]+)/cryptoKeys/([^/]+)`
273273

274+
* `consumer_accept_list` -
275+
(Optional)
276+
Optional. Customer accept list represents the list of projects (id/number) on customer
277+
side that can privately connect to the service attachment. It is an optional field
278+
which the customers can provide during the instance creation. By default, the customer
279+
project associated with the Apigee organization will be included to the list.
280+
274281

275282
## Attributes Reference
276283

@@ -284,6 +291,11 @@ In addition to the arguments listed above, the following computed attributes are
284291
* `port` -
285292
Output only. Port number of the exposed Apigee endpoint.
286293

294+
* `service_attachment` -
295+
Output only. Resource name of the service attachment created for the instance in
296+
the format: projects/*/regions/*/serviceAttachments/* Apigee customers can privately
297+
forward traffic to this service attachment using the PSC endpoints.
298+
287299

288300
## Timeouts
289301

0 commit comments

Comments
 (0)