diff --git a/cinder/templates/deployment-api.yaml b/cinder/templates/deployment-api.yaml
index 448044fbfb..0c265800d3 100644
--- a/cinder/templates/deployment-api.yaml
+++ b/cinder/templates/deployment-api.yaml
@@ -43,6 +43,7 @@ spec:
     spec:
       nodeSelector:
         {{ .Values.labels.node_selector_key }}: {{ .Values.labels.node_selector_value }}
+      terminationGracePeriodSeconds: {{ .Values.termination_grace_period.api.timeout | default "30" }}
       containers:
         - name: cinder-api
           image: {{ .Values.images.api }}
@@ -62,6 +63,13 @@ spec:
           ports:
             - name: c-api
               containerPort: {{ .Values.conf.cinder.default.cinder.osapi_volume_listen_port }}
+          lifecycle:
+            preStop:
+              exec:
+                command:
+                  - kill
+                  - -TERM
+                  - "1"
           readinessProbe:
             tcpSocket:
               port: {{ .Values.conf.cinder.default.cinder.osapi_volume_listen_port }}
diff --git a/cinder/values.yaml b/cinder/values.yaml
index 08dbfa8071..9db2144f68 100644
--- a/cinder/values.yaml
+++ b/cinder/values.yaml
@@ -51,6 +51,10 @@ pod_disruption_budget:
   api:
     min_available: 0
 
+termination_grace_period:
+  api:
+    timeout: 30
+
 keystone:
   admin_user: "admin"
   admin_user_domain: "default"
diff --git a/glance/templates/deployment-api.yaml b/glance/templates/deployment-api.yaml
index 4d7639777a..e1c656ebc1 100644
--- a/glance/templates/deployment-api.yaml
+++ b/glance/templates/deployment-api.yaml
@@ -43,6 +43,7 @@ spec:
     spec:
       nodeSelector:
         {{ .Values.labels.node_selector_key }}: {{ .Values.labels.node_selector_value }}
+      terminationGracePeriodSeconds: {{ .Values.termination_grace_period.api.timeout | default "600" }}
       containers:
         - name: glance-api
           image: {{ .Values.images.api }}
@@ -61,6 +62,13 @@ spec:
             - /tmp/glance-api.sh
           ports:
             - containerPort: {{ .Values.conf.glance.default.glance.api.bind_port }}
+          lifecycle:
+            preStop:
+              exec:
+                command:
+                  - kill
+                  - -TERM
+                  - "1"
           readinessProbe:
             tcpSocket:
               port: {{ .Values.conf.glance.default.glance.api.bind_port }}
diff --git a/glance/templates/deployment-registry.yaml b/glance/templates/deployment-registry.yaml
index 394ad2f77e..2c78b2d39e 100644
--- a/glance/templates/deployment-registry.yaml
+++ b/glance/templates/deployment-registry.yaml
@@ -35,6 +35,7 @@ spec:
     spec:
       nodeSelector:
         {{ .Values.labels.node_selector_key }}: {{ .Values.labels.node_selector_value }}
+      terminationGracePeriodSeconds: {{ .Values.termination_grace_period.registry.timeout | default "600" }}
       containers:
         - name: glance-registry
           image: {{ .Values.images.registry }}
@@ -53,6 +54,13 @@ spec:
             - /tmp/glance-registry.sh
           ports:
             - containerPort: {{ .Values.conf.glance_registry.default.glance.registry.bind_port }}
+          lifecycle:
+            preStop:
+              exec:
+                command:
+                  - kill
+                  - -TERM
+                  - "1"
           readinessProbe:
             tcpSocket:
               port: {{ .Values.conf.glance_registry.default.glance.registry.bind_port }}
diff --git a/glance/values.yaml b/glance/values.yaml
index dde993ff7b..41b3aa31c8 100644
--- a/glance/values.yaml
+++ b/glance/values.yaml
@@ -52,6 +52,12 @@ pod_disruption_budget:
   registry:
     min_available: 0
 
+termination_grace_period:
+  api:
+    timeout: 600
+  registry:
+    timeout: 600
+
 bootstrap:
   enabled: true
   images:
diff --git a/heat/templates/deployment-api.yaml b/heat/templates/deployment-api.yaml
index 5c409ecb1c..7501674b39 100644
--- a/heat/templates/deployment-api.yaml
+++ b/heat/templates/deployment-api.yaml
@@ -43,6 +43,7 @@ spec:
     spec:
       nodeSelector:
         {{ .Values.labels.node_selector_key }}: {{ .Values.labels.node_selector_value }}
+      terminationGracePeriodSeconds: {{ .Values.termination_grace_period.api.timeout | default "30" }}
       containers:
         - name: heat-api
           image: {{ .Values.images.api }}
@@ -61,6 +62,13 @@ spec:
             - /tmp/heat-api.sh
           ports:
             - containerPort: {{ .Values.conf.heat.heat_api.heat.common.wsgi.bind_port }}
+          lifecycle:
+            preStop:
+              exec:
+                command:
+                  - kill
+                  - -TERM
+                  - "1"
           readinessProbe:
             tcpSocket:
               port: {{ .Values.conf.heat.heat_api.heat.common.wsgi.bind_port }}
diff --git a/heat/templates/deployment-cfn.yaml b/heat/templates/deployment-cfn.yaml
index d51ebdd59d..e2b5a14713 100644
--- a/heat/templates/deployment-cfn.yaml
+++ b/heat/templates/deployment-cfn.yaml
@@ -43,6 +43,7 @@ spec:
     spec:
       nodeSelector:
         {{ .Values.labels.node_selector_key }}: {{ .Values.labels.node_selector_value }}
+      terminationGracePeriodSeconds: {{ .Values.termination_grace_period.cfn.timeout | default "30" }}
       containers:
         - name: heat-cfn
           image: {{ .Values.images.cfn }}
@@ -61,6 +62,13 @@ spec:
             - /tmp/heat-cfn.sh
           ports:
             - containerPort: {{ .Values.conf.heat.heat_api_cfn.heat.common.wsgi.bind_port }}
+          lifecycle:
+            preStop:
+              exec:
+                command:
+                  - kill
+                  - -TERM
+                  - "1"
           readinessProbe:
             tcpSocket:
               port: {{ .Values.conf.heat.heat_api_cfn.heat.common.wsgi.bind_port }}
diff --git a/heat/templates/deployment-cloudwatch.yaml b/heat/templates/deployment-cloudwatch.yaml
index d75657083e..2056773aff 100644
--- a/heat/templates/deployment-cloudwatch.yaml
+++ b/heat/templates/deployment-cloudwatch.yaml
@@ -43,6 +43,7 @@ spec:
     spec:
       nodeSelector:
         {{ .Values.labels.node_selector_key }}: {{ .Values.labels.node_selector_value }}
+      terminationGracePeriodSeconds: {{ .Values.termination_grace_period.cloudwatch.timeout | default "30" }}
       containers:
         - name: heat-cloudwatch
           image: {{ .Values.images.cloudwatch }}
@@ -61,6 +62,13 @@ spec:
             - /tmp/heat-cloudwatch.sh
           ports:
             - containerPort: {{ .Values.conf.heat.heat_api_cloudwatch.heat.common.wsgi.bind_port }}
+          lifecycle:
+            preStop:
+              exec:
+                command:
+                  - kill
+                  - -TERM
+                  - "1"
           readinessProbe:
             tcpSocket:
               port: {{ .Values.conf.heat.heat_api_cloudwatch.heat.common.wsgi.bind_port }}
diff --git a/heat/values.yaml b/heat/values.yaml
index 49cf00668a..c0a4712832 100644
--- a/heat/values.yaml
+++ b/heat/values.yaml
@@ -56,6 +56,14 @@ pod_disruption_budget:
   cloudwatch:
     min_available: 0
 
+termination_grace_period:
+  api:
+    timeout: 30
+  cfn:
+    timeout: 30
+  cloudwatch:
+    timeout: 30
+
 keystone_secrets:
   admin: "heat-env-keystone-admin"
   user: "heat-env-keystone-user"
diff --git a/horizon/templates/deployment.yaml b/horizon/templates/deployment.yaml
index ffa3520c8a..391439e951 100644
--- a/horizon/templates/deployment.yaml
+++ b/horizon/templates/deployment.yaml
@@ -43,6 +43,7 @@ spec:
     spec:
       nodeSelector:
         {{ .Values.labels.node_selector_key }}: {{ .Values.labels.node_selector_value }}
+      terminationGracePeriodSeconds: {{ .Values.termination_grace_period.horizon.timeout | default "30" }}
       containers:
         - name: horizon
           image: {{ .Values.images.horizon }}
@@ -61,6 +62,13 @@ spec:
             - /tmp/start.sh
           ports:
             - containerPort: {{ .Values.network.port }}
+          lifecycle:
+            preStop:
+              exec:
+                command:
+                  - apachectl
+                  - -k
+                  - graceful-stop
           readinessProbe:
             tcpSocket:
               port: {{ .Values.network.port }}
diff --git a/horizon/values.yaml b/horizon/values.yaml
index 5bd6aa2246..04439e1864 100644
--- a/horizon/values.yaml
+++ b/horizon/values.yaml
@@ -35,6 +35,10 @@ pod_disruption_budget:
   horizon:
     min_available: 0
 
+termination_grace_period:
+  horizon:
+    timeout: 30
+
 labels:
   node_selector_key: openstack-control-plane
   node_selector_value: enabled
diff --git a/keystone/templates/deployment.yaml b/keystone/templates/deployment.yaml
index 7c9fd6bab5..31e9d9c877 100644
--- a/keystone/templates/deployment.yaml
+++ b/keystone/templates/deployment.yaml
@@ -43,6 +43,7 @@ spec:
     spec:
       nodeSelector:
         {{ .Values.labels.node_selector_key }}: {{ .Values.labels.node_selector_value }}
+      terminationGracePeriodSeconds: {{ .Values.termination_grace_period.api.timeout | default "30" }}
       containers:
         - name: keystone-api
           image: {{ .Values.images.api }}
diff --git a/keystone/values.yaml b/keystone/values.yaml
index b77f2f8cfb..e7a27ef0ba 100644
--- a/keystone/values.yaml
+++ b/keystone/values.yaml
@@ -41,6 +41,10 @@ pod_disruption_budget:
   api:
     min_available: 0
 
+termination_grace_period:
+  api:
+    timeout: 30
+
 keystone:
   version: v3
   scheme: http
diff --git a/magnum/templates/deployment-api.yaml b/magnum/templates/deployment-api.yaml
index 86a3dda62c..aebef2ed7d 100644
--- a/magnum/templates/deployment-api.yaml
+++ b/magnum/templates/deployment-api.yaml
@@ -43,6 +43,7 @@ spec:
     spec:
       nodeSelector:
         {{ .Values.labels.node_selector_key }}: {{ .Values.labels.node_selector_value }}
+      terminationGracePeriodSeconds: {{ .Values.termination_grace_period.api.timeout | default "30" }}
       containers:
         - name: magnum-api
           image: {{ .Values.images.api }}
@@ -58,6 +59,13 @@ spec:
           {{- end }}
           ports:
             - containerPort: {{ .Values.conf.magnum.api.magnum.port }}
+          lifecycle:
+            preStop:
+              exec:
+                command:
+                  - kill
+                  - -TERM
+                  - "1"
           readinessProbe:
             tcpSocket:
               port: {{ .Values.conf.magnum.api.magnum.port }}
diff --git a/magnum/values.yaml b/magnum/values.yaml
index 04164c553f..a59f7a4de5 100644
--- a/magnum/values.yaml
+++ b/magnum/values.yaml
@@ -48,6 +48,10 @@ pod_disruption_budget:
   api:
     min_available: 0
 
+termination_grace_period:
+  api:
+    timeout: 30
+
 keystone_secrets:
   admin: "magnum-env-keystone-admin"
   user: "magnum-env-keystone-user"
diff --git a/mistral/templates/deployment-api.yaml b/mistral/templates/deployment-api.yaml
index b846ff3abc..29787bdf1f 100644
--- a/mistral/templates/deployment-api.yaml
+++ b/mistral/templates/deployment-api.yaml
@@ -43,6 +43,7 @@ spec:
     spec:
       nodeSelector:
         {{ .Values.labels.node_selector_key }}: {{ .Values.labels.node_selector_value }}
+      terminationGracePeriodSeconds: {{ .Values.termination_grace_period.api.timeout | default "30" }}
       containers:
         - name: mistral-api
           image: {{ .Values.images.api }}
@@ -62,6 +63,13 @@ spec:
           ports:
             - name: {{ .Values.network.api.name }}
               containerPort: {{ .Values.conf.mistral.api.mistral.config.port }}
+          lifecycle:
+            preStop:
+              exec:
+                command:
+                  - kill
+                  - -TERM
+                  - "1"
           readinessProbe:
             tcpSocket:
               port: {{ .Values.conf.mistral.api.mistral.config.port }}
diff --git a/mistral/values.yaml b/mistral/values.yaml
index 0884cd0777..46acc4c1cb 100644
--- a/mistral/values.yaml
+++ b/mistral/values.yaml
@@ -52,6 +52,10 @@ pod_disruption_budget:
   api:
     min_available: 0
 
+termination_grace_period:
+  api:
+    timeout: 30
+
 keystone_secrets:
   admin: "mistral-env-keystone-admin"
   user: "mistral-env-keystone-user"
diff --git a/neutron/templates/deployment-server.yaml b/neutron/templates/deployment-server.yaml
index 74893237a5..95320a109c 100644
--- a/neutron/templates/deployment-server.yaml
+++ b/neutron/templates/deployment-server.yaml
@@ -43,6 +43,7 @@ spec:
     spec:
       nodeSelector:
         {{ .Values.labels.server.node_selector_key }}: {{ .Values.labels.server.node_selector_value }}
+      terminationGracePeriodSeconds: {{ .Values.termination_grace_period.server.timeout | default "30" }}
       containers:
         - name: neutron-server
           image: {{ .Values.images.server }}
@@ -58,6 +59,13 @@ spec:
           {{- end }}
           ports:
             - containerPort: {{ .Values.network.server.port }}
+          lifecycle:
+            preStop:
+              exec:
+                command:
+                  - kill
+                  - -TERM
+                  - "1"
           readinessProbe:
             tcpSocket:
               port: {{ .Values.network.server.port }}
diff --git a/neutron/values.yaml b/neutron/values.yaml
index 0b9cbc5b9c..cee9d9f460 100644
--- a/neutron/values.yaml
+++ b/neutron/values.yaml
@@ -47,6 +47,10 @@ pod_disruption_budget:
   server:
     min_available: 0
 
+termination_grace_period:
+  server:
+    timeout: 30
+
 labels:
   # ovs is a special case, requiring a special
   # label that can apply to both control hosts
@@ -518,4 +522,4 @@ mounts:
     neutron_metadata_agent:
   neutron_ovs_agent:
     init_container: null
-    neutron_ovs_agent:
\ No newline at end of file
+    neutron_ovs_agent:
diff --git a/nova/templates/deployment-api-metadata.yaml b/nova/templates/deployment-api-metadata.yaml
index e1833d853f..13a0a9f7b2 100644
--- a/nova/templates/deployment-api-metadata.yaml
+++ b/nova/templates/deployment-api-metadata.yaml
@@ -43,6 +43,7 @@ spec:
     spec:
       nodeSelector:
         {{ .Values.labels.api_metadata.node_selector_key }}: {{ .Values.labels.api_metadata.node_selector_value }}
+      terminationGracePeriodSeconds: {{ .Values.termination_grace_period.metadata.timeout | default "30" }}
       containers:
         - name: nova-api
           image: {{ .Values.images.api }}
@@ -63,6 +64,13 @@ spec:
                 - NET_ADMIN
           ports:
             - containerPort: {{ .Values.network.metadata.port }}
+          lifecycle:
+            preStop:
+              exec:
+                command:
+                  - kill
+                  - -TERM
+                  - "1"
           readinessProbe:
             tcpSocket:
               port: {{ .Values.network.metadata.port }}
diff --git a/nova/templates/deployment-api-osapi.yaml b/nova/templates/deployment-api-osapi.yaml
index 18850a6f91..d53c4568e3 100644
--- a/nova/templates/deployment-api-osapi.yaml
+++ b/nova/templates/deployment-api-osapi.yaml
@@ -43,6 +43,7 @@ spec:
     spec:
       nodeSelector:
         {{ .Values.labels.osapi.node_selector_key }}: {{ .Values.labels.osapi.node_selector_value }}
+      terminationGracePeriodSeconds: {{ .Values.termination_grace_period.osapi.timeout | default "30" }}
       containers:
         - name: nova-osapi
           image: {{ .Values.images.api }}
@@ -62,6 +63,13 @@ spec:
           {{- end }}
           ports:
             - containerPort: {{ .Values.network.osapi.port }}
+          lifecycle:
+            preStop:
+              exec:
+                command:
+                  - kill
+                  - -TERM
+                  - "1"
           readinessProbe:
             tcpSocket:
               port: {{ .Values.network.osapi.port }}
diff --git a/nova/values.yaml b/nova/values.yaml
index ac4397f05f..8c407a14a2 100644
--- a/nova/values.yaml
+++ b/nova/values.yaml
@@ -81,6 +81,12 @@ pod_disruption_budget:
   osapi:
     min_available: 0
 
+termination_grace_period:
+  metadata:
+    timeout: 30
+  osapi:
+    timeout: 30
+
 bootstrap:
   enabled: true
   flavors:
diff --git a/senlin/templates/deployment-api.yaml b/senlin/templates/deployment-api.yaml
index 59d4094897..b6e51ecbba 100644
--- a/senlin/templates/deployment-api.yaml
+++ b/senlin/templates/deployment-api.yaml
@@ -43,6 +43,7 @@ spec:
     spec:
       nodeSelector:
         {{ .Values.labels.node_selector_key }}: {{ .Values.labels.node_selector_value }}
+      terminationGracePeriodSeconds: {{ .Values.termination_grace_period.api.timeout | default "30" }}
       containers:
         - name: senlin-api
           image: {{ .Values.images.api }}
@@ -64,6 +65,13 @@ spec:
           command:
             - bash
             - /tmp/senlin-api.sh
+          lifecycle:
+            preStop:
+              exec:
+                command:
+                  - kill
+                  - -TERM
+                  - "1"
           volumeMounts:
             - name: senlin-bin
               mountPath: /tmp/senlin-api.sh
diff --git a/senlin/values.yaml b/senlin/values.yaml
index 83d85a956f..1dfe20f471 100644
--- a/senlin/values.yaml
+++ b/senlin/values.yaml
@@ -48,6 +48,10 @@ pod_disruption_budget:
   api:
     min_available: 0
 
+termination_grace_period:
+  api:
+    timeout: 30
+
 keystone_secrets:
   admin: "senlin-env-keystone-admin"
   user: "senlin-env-keystone-user"