Skip to content

Commit

Permalink
Add support for instance_ip_mode to appengine flexible in beta (#10326)…
Browse files Browse the repository at this point in the history
… (#18168)

[upstream:4b33dad60013f723d40fc3f36686e14b1c9d6a6b]

Signed-off-by: Modular Magician <magic-modules@google.com>
  • Loading branch information
modular-magician committed May 16, 2024
1 parent c5148c6 commit 04ba3d2
Show file tree
Hide file tree
Showing 5 changed files with 180 additions and 40 deletions.
65 changes: 46 additions & 19 deletions google/services/appengine/resource_app_engine_domain_mapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,6 @@ import (
"github.com/hashicorp/terraform-provider-google/google/verify"
)

func sslSettingsDiffSuppress(k, old, new string, d *schema.ResourceData) bool {
// If certificate id is empty, and ssl management type is `MANUAL`, then
// ssl settings will not be configured, and ssl_settings block is not returned

if k == "ssl_settings.#" &&
old == "0" && new == "1" &&
d.Get("ssl_settings.0.certificate_id") == "" &&
d.Get("ssl_settings.0.ssl_management_type") == "MANUAL" {
return true
}

return false
}

func ResourceAppEngineDomainMapping() *schema.Resource {
return &schema.Resource{
Create: resourceAppEngineDomainMappingCreate,
Expand Down Expand Up @@ -84,11 +70,11 @@ By default, overrides are rejected. Default value: "STRICT" Possible values: ["S
Default: "STRICT",
},
"ssl_settings": {
Type: schema.TypeList,
Optional: true,
DiffSuppressFunc: sslSettingsDiffSuppress,
Description: `SSL configuration for this domain. If unconfigured, this domain will not serve with SSL.`,
MaxItems: 1,
Type: schema.TypeList,
Computed: true,
Optional: true,
Description: `SSL configuration for this domain. If unconfigured, this domain will not serve with SSL.`,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"ssl_management_type": {
Expand Down Expand Up @@ -245,6 +231,14 @@ func resourceAppEngineDomainMappingCreate(d *schema.ResourceData, meta interface
return fmt.Errorf("Error waiting to create DomainMapping: %s", err)
}

opRes, err = resourceAppEngineDomainMappingDecoder(d, meta, opRes)
if err != nil {
return fmt.Errorf("Error decoding response from operation: %s", err)
}
if opRes == nil {
return fmt.Errorf("Error decoding response from operation, could not find object")
}

if err := d.Set("name", flattenAppEngineDomainMappingName(opRes["name"], d, config)); err != nil {
return err
}
Expand Down Expand Up @@ -299,6 +293,18 @@ func resourceAppEngineDomainMappingRead(d *schema.ResourceData, meta interface{}
return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("AppEngineDomainMapping %q", d.Id()))
}

res, err = resourceAppEngineDomainMappingDecoder(d, meta, res)
if err != nil {
return err
}

if res == nil {
// Decoding the object has resulted in it being gone. It may be marked deleted
log.Printf("[DEBUG] Removing AppEngineDomainMapping because it no longer exists.")
d.SetId("")
return nil
}

if err := d.Set("project", project); err != nil {
return fmt.Errorf("Error reading DomainMapping: %s", err)
}
Expand Down Expand Up @@ -605,3 +611,24 @@ func expandAppEngineDomainMappingSslSettingsPendingManagedCertificateId(v interf
func expandAppEngineDomainMappingDomainName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
return v, nil
}

func resourceAppEngineDomainMappingDecoder(d *schema.ResourceData, meta interface{}, res map[string]interface{}) (map[string]interface{}, error) {
// sslManagementType does not get returned with the beta endpoint. Hence, if sslSettings is set
// and sslManagementType is set, we return that value. Otherwise, we carry over the old value
// from state by calling d.Get("ssl_settings.0.ssl_management_type")
if v, ok := res["sslSettings"]; ok {
original := v.(map[string]interface{})
if _, ok := original["sslManagementType"]; !ok {
original["sslManagementType"] = d.Get("ssl_settings.0.ssl_management_type")
}
res["sslSettings"] = original
} else {
// If ssl_settings is not set, we call d.Get("ssl_settings.0.ssl_management_type"), create sslSettings,
// and store the retrieved value in sslManagementType
transformed := make(map[string]interface{})
transformed["sslManagementType"] = d.Get("ssl_settings.0.ssl_management_type")
res["sslSettings"] = transformed
}

return res, nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func TestAccAppEngineDomainMapping_appEngineDomainMappingBasicExample(t *testing
ResourceName: "google_app_engine_domain_mapping.domain_mapping",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"override_strategy"},
ImportStateVerifyIgnore: []string{"override_strategy", "ssl_settings.0.ssl_management_type"},
},
},
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func TestAccAppEngineDomainMapping_update(t *testing.T) {
ResourceName: "google_app_engine_domain_mapping.domain_mapping",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"override_strategy"},
ImportStateVerifyIgnore: []string{"override_strategy", "ssl_settings.0.ssl_management_type"},
},
{
Config: testAccAppEngineDomainMapping_update(domainName),
Expand All @@ -36,7 +36,7 @@ func TestAccAppEngineDomainMapping_update(t *testing.T) {
ResourceName: "google_app_engine_domain_mapping.domain_mapping",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"override_strategy"},
ImportStateVerifyIgnore: []string{"override_strategy", "ssl_settings.0.ssl_management_type"},
},
},
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func TestAccAppEngineFlexibleAppVersion_update(t *testing.T) {
ResourceName: "google_app_engine_flexible_app_version.foo",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"env_variables", "deployment", "entrypoint", "service", "noop_on_destroy"},
ImportStateVerifyIgnore: []string{"env_variables", "deployment", "entrypoint", "service", "delete_service_on_destroy"},
},
},
})
Expand All @@ -55,28 +55,79 @@ resource "google_project" "my_project" {
billing_account = "%{billing_account}"
}
resource "google_app_engine_application" "app" {
project = google_project.my_project.project_id
location_id = "us-central"
resource "google_project_service" "compute" {
project = google_project.my_project.project_id
service = "compute.googleapis.com"
disable_dependent_services = false
}
resource "google_project_service" "project" {
resource "google_project_service" "appengineflex" {
project = google_project.my_project.project_id
service = "appengineflex.googleapis.com"
disable_dependent_services = false
}
resource "google_compute_network" "network" {
project = google_project_service.compute.project
name = "custom"
auto_create_subnetworks = "false"
}
resource "google_compute_subnetwork" "subnetwork" {
project = google_project_service.compute.project
name = "custom"
region = "us-central1"
network = google_compute_network.network.id
ip_cidr_range = "10.0.0.0/16"
private_ip_google_access = true
}
resource "google_app_engine_application" "app" {
project = google_project.my_project.project_id
location_id = "us-central"
}
resource "google_project_iam_member" "gae_api" {
project = google_project_service.project.project
project = google_project_service.appengineflex.project
role = "roles/compute.networkUser"
member = "serviceAccount:service-${google_project.my_project.number}@gae-api-prod.google.com.iam.gserviceaccount.com"
}
resource "google_app_engine_flexible_app_version" "foo" {
resource "google_app_engine_standard_app_version" "foo" {
project = google_project_iam_member.gae_api.project
version_id = "v1"
service = "default"
runtime = "python38"
entrypoint {
shell = "gunicorn -b :$PORT main:app"
}
deployment {
files {
name = "main.py"
source_url = "https://storage.googleapis.com/${google_storage_bucket.bucket.name}/${google_storage_bucket_object.main.name}"
}
files {
name = "requirements.txt"
source_url = "https://storage.googleapis.com/${google_storage_bucket.bucket.name}/${google_storage_bucket_object.requirements.name}"
}
}
env_variables = {
port = "8000"
}
noop_on_destroy = true
}
resource "google_app_engine_flexible_app_version" "foo" {
project = google_project_iam_member.gae_api.project
version_id = "v1"
service = "custom"
runtime = "python"
runtime_api_version = "1"
Expand Down Expand Up @@ -121,8 +172,9 @@ resource "google_app_engine_flexible_app_version" "foo" {
}
network {
name = "default"
subnetwork = "default"
name = google_compute_network.network.name
subnetwork = google_compute_subnetwork.subnetwork.name
instance_ip_mode = "EXTERNAL"
}
instance_class = "B1"
Expand All @@ -132,6 +184,8 @@ resource "google_app_engine_flexible_app_version" "foo" {
}
noop_on_destroy = true
depends_on = [google_app_engine_standard_app_version.foo]
}
resource "google_storage_bucket" "bucket" {
Expand Down Expand Up @@ -168,28 +222,79 @@ resource "google_project" "my_project" {
billing_account = "%{billing_account}"
}
resource "google_app_engine_application" "app" {
project = google_project.my_project.project_id
location_id = "us-central"
resource "google_project_service" "compute" {
project = google_project.my_project.project_id
service = "compute.googleapis.com"
disable_dependent_services = false
}
resource "google_project_service" "project" {
resource "google_project_service" "appengineflex" {
project = google_project.my_project.project_id
service = "appengineflex.googleapis.com"
disable_dependent_services = false
}
resource "google_compute_network" "network" {
project = google_project_service.compute.project
name = "custom"
auto_create_subnetworks = "false"
}
resource "google_compute_subnetwork" "subnetwork" {
project = google_project_service.compute.project
name = "custom"
region = "us-central1"
network = google_compute_network.network.id
ip_cidr_range = "10.0.0.0/16"
private_ip_google_access = true
}
resource "google_app_engine_application" "app" {
project = google_project.my_project.project_id
location_id = "us-central"
}
resource "google_project_iam_member" "gae_api" {
project = google_project_service.project.project
project = google_project_service.appengineflex.project
role = "roles/compute.networkUser"
member = "serviceAccount:service-${google_project.my_project.number}@gae-api-prod.google.com.iam.gserviceaccount.com"
}
resource "google_app_engine_flexible_app_version" "foo" {
resource "google_app_engine_standard_app_version" "foo" {
project = google_project_iam_member.gae_api.project
version_id = "v1"
service = "default"
runtime = "python38"
entrypoint {
shell = "gunicorn -b :$PORT main:app"
}
deployment {
files {
name = "main.py"
source_url = "https://storage.googleapis.com/${google_storage_bucket.bucket.name}/${google_storage_bucket_object.main.name}"
}
files {
name = "requirements.txt"
source_url = "https://storage.googleapis.com/${google_storage_bucket.bucket.name}/${google_storage_bucket_object.requirements.name}"
}
}
env_variables = {
port = "8000"
}
noop_on_destroy = true
}
resource "google_app_engine_flexible_app_version" "foo" {
project = google_project_iam_member.gae_api.project
version_id = "v1"
service = "custom"
runtime = "python"
runtime_api_version = "1"
Expand Down Expand Up @@ -234,8 +339,9 @@ resource "google_app_engine_flexible_app_version" "foo" {
}
network {
name = "default"
subnetwork = "default"
name = google_compute_network.network.name
subnetwork = google_compute_subnetwork.subnetwork.name
instance_ip_mode = "INTERNAL"
}
instance_class = "B2"
Expand All @@ -244,7 +350,9 @@ resource "google_app_engine_flexible_app_version" "foo" {
instances = 2
}
noop_on_destroy = true
delete_service_on_destroy = true
depends_on = [google_app_engine_standard_app_version.foo]
}
resource "google_storage_bucket" "bucket" {
Expand Down
5 changes: 5 additions & 0 deletions website/docs/r/app_engine_flexible_app_version.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,11 @@ The following arguments are supported:
(Optional)
List of ports, or port pairs, to forward from the virtual machine to the application container.

* `instance_ip_mode` -
(Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html))
Prevent instances from receiving an ephemeral external IP address.
Possible values are: `EXTERNAL`, `INTERNAL`.

* `instance_tag` -
(Optional)
Tag to apply to the instance during creation.
Expand Down

0 comments on commit 04ba3d2

Please sign in to comment.