From 788b3fe8e7cb6b3ce931cf02184dd67304feb060 Mon Sep 17 00:00:00 2001 From: Andrew Page Date: Thu, 27 Feb 2025 10:42:22 -0800 Subject: [PATCH 1/6] Support Probe-level `termination_grace_period_seconds` in schema --- kubernetes/schema_container.go | 33 +++++++++++++++++++++++++----- kubernetes/structures_container.go | 3 +++ 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/kubernetes/schema_container.go b/kubernetes/schema_container.go index 499ea0236a..8544157193 100644 --- a/kubernetes/schema_container.go +++ b/kubernetes/schema_container.go @@ -528,7 +528,7 @@ func containerFields(isUpdatable bool) map[string]*schema.Schema { MaxItems: 1, ForceNew: !isUpdatable, Description: "Periodic probe of container liveness. Container will be restarted if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes", - Elem: probeSchema(), + Elem: probeSchema(LivenessProbe), }, "name": { Type: schema.TypeString, @@ -589,7 +589,7 @@ func containerFields(isUpdatable bool) map[string]*schema.Schema { MaxItems: 1, ForceNew: !isUpdatable, Description: "Periodic probe of container service readiness. Container will be removed from service endpoints if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes", - Elem: probeSchema(), + Elem: probeSchema(ReadinessProbe), }, "resources": { Type: schema.TypeList, @@ -616,7 +616,7 @@ func containerFields(isUpdatable bool) map[string]*schema.Schema { MaxItems: 1, ForceNew: !isUpdatable, Description: "StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. This is an alpha feature enabled by the StartupProbe feature flag. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes", - Elem: probeSchema(), + Elem: probeSchema(StartupProbe), }, "stdin": { Type: schema.TypeBool, @@ -685,7 +685,18 @@ func containerFields(isUpdatable bool) map[string]*schema.Schema { return s } -func probeSchema() *schema.Resource { +type ProbeType int + +const ( + LivenessProbe ProbeType = iota + ReadinessProbe + StartupProbe +) + +// probeSchema generates the schema for a Liveness/Readiness/Startup probe +// +// probeType specifies the type of probe to generate the schema for (liveness, readiness, startup) +func probeSchema(probeType ProbeType) *schema.Resource { h := lifecycleHandlerFields() h["grpc"] = &schema.Schema{ Type: schema.TypeList, @@ -741,10 +752,22 @@ func probeSchema() *schema.Resource { ValidateFunc: validatePositiveInteger, Description: "Number of seconds after which the probe times out. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes", } + + // Conditionally add a `termination_grace_period_seconds` to this schema if the probe type is Liveness or Startup + // `Probe-level terminationGracePeriodSeconds cannot be set for readiness probes. It will be rejected by the API server.` + // https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#probe-level-terminationgraceperiodseconds + if probeType == LivenessProbe || probeType == StartupProbe { + h["termination_grace_period_seconds"] = &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validateTerminationGracePeriodSeconds, + Description: "Duration in seconds the Pod needs to terminate gracefully after a probe failure. The kubelet always honors the probe-level terminationGracePeriodSeconds field if it is present on a Pod.", + } + } + return &schema.Resource{ Schema: h, } - } func securityContextSchema(isUpdatable bool) *schema.Resource { diff --git a/kubernetes/structures_container.go b/kubernetes/structures_container.go index e116825050..e1b79cfe37 100644 --- a/kubernetes/structures_container.go +++ b/kubernetes/structures_container.go @@ -177,6 +177,9 @@ func flattenProbe(in *v1.Probe) []interface{} { if in.GRPC != nil { att["grpc"] = flattenGRPC(in.GRPC) } + if in.TerminationGracePeriodSeconds != nil { + att["termination_grace_period_seconds"] = *in.TerminationGracePeriodSeconds + } return []interface{}{att} } From 4e8e14b1295690ced6bba203528d730095b78a9e Mon Sep 17 00:00:00 2001 From: Andrew Page Date: Thu, 27 Feb 2025 10:52:07 -0800 Subject: [PATCH 2/6] Docs updates --- docs/resources/pod.md | 4 ++-- kubernetes/schema_container.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/resources/pod.md b/docs/resources/pod.md index 548a508040..bb7f644c92 100644 --- a/docs/resources/pod.md +++ b/docs/resources/pod.md @@ -594,7 +594,7 @@ Optional: - `success_threshold` (Number) Minimum consecutive successes for the probe to be considered successful after having failed. - `tcp_socket` (Block List) TCPSocket specifies an action involving a TCP port. TCP hooks not yet supported (see [below for nested schema](#nestedblock--spec--container--liveness_probe--tcp_socket)) - `timeout_seconds` (Number) Number of seconds after which the probe times out. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes - +- `termination_grace_period_seconds` (Number) Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's `terminationGracePeriodSeconds` will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). Minimum value is 1. `spec.terminationGracePeriodSeconds` is used if unset. ### Nested Schema for `spec.container.liveness_probe.exec` @@ -793,6 +793,7 @@ Optional: - `success_threshold` (Number) Minimum consecutive successes for the probe to be considered successful after having failed. - `tcp_socket` (Block List) TCPSocket specifies an action involving a TCP port. TCP hooks not yet supported (see [below for nested schema](#nestedblock--spec--container--startup_probe--tcp_socket)) - `timeout_seconds` (Number) Number of seconds after which the probe times out. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes +- `termination_grace_period_seconds` (Number) Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's `terminationGracePeriodSeconds` will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). Minimum value is 1. `spec.terminationGracePeriodSeconds` is used if unset. ### Nested Schema for `spec.container.startup_probe.exec` @@ -1155,7 +1156,6 @@ Optional: - `success_threshold` (Number) Minimum consecutive successes for the probe to be considered successful after having failed. - `tcp_socket` (Block List) TCPSocket specifies an action involving a TCP port. TCP hooks not yet supported (see [below for nested schema](#nestedblock--spec--init_container--liveness_probe--tcp_socket)) - `timeout_seconds` (Number) Number of seconds after which the probe times out. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes - ### Nested Schema for `spec.init_container.liveness_probe.exec` diff --git a/kubernetes/schema_container.go b/kubernetes/schema_container.go index 8544157193..f25c7dd829 100644 --- a/kubernetes/schema_container.go +++ b/kubernetes/schema_container.go @@ -761,7 +761,7 @@ func probeSchema(probeType ProbeType) *schema.Resource { Type: schema.TypeInt, Optional: true, ValidateFunc: validateTerminationGracePeriodSeconds, - Description: "Duration in seconds the Pod needs to terminate gracefully after a probe failure. The kubelet always honors the probe-level terminationGracePeriodSeconds field if it is present on a Pod.", + Description: "Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's `terminationGracePeriodSeconds` will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). Minimum value is 1. `spec.terminationGracePeriodSeconds` is used if unset.", } } From f2d4360ce0b6cb8f651acc14135134ef2624b362 Mon Sep 17 00:00:00 2001 From: Andrew Page Date: Thu, 27 Feb 2025 11:02:22 -0800 Subject: [PATCH 3/6] Revert docs change --- docs/resources/pod.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/resources/pod.md b/docs/resources/pod.md index bb7f644c92..548a508040 100644 --- a/docs/resources/pod.md +++ b/docs/resources/pod.md @@ -594,7 +594,7 @@ Optional: - `success_threshold` (Number) Minimum consecutive successes for the probe to be considered successful after having failed. - `tcp_socket` (Block List) TCPSocket specifies an action involving a TCP port. TCP hooks not yet supported (see [below for nested schema](#nestedblock--spec--container--liveness_probe--tcp_socket)) - `timeout_seconds` (Number) Number of seconds after which the probe times out. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes -- `termination_grace_period_seconds` (Number) Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's `terminationGracePeriodSeconds` will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). Minimum value is 1. `spec.terminationGracePeriodSeconds` is used if unset. + ### Nested Schema for `spec.container.liveness_probe.exec` @@ -793,7 +793,6 @@ Optional: - `success_threshold` (Number) Minimum consecutive successes for the probe to be considered successful after having failed. - `tcp_socket` (Block List) TCPSocket specifies an action involving a TCP port. TCP hooks not yet supported (see [below for nested schema](#nestedblock--spec--container--startup_probe--tcp_socket)) - `timeout_seconds` (Number) Number of seconds after which the probe times out. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes -- `termination_grace_period_seconds` (Number) Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's `terminationGracePeriodSeconds` will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). Minimum value is 1. `spec.terminationGracePeriodSeconds` is used if unset. ### Nested Schema for `spec.container.startup_probe.exec` @@ -1156,6 +1155,7 @@ Optional: - `success_threshold` (Number) Minimum consecutive successes for the probe to be considered successful after having failed. - `tcp_socket` (Block List) TCPSocket specifies an action involving a TCP port. TCP hooks not yet supported (see [below for nested schema](#nestedblock--spec--init_container--liveness_probe--tcp_socket)) - `timeout_seconds` (Number) Number of seconds after which the probe times out. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes + ### Nested Schema for `spec.init_container.liveness_probe.exec` From c748f205dfe6b9d7ad3e1e531eb3e4acf13d1934 Mon Sep 17 00:00:00 2001 From: Andrew Page Date: Thu, 27 Feb 2025 11:10:28 -0800 Subject: [PATCH 4/6] Add tests for Probe-level termination_grace_period_seconds --- kubernetes/resource_kubernetes_pod_v1_test.go | 141 ++++++++++++++++++ 1 file changed, 141 insertions(+) diff --git a/kubernetes/resource_kubernetes_pod_v1_test.go b/kubernetes/resource_kubernetes_pod_v1_test.go index d1970deb96..957b31ca03 100644 --- a/kubernetes/resource_kubernetes_pod_v1_test.go +++ b/kubernetes/resource_kubernetes_pod_v1_test.go @@ -571,6 +571,47 @@ func TestAccKubernetesPodV1_with_container_liveness_probe_using_http_get(t *test }) } +func TestAccKubernetesPodV1_with_container_liveness_probe_using_termination_grace_period_seconds(t *testing.T) { + var conf api.Pod + + podName := acctest.RandomWithPrefix("tf-acc-test") + imageName := agnhostImage + resourceName := "kubernetes_pod_v1.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + skipIfClusterVersionLessThan(t, "1.25.0") + }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckKubernetesPodV1Destroy, + Steps: []resource.TestStep{ + { + Config: testAccKubernetesPodV1ConfigWithLivenessProbeUsingTerminationGracePeriod(podName, imageName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckKubernetesPodV1Exists(resourceName, &conf), + resource.TestCheckResourceAttr(resourceName, "spec.0.container.0.args.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.container.0.liveness_probe.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.container.0.liveness_probe.0.http_get.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.container.0.liveness_probe.0.http_get.0.path", "/healthz"), + resource.TestCheckResourceAttr(resourceName, "spec.0.container.0.liveness_probe.0.http_get.0.port", "8080"), + resource.TestCheckResourceAttr(resourceName, "spec.0.container.0.liveness_probe.0.http_get.0.http_header.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.container.0.liveness_probe.0.http_get.0.http_header.0.name", "X-Custom-Header"), + resource.TestCheckResourceAttr(resourceName, "spec.0.container.0.liveness_probe.0.http_get.0.http_header.0.value", "Awesome"), + resource.TestCheckResourceAttr(resourceName, "spec.0.container.0.liveness_probe.0.initial_delay_seconds", "3"), + resource.TestCheckResourceAttr(resourceName, "spec.0.container.0.liveness_probe.0.termination_grace_period_seconds", "10"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"metadata.0.resource_version"}, + }, + }, + }) +} + func TestAccKubernetesPodV1_with_container_liveness_probe_using_tcp(t *testing.T) { var conf api.Pod @@ -1188,6 +1229,43 @@ func TestAccKubernetesPodV1_config_container_startup_probe(t *testing.T) { }) } +func TestAccKubernetesPodV1_config_container_startup_probe_termination_grace_period_seconds(t *testing.T) { + var confPod api.Pod + + podName := acctest.RandomWithPrefix("tf-acc-test") + imageName := busyboxImage + resourceName := "kubernetes_pod_v1.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + skipIfClusterVersionLessThan(t, "1.25.0") + }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckKubernetesPodV1Destroy, + Steps: []resource.TestStep{ + { + Config: testAccKubernetesPodV1ContainerStartupProbe(podName, imageName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckKubernetesPodV1Exists(resourceName, &confPod), + resource.TestCheckResourceAttr(resourceName, "metadata.0.generation", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.container.0.startup_probe.0.http_get.0.path", "/index.html"), + resource.TestCheckResourceAttr(resourceName, "spec.0.container.0.startup_probe.0.http_get.0.port", "80"), + resource.TestCheckResourceAttr(resourceName, "spec.0.container.0.startup_probe.0.initial_delay_seconds", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.container.0.startup_probe.0.timeout_seconds", "2"), + resource.TestCheckResourceAttr(resourceName, "spec.0.container.0.startup_probe.0.termination_grace_period_seconds", "10"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"metadata.0.resource_version"}, + }, + }, + }) +} + func TestAccKubernetesPodV1_termination_message_policy_default(t *testing.T) { var confPod api.Pod @@ -2117,6 +2195,42 @@ func testAccKubernetesPodV1ConfigWithLivenessProbeUsingHTTPGet(podName, imageNam `, podName, imageName) } +func testAccKubernetesPodV1ConfigWithLivenessProbeUsingTerminationGracePeriod(podName, imageName string) string { + return fmt.Sprintf(`resource "kubernetes_pod_v1" "test" { + metadata { + labels = { + app = "pod_label" + } + + name = "%s" + } + + spec { + container { + image = "%s" + name = "containername" + args = ["liveness"] + + liveness_probe { + http_get { + path = "/healthz" + port = 8080 + + http_header { + name = "X-Custom-Header" + value = "Awesome" + } + } + initial_delay_seconds = 3 + period_seconds = 1 + termination_grace_period_seconds = 10 + } + } + } +} +`, podName, imageName) +} + func testAccKubernetesPodV1ConfigWithLivenessProbeUsingTCP(podName, imageName string) string { return fmt.Sprintf(`resource "kubernetes_pod_v1" "test" { metadata { @@ -2946,6 +3060,33 @@ func testAccKubernetesPodV1ContainerStartupProbe(podName, imageName string) stri `, podName, imageName) } +func testAccKubernetesPodV1ContainerStartupProbe_termination_grace_period_seconds(podName, imageName string) string { + return fmt.Sprintf(`resource "kubernetes_pod_v1" "test" { + metadata { + name = "%s" + } + + spec { + container { + image = "%s" + name = "containername" + + startup_probe { + http_get { + path = "/index.html" + port = 80 + } + + initial_delay_seconds = 1 + timeout_seconds = 2 + termination_grace_period_seconds = 10 + } + } + } +} +`, podName, imageName) +} + func testAccKubernetesTerminationMessagePolicyDefault(podName, imageName string) string { return fmt.Sprintf(`resource "kubernetes_pod_v1" "test" { metadata { From a57c9f72ef662757abed5e4b9ceacc7936d976d2 Mon Sep 17 00:00:00 2001 From: Andrew Page Date: Thu, 27 Feb 2025 11:35:51 -0800 Subject: [PATCH 5/6] Working TGP, working tests --- .../resource_kubernetes_deployment_v1_test.go | 85 +++++++++++++++++++ kubernetes/resource_kubernetes_pod_v1_test.go | 2 +- kubernetes/structures_container.go | 3 + 3 files changed, 89 insertions(+), 1 deletion(-) diff --git a/kubernetes/resource_kubernetes_deployment_v1_test.go b/kubernetes/resource_kubernetes_deployment_v1_test.go index 85872dec7e..3de9be9396 100644 --- a/kubernetes/resource_kubernetes_deployment_v1_test.go +++ b/kubernetes/resource_kubernetes_deployment_v1_test.go @@ -462,6 +462,38 @@ func TestAccKubernetesDeploymentV1_with_container_liveness_probe_using_tcp(t *te }) } +func TestAccKubernetesDeploymentV1_with_container_liveness_probe_using_termination_grace_period_seconds(t *testing.T) { + var conf appsv1.Deployment + + deploymentName := fmt.Sprintf("tf-acc-test-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)) + resourceName := "kubernetes_deployment_v1.test" + imageName := agnhostImage + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckKubernetesDeploymentV1Destroy, + Steps: []resource.TestStep{ + { + Config: testAccKubernetesDeploymentV1ConfigWithLivenessProbeUsingTerminationGracePeriodSeconds(deploymentName, imageName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckKubernetesDeploymentV1Exists(resourceName, &conf), + resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.spec.0.container.0.args.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.spec.0.container.0.liveness_probe.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.spec.0.container.0.liveness_probe.0.http_get.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.spec.0.container.0.liveness_probe.0.http_get.0.path", "/healthz"), + resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.spec.0.container.0.liveness_probe.0.http_get.0.port", "8080"), + resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.spec.0.container.0.liveness_probe.0.http_get.0.http_header.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.spec.0.container.0.liveness_probe.0.http_get.0.http_header.0.name", "X-Custom-Header"), + resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.spec.0.container.0.liveness_probe.0.http_get.0.http_header.0.value", "Awesome"), + resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.spec.0.container.0.liveness_probe.0.initial_delay_seconds", "3"), + resource.TestCheckResourceAttr(resourceName, "spec.0.template.0.spec.0.container.0.liveness_probe.0.termination_grace_period_seconds", "10"), + ), + }, + }, + }) +} + func TestAccKubernetesDeploymentV1_with_container_lifecycle(t *testing.T) { var conf appsv1.Deployment @@ -2012,6 +2044,59 @@ func testAccKubernetesDeploymentV1ConfigWithLivenessProbeUsingHTTPGet(deployment `, deploymentName, imageName) } +func testAccKubernetesDeploymentV1ConfigWithLivenessProbeUsingTerminationGracePeriodSeconds(deploymentName, imageName string) string { + return fmt.Sprintf(`resource "kubernetes_deployment_v1" "test" { + metadata { + name = "%s" + + labels = { + Test = "TfAcceptanceTest" + } + } + + spec { + selector { + match_labels = { + Test = "TfAcceptanceTest" + } + } + + template { + metadata { + labels = { + Test = "TfAcceptanceTest" + } + } + + spec { + container { + image = "%s" + name = "containername" + args = ["liveness"] + + liveness_probe { + http_get { + path = "/healthz" + port = 8080 + + http_header { + name = "X-Custom-Header" + value = "Awesome" + } + } + initial_delay_seconds = 3 + period_seconds = 1 + termination_grace_period_seconds = 10 + } + } + termination_grace_period_seconds = 1 + } + } + } +} +`, deploymentName, imageName) +} + func testAccKubernetesDeploymentV1ConfigWithLivenessProbeUsingTCP(deploymentName, imageName string) string { return fmt.Sprintf(`resource "kubernetes_deployment_v1" "test" { metadata { diff --git a/kubernetes/resource_kubernetes_pod_v1_test.go b/kubernetes/resource_kubernetes_pod_v1_test.go index 957b31ca03..0cbf6dafed 100644 --- a/kubernetes/resource_kubernetes_pod_v1_test.go +++ b/kubernetes/resource_kubernetes_pod_v1_test.go @@ -1245,7 +1245,7 @@ func TestAccKubernetesPodV1_config_container_startup_probe_termination_grace_per CheckDestroy: testAccCheckKubernetesPodV1Destroy, Steps: []resource.TestStep{ { - Config: testAccKubernetesPodV1ContainerStartupProbe(podName, imageName), + Config: testAccKubernetesPodV1ContainerStartupProbe_termination_grace_period_seconds(podName, imageName), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckKubernetesPodV1Exists(resourceName, &confPod), resource.TestCheckResourceAttr(resourceName, "metadata.0.generation", "0"), diff --git a/kubernetes/structures_container.go b/kubernetes/structures_container.go index e1b79cfe37..db5be5b591 100644 --- a/kubernetes/structures_container.go +++ b/kubernetes/structures_container.go @@ -767,6 +767,9 @@ func expandProbe(l []interface{}) *v1.Probe { if v, ok := in["timeout_seconds"].(int); ok { obj.TimeoutSeconds = int32(v) } + if v, ok := in["termination_grace_period_seconds"].(int); ok { + obj.TerminationGracePeriodSeconds = ptr.To(int64(v)) + } return &obj } From 3eafec987efbcbcbd7af715b1e8e8dd1de2eeb9f Mon Sep 17 00:00:00 2001 From: Andrew Page Date: Thu, 27 Feb 2025 12:04:33 -0800 Subject: [PATCH 6/6] Exclude zero values from the probe TGP field --- kubernetes/schema_container.go | 4 ++-- kubernetes/structures_container.go | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/kubernetes/schema_container.go b/kubernetes/schema_container.go index f25c7dd829..d3d12ed062 100644 --- a/kubernetes/schema_container.go +++ b/kubernetes/schema_container.go @@ -760,8 +760,8 @@ func probeSchema(probeType ProbeType) *schema.Resource { h["termination_grace_period_seconds"] = &schema.Schema{ Type: schema.TypeInt, Optional: true, - ValidateFunc: validateTerminationGracePeriodSeconds, - Description: "Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's `terminationGracePeriodSeconds` will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). Minimum value is 1. `spec.terminationGracePeriodSeconds` is used if unset.", + ValidateFunc: validateIntGreaterThan(0), + Description: "Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's `terminationGracePeriodSeconds` will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer greater than zero. `spec.terminationGracePeriodSeconds` is used if unset.", } } diff --git a/kubernetes/structures_container.go b/kubernetes/structures_container.go index db5be5b591..69fbfab531 100644 --- a/kubernetes/structures_container.go +++ b/kubernetes/structures_container.go @@ -767,7 +767,9 @@ func expandProbe(l []interface{}) *v1.Probe { if v, ok := in["timeout_seconds"].(int); ok { obj.TimeoutSeconds = int32(v) } - if v, ok := in["termination_grace_period_seconds"].(int); ok { + + // Set the `TerminationGracePeriodSeconds` field only if it is not set to the default (0) + if v, ok := in["termination_grace_period_seconds"].(int); ok && v != 0 { obj.TerminationGracePeriodSeconds = ptr.To(int64(v)) }