> 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/containerized-step-groups.md).

# Containerize step groups

By default, the tasks performed by Harness CD steps are run on the Harness Delegate host system, for example, the Kubernetes cluster where a Kubernetes delegate is running.

To provide greater control over the resources used for CD steps, Harness also lets you use your own Kubernetes cluster or VMs as the runtime infrastructure for CD steps.

You can use a CD step group that points to your Kubernetes cluster or VM infrastructure as the runtime. Next, in the step group, you can add the steps supported by containerized step groups.

In this architecture, no tooling is installed on delegates. Delegates simply act as orchestrators. Any tooling is installed and removed on demand in the ephemeral step containers.

When you use deployment types that support containerized step groups (for example, AWS SAM), containerized steps are automatically generated when you add the execution strategy for the stage.

When you manually add a step group, you can enable containerized step groups by selecting the **Enable container based execution** option.

<figure><img src="/files/tGKlePqeIeFw8vsfqj9O" alt=""><figcaption><p>Click to view full size image</p></figcaption></figure>

This option is disabled for deployment types that do not support containerized step groups.

#### Infrastructure Options <a href="#infrastructure-options" id="infrastructure-options"></a>

When you enable container based execution, you can choose between three infrastructure types:

* **Kubernetes**: Run steps in containers on a Kubernetes cluster.
* **VMs**: Run steps in containers on virtual machines.
* **Amazon ECS**: Run steps in containers on AWS ECS Fargate.

### Important notes <a href="#important-notes" id="important-notes"></a>

* CD containerized step groups are supported in Deploy and Custom stages.
* Not all steps are supported in containerized step groups. You can see which steps are supported when you try to add steps in the containerized step group.
* When using Kubernetes infrastructure:
  * You can use the same cluster to run the Harness Delegate and the containerized step group(s), but it is not required.
* Permissions configuration are inherited by a step within a step group. This logic has been updated over the course of Harness lifespan. This has caused breaking changes for some users. To learn more about it, go to [Step Group Inheritance Logic](/continuous-delivery/troubleshooting-and-resources/knowledge-base-article/configuration-inheritance-stepgroup-step.md).
* A containerized step group may fail when using a cross-account role if the delegate responsible for execution lacks the necessary permissions to assume the role. To resolve this, ensure that the delegate has the required permissions to assume the cross-account role.
* You can use containerized step groups with mTLS connections. To learn more, go to [mTLS Support via Delegates](/harness-ai/use-harness-platform/delegates/delegate/secure-delegates/delegate-mtls-support.md).

### Add a containerized step group <a href="#add-a-containerized-step-group" id="add-a-containerized-step-group"></a>

Typically, Harness adds the step group and steps needed for a deployment automatically when you select the stage execution strategy in the **Execution** section.

Whether the containerized step group is added automatically or manually, you must configure it.

Here are the steps for adding a containerized step group manually:

1. In your Deploy (CD) stage, in **Execution**, select **Add Step**, and then select **Add Step Group**.
2. To configure a step group as containerized, enable the **Enable container based execution** setting.
3. Select your infrastructure type: **Kubernetes**, **VMs**, or **Amazon ECS**.
4. Configure the settings based on your selected infrastructure type.

### VM Infrastructure <a href="#vm-infrastructure" id="vm-infrastructure"></a>

{% hint style="info" %}
VM support for containerized step groups is currently behind the feature flag `CDS_ENABLE_VM_CONTAINER_STEP_GROUP_INFRA`. Contact [Harness Support](mailto:support@harness.io) to enable the feature.
{% endhint %}

When you select **VMs** as your infrastructure type, the containerized step group will run on virtual machine infrastructure.

#### Prerequisites <a href="#prerequisites" id="prerequisites"></a>

* **VM Runner**: The Drone VM Runner must be installed on your VM infrastructure to communicate with Harness and manage containerized step execution.
* **Operating System**: Only Linux VMs are supported for CD containerized step groups.

For detailed information on setting up VM infrastructure with the runner, go to [Set up VM build infrastructures](/continuous-integration/use-harness-ci/use-harness-ci/set-up-build-infrastructure/vm-build-infrastructure.md).

#### Operating System <a href="#operating-system" id="operating-system"></a>

Select the operating system for your VM infrastructure. Currently, only **Linux** is supported.

#### Pool Name <a href="#pool-name" id="pool-name"></a>

Enter the name of the VM pool as defined in your `pool.yml` configuration file. The pool defines the VM specifications and pool size for running your containerized steps.

#### Override Image Connector <a href="#override-image-connector" id="override-image-connector"></a>

By default, Harness pulls images from public Docker Hub repos for backend processes. You can optionally override this by selecting a different connector to use for the Harness Container Image Registry.

For more information, go to [Connect to the Harness container image registry](/harness-ai/use-harness-platform/connectors/artifact-repositories/connect-to-harness-container-image-registry-using-docker-connector.md).

#### Supported Steps <a href="#supported-steps" id="supported-steps"></a>

When using VM infrastructure, only the following steps are supported:

**SBOM Steps:**

* SBOM Orchestration
* SBOM Policy Enforcement
* SLSA Verification

**AWS CDK Steps:**

* AWS CDK Bootstrap
* AWS CDK Deploy
* AWS CDK Rollback
* AWS CDK Destroy

**Serverless AWS Lambda Steps:**

* Serverless AWS Lambda Prepare
* Serverless AWS Lambda Package
* Serverless AWS Lambda Deploy V2
* Serverless AWS Lambda Rollback

**Download Steps:**

* Download AWS S3
* Download Harness Store

**Source Control Steps:**

* Git Clone

### Amazon ECS Infrastructure <a href="#amazon-ecs-infrastructure" id="amazon-ecs-infrastructure"></a>

{% hint style="info" %}
Amazon ECS support for containerized step groups is currently behind the feature flag `CDS_ENABLE_ECS_CONTAINER_STEP_GROUP_INFRA`. Contact [Harness Support](mailto:support@harness.io) to enable the feature.
{% endhint %}

When you select **Amazon ECS** as your infrastructure type, the containerized step group will run on AWS ECS Fargate infrastructure. This allows you to execute containerized CD steps such as AWS CDK deployments without requiring a Kubernetes cluster, providing consistency for teams already operating in ECS environments.

#### AWS Cloud Provider <a href="#aws-cloud-provider" id="aws-cloud-provider"></a>

Select or add a Harness AWS connector configured with the necessary ECS permissions, VPC settings, cluster information, and IAM roles. The connector configuration includes all the necessary settings for ECS Fargate execution, including region, cluster, VPC, subnets, security groups, and IAM roles.

Go to [Add an AWS connector](/harness-ai/use-harness-platform/connectors/cloud-providers/add-aws-connector.md) to configure a connector.

#### Supported Steps <a href="#supported-steps" id="supported-steps"></a>

When using Amazon ECS infrastructure, only the following steps are supported:

**SBOM Steps:**

* SBOM Orchestration
* SBOM Policy Enforcement
* SLSA Verification

**AWS CDK Steps:**

* AWS CDK Bootstrap
* AWS CDK Deploy
* AWS CDK Rollback
* AWS CDK Destroy

**Serverless AWS Lambda Steps:**

* Serverless AWS Lambda Prepare
* Serverless AWS Lambda Package
* Serverless AWS Lambda Deploy V2
* Serverless AWS Lambda Rollback

**Download Steps:**

* Download AWS S3
* Download Harness Store

**Source Control Steps:**

* Git Clone

***

### Kubernetes Infrastructure <a href="#kubernetes-infrastructure" id="kubernetes-infrastructure"></a>

{% hint style="info" %}
**ECS FARGATE DELEGATE SUPPORT**

Kubernetes infrastructure for containerized step groups supports ECS Fargate-based delegates. You can use delegates running on AWS ECS Fargate to orchestrate containerized step execution on your Kubernetes cluster. In most configurations, this removes the need for Kubernetes-based delegates when your delegate infrastructure is on ECS.

To use ECS Fargate delegates with Kubernetes containerized step groups, contact [Harness Support](mailto:support@harness.io) to enable the following feature flags:

**Required for all ECS Fargate delegate configurations:**

* **`CDS_INIT_CONTAINER_V2_ASYNC_STEP`:** Uses `AsyncExecutable` for the `InitContainerV2` step, allowing it to submit a delegate task and return a callback ID for asynchronous execution without blocking pipeline progress.
* **`CDS_CONTAINER_STEP_DELEGATE_SELECTOR_PRECEDENCE`:** Ensures delegate selectors follow proper precedence rules when routing containerized step tasks to prevent conflicts when using a mix of Delegate 1.0 and Delegate 3.x.

**Required for Kubernetes infrastructure with Delegate 3.x:**

* **`CDS_CONTAINER_STEP_USE_SINGLE_STEP_TASK`:** Enables single task-based execution for Kubernetes containerized step groups on Delegate 3.x, streamlining the task execution flow.
* **`CDS_CONTAINER_STEP_GROUP_STEPS_USE_RUNNER`:** Switches to runner-based execution for CD container step group steps, allowing containerized steps to leverage the new runner architecture.
* **`PL_RUNNER_K8S_INFRA_USE_SCHEDULED_TASK_API`:** Routes containerized step execution to the new Runner Scheduled Task API for Kubernetes infrastructure.

Go to [Install a delegate on Amazon ECS or AWS Fargate](/harness-ai/use-harness-platform/delegates/delegate-3x-closed-beta/install-a-delegate/install-delegate-ecs-fargate.md) to set up an ECS Fargate delegate.
{% endhint %}

When you select **Kubernetes** as your infrastructure type, configure the following settings:

#### Kubernetes Cluster <a href="#kubernetes-cluster" id="kubernetes-cluster"></a>

Select or add a Harness Kubernetes Cluster connector to connect to the cluster where the containers will run.

#### Namespace <a href="#namespace" id="namespace"></a>

Enter an existing namespace in the cluster.

#### Shared Paths <a href="#shared-paths" id="shared-paths"></a>

This setting is the same as Kubernetes `mountPath`. The `name` for the `volumeMounts` is added internally.

Enter shared directories or specific paths within the filesystem to have them shared between containers running within the same pod.

#### Volumes <a href="#volumes" id="volumes"></a>

This setting maps directly to Kubernetes volumes. Harness supports the following volume types:

* Host Path (`hostPath`)
* Empty Directory (`emptyDir`)
* Persistent Volume Claim (`persistentVolumeClaim`)
* ConfigMaps (`configMap`)
* Kubernetes Secrets (`secret`)

**Config Maps and Secrets as Volumes**

**Mounting a ConfigMap as a Volume**

To mount a Kubernetes ConfigMap as a volume in a pod:

1. Under **Volumes**, click **Add**.
2. Set the following values:

* **Mount Path**: Path inside the container where the ConfigMap should be mounted.
* **Type**: Select **Config Map** from the dropdown.
* **Config Map Name**: Enter the name of the Kubernetes ConfigMap.
* **Optional**: Check this box to make the ConfigMap optional (i.e., not cause failure if missing).

Once configured, the specified ConfigMap will be mounted at the defined path in the pod.

<details>

<summary>Sample YAML for adding Config Maps in Volume</summary>

```yaml
volumes:
  - mountPath: /dir
    type: ConfigMap
    spec:
      name: test_config
      optional: false
```

</details>

For more information, refer to the [Kubernetes documentation on mounting ConfigMaps as volumes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#add-configmap-data-to-a-volume)

**Mounting a Kubernetes Secret as a Volume**

To mount a Kubernetes Secret:

1. Under **Volumes**, click **Add**.
2. Set the following values:

* **Mount Path**: Path inside the container where the secret should be mounted.
* **Type**: Select **Secret** from the dropdown.
* **Secret Name**: Enter the name of the Kubernetes Secret.
* **Optional**: Check this box to make the Secret optional.

Note: These are Kubernetes-native secrets, not Harness secrets. Therefore, masking or redacting of secret values is not handled by Harness in this case.

For more information, refer to the [Kubernetes documentation on mounting Secrets as volumes](https://kubernetes.io/docs/concepts/configuration/secret/)

<details>

<summary>Sample YAML for Secret Volume</summary>

```yaml
volumes:
  - mountPath: /dir/test
    type: Secret
    spec:
      name: test
      optional: false
```

</details>

<figure><img src="/files/D3hI0AoOfMc98cSBGgHM" alt=""><figcaption><p>Click to view full size image</p></figcaption></figure>

**Additional Notes:** You can only mount one volume per mount path.

#### Service Account Name <a href="#service-account-name" id="service-account-name"></a>

Specify a Kubernetes service account for step containers to use when communicating with the Kubernetes API server. Leave blank to use the namespace's default service account.

#### Automount Service Account Token <a href="#automount-service-account-token" id="automount-service-account-token"></a>

An application running inside a pod can access the Kubernetes API using automatically mounted service account credentials. See [Accessing the Cluster](https://kubernetes.io/docs/tasks/access-application-cluster/access-cluster/) to learn more.

To use a different service account, enter its name here.

#### Labels <a href="#labels" id="labels"></a>

Enter any labels to apply to the pods.

#### Annotations <a href="#annotations" id="annotations"></a>

Enter any annotations to apply to the pods.

#### Privileged <a href="#privileged" id="privileged"></a>

The standard `privileged` property for Kubernetes `securityContext`.

When this setting is enabled, it grants the container elevated privileges within the underlying host environment. This means that the container has access to all Linux kernel capabilities and devices, similar to running processes outside the container. It effectively removes the isolation provided by the container runtime and can potentially pose security risks if not used carefully.

#### Allow Privilege Escalation <a href="#allow-privilege-escalation" id="allow-privilege-escalation"></a>

The standard `allowPrivilegeEscalation` property for Kubernetes `securityContext`.

When this setting in enabled, it allows the container to gain additional privileges beyond those initially granted during container startup.

#### Add Capabilities <a href="#add-capabilities" id="add-capabilities"></a>

The standard `add` setting for the `capabilities` property in the Kubernetes `securityContext`.

Simply add the name of the capability, like `NET_ADMIN`.

#### Drop Capabilities <a href="#drop-capabilities" id="drop-capabilities"></a>

The standard `drop` setting for the `capabilities` property in the Kubernetes `securityContext`.

Simply add the name of the capability, like `CHOWN`.

#### Run as Non Root <a href="#run-as-non-root" id="run-as-non-root"></a>

Enable this setting to run the container as a non-root user.

#### Read-only Root Filesystem <a href="#read-only-root-filesystem" id="read-only-root-filesystem"></a>

The standard `readOnlyRootFilesystem` setting for the `securityContext` property.

Enable this setting to ensure that the root filesystem of the container is mounted as read-only.

#### Run as User <a href="#run-as-user" id="run-as-user"></a>

The standard `runAsUser` setting for the `securityContext` property.

Specify the user ID (UID) under which the container should run.

#### Priority Class <a href="#priority-class" id="priority-class"></a>

The standard Kubernetes `PriorityClass`.

Enter a standard `priorityClassName` like `system-node-critical`.

#### Node Selector <a href="#node-selector" id="node-selector"></a>

The standard Kubernetes `nodeSelector`.

Enter a key like `disktype` and value like `ssd`.

#### Tolerations <a href="#tolerations" id="tolerations"></a>

The standard Kubernetes `tolerations`. Use the settings to specify that a pod can tolerate (or ignore) the effects of node taints.

#### Init Timeout <a href="#init-timeout" id="init-timeout"></a>

The standard Kubernetes `timeoutSeconds` for `initContainers`.

#### Override Image Connector <a href="#override-image-connector" id="override-image-connector"></a>

By default, at pipeline runtime, Harness pulls certain images from public Docker Hub repos. These images are only used for backend processes. At runtime, the Harness Delegate makes an outbound connection to the public repo and pulls the images.

The Harness Container Image Registry is dedicated exclusively to Harness-supported images.

You might want to override the default behavior and download your build images from this repo instead. To view the list of images in this registry, enter the following command.

```
curl -X  GET https://app.harness.io/registry/_catalog
```

Add or select a connector to use instead of the default connector used for the Harness Container Image Registry.

For more information, go to [Connect to the Harness container image registry](/harness-ai/use-harness-platform/connectors/artifact-repositories/connect-to-harness-container-image-registry-using-docker-connector.md).

#### Advanced settings <a href="#advanced-settings" id="advanced-settings"></a>

In **Advanced**, you can use the following options:

* [Delegate Selector](/harness-ai/use-harness-platform/delegates/delegate/manage-delegates/select-delegates-with-selectors.md)
* [Conditional Execution](/harness-ai/use-harness-platform/pipelines/step-skip-condition-settings.md)
* [Failure Strategy](/harness-ai/use-harness-platform/pipelines/failure-handling/define-a-failure-strategy-on-stages-and-steps.md)
* [Looping Strategy](/harness-ai/use-harness-platform/pipelines/looping-strategies/looping-strategies-matrix-repeat-and-parallelism.md)

### Containerized step group example <a href="#containerized-step-group-example" id="containerized-step-group-example"></a>

When you run a pipeline that uses a containerized step group, you can see the container set up in the automatically generated **Initialize** step in the pipeline execution.

Select **Initialize** to see its log and how the container is set up.

<details>

<summary>Step group setup log</summary>

In the following log, the containerized step group is created and a Background step using Docker in Docker (DinD) is also set up. The Background step is only required for certain subsequent step types that need DinD. It is provided here as an example only.

```
Successfully assigned harness-delegate-ng/harnesscd-asdasd-89xlhk71 to gke-qa-target-ng-pool-1-b4499db2-2431
Pulling image "harness/ci-addon:1.16.8"
Successfully pulled image "harness/ci-addon:1.16.8" in 437.806182ms (437.815597ms including waiting)
Created container setup-addon
Started container setup-addon
Container image "harness/drone-git:1.3.4-rootless" already present on machine
Created container step-harness-git-clonem1
Started container step-harness-git-clonem1
Container image "harness/drone-git:1.3.4-rootless" already present on machine
Created container step-harness-git-clonem2
Started container step-harness-git-clonem2
Pulling image "harnessdev/sam-deploy:1.82.0-latest"
Successfully pulled image "harnessdev/sam-deploy:1.82.0-latest" in 429.518494ms (429.527506ms including waiting)
Created container step-samdeploy
Started container step-samdeploy
Pulling image "harnessdev/sam-build:1.82.0-latest"
Successfully pulled image "harnessdev/sam-build:1.82.0-latest" in 380.845932ms (380.855397ms including waiting)
Created container step-sambuild
Started container step-sambuild
Container image "docker:dind" already present on machine
Created container step-dind
Started container step-dind
Pulling image "harness/ci-lite-engine:1.16.8"
Successfully pulled image "harness/ci-lite-engine:1.16.8" in 355.654902ms (355.690135ms including waiting)
Created container lite-engine
Started container lite-engine
```

</details>

### Harness Docker connector for all group steps <a href="#harness-docker-connector-for-all-group-steps" id="harness-docker-connector-for-all-group-steps"></a>

In each step in a containerized step group, you must provide a [Harness connector](/harness-ai/use-harness-platform/connectors.md) to a Docker container registry and an image for the container step to run.

You can create connectors in-line while adding steps or separately outside of the pipeline creation process. Images are specified at the step level.

<details>

<summary>Add a Docker registry connector</summary>

Harness offers several types of Docker-compliant cloud provider and artifact repository connectors, and there are several ways you can create connectors. These steps demonstrate several ways you can create a [Docker connector](/harness-ai/use-harness-platform/connectors/cloud-providers/ref-cloud-providers/docker-registry-connector-settings-reference.md).

In the Harness Platform, you can use the connector creation wizard to create connectors.In Harness, go to Account Settings, Organization Settings, or Project Settings, depending on the scope at which you want to create the connector.Select Connectors, select New Connector, and then select the Docker Registry connector.Enter a Name and select Continue.Configure the Details settings as follows, and then select Continue:Provider Type: Select DockerHub.Docker Registry URL: Enter <https://docker.dev.harness.io/v2/.Authentication>: For the quickest setup, select Anonymous.Connect using a Harness Delegate, and select Continue.Select any delegate or select/create a specific delegate, and then select Save and Continue.When the connection test is complete, select Finish.You can create connectors in Harness YAML, for example:connector: name: Docker Hub with Pwd identifier: Docker\_Hub\_with\_Pwd description: "" orgIdentifier: default projectIdentifier: CD\_Docs type: DockerRegistry spec: dockerRegistryUrl: <https://docker.dev.harness.io/v2/> providerType: DockerHub auth: type: Anonymous executeOnDelegate: trueYou can create a Docker connector using the Create a Connector endpoint, for example:curl --location --request POST '<https://app.harness.io/gateway/ng/api/connectors?accountIdentifier=123456>' \\--header 'Content-Type: text/yaml' \\--header 'x-api-key: PERSONAL\_ACCESS\_TOKEN' \\--data-raw 'connector: name: dockerhub identifier: dockerhub description: "" tags: {} orgIdentifier: default projectIdentifier: APISample type: DockerRegistry spec: dockerRegistryUrl: <https://docker.dev.harness.io/v2/> providerType: DockerHub auth: type: Anonymous'For the Terraform Provider Docker connector resource, go to the Terraform documentation for the harness\_platform\_connector\_docker.Here's an example of Terraform provider Docker connector JSON:# credentials anonymous \<a href="#credentials-anonymous" id="credentials-anonymous">\</a>resource "harness\_platform\_connector\_docker" "test" { identifier = "identifier" name = "name" description = "test" tags = \["foo:bar"] type = "DockerHub" url = "<https://docker.dev.harness.io/v2/>" delegate\_selectors = \["harness-delegate"]}

{% hint style="info" %}

* When pulling images from Docker repos, Harness is restricted by Docker repo limits, such as [Docker Hub limits](https://docs.docker.com/docker-hub/download-rate-limit/).
* The maximum number of artifact image tags fetched by Harness is 10000.
  {% endhint %}

</details>

When configuring pipelines, you'll most often select a Docker connector when you need to pull images into individual steps. For example, if a Shell Script step needs to run curl commands, you might pull an image containing the curl binary.

Behind the scenes, Harness also uses a Docker connector to pull the required Harness images that support pipeline execution. Harness can pull the images from the public Harness container registry (using the default, built-in Harness Image connector) or you can configure your pipelines to use your own Docker connector to pull with authentication credentials or pull from a private container registry where you have cloned the Harness images. For more information, go to [Connect to the Harness container image registry](/harness-ai/use-harness-platform/connectors/artifact-repositories/connect-to-harness-container-image-registry-using-docker-connector.md).

### DinD Background step <a href="#dind-background-step" id="dind-background-step"></a>

Some steps in a containerized step group might require Docker in Docker (DinD). For example, some deployment types might use DinD because of the requirements of their platforms.

{% hint style="info" %}
There is no DinD requirement for containerized step groups. Unless a step requires DinD, Harness needs only a Kubernetes cluster to run the containerized step.

If a Harness deployment type requires DinD, the Background step is added automatically as part of the stage Execution setup.

Whether the dind step is added automatically or manually, you must configure it.
{% endhint %}

If step(s) in a containerized step group require DinD, you can add a **Background** step that performs the Docker in Docker (DinD) setup.

![Background step](/files/dJP779EJNHsRHaILJ9Gd)

The Background step creates the DinD environment. In this environment, each subsequent step group step is run inside the Kubernetes pod as containers.

#### Container Registry <a href="#container-registry" id="container-registry"></a>

**Container Registry** is the Harness container registry connector that connects to the container registry hosting the image to use for this step.

#### Image <a href="#image" id="image"></a>

This is the container image to use for the background service.

Simply enter `docker:dind`.

#### Entry Point <a href="#entry-point" id="entry-point"></a>

Supply a list of arguments in `exec` format. Enter each argument separately.

{% tabs %}
{% tab title="Visual" %}

<figure><img src="/files/z0Ea2OgT5SNPqYdeTaDE" alt="Entry Point commands"><figcaption><p>Entry Point arguments in the Pipeline Studio Visual editor.</p></figcaption></figure>
{% endtab %}

{% tab title="YAML" %}

```yaml
entrypoint:
  - dockerd-entrypoint.sh
  - "--mtu=1450"
```

{% endtab %}
{% endtabs %}

**Entry Point** arguments override the image `ENTRYPOINT` and any commands in the **Command** field.

#### Shell and Command <a href="#shell-and-command" id="shell-and-command"></a>

For **Shell**, select the shell script type for the arguments and commands defined in **Entry Point** and **Command**.

In **Command**, enter POSIX shell script commands to execute inside the container.

For example, a command that checks the Java version installed on the system and verifies if it is equal to 17.

```
JAVA_VER=$(java -version 2>&1 | head -1 | cut -d'"' -f2 | sed '/^1\./s///' | cut -d'.' -f1)
if [[ $JAVA_VER == 17 ]]; then
  echo successfully installed $JAVA_VER
else
  exit 1
fi
```

Notes:

* You can use `docker-compose up` to start multiple services in one Background step.
* You can run PowerShell commands on Windows VMs running in AWS build farms.
* You can run PowerShell Core commands in pods or containers that have pwsh installed.

#### Privileged <a href="#privileged" id="privileged"></a>

Enable this option to run the container with escalated privileges. This is equivalent to running a container with the Docker `--privileged` flag.

#### Report Paths <a href="#report-paths" id="report-paths"></a>

Specify the file paths or directories within the container where various reports or log files generated by applications or processes running inside the container are stored.

#### Environment Variables <a href="#environment-variables" id="environment-variables"></a>

You can inject environment variables into a container and use them in the **Command** script. You must input a **Name** and **Value** for each variable.

You can reference environment variables in the **Command** script by their name. For example, a Bash script would use `$var_name` or `${var_name}`, and a Windows PowerShell script would use `$Env:varName`.

#### Image Pull Policy <a href="#image-pull-policy" id="image-pull-policy"></a>

Select an option to set the pull policy for the image.

* **Always:** The kubelet queries the container image registry to resolve the name to an image digest every time the kubelet launches a container. If the kubelet encounters an exact digest cached locally, it uses its cached image; otherwise, the kubelet downloads (pulls) the image with the resolved digest, and uses that image to launch the container.
* **If Not Present:** The image is pulled only if it is not already present locally.
* **Never:** The image is assumed to exist locally. No attempt is made to pull the image.

#### Set Container Resources <a href="#set-container-resources" id="set-container-resources"></a>

Maximum resource limits for containers that clone the codebase at runtime. For more information, go to [Resource units in Kubernetes](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#resource-units-in-kubernetes).

#### DinD Background step example <a href="#dind-background-step-example" id="dind-background-step-example"></a>

When you run a pipeline that uses a containerized step group and Background step, you can see the DinD set up in the step log in the pipeline execution.

Select the step to see its log and how the DinD is set up. The general sequence is:

1. The log shows certificate requests being self-signed for the Docker in Docker (DinD) server and client.
2. The DinD environment is starting up.
3. It indicates that containerd is not running and starts the managed containerd process.
4. Containerd starts with information about the revision and version.
5. Various plugins are loaded, such as snapshotter, content, metadata, differ, event, GC scheduler, lease manager, NRI (disabled), runtime, sandbox, streaming, and services.
6. The log ends without further actions or errors.

### Using AWS SAM and Serverless.com Harness Connectors with containerized step groups <a href="#using-aws-sam-and-serverlesscom-harness-connectors-with-containerized-step-groups" id="using-aws-sam-and-serverlesscom-harness-connectors-with-containerized-step-groups"></a>

For AWS SAM and Serverless deployments with CD containerized steps, users were not able to deploy with a Harness connector using ISRA and IAM roles for the authentication performed by the Harness Delegate.

The primary issue stemmed from the fact that the service account specified in the step group configuration was not being utilized by the step images during deployment.

To address this issue, we've made the following enhancements.

* **Additional Credential Parameters:** In addition to passing the Access Key and Secret Key, Harness now transmits the Cross Account Role ARN and an optional External Id. These credentials are utilized by the step images to assume the necessary roles for deployment.
* **Service Account Integration:** Harness has introduced the functionality to use the Service Account specified in the step group configuration.

The following environment variables have been configured in the images:

1. Specified in the Connector - `PLUGIN_AWS_ROLE_ARN` (Cross account role) - `PLUGIN_AWS_STS_EXTERNAL_ID` - `PLUGIN_AWS_ACCESS_KEY` - `PLUGIN_AWS_SECRET_KEY`
2. `PLUGIN_REGION` (region provided in the infrastructure configuration)

To leverage the Harness Connector for AWS SAM and Serverless.com container steps, follow these steps:

#### Connector configuration <a href="#connector-configuration" id="connector-configuration"></a>

In your Connector configuration, configure the Cross Account Role and an optional External Id.

![Connector Configuration](/files/IKJzzjxDErHsk5moYjP8)

![Connector Configuration](/files/xOsHDVDZ65MORz53izXK)

The Connection test is used to verify delegate connectivity to the AWS account.

![Connector Connection Test](/files/els4oiIUopOa1jIK598N)

#### Service Account configuration <a href="#service-account-configuration" id="service-account-configuration"></a>

For the pods to connect to the AWS account, you will have to configure the service account in the step group level settings:

![Step Group Configuration](/files/Agtx9ZDYdgFqZ8TvJXwK)

If the Access Key and Secret Key environment variables are set, then the image uses these keys for deployment. However, if the Access Key and Secret Key are not configured, the image will assume the role of service account configured for deployment.

Harness will pass the cross account role in the image. If you do not want to use that in the image, you can set it to empty:

![Blank Cross Account role](/files/CNURut5DCTyIQedOLpuw)
