Skip to content

Commit 04ba3d2

Browse files
Add support for instance_ip_mode to appengine flexible in beta (#10326) (#18168)
[upstream:4b33dad60013f723d40fc3f36686e14b1c9d6a6b] Signed-off-by: Modular Magician <[email protected]>
1 parent c5148c6 commit 04ba3d2

5 files changed

+180
-40
lines changed

google/services/appengine/resource_app_engine_domain_mapping.go

+46-19
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,6 @@ import (
3333
"github.com/hashicorp/terraform-provider-google/google/verify"
3434
)
3535

36-
func sslSettingsDiffSuppress(k, old, new string, d *schema.ResourceData) bool {
37-
// If certificate id is empty, and ssl management type is `MANUAL`, then
38-
// ssl settings will not be configured, and ssl_settings block is not returned
39-
40-
if k == "ssl_settings.#" &&
41-
old == "0" && new == "1" &&
42-
d.Get("ssl_settings.0.certificate_id") == "" &&
43-
d.Get("ssl_settings.0.ssl_management_type") == "MANUAL" {
44-
return true
45-
}
46-
47-
return false
48-
}
49-
5036
func ResourceAppEngineDomainMapping() *schema.Resource {
5137
return &schema.Resource{
5238
Create: resourceAppEngineDomainMappingCreate,
@@ -84,11 +70,11 @@ By default, overrides are rejected. Default value: "STRICT" Possible values: ["S
8470
Default: "STRICT",
8571
},
8672
"ssl_settings": {
87-
Type: schema.TypeList,
88-
Optional: true,
89-
DiffSuppressFunc: sslSettingsDiffSuppress,
90-
Description: `SSL configuration for this domain. If unconfigured, this domain will not serve with SSL.`,
91-
MaxItems: 1,
73+
Type: schema.TypeList,
74+
Computed: true,
75+
Optional: true,
76+
Description: `SSL configuration for this domain. If unconfigured, this domain will not serve with SSL.`,
77+
MaxItems: 1,
9278
Elem: &schema.Resource{
9379
Schema: map[string]*schema.Schema{
9480
"ssl_management_type": {
@@ -245,6 +231,14 @@ func resourceAppEngineDomainMappingCreate(d *schema.ResourceData, meta interface
245231
return fmt.Errorf("Error waiting to create DomainMapping: %s", err)
246232
}
247233

234+
opRes, err = resourceAppEngineDomainMappingDecoder(d, meta, opRes)
235+
if err != nil {
236+
return fmt.Errorf("Error decoding response from operation: %s", err)
237+
}
238+
if opRes == nil {
239+
return fmt.Errorf("Error decoding response from operation, could not find object")
240+
}
241+
248242
if err := d.Set("name", flattenAppEngineDomainMappingName(opRes["name"], d, config)); err != nil {
249243
return err
250244
}
@@ -299,6 +293,18 @@ func resourceAppEngineDomainMappingRead(d *schema.ResourceData, meta interface{}
299293
return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("AppEngineDomainMapping %q", d.Id()))
300294
}
301295

296+
res, err = resourceAppEngineDomainMappingDecoder(d, meta, res)
297+
if err != nil {
298+
return err
299+
}
300+
301+
if res == nil {
302+
// Decoding the object has resulted in it being gone. It may be marked deleted
303+
log.Printf("[DEBUG] Removing AppEngineDomainMapping because it no longer exists.")
304+
d.SetId("")
305+
return nil
306+
}
307+
302308
if err := d.Set("project", project); err != nil {
303309
return fmt.Errorf("Error reading DomainMapping: %s", err)
304310
}
@@ -605,3 +611,24 @@ func expandAppEngineDomainMappingSslSettingsPendingManagedCertificateId(v interf
605611
func expandAppEngineDomainMappingDomainName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
606612
return v, nil
607613
}
614+
615+
func resourceAppEngineDomainMappingDecoder(d *schema.ResourceData, meta interface{}, res map[string]interface{}) (map[string]interface{}, error) {
616+
// sslManagementType does not get returned with the beta endpoint. Hence, if sslSettings is set
617+
// and sslManagementType is set, we return that value. Otherwise, we carry over the old value
618+
// from state by calling d.Get("ssl_settings.0.ssl_management_type")
619+
if v, ok := res["sslSettings"]; ok {
620+
original := v.(map[string]interface{})
621+
if _, ok := original["sslManagementType"]; !ok {
622+
original["sslManagementType"] = d.Get("ssl_settings.0.ssl_management_type")
623+
}
624+
res["sslSettings"] = original
625+
} else {
626+
// If ssl_settings is not set, we call d.Get("ssl_settings.0.ssl_management_type"), create sslSettings,
627+
// and store the retrieved value in sslManagementType
628+
transformed := make(map[string]interface{})
629+
transformed["sslManagementType"] = d.Get("ssl_settings.0.ssl_management_type")
630+
res["sslSettings"] = transformed
631+
}
632+
633+
return res, nil
634+
}

google/services/appengine/resource_app_engine_domain_mapping_generated_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func TestAccAppEngineDomainMapping_appEngineDomainMappingBasicExample(t *testing
4949
ResourceName: "google_app_engine_domain_mapping.domain_mapping",
5050
ImportState: true,
5151
ImportStateVerify: true,
52-
ImportStateVerifyIgnore: []string{"override_strategy"},
52+
ImportStateVerifyIgnore: []string{"override_strategy", "ssl_settings.0.ssl_management_type"},
5353
},
5454
},
5555
})

google/services/appengine/resource_app_engine_domain_mapping_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ func TestAccAppEngineDomainMapping_update(t *testing.T) {
2727
ResourceName: "google_app_engine_domain_mapping.domain_mapping",
2828
ImportState: true,
2929
ImportStateVerify: true,
30-
ImportStateVerifyIgnore: []string{"override_strategy"},
30+
ImportStateVerifyIgnore: []string{"override_strategy", "ssl_settings.0.ssl_management_type"},
3131
},
3232
{
3333
Config: testAccAppEngineDomainMapping_update(domainName),
@@ -36,7 +36,7 @@ func TestAccAppEngineDomainMapping_update(t *testing.T) {
3636
ResourceName: "google_app_engine_domain_mapping.domain_mapping",
3737
ImportState: true,
3838
ImportStateVerify: true,
39-
ImportStateVerifyIgnore: []string{"override_strategy"},
39+
ImportStateVerifyIgnore: []string{"override_strategy", "ssl_settings.0.ssl_management_type"},
4040
},
4141
},
4242
})

google/services/appengine/resource_app_engine_flexible_app_version_test.go

+126-18
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ func TestAccAppEngineFlexibleAppVersion_update(t *testing.T) {
4040
ResourceName: "google_app_engine_flexible_app_version.foo",
4141
ImportState: true,
4242
ImportStateVerify: true,
43-
ImportStateVerifyIgnore: []string{"env_variables", "deployment", "entrypoint", "service", "noop_on_destroy"},
43+
ImportStateVerifyIgnore: []string{"env_variables", "deployment", "entrypoint", "service", "delete_service_on_destroy"},
4444
},
4545
},
4646
})
@@ -55,28 +55,79 @@ resource "google_project" "my_project" {
5555
billing_account = "%{billing_account}"
5656
}
5757
58-
resource "google_app_engine_application" "app" {
59-
project = google_project.my_project.project_id
60-
location_id = "us-central"
58+
resource "google_project_service" "compute" {
59+
project = google_project.my_project.project_id
60+
service = "compute.googleapis.com"
61+
62+
disable_dependent_services = false
6163
}
6264
63-
resource "google_project_service" "project" {
65+
resource "google_project_service" "appengineflex" {
6466
project = google_project.my_project.project_id
6567
service = "appengineflex.googleapis.com"
6668
6769
disable_dependent_services = false
6870
}
6971
72+
resource "google_compute_network" "network" {
73+
project = google_project_service.compute.project
74+
name = "custom"
75+
auto_create_subnetworks = "false"
76+
}
77+
78+
resource "google_compute_subnetwork" "subnetwork" {
79+
project = google_project_service.compute.project
80+
name = "custom"
81+
region = "us-central1"
82+
network = google_compute_network.network.id
83+
ip_cidr_range = "10.0.0.0/16"
84+
private_ip_google_access = true
85+
}
86+
87+
resource "google_app_engine_application" "app" {
88+
project = google_project.my_project.project_id
89+
location_id = "us-central"
90+
}
91+
7092
resource "google_project_iam_member" "gae_api" {
71-
project = google_project_service.project.project
93+
project = google_project_service.appengineflex.project
7294
role = "roles/compute.networkUser"
7395
member = "serviceAccount:service-${google_project.my_project.number}@gae-api-prod.google.com.iam.gserviceaccount.com"
7496
}
7597
76-
resource "google_app_engine_flexible_app_version" "foo" {
98+
resource "google_app_engine_standard_app_version" "foo" {
7799
project = google_project_iam_member.gae_api.project
78100
version_id = "v1"
79101
service = "default"
102+
runtime = "python38"
103+
104+
entrypoint {
105+
shell = "gunicorn -b :$PORT main:app"
106+
}
107+
108+
deployment {
109+
files {
110+
name = "main.py"
111+
source_url = "https://storage.googleapis.com/${google_storage_bucket.bucket.name}/${google_storage_bucket_object.main.name}"
112+
}
113+
114+
files {
115+
name = "requirements.txt"
116+
source_url = "https://storage.googleapis.com/${google_storage_bucket.bucket.name}/${google_storage_bucket_object.requirements.name}"
117+
}
118+
}
119+
120+
env_variables = {
121+
port = "8000"
122+
}
123+
124+
noop_on_destroy = true
125+
}
126+
127+
resource "google_app_engine_flexible_app_version" "foo" {
128+
project = google_project_iam_member.gae_api.project
129+
version_id = "v1"
130+
service = "custom"
80131
runtime = "python"
81132
82133
runtime_api_version = "1"
@@ -121,8 +172,9 @@ resource "google_app_engine_flexible_app_version" "foo" {
121172
}
122173
123174
network {
124-
name = "default"
125-
subnetwork = "default"
175+
name = google_compute_network.network.name
176+
subnetwork = google_compute_subnetwork.subnetwork.name
177+
instance_ip_mode = "EXTERNAL"
126178
}
127179
128180
instance_class = "B1"
@@ -132,6 +184,8 @@ resource "google_app_engine_flexible_app_version" "foo" {
132184
}
133185
134186
noop_on_destroy = true
187+
188+
depends_on = [google_app_engine_standard_app_version.foo]
135189
}
136190
137191
resource "google_storage_bucket" "bucket" {
@@ -168,28 +222,79 @@ resource "google_project" "my_project" {
168222
billing_account = "%{billing_account}"
169223
}
170224
171-
resource "google_app_engine_application" "app" {
172-
project = google_project.my_project.project_id
173-
location_id = "us-central"
225+
resource "google_project_service" "compute" {
226+
project = google_project.my_project.project_id
227+
service = "compute.googleapis.com"
228+
229+
disable_dependent_services = false
174230
}
175231
176-
resource "google_project_service" "project" {
232+
resource "google_project_service" "appengineflex" {
177233
project = google_project.my_project.project_id
178234
service = "appengineflex.googleapis.com"
179235
180236
disable_dependent_services = false
181237
}
182238
239+
resource "google_compute_network" "network" {
240+
project = google_project_service.compute.project
241+
name = "custom"
242+
auto_create_subnetworks = "false"
243+
}
244+
245+
resource "google_compute_subnetwork" "subnetwork" {
246+
project = google_project_service.compute.project
247+
name = "custom"
248+
region = "us-central1"
249+
network = google_compute_network.network.id
250+
ip_cidr_range = "10.0.0.0/16"
251+
private_ip_google_access = true
252+
}
253+
254+
resource "google_app_engine_application" "app" {
255+
project = google_project.my_project.project_id
256+
location_id = "us-central"
257+
}
258+
183259
resource "google_project_iam_member" "gae_api" {
184-
project = google_project_service.project.project
260+
project = google_project_service.appengineflex.project
185261
role = "roles/compute.networkUser"
186262
member = "serviceAccount:service-${google_project.my_project.number}@gae-api-prod.google.com.iam.gserviceaccount.com"
187263
}
188264
189-
resource "google_app_engine_flexible_app_version" "foo" {
265+
resource "google_app_engine_standard_app_version" "foo" {
190266
project = google_project_iam_member.gae_api.project
191267
version_id = "v1"
192268
service = "default"
269+
runtime = "python38"
270+
271+
entrypoint {
272+
shell = "gunicorn -b :$PORT main:app"
273+
}
274+
275+
deployment {
276+
files {
277+
name = "main.py"
278+
source_url = "https://storage.googleapis.com/${google_storage_bucket.bucket.name}/${google_storage_bucket_object.main.name}"
279+
}
280+
281+
files {
282+
name = "requirements.txt"
283+
source_url = "https://storage.googleapis.com/${google_storage_bucket.bucket.name}/${google_storage_bucket_object.requirements.name}"
284+
}
285+
}
286+
287+
env_variables = {
288+
port = "8000"
289+
}
290+
291+
noop_on_destroy = true
292+
}
293+
294+
resource "google_app_engine_flexible_app_version" "foo" {
295+
project = google_project_iam_member.gae_api.project
296+
version_id = "v1"
297+
service = "custom"
193298
runtime = "python"
194299
195300
runtime_api_version = "1"
@@ -234,8 +339,9 @@ resource "google_app_engine_flexible_app_version" "foo" {
234339
}
235340
236341
network {
237-
name = "default"
238-
subnetwork = "default"
342+
name = google_compute_network.network.name
343+
subnetwork = google_compute_subnetwork.subnetwork.name
344+
instance_ip_mode = "INTERNAL"
239345
}
240346
241347
instance_class = "B2"
@@ -244,7 +350,9 @@ resource "google_app_engine_flexible_app_version" "foo" {
244350
instances = 2
245351
}
246352
247-
noop_on_destroy = true
353+
delete_service_on_destroy = true
354+
355+
depends_on = [google_app_engine_standard_app_version.foo]
248356
}
249357
250358
resource "google_storage_bucket" "bucket" {

website/docs/r/app_engine_flexible_app_version.html.markdown

+5
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,11 @@ The following arguments are supported:
357357
(Optional)
358358
List of ports, or port pairs, to forward from the virtual machine to the application container.
359359

360+
* `instance_ip_mode` -
361+
(Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html))
362+
Prevent instances from receiving an ephemeral external IP address.
363+
Possible values are: `EXTERNAL`, `INTERNAL`.
364+
360365
* `instance_tag` -
361366
(Optional)
362367
Tag to apply to the instance during creation.

0 commit comments

Comments
 (0)