diff --git a/mmv1/third_party/terraform/services/container/resource_container_cluster_meta.yaml.tmpl b/mmv1/third_party/terraform/services/container/resource_container_cluster_meta.yaml.tmpl
index 367aae00f554..cb9d9de99a05 100644
--- a/mmv1/third_party/terraform/services/container/resource_container_cluster_meta.yaml.tmpl
+++ b/mmv1/third_party/terraform/services/container/resource_container_cluster_meta.yaml.tmpl
@@ -657,6 +657,8 @@ fields:
api_field: 'nodePools.config.windowsNodeConfig.osVersion'
- field: 'node_pool.node_config.workload_metadata_config.mode'
api_field: 'nodePools.config.workloadMetadataConfig.mode'
+ - field: 'node_pool.node_drain_config.respect_pdb_during_node_pool_deletion'
+ api_field: 'nodePools.nodeDrainConfig.respectPdbDuringNodePoolDeletion'
- field: 'node_pool.node_count'
provider_only: true
- field: 'node_pool.node_locations'
diff --git a/mmv1/third_party/terraform/services/container/resource_container_cluster_test.go.tmpl b/mmv1/third_party/terraform/services/container/resource_container_cluster_test.go.tmpl
index 9c51016b0c48..61ed07ca037e 100644
--- a/mmv1/third_party/terraform/services/container/resource_container_cluster_test.go.tmpl
+++ b/mmv1/third_party/terraform/services/container/resource_container_cluster_test.go.tmpl
@@ -3379,6 +3379,36 @@ func TestAccContainerCluster_withNodePoolNodeConfig(t *testing.T) {
})
}
+func TestAccContainerCluster_withNodePoolNodeDrainConfig(t *testing.T) {
+ t.Parallel()
+
+ cluster := fmt.Sprintf("tf-test-cluster-%s", acctest.RandString(t, 10))
+ np := fmt.Sprintf("tf-test-np-%s", acctest.RandString(t, 10))
+ networkName := acctest.BootstrapSharedTestNetwork(t, "gke-cluster")
+ subnetworkName := acctest.BootstrapSubnet(t, "gke-cluster", networkName)
+
+ acctest.VcrTest(t, resource.TestCase{
+ PreCheck: func() { acctest.AccTestPreCheck(t) },
+ ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
+ CheckDestroy: testAccCheckContainerClusterDestroyProducer(t),
+ Steps: []resource.TestStep{
+ {
+ Config: testAccContainerCluster_withNodePoolNodeDrainConfig(cluster, np, networkName, subnetworkName),
+ Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttr("google_container_cluster.with_node_pool_node_drain_config",
+ "node_pool.0.node_drain_config.0.respect_pdb_during_node_pool_deletion", "true"),
+ ),
+ },
+ {
+ ResourceName: "google_container_cluster.with_node_pool_node_drain_config",
+ ImportState: true,
+ ImportStateVerify: true,
+ ImportStateVerifyIgnore: []string{"min_master_version", "deletion_protection"},
+ },
+ },
+ })
+}
+
func TestAccContainerCluster_withMaintenanceWindow(t *testing.T) {
t.Parallel()
@@ -10693,6 +10723,31 @@ resource "google_container_cluster" "with_node_pool_node_config" {
`, cluster, np, networkName, subnetworkName)
}
+func testAccContainerCluster_withNodePoolNodeDrainConfig(cluster, np, networkName, subnetworkName string) string {
+ return fmt.Sprintf(`
+data "google_container_engine_versions" "central1a" {
+ location = "us-central1-a"
+}
+
+resource "google_container_cluster" "with_node_pool_node_drain_config" {
+ name = "%s"
+ location = "us-central1-a"
+ min_master_version = data.google_container_engine_versions.central1a.latest_master_version
+ node_pool {
+ name = "%s"
+ initial_node_count = 1
+ node_drain_config {
+ respect_pdb_during_node_pool_deletion = true
+ }
+ }
+
+ network = "%s"
+ subnetwork = "%s"
+ deletion_protection = false
+}
+`, cluster, np, networkName, subnetworkName)
+}
+
func testAccContainerCluster_withMaintenanceWindow(clusterName, startTime, networkName, subnetworkName string) string {
maintenancePolicy := ""
if len(startTime) > 0 {
diff --git a/mmv1/third_party/terraform/services/container/resource_container_node_pool.go.tmpl b/mmv1/third_party/terraform/services/container/resource_container_node_pool.go.tmpl
index 469a97ea0ae3..4f9549592388 100644
--- a/mmv1/third_party/terraform/services/container/resource_container_node_pool.go.tmpl
+++ b/mmv1/third_party/terraform/services/container/resource_container_node_pool.go.tmpl
@@ -662,6 +662,22 @@ var schemaNodePool = map[string]*schema.Schema{
},
},
+ "node_drain_config": {
+ Type: schema.TypeList,
+ Optional: true,
+ Computed: true,
+ Description: `Node drain configuration for this NodePool.`,
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "respect_pdb_during_node_pool_deletion": {
+ Type: schema.TypeBool,
+ Optional: true,
+ Description: `Whether to respect PodDisruptionBudget policy during node pool deletion.`,
+ },
+ },
+ },
+ },
+
}
type NodePoolInformation struct {
@@ -1304,6 +1320,15 @@ func expandNodePool(d *schema.ResourceData, prefix string) (*container.NodePool,
}
}
+ if v, ok := d.GetOk(prefix + "node_drain_config"); ok {
+ nodeDrainConfig := v.([]interface{})[0].(map[string]interface{})
+ np.NodeDrainConfig = &container.NodeDrainConfig{}
+
+ if v, ok := nodeDrainConfig["respect_pdb_during_node_pool_deletion"]; ok {
+ np.NodeDrainConfig.RespectPdbDuringNodePoolDeletion = v.(bool)
+ }
+ }
+
return np, nil
}
@@ -1365,6 +1390,17 @@ func flattenNodePoolUpgradeSettings(us *container.UpgradeSettings) []map[string]
return []map[string]interface{}{upgradeSettings}
}
+func flattenNodePoolNodeDrainConfig(ndc *container.NodeDrainConfig) []map[string]interface{} {
+ if ndc == nil {
+ return nil
+ }
+
+ nodeDrainConfig := make(map[string]interface{})
+
+ nodeDrainConfig["respect_pdb_during_node_pool_deletion"] = ndc.RespectPdbDuringNodePoolDeletion
+ return []map[string]interface{}{nodeDrainConfig}
+}
+
func flattenNodePool(d *schema.ResourceData, config *transport_tpg.Config, np *container.NodePool, prefix string) (map[string]interface{}, error) {
userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent)
if err != nil {
@@ -1480,6 +1516,10 @@ func flattenNodePool(d *schema.ResourceData, config *transport_tpg.Config, np *c
delete(nodePool, "upgrade_settings")
}
+ if np.NodeDrainConfig != nil {
+ nodePool["node_drain_config"] = flattenNodePoolNodeDrainConfig(np.NodeDrainConfig)
+ }
+
return nodePool, nil
}
@@ -1925,6 +1965,43 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node
}
}
+ if d.HasChange(prefix + "node_drain_config") {
+ nodeDrainConfig := &container.NodeDrainConfig{}
+ if v, ok := d.GetOk(prefix + "node_drain_config"); ok {
+ nodeDrain := v.([]interface{})[0].(map[string]interface{})
+ if v, ok := nodeDrain["respect_pdb_during_node_pool_deletion"]; ok {
+ nodeDrainConfig.RespectPdbDuringNodePoolDeletion = v.(bool)
+ }
+ }
+ req := &container.UpdateNodePoolRequest{
+ NodeDrainConfig: nodeDrainConfig,
+ }
+
+ updateF := func() error {
+ clusterNodePoolsUpdateCall := config.NewContainerClient(userAgent).Projects.Locations.Clusters.NodePools.Update(nodePoolInfo.fullyQualifiedName(name),req)
+
+ if config.UserProjectOverride {
+ clusterNodePoolsUpdateCall.Header().Add("X-Goog-User-Project", nodePoolInfo.project)
+ }
+ op, err := clusterNodePoolsUpdateCall.Do()
+
+ if err != nil {
+ return err
+ }
+
+ // Wait until it's updated
+ return ContainerOperationWait(config, op,
+ nodePoolInfo.project,
+ nodePoolInfo.location,
+ "updating GKE node pool node_drain_config", userAgent, timeout)
+ }
+
+ if err := retryWhileIncompatibleOperation(timeout, npLockKey, updateF); err != nil {
+ return err
+ }
+ log.Printf("[INFO] Updated node_drain_config in Node Pool %s", name)
+ }
+
return nil
}
diff --git a/mmv1/third_party/terraform/services/container/resource_container_node_pool_meta.yaml.tmpl b/mmv1/third_party/terraform/services/container/resource_container_node_pool_meta.yaml.tmpl
index b88e191a01d3..363996296621 100644
--- a/mmv1/third_party/terraform/services/container/resource_container_node_pool_meta.yaml.tmpl
+++ b/mmv1/third_party/terraform/services/container/resource_container_node_pool_meta.yaml.tmpl
@@ -270,6 +270,8 @@ fields:
api_field: 'config.windowsNodeConfig.osVersion'
- field: 'node_config.workload_metadata_config.mode'
api_field: 'config.workloadMetadataConfig.mode'
+ - field: 'node_drain_config.respect_pdb_during_node_pool_deletion'
+ api_field: 'nodeDrainConfig.respectPdbDuringNodePoolDeletion'
- field: 'node_count'
provider_only: true
- field: 'node_locations'
diff --git a/mmv1/third_party/terraform/services/container/resource_container_node_pool_test.go.tmpl b/mmv1/third_party/terraform/services/container/resource_container_node_pool_test.go.tmpl
index 92f649eb3f72..217a2a462696 100644
--- a/mmv1/third_party/terraform/services/container/resource_container_node_pool_test.go.tmpl
+++ b/mmv1/third_party/terraform/services/container/resource_container_node_pool_test.go.tmpl
@@ -1594,6 +1594,34 @@ func TestAccContainerNodePool_withManagement(t *testing.T) {
})
}
+func TestAccContainerNodePool_withNodeDrainConfig(t *testing.T) {
+ t.Parallel()
+
+ cluster := fmt.Sprintf("tf-test-cluster-%s", acctest.RandString(t, 10))
+ nodePool := fmt.Sprintf("tf-test-nodepool-%s", acctest.RandString(t, 10))
+ networkName := acctest.BootstrapSharedTestNetwork(t, "gke-cluster")
+ subnetworkName := acctest.BootstrapSubnet(t, "gke-cluster", networkName)
+
+ acctest.VcrTest(t, resource.TestCase{
+ PreCheck: func() { acctest.AccTestPreCheck(t) },
+ ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
+ CheckDestroy: testAccCheckContainerNodePoolDestroyProducer(t),
+ Steps: []resource.TestStep{
+ {
+ Config: testAccContainerNodePool_withNodeDrainConfig(cluster, nodePool, networkName, subnetworkName),
+ Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttr("google_container_node_pool.np_with_node_drain_config", "node_drain_config.0.respect_pdb_during_node_pool_deletion", "true"),
+ ),
+ },
+ {
+ ResourceName: "google_container_node_pool.np_with_node_drain_config",
+ ImportState: true,
+ ImportStateVerify: true,
+ },
+ },
+ })
+}
+
func TestAccContainerNodePool_withNodeConfigScopeAlias(t *testing.T) {
t.Parallel()
@@ -4752,6 +4780,34 @@ resource "google_container_node_pool" "np_with_node_config_scope_alias" {
`, cluster, networkName, subnetworkName, np)
}
+func testAccContainerNodePool_withNodeDrainConfig(cluster, np, networkName, subnetworkName string) string {
+ return fmt.Sprintf(`
+data "google_container_engine_versions" "central1a" {
+ location = "us-central1-a"
+}
+
+resource "google_container_cluster" "cluster" {
+ name = "%s"
+ location = "us-central1-a"
+ initial_node_count = 1
+ min_master_version = data.google_container_engine_versions.central1a.latest_master_version
+ deletion_protection = false
+ network = "%s"
+ subnetwork = "%s"
+}
+
+resource "google_container_node_pool" "np_with_node_drain_config" {
+ name = "%s"
+ location = "us-central1-a"
+ cluster = google_container_cluster.cluster.name
+ initial_node_count = 1
+ node_drain_config {
+ respect_pdb_during_node_pool_deletion = true
+ }
+}
+`, cluster, networkName, subnetworkName, np)
+}
+
func testAccContainerNodePool_version(cluster, np, networkName, subnetworkName string) string {
return fmt.Sprintf(`
data "google_container_engine_versions" "central1a" {
diff --git a/mmv1/third_party/terraform/website/docs/r/container_node_pool.html.markdown b/mmv1/third_party/terraform/website/docs/r/container_node_pool.html.markdown
index f26393c1bd62..1f2d87d6ed4c 100644
--- a/mmv1/third_party/terraform/website/docs/r/container_node_pool.html.markdown
+++ b/mmv1/third_party/terraform/website/docs/r/container_node_pool.html.markdown
@@ -154,6 +154,8 @@ cluster.
* `node_count` - (Optional) The number of nodes per instance group. This field can be used to
update the number of nodes per instance group but should not be used alongside `autoscaling`.
+* `node_drain_config` - (Optional) The node drain configuration of the pool. Structure is [documented below](#nested_node_drain_config).
+
* `project` - (Optional) The ID of the project in which to create the node pool. If blank,
the provider-configured project will be used.
@@ -240,12 +242,15 @@ cluster.
The `network_performance_config` block supports:
* `total_egress_bandwidth_tier` (Required) - Specifies the total network bandwidth tier for the NodePool. [Valid values](https://cloud.google.com/kubernetes-engine/docs/reference/rest/v1/projects.locations.clusters.nodePools#NodePool.Tier) include: "TIER_1" and "TIER_UNSPECIFIED".
-* ```
The `pod_cidr_overprovision_config` block supports:
* `disabled` (Required) - Whether pod cidr overprovision is disabled.
+The `node_drain_config` block supports:
+
+* `respect_pdb_during_node_pool_deletion` - (Optional) Whether to respect PodDisruptionBudget policy during node pool deletion.
+
The `upgrade_settings` block supports:
* `max_surge` - (Optional) The number of additional nodes that can be added to the node pool during