From a13232e26098c03234800aa3b1dc13c852e7f545 Mon Sep 17 00:00:00 2001 From: Riley Karson Date: Fri, 8 Nov 2019 10:02:27 -0800 Subject: [PATCH] Remove automatic subnetwork creation in GKE (#2615) * Remove automatic subnetwork creation in GKE * Update docs, add Computed --- .../resource_container_cluster.go.erb | 145 ++++------- .../resource_container_cluster_test.go.erb | 240 ++---------------- .../docs/r/container_cluster.html.markdown | 64 ++--- 3 files changed, 90 insertions(+), 359 deletions(-) diff --git a/third_party/terraform/resources/resource_container_cluster.go.erb b/third_party/terraform/resources/resource_container_cluster.go.erb index 524c4b04c919..5d04a416cdd3 100644 --- a/third_party/terraform/resources/resource_container_cluster.go.erb +++ b/third_party/terraform/resources/resource_container_cluster.go.erb @@ -43,8 +43,7 @@ var ( }, } - ipAllocationSubnetFields = []string{"ip_allocation_policy.0.create_subnetwork", "ip_allocation_policy.0.subnetwork_name"} - ipAllocationCidrBlockFields = []string{"ip_allocation_policy.0.cluster_ipv4_cidr_block", "ip_allocation_policy.0.services_ipv4_cidr_block", "ip_allocation_policy.0.node_ipv4_cidr_block"} + ipAllocationCidrBlockFields = []string{"ip_allocation_policy.0.cluster_ipv4_cidr_block", "ip_allocation_policy.0.services_ipv4_cidr_block"} ipAllocationRangeFields = []string{"ip_allocation_policy.0.cluster_secondary_range_name", "ip_allocation_policy.0.services_secondary_range_name"} addonsConfigKeys = []string{ @@ -90,7 +89,6 @@ func resourceContainerCluster() *schema.Resource { Delete: resourceContainerClusterDelete, CustomizeDiff: customdiff.All( - resourceContainerClusterIpAllocationCustomizeDiff, resourceNodeConfigEmptyGuestAccelerator, containerClusterPrivateClusterConfigCustomDiff, ), @@ -326,6 +324,7 @@ func resourceContainerCluster() *schema.Resource { Computed: true, ForceNew: true, ValidateFunc: orEmpty(validateRFC1918Network(8, 32)), + ConflictsWith: []string{"ip_allocation_policy"}, }, "description": { @@ -658,37 +657,9 @@ func resourceContainerCluster() *schema.Resource { MaxItems: 1, ForceNew: true, Optional: true, - Computed: true, - ConfigMode: schema.SchemaConfigModeAttr, + ConflictsWith: []string{"cluster_ipv4_cidr"}, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "use_ip_aliases": { - Type: schema.TypeBool, - Deprecated: "This field is being removed in 3.0.0. If set to true, remove it from your config. If false, remove i.", - Optional: true, - Default: true, - ForceNew: true, - }, - - // GKE creates subnetwork automatically - "create_subnetwork": { - Type: schema.TypeBool, - Deprecated: "This field is being removed in 3.0.0. Define an explicit google_compute_subnetwork and use subnetwork instead.", - Computed: true, - Optional: true, - ForceNew: true, - ConflictsWith: ipAllocationRangeFields, - }, - - "subnetwork_name": { - Type: schema.TypeString, - Deprecated: "This field is being removed in 3.0.0. Define an explicit google_compute_subnetwork and use subnetwork instead.", - Computed: true, - Optional: true, - ForceNew: true, - ConflictsWith: ipAllocationRangeFields, - }, - // GKE creates/deletes secondary ranges in VPC "cluster_ipv4_cidr_block": { Type: schema.TypeString, @@ -698,6 +669,7 @@ func resourceContainerCluster() *schema.Resource { ConflictsWith: ipAllocationRangeFields, DiffSuppressFunc: cidrOrSizeDiffSuppress, }, + "services_ipv4_cidr_block": { Type: schema.TypeString, Optional: true, @@ -706,15 +678,6 @@ func resourceContainerCluster() *schema.Resource { ConflictsWith: ipAllocationRangeFields, DiffSuppressFunc: cidrOrSizeDiffSuppress, }, - "node_ipv4_cidr_block": { - Type: schema.TypeString, - Deprecated: "This field is being removed in 3.0.0. Define an explicit google_compute_subnetwork and use subnetwork instead.", - Computed: true, - Optional: true, - ForceNew: true, - ConflictsWith: ipAllocationRangeFields, - DiffSuppressFunc: cidrOrSizeDiffSuppress, - }, // User manages secondary ranges manually "cluster_secondary_range_name": { @@ -722,14 +685,44 @@ func resourceContainerCluster() *schema.Resource { Optional: true, Computed: true, ForceNew: true, - ConflictsWith: append(ipAllocationSubnetFields, ipAllocationCidrBlockFields...), + ConflictsWith: ipAllocationCidrBlockFields, }, + "services_secondary_range_name": { Type: schema.TypeString, Optional: true, Computed: true, ForceNew: true, - ConflictsWith: append(ipAllocationSubnetFields, ipAllocationCidrBlockFields...), + ConflictsWith: ipAllocationCidrBlockFields, + }, + + "use_ip_aliases": { + Type: schema.TypeBool, + Removed: "This field is removed as of 3.0.0. If previously set to true, remove it from your config. If false, remove it.", + Computed: true, + Optional: true, + }, + + // GKE creates subnetwork automatically + "create_subnetwork": { + Type: schema.TypeBool, + Removed: "This field is removed as of 3.0.0. Define an explicit google_compute_subnetwork and use subnetwork instead.", + Computed: true, + Optional: true, + }, + + "subnetwork_name": { + Type: schema.TypeString, + Removed: "This field is removed as of 3.0.0. Define an explicit google_compute_subnetwork and use subnetwork instead.", + Computed: true, + Optional: true, + }, + + "node_ipv4_cidr_block": { + Type: schema.TypeString, + Removed: "This field is removed as of 3.0.0. Define an explicit google_compute_subnetwork and use subnetwork instead.", + Computed: true, + Optional: true, }, }, }, @@ -966,36 +959,6 @@ func resourceNodeConfigEmptyGuestAccelerator(diff *schema.ResourceDiff, meta int return nil } -func resourceContainerClusterIpAllocationCustomizeDiff(diff *schema.ResourceDiff, meta interface{}) error { - // separate func to allow unit testing - return resourceContainerClusterIpAllocationCustomizeDiffFunc(diff) -} - -func resourceContainerClusterIpAllocationCustomizeDiffFunc(diff TerraformResourceDiff) error { - o, n := diff.GetChange("ip_allocation_policy") - - oList := o.([]interface{}) - nList := n.([]interface{}) - if len(oList) > 0 || len(nList) == 0 { - // we only care about going from unset to set, so return early if the field was set before - // or is unset now - return nil - } - - // Unset is equivalent to a block where all the values are zero - // This might change if use_ip_aliases ends up defaulting to true server-side. - // The console says it will eventually, but it's unclear whether that's in the API - // too or just client code. - polMap := nList[0].(map[string]interface{}) - for _, v := range polMap { - if !isEmptyValue(reflect.ValueOf(v)) { - // found a non-empty value, so continue with the diff as it was - return nil - } - } - return diff.Clear("ip_allocation_policy") -} - func resourceContainerClusterCreate(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) @@ -2180,20 +2143,17 @@ func expandClusterAddonsConfig(configured interface{}) *containerBeta.AddonsConf func expandIPAllocationPolicy(configured interface{}) *containerBeta.IPAllocationPolicy { l := configured.([]interface{}) if len(l) == 0 || l[0] == nil { - return nil + return &containerBeta.IPAllocationPolicy{ + UseIpAliases: false, + ForceSendFields: []string{"UseIpAliases"}, + } } config := l[0].(map[string]interface{}) - return &containerBeta.IPAllocationPolicy{ - UseIpAliases: config["use_ip_aliases"].(bool), - - CreateSubnetwork: config["create_subnetwork"].(bool), - SubnetworkName: config["subnetwork_name"].(string), - + UseIpAliases: true, ClusterIpv4CidrBlock: config["cluster_ipv4_cidr_block"].(string), ServicesIpv4CidrBlock: config["services_ipv4_cidr_block"].(string), - NodeIpv4CidrBlock: config["node_ipv4_cidr_block"].(string), ClusterSecondaryRangeName: config["cluster_secondary_range_name"].(string), ServicesSecondaryRangeName: config["services_secondary_range_name"].(string), @@ -2657,33 +2617,16 @@ func flattenWorkloadIdentityConfig(c *containerBeta.WorkloadIdentityConfig) []ma <% end -%> func flattenIPAllocationPolicy(c *containerBeta.Cluster, d *schema.ResourceData, config *Config) []map[string]interface{} { - if c == nil || c.IpAllocationPolicy == nil { + // If IP aliasing isn't enabled, none of the values in this block can be set. + if c == nil || c.IpAllocationPolicy == nil || c.IpAllocationPolicy.UseIpAliases == false { return nil } - nodeCidrBlock := "" - if c.Subnetwork != "" { - subnetwork, err := ParseSubnetworkFieldValue(c.Subnetwork, d, config) - if err == nil { - sn, err := config.clientCompute.Subnetworks.Get(subnetwork.Project, subnetwork.Region, subnetwork.Name).Do() - if err == nil { - nodeCidrBlock = sn.IpCidrRange - } - } else { - log.Printf("[WARN] Unable to parse subnetwork name, got error while trying to get new subnetwork: %s", err) - } - } + p := c.IpAllocationPolicy return []map[string]interface{}{ { - "use_ip_aliases": p.UseIpAliases, - - "create_subnetwork": p.CreateSubnetwork, - "subnetwork_name": p.SubnetworkName, - "cluster_ipv4_cidr_block": p.ClusterIpv4CidrBlock, "services_ipv4_cidr_block": p.ServicesIpv4CidrBlock, - "node_ipv4_cidr_block": nodeCidrBlock, - "cluster_secondary_range_name": p.ClusterSecondaryRangeName, "services_secondary_range_name": p.ServicesSecondaryRangeName, }, 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 408e3693175d..e6a3f7ffbdb9 100644 --- a/third_party/terraform/tests/resource_container_cluster_test.go.erb +++ b/third_party/terraform/tests/resource_container_cluster_test.go.erb @@ -14,69 +14,6 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/terraform" ) -func TestContainerClusterIpAllocationCustomizeDiff(t *testing.T) { - t.Parallel() - - cases := map[string]struct { - BeforePolicy []interface{} - AfterPolicy []interface{} - ExpectDiffCleared bool - }{ - "empty to false value": { - BeforePolicy: []interface{}{}, - AfterPolicy: []interface{}{ - map[string]interface{}{ - "use_ip_aliases": false, - }, - }, - ExpectDiffCleared: true, - }, - "empty to true value": { - BeforePolicy: []interface{}{}, - AfterPolicy: []interface{}{ - map[string]interface{}{ - "use_ip_aliases": true, - }, - }, - ExpectDiffCleared: false, - }, - "empty to empty": { - BeforePolicy: []interface{}{}, - AfterPolicy: []interface{}{}, - ExpectDiffCleared: false, - }, - "non-empty to non-empty": { - BeforePolicy: []interface{}{ - map[string]interface{}{ - "use_ip_aliases": false, - }, - }, - AfterPolicy: []interface{}{ - map[string]interface{}{ - "use_ip_aliases": false, - }, - }, - }, - } - - for tn, tc := range cases { - d := &ResourceDiffMock{ - Before: map[string]interface{}{ - "ip_allocation_policy": tc.BeforePolicy, - }, - After: map[string]interface{}{ - "ip_allocation_policy": tc.AfterPolicy, - }, - } - if err := resourceContainerClusterIpAllocationCustomizeDiffFunc(d); err != nil { - t.Errorf("%s failed, error calculating diff: %s", tn, err) - } - if _, ok := d.Cleared["ip_allocation_policy"]; ok != tc.ExpectDiffCleared { - t.Errorf("%s failed, expected cleared to be %v, was %v", tn, tc.ExpectDiffCleared, ok) - } - } -} - func TestAccContainerCluster_basic(t *testing.T) { t.Parallel() @@ -1277,70 +1214,6 @@ func TestAccContainerCluster_withIPAllocationPolicy_specificSizes(t *testing.T) }) } -func TestAccContainerCluster_withIPAllocationPolicy_createSubnetwork(t *testing.T) { - t.Parallel() - - cluster := 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_withIPAllocationPolicy_createSubnetwork(cluster), - }, - { - ResourceName: "google_container_cluster.with_ip_allocation_policy", - ImportStateIdPrefix: "us-central1-a/", - ImportState: true, - ImportStateVerify: true, - }, - { - Config: testAccContainerCluster_withIPAllocationPolicy_createSubnetworkUpdated(cluster), - PlanOnly: true, - ExpectNonEmptyPlan: false, - }, - { - ResourceName: "google_container_cluster.with_ip_allocation_policy", - ImportStateIdPrefix: "us-central1-a/", - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -// This test will intentionally perform a recreate. Without attr syntax, there's -// no way to go from allocation policy set -> unset without one. -func TestAccContainerCluster_withIPAllocationPolicy_explicitEmpty(t *testing.T) { - t.Parallel() - - cluster := 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_withIPAllocationPolicy_createSubnetwork(cluster), - }, - { - ResourceName: "google_container_cluster.with_ip_allocation_policy", - ImportState: true, - ImportStateVerify: true, - }, - { - Config: testAccContainerCluster_withIPAllocationPolicy_explicitEmpty(cluster), - }, - { - ResourceName: "google_container_cluster.with_ip_allocation_policy", - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - <% unless version == 'ga' -%> func TestAccContainerCluster_nodeAutoprovisioning(t *testing.T) { @@ -2932,17 +2805,18 @@ resource "google_compute_network" "container_network" { } resource "google_compute_subnetwork" "container_subnetwork" { - name = "${google_compute_network.container_network.name}" - network = "${google_compute_network.container_network.name}" + name = "${google_compute_network.container_network.name}" + network = "${google_compute_network.container_network.name}" + region = "us-central1" + ip_cidr_range = "10.0.0.0/24" - region = "us-central1" secondary_ip_range { - range_name = "pods" + range_name = "pods" ip_cidr_range = "10.1.0.0/16" } secondary_ip_range { - range_name = "services" + range_name = "services" ip_cidr_range = "10.2.0.0/20" } } @@ -2956,7 +2830,6 @@ resource "google_container_cluster" "with_ip_allocation_policy" { initial_node_count = 1 ip_allocation_policy { - use_ip_aliases = true cluster_secondary_range_name = "pods" services_secondary_range_name = "services" } @@ -2970,18 +2843,24 @@ resource "google_compute_network" "container_network" { auto_create_subnetworks = false } +resource "google_compute_subnetwork" "container_subnetwork" { + name = "${google_compute_network.container_network.name}" + network = "${google_compute_network.container_network.name}" + region = "us-central1" + + ip_cidr_range = "10.2.0.0/16" +} + resource "google_container_cluster" "with_ip_allocation_policy" { - name = "%s" + name = "%s" location = "us-central1-a" network = "${google_compute_network.container_network.name}" + subnetwork = "${google_compute_subnetwork.container_subnetwork.name}" initial_node_count = 1 ip_allocation_policy { - use_ip_aliases = true - create_subnetwork = true cluster_ipv4_cidr_block = "10.0.0.0/16" services_ipv4_cidr_block = "10.1.0.0/16" - node_ipv4_cidr_block = "10.2.0.0/16" } }`, cluster, cluster) } @@ -2994,93 +2873,24 @@ resource "google_compute_network" "container_network" { } resource "google_compute_subnetwork" "container_subnetwork" { - name = "${google_compute_network.container_network.name}" - network = "${google_compute_network.container_network.name}" - ip_cidr_range = "10.0.0.0/24" - region = "us-central1" + name = "${google_compute_network.container_network.name}" + network = "${google_compute_network.container_network.name}" + region = "us-central1" + + ip_cidr_range = "10.2.0.0/16" } resource "google_container_cluster" "with_ip_allocation_policy" { - name = "%s" - location = "us-central1-a" - - network = "${google_compute_network.container_network.name}" + name = "%s" + location = "us-central1-a" + network = "${google_compute_network.container_network.name}" + subnetwork = "${google_compute_subnetwork.container_subnetwork.name}" initial_node_count = 1 ip_allocation_policy { - use_ip_aliases = true - create_subnetwork = true - subnetwork_name = "tf-test-%s" cluster_ipv4_cidr_block = "/16" services_ipv4_cidr_block = "/22" - node_ipv4_cidr_block = "/22" } -}`, cluster, cluster, cluster) -} - -func testAccContainerCluster_withIPAllocationPolicy_createSubnetwork(cluster string) string { - return fmt.Sprintf(` -resource "google_compute_network" "container_network" { - name = "%s-network" - auto_create_subnetworks = false -} - -resource "google_container_cluster" "with_ip_allocation_policy" { - name = "%s" - location = "us-central1-a" - network = "${google_compute_network.container_network.name}" - - initial_node_count = 1 - - ip_allocation_policy { - use_ip_aliases = true - create_subnetwork = true - subnetwork_name = "%s-subnet" - cluster_ipv4_cidr_block = "10.0.0.0/16" - services_ipv4_cidr_block = "10.1.0.0/16" - node_ipv4_cidr_block = "10.2.0.0/16" - } -}`, cluster, cluster, cluster) -} - - -func testAccContainerCluster_withIPAllocationPolicy_createSubnetworkUpdated(cluster string) string { - return fmt.Sprintf(` -resource "google_compute_network" "container_network" { - name = "%s-network" - auto_create_subnetworks = false -} - -resource "google_container_cluster" "with_ip_allocation_policy" { - name = "%s" - location = "us-central1-a" - network = "${google_compute_network.container_network.name}" - subnetwork = "%s-subnet" - - initial_node_count = 1 - - ip_allocation_policy { - use_ip_aliases = true - cluster_ipv4_cidr_block = "10.0.0.0/16" - services_ipv4_cidr_block = "10.1.0.0/16" - } -}`, cluster, cluster, cluster) -} - -func testAccContainerCluster_withIPAllocationPolicy_explicitEmpty(cluster string) string { - return fmt.Sprintf(` -resource "google_compute_network" "container_network" { - name = "%s-network" - auto_create_subnetworks = false -} - -resource "google_container_cluster" "with_ip_allocation_policy" { - name = "%s" - location = "us-central1-a" - - initial_node_count = 1 - - ip_allocation_policy = [] }`, cluster, cluster) } 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 a2602e131b5c..284b4e62e2f1 100644 --- a/third_party/terraform/website/docs/r/container_cluster.html.markdown +++ b/third_party/terraform/website/docs/r/container_cluster.html.markdown @@ -133,11 +133,9 @@ preferred. Structure is documented below. * `cluster_ipv4_cidr` - (Optional) The IP address range of the Kubernetes pods -in this cluster in CIDR notation (e.g. 10.96.0.0/14). Leave blank to have one -automatically chosen or specify a /14 block in 10.0.0.0/8. This field will only -work if your cluster is not VPC-native- when an `ip_allocation_policy` block is -not defined, or `ip_allocation_policy.use_ip_aliases` is set to false. If your -cluster is VPC-native, use `ip_allocation_policy.cluster_ipv4_cidr_block`. +in this cluster in CIDR notation (e.g. `10.96.0.0/14`). Leave blank to have one +automatically chosen or specify a `/14` block in `10.0.0.0/8`. This field will +only work for routes-based clusters, where `ip_allocation_policy` is not defined. * `cluster_autoscaling` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) Per-cluster configuration of Node Auto-Provisioning with Cluster Autoscaler to @@ -180,10 +178,10 @@ number of nodes per zone. Must be set if `node_pool` is not set. If you're using set this to a value of at least `1`, alongside setting `remove_default_node_pool` to `true`. -* `ip_allocation_policy` - (Optional) Configuration for cluster IP allocation. As of now, only pre-allocated subnetworks (custom type with secondary ranges) are supported. - This will activate IP aliases. See the [official documentation](https://cloud.google.com/kubernetes-engine/docs/how-to/ip-aliases) - Structure is documented below. This field is marked to use [Attribute as Block](/docs/configuration/attr-as-blocks.html) - in order to support explicit removal with `ip_allocation_policy = []`. +* `ip_allocation_policy` - (Optional) Configuration of cluster IP allocation for +VPC-native clusters. Adding this block enables [IP aliasing](https://cloud.google.com/kubernetes-engine/docs/how-to/ip-aliases), +making the cluster VPC-native instead of routes-based. Structure is documented +below. * `logging_service` - (Optional) The logging service that the cluster should write logs to. Available options include `logging.googleapis.com`, @@ -285,8 +283,8 @@ region are guaranteed to support the same version. [ResourceUsageExportConfig](https://cloud.google.com/kubernetes-engine/docs/how-to/cluster-usage-metering) feature. Structure is documented below. -* `subnetwork` - (Optional) The name or self_link of the Google Compute Engine subnetwork in - which the cluster's instances are launched. +* `subnetwork` - (Optional) The name or self_link of the Google Compute Engine +subnetwork in which the cluster's instances are launched. * `vertical_pod_autoscaling` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) Vertical Pod Autoscaling automatically adjusts the resources of pods controlled by it. @@ -414,46 +412,26 @@ In beta, one or the other of `recurring_window` and `daily_maintenance_window` i The `ip_allocation_policy` block supports: -* `use_ip_aliases` - (Optional) Whether alias IPs will be used for pod IPs in -the cluster. Defaults to `true` if the `ip_allocation_policy` block is defined, -and to the API default otherwise. Prior to June 17th 2019, the default on the -API is `false`; afterwards, it's `true`. +* `cluster_secondary_range_name` - (Optional) The name of the existing secondary +range in the cluster's subnetwork to use for pod IP addresses. Alternatively, +`cluster_ipv4_cidr_block` can be used to automatically create a GKE-managed one. -* `cluster_secondary_range_name` - (Optional) The name of the secondary range to be - used as for the cluster CIDR block. The secondary range will be used for pod IP - addresses. This must be an existing secondary range associated with the cluster - subnetwork. - -* `services_secondary_range_name` - (Optional) The name of the secondary range to be - used as for the services CIDR block. The secondary range will be used for service - ClusterIPs. This must be an existing secondary range associated with the cluster - subnetwork. +* `services_secondary_range_name` - (Optional) The name of the existing +secondary range in the cluster's subnetwork to use for service `ClusterIP`s. +Alternatively, `services_ipv4_cidr_block` can be used to automatically create a +GKE-managed one. * `cluster_ipv4_cidr_block` - (Optional) The IP address range for the cluster pod IPs. Set to blank to have a range chosen with the default size. Set to /netmask (e.g. /14) to have a range chosen with a specific netmask. Set to a CIDR notation (e.g. 10.96.0.0/14) from the RFC-1918 private networks (e.g. 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) to -pick a specific range to use. This field will only work if your cluster is -VPC-native- when `ip_allocation_policy.use_ip_aliases` is undefined or set to -true. If your cluster is not VPC-native, use `cluster_ipv4_cidr`. - -* `node_ipv4_cidr_block` - (Optional) The IP address range of the node IPs in this cluster. - This should be set only if `create_subnetwork` is true. - Set to blank to have a range chosen with the default size. Set to /netmask (e.g. /14) - to have a range chosen with a specific netmask. Set to a CIDR notation (e.g. 10.96.0.0/14) - from the RFC-1918 private networks (e.g. 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) to - pick a specific range to use. +pick a specific range to use. * `services_ipv4_cidr_block` - (Optional) The IP address range of the services IPs in this cluster. - Set to blank to have a range chosen with the default size. Set to /netmask (e.g. /14) - to have a range chosen with a specific netmask. Set to a CIDR notation (e.g. 10.96.0.0/14) - from the RFC-1918 private networks (e.g. 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) to - pick a specific range to use. - -* `create_subnetwork`- (Optional) Whether a new subnetwork will be created automatically for the cluster. - -* `subnetwork_name` - (Optional) A custom subnetwork name to be used if create_subnetwork is true. - If this field is empty, then an automatic name will be chosen for the new subnetwork. +Set to blank to have a range chosen with the default size. Set to /netmask (e.g. /14) +to have a range chosen with a specific netmask. Set to a CIDR notation (e.g. 10.96.0.0/14) +from the RFC-1918 private networks (e.g. 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) to +pick a specific range to use. The `master_auth` block supports: