> For the complete documentation index, see [llms.txt](https://developer.harness.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.harness.io/continuous-delivery/use-continuous-delivery/cd-building-blocks/cd-steps/containerized-steps/approval-steps-in-container-step-groups.md).

# Use Harness Approval steps in container step groups

Add manual approval steps to containerized Continuous Delivery workflows for deployment validation and traffic management.

You can add Harness Approval steps inside container step groups in Continuous Delivery pipelines. Manual approval gates in these workflows support canary, blue-green, and traffic-based rollouts. This topic explains how to configure stage timeouts so a long-running approval can finish inside a containerized workflow.

{% hint style="info" %}
**Feature flag**

This feature is behind the feature flag `CDS_CONTAINER_STEP_GROUP_STAGE_TIMEOUT`. Contact [Harness Support](mailto:support@harness.io) to enable the feature.
{% endhint %}

***

## What you will learn from this topic

* How to [run a Harness Approval step inside a container step group](#how-approval-steps-work-in-container-step-groups)
* How to [extend the stage timeout](#configure-stage-timeout-for-approvals) when an approval needs more than 24 hours
* How to [set pipeline, stage, and approval timeouts](#configure-timeout-hierarchy-correctly) so the approval can finish
* How to [set the stage timeout in YAML](#configure-stage-timeout-in-yaml) or [in the UI](#configure-stage-timeout-in-the-ui) so the pod stays up until the approval completes

***

## Before you begin <a href="#before-you-begin" id="before-you-begin"></a>

Before you add Harness Approval steps to container step groups, review the following concepts and setup:

* **Container step groups**: Run Continuous Delivery steps in your Kubernetes cluster. Go to [Containerize step groups](/continuous-delivery/use-continuous-delivery/cd-building-blocks/cd-steps/containerized-steps/containerized-step-groups.md) to understand pod lifecycle and resource requirements.
* **Harness Approval steps**: Configure manual gates in Harness pipelines. Go to [Approvals tutorial](https://developer.harness.io/docs/platform/approvals/approvals-tutorial/) to review approver configuration and notification options.
* **Stage timeouts**: Container step group pods have a default 24-hour lifetime. Approval steps that wait longer than 24 hours require an extended stage timeout.

***

## How approval steps work in container step groups <a href="#how-approval-steps-work-in-container-step-groups" id="how-approval-steps-work-in-container-step-groups"></a>

When a Harness Approval step runs inside a container step group, the approval process works as follows:

The container step group creates a pod in your Kubernetes cluster that hosts all steps in the group. When execution reaches a Harness Approval step, the pipeline pauses and waits for human approval. The approval request appears in the Harness UI, and approvers can grant or reject the request. Once approved, execution resumes with the next step in the group.

This workflow supports deployment patterns where you need manual validation between automated deployment phases. For example, you can deploy without traffic, validate the deployment, grant approval, and then shift production traffic to the new version.

***

## Configure stage timeout for approvals <a href="#configure-stage-timeout-for-approvals" id="configure-stage-timeout-for-approvals"></a>

Container step group pods have a default maximum lifetime of 24 hours. If your approval step requires more than 24 hours for an approver to respond, configure an extended stage timeout.

### When to configure stage timeout <a href="#when-to-configure-stage-timeout" id="when-to-configure-stage-timeout"></a>

Configure an extended stage timeout when your approval steps may require more than 24 hours for a human response. Common scenarios include the following:

* Deployments that span multiple time zones or business days
* Approvals that require coordination across multiple teams
* Production deployments that wait for low-traffic windows

### How stage timeout affects pod lifetime <a href="#how-stage-timeout-affects-pod-lifetime" id="how-stage-timeout-affects-pod-lifetime"></a>

The pod time to live (TTL) is set using the Kubernetes `activeDeadlineSeconds` field on the container step group pod. The `CDS_CONTAINER_STEP_GROUP_STAGE_TIMEOUT` feature flag controls how this value is determined.

**When the feature flag is off**: Pod TTL is always 24 hours (the default), regardless of the stage timeout configuration.

**When the feature flag is on**: Pod TTL is set as follows:

* **No stage timeout set in YAML**: Pod TTL defaults to 24 hours.
* **Stage timeout ≤ 24 hours**: Pod TTL defaults to 24 hours.
* **Stage timeout > 24 hours**: Pod TTL equals the stage timeout value.

When the feature flag is enabled, Harness reads the `timeout` field from the stage YAML. If the stage timeout exceeds 24 hours, the pod TTL is set to match that timeout value. If no stage timeout is specified in the YAML, or if the stage timeout is 24 hours or less, the pod TTL remains at the default 24 hours.

The stage timeout field supports Harness expressions (for example, `<+pipeline.variables.timeout>`), which are resolved at runtime. For example, if the stage timeout is set to `30h`, the pod TTL is set to 30 hours.

### Configure timeout hierarchy correctly <a href="#configure-timeout-hierarchy-correctly" id="configure-timeout-hierarchy-correctly"></a>

When you use Harness Approval steps in container step groups, configure timeouts at three levels so the approval can complete. Each level must accommodate the level below it:

1. **Pipeline timeout** must be greater than the stage timeout.
2. **Stage timeout** must be greater than or equal to the approval step timeout.
3. **Approval step timeout** determines how long the approval can wait for a human response.

**Example configuration**:

If your approval step may take 30 hours for a response, configure the following timeouts:

* Approval step timeout: `30h` (or more)
* Stage timeout: `30h` (or more), to set the pod TTL to 30 hours
* Pipeline timeout: `> 30h`, to allow the entire pipeline to complete

If the stage timeout is less than the approval step timeout, the approval can succeed, but the stage fails when it exceeds the stage timeout. If the stage timeout is 24 hours or less, the pod TTL remains at 24 hours, and the pod is terminated if the approval takes longer than 24 hours.

### Configure stage timeout in YAML <a href="#configure-stage-timeout-in-yaml" id="configure-stage-timeout-in-yaml"></a>

Add the `timeout` field to your stage configuration. The timeout value uses duration format (for example, `30h` for 30 hours, or `2d` for two days).

<details>

<summary>Google Cloud Run deployment with approval YAML example</summary>

```yaml
execution:
  steps:
    - stepGroup:
        steps:
          - step:
              type: DownloadManifests
              name: DownloadManifests
              identifier: DownloadManifests
              spec: {}
              failureStrategies: []
          - step:
              type: GoogleCloudRunPrepareRollbackData
              name: Google Cloud Run Prepare Rollback Data
              identifier: Google_Cloud_Run_Prepare_Rollback_Data
              spec:
                connectorRef: account.harnessImage
                image: harness/google-cloud-run-plugin:1.0.9-linux-amd64
                imagePullPolicy: Always
          - step:
              type: GoogleCloudRunDeploy
              name: Google Cloud Run Deploy
              identifier: Google_Cloud_Run_Deploy
              spec:
                connectorRef: account.harnessImage
                image: harness/google-cloud-run-plugin:1.0.9-linux-amd64
                imagePullPolicy: Always
          - step:
              type: HarnessApproval
              name: HarnessApproval_1
              identifier: HarnessApproval_1
              spec:
                approvalMessage: Please review the following information and approve the pipeline progression
                includePipelineExecutionHistory: true
                isAutoRejectEnabled: false
                approvers:
                  userGroups:
                    - account._account_all_users
                  minimumCount: 1
                  disallowPipelineExecutor: false
                approverInputs: []
              timeout: 1d
          - step:
              type: GoogleCloudRunTrafficShift
              name: Google Cloud Run Traffic Shift
              identifier: Google_Cloud_Run_Traffic_Shift
              spec:
                revisionTrafficDetails:
                  - revisionName: latest
                    trafficValue: 100
                connectorRef: account.harnessImage
                image: harness/google-cloud-run-plugin:1.0.9-linux-amd64
                imagePullPolicy: Always
        name: Google Cloud Run Step Group
        identifier: Google_Cloud_Run_Step_Group
        sharedPaths:
          - /var/run
          - /var/lib/docker
        stepGroupInfra:
          type: KubernetesDirect
          spec:
            connectorRef: <+input>
            namespace: default
  rollbackSteps:
    - stepGroup:
        name: Google Cloud Run Rollback Step Group
        identifier: Google_Cloud_Run_Rollback_Step_Group
        steps:
          - step:
              type: GoogleCloudRunRollback
              name: Google Cloud Run Rollback
              identifier: Google_Cloud_Run_Rollback
              spec:
                connectorRef: account.harnessImage
                image: harness/google-cloud-run-plugin:1.0.9-linux-amd64
                imagePullPolicy: Always
        sharedPaths:
          - /var/run
          - /var/lib/docker
        stepGroupInfra:
          type: KubernetesDirect
          spec:
            connectorRef: <+input>
            namespace: default
```

</details>

### Configure stage timeout in the UI <a href="#configure-stage-timeout-in-the-ui" id="configure-stage-timeout-in-the-ui"></a>

Perform the following steps to set the stage timeout:

1. In your pipeline, select the deployment stage that contains the container step group.
2. Select the **Advanced** tab for the stage.
3. In the **Timeout** field, enter a duration value (for example, `48h` for 48 hours).
4. Save the pipeline.

The pod that hosts the container step group remains active for the configured timeout duration, so approval steps can wait for a human response without the pod being terminated.

***

{% hint style="info" %}
**Limits for approval steps in container step groups** The following limits apply when you add a Harness Approval step to a container step group:

* Only Harness Approval steps are supported in container step groups. Other approval step types (Jira Approval, ServiceNow Approval, and Custom Approval) are not supported.
* The pod that hosts the container step group remains active during approval wait time. Your Kubernetes cluster needs sufficient resources to support long-running pods if you use extended stage timeouts.
* Stage timeout configuration applies to the entire stage, not just the approval step. The pod lifetime extends to accommodate any long-running approvals within the stage.
* The stage timeout field supports Harness expressions, so you can set dynamic timeout values from pipeline variables or runtime inputs.
  {% endhint %}

***

## Next steps <a href="#next-steps" id="next-steps"></a>

* Go to [Containerize step groups](/continuous-delivery/use-continuous-delivery/cd-building-blocks/cd-steps/containerized-steps/containerized-step-groups.md) to understand pod lifecycle and resource configuration for Continuous Delivery steps in your Kubernetes cluster.
* Go to [Using manual Harness approval stages](https://developer.harness.io/docs/platform/approvals/adding-harness-approval-stages/) to explore Harness Approval configuration options and approval workflows.
* Go to [Define failure strategies for stages and steps](https://developer.harness.io/docs/platform/pipelines/failure-handling/define-a-failure-strategy-on-stages-and-steps) to configure what happens if an approval is rejected or times out.

{% @harness-feedback/feedback %}
