diff --git a/third_party/terraform/resources/resource_container_cluster.go.erb b/third_party/terraform/resources/resource_container_cluster.go.erb index 84bb281fdf16..a438387e5580 100644 --- a/third_party/terraform/resources/resource_container_cluster.go.erb +++ b/third_party/terraform/resources/resource_container_cluster.go.erb @@ -317,6 +317,7 @@ func resourceContainerCluster() *schema.Resource { Type: schema.TypeList, MaxItems: 1, Optional: true, + Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "oauth_scopes": { @@ -2879,7 +2880,14 @@ func cidrOrSizeDiffSuppress(k, old, new string, d *schema.ResourceData) bool { return strings.HasPrefix(new, "/") && strings.HasSuffix(old, new) } -// We want to suppress diffs for the scopes automatically added by GKE +// Suppress unremovable default scope values from GCP. +// If the default service account would not otherwise have it, the `monitoring.write` scope +// is added to a GKE cluster's scopes regardless of what the user provided. +// monitoring.write is inherited from monitoring (rw) and cloud-platform, so it won't always +// be present. +// Enabling Stackdriver features through logging_service and monitoring_service may enable +// monitoring or logging.write. We've chosen not to suppress in those cases because they're +// removable by disabling those features. func containerClusterAddedScopesSuppress(k, old, new string, d *schema.ResourceData) bool { o, n := d.GetChange("cluster_autoscaling.0.auto_provisioning_defaults.0.oauth_scopes") diff --git a/third_party/terraform/tests/resource_container_cluster_test.go.erb b/third_party/terraform/tests/resource_container_cluster_test.go.erb index d5823031dea1..3c238d97071e 100644 --- a/third_party/terraform/tests/resource_container_cluster_test.go.erb +++ b/third_party/terraform/tests/resource_container_cluster_test.go.erb @@ -1231,6 +1231,38 @@ func TestAccContainerCluster_nodeAutoprovisioning(t *testing.T) { }) } +func TestAccContainerCluster_nodeAutoprovisioningDefaults(t *testing.T) { + t.Parallel() + + clusterName := fmt.Sprintf("cluster-test-%s", acctest.RandString(10)) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckContainerClusterDestroy, + Steps: []resource.TestStep{ + { + Config: testAccContainerCluster_autoprovisioningDefaults(clusterName, false), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("google_container_cluster.with_autoprovisioning", + "cluster_autoscaling.0.enabled", "true"), + ), + }, + { + ResourceName: "google_container_cluster.with_autoprovisioning", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"min_master_version"}, + }, + { + Config: testAccContainerCluster_autoprovisioningDefaults(clusterName, true), + PlanOnly: true, + ExpectNonEmptyPlan: false, + }, + }, + }) +} + <% unless version == 'ga' -%> func TestAccContainerCluster_sharedVpc(t *testing.T) { t.Parallel() @@ -2628,9 +2660,6 @@ resource "google_container_cluster" "with_autoprovisioning" { min_master_version = data.google_container_engine_versions.central1a.latest_master_version initial_node_count = 1 - logging_service = "none" - monitoring_service = "none" - `, cluster) if autoprovisioning { config += ` @@ -2644,12 +2673,6 @@ resource "google_container_cluster" "with_autoprovisioning" { resource_type = "memory" maximum = 2048 } - auto_provisioning_defaults { - oauth_scopes = [ - "https://www.googleapis.com/auth/pubsub", - "https://www.googleapis.com/auth/devstorage.read_only" - ] - } }` } else { config += ` @@ -2662,6 +2685,51 @@ resource "google_container_cluster" "with_autoprovisioning" { return config } +func testAccContainerCluster_autoprovisioningDefaults(cluster string, monitoringWrite bool) string { + config := fmt.Sprintf(` +data "google_container_engine_versions" "central1a" { + location = "us-central1-a" +} + +resource "google_container_cluster" "with_autoprovisioning" { + name = "%s" + location = "us-central1-a" + min_master_version = data.google_container_engine_versions.central1a.latest_master_version + initial_node_count = 1 + + logging_service = "none" + monitoring_service = "none" + + cluster_autoscaling { + enabled = true + resource_limits { + resource_type = "cpu" + maximum = 2 + } + resource_limits { + resource_type = "memory" + maximum = 2048 + } + + auto_provisioning_defaults { + oauth_scopes = [ + "https://www.googleapis.com/auth/pubsub", + "https://www.googleapis.com/auth/devstorage.read_only",`, +cluster) + +if monitoringWrite { + config += ` + "https://www.googleapis.com/auth/monitoring.write", +` + } + config += ` + ] + } + } +}` + return config +} + func testAccContainerCluster_withNodePoolAutoscaling(cluster, np string) string { return fmt.Sprintf(` resource "google_container_cluster" "with_node_pool" { diff --git a/third_party/terraform/website/docs/r/container_cluster.html.markdown b/third_party/terraform/website/docs/r/container_cluster.html.markdown index 024e19c49118..56292f5f44e3 100644 --- a/third_party/terraform/website/docs/r/container_cluster.html.markdown +++ b/third_party/terraform/website/docs/r/container_cluster.html.markdown @@ -380,6 +380,9 @@ The `auto_provisioning_defaults` block supports: * `oauth_scopes` - (Optional) Scopes that are used by NAP when creating node pools. If `oauth_scopes` are specified, `service_account` must be empty. +-> `monitoring.write` is always enabled regardless of user input. `monitoring` and `logging.write` may also be enabled +depending on the values for `monitoring_service` and `logging_service`. + * `service_account` - (Optional) The Google Cloud Platform Service Account to be used by the node VMs. If `service_account` is specified, `oauth_scopes` must be empty.