For the complete documentation index, see llms.txt. This page is also available as Markdown.

Shell Script Provisioning

Provision a target environment or resources with your existing shell scripts in Harness CD.

Harness supports infrastructure provisioning through Shell Scripts, making it easy to work with existing shell-based workflows or custom provisioners. For Infrastructure as Code (IaC) use cases, Harness also supports Terraform, Terragrunt, AWS CloudFormation, Azure ARM, and Azure Blueprints.

Use Shell Script provisioning to run inline or remote Bash scripts that provision target environments or resources, either on demand (ad hoc) or as part of the deployment that consumes them (dynamic).

For details on Harness provisioning, go to Provisioning overview.


What you will learn from this topic


Before you begin

Ensure you have the following:

  • Role permissions: You need View/Create, Edit, Access, and Delete on Environments. Go to RBAC in Harness to configure roles and permissions.

  • Target environment access: Ensure the credentials your provisioner script uses (for example, a cloud provider connector or service account) have the permissions needed to provision resources in the target environment.

  • Secrets: Store any secret text or files your script uses in a secret manager. Go to Harness secrets management overview to get started, then add text secrets or add file secrets.


Provisioning modes

Harness Shell Script provisioning supports two provisioning modes. The two modes differ in where you add the Shell Script Provision step and how Harness uses its outputs.

Ad hoc provisioning

Ad hoc provisioning creates temporary, pipeline-scoped resources that are not part of the deployment target. You add the Shell Script Provision step to the stage Execution section, so it runs during pipeline execution. Outputs from the step can be used by later pipeline steps, but they are not mapped to the Infrastructure Definition.

The following diagram shows how ad hoc provisioning runs in the pipeline:

The example use cases include:

  • Creating a temporary AWS EC2 instance for testing.

  • Creating a temporary Kubernetes namespace.

  • Provisioning resources for a one-time validation or experiment.

If your script writes outputs to $PROVISIONER_OUTPUT_PATH, reference them in later pipeline steps with the fully qualified step-output path. For example, for a step named Ad_Hoc_Provision in a stage named Deploy, reference the server output as <+pipeline.stages.Deploy.spec.execution.steps.Ad_Hoc_Provision.output.server>. The <+provisioner.KEY> shorthand resolves only inside the Infrastructure Definition mapping, which ad hoc provisioning does not use.

To configure ad hoc provisioning, go to Configure ad hoc provisioning.

Dynamic infrastructure provisioning

Dynamic infrastructure provisioning is the recommended provisioning mode for deployments. You add the Shell Script Provision step to the stage Environment section. The step writes provisioning outputs that you map to the Infrastructure Definition. Harness uses these outputs to resolve the deployment infrastructure before the deployment runs.

The following diagram shows how dynamic provisioning runs in the pipeline:

Your script provisions the infrastructure (for example, by calling Terraform or a cloud CLI) and writes the resulting values to $PROVISIONER_OUTPUT_PATH. Harness uses those values to resolve the Infrastructure Definition before deployment starts.

For example, your script can:

  • Create an AWS EC2 instance.

  • Create a Kubernetes cluster or namespace.

  • Provision Azure resources.

  • Run Terraform to create infrastructure.

Use dynamic provisioning whenever your pipeline needs to provision the deployment target. Common use cases include temporary development, test, and QA environments. Production environments are typically pre-existing.

To configure dynamic provisioning, go to Configure dynamic provisioning.


Create a Shell Script Provision step

The Shell Script Provision step runs an inline or remote Bash script to provision your target environment or resources.

Perform the following steps to add a Shell Script Provision step:

  1. In your pipeline, open the section where you want to provision:

    • For ad hoc provisioning, open the Execution section of a Continuous Delivery (CD) Deploy stage or a Custom stage.

    • For dynamic provisioning, open the Environment section and enable dynamic provisioning. Go to Configure dynamic provisioning to set this up.

  2. Select Add Step, then select Shell Script Provision.

  3. In Name, enter a name for the step.

  4. In Script, set the script source:

    • Inline: enter your Bash script directly in the step.

    • File Store: select a script stored in the Harness File Store.

  5. (Optional) To parameterize your script, expand Optional Configuration and add Script Input Variables. Go to Script input variables to configure them.

  6. If your script produces outputs, write them to $PROVISIONER_OUTPUT_PATH. Go to Provisioner output path variable to reference the output in later steps.

  7. In Timeout, set the maximum run time, then select Apply Changes.

YAML example: Shell Script Provision step

Script input variables

Use Script Input Variables to pass values into your shell script without hardcoding them. This makes your script reusable and allows you to pass Harness expressions or other values into the script.

Perform the following steps to add an input variable:

  1. Expand Optional Configuration.

  2. Under Script Input Variables, enter a Name and Value.

  3. Reference the variable in your script using $<name>.

If the value comes from a Harness expression, select Expression for Value and paste the expression.

In the Script, you declare the variable using the Name from Script Input Variables (in this example, foo).


Configure ad hoc provisioning

Perform the following steps to configure ad hoc provisioning:

  1. Open a CD Deploy stage or a Custom stage.

  2. In the Execution section, select Add Step, then select Shell Script Provision.

  3. Configure the step with your provisioning script. Go to Create a Shell Script Provision step to set the script and input variables.

  4. If your script produces outputs, write them to $PROVISIONER_OUTPUT_PATH and reference them in later steps. Go to Provisioner output path variable to reference the output.

For ad hoc provisioning, $PROVISIONER_OUTPUT_PATH is optional. Use it only when you need to expose script outputs to later steps.

YAML example: ad hoc provisioning stage (placed in Execution)
YAML example: complete ad hoc provisioning pipeline

Configure dynamic provisioning

Add a Shell Script Provision step to the Environment section of a CD Deploy stage and map the script outputs to the Infrastructure Definition.

Before deployment starts, Harness runs the provisioning script, uses its outputs to resolve the Infrastructure Definition, and then deploys to the provisioned target.

The Infrastructure Definition is still required because Harness uses it to identify the deployment target. Your script provisions the infrastructure (for example, by calling Terraform or a cloud CLI) and writes the resulting values to $PROVISIONER_OUTPUT_PATH.

Perform the following steps to configure dynamic provisioning:

  1. In the CD Deploy stage, open the Environment section and enable the Provision your target infrastructure dynamically during the execution of your Pipeline option.

  2. In What type of provisioner do you want to use?, select Script.

    The Shell Script Provision step is added.

  3. Configure the Shell Script Provision step with your provisioning script. Go to Create a Shell Script Provision step to set the script and input variables.

  4. Map the outputs from your script to the Infrastructure Definition. Harness recommends dynamic mapping, where the Infrastructure Definition is resolved from the provisioner outputs at runtime.

    Set the required Infrastructure Definition fields to runtime inputs (<+input>), then map each field to the corresponding <+provisioner.KEY> expression. For example, if your script outputs {"namespace":"prod"}, set the Namespace field to <+input> and provide <+provisioner.namespace> at runtime.

    Go to Map script outputs for the settings each deployment type requires, and Dynamic provisioning by deployment type for the per-platform setup steps.

  • If your Infrastructure Definition already contains the required values, you don't need to map provisioner outputs. Your script must still write valid JSON (for example, {}) to $PROVISIONER_OUTPUT_PATH.

YAML example: complete dynamic provisioning pipeline (Kubernetes)

This is a complete Kubernetes pipeline. It runs a Shell Script Provision step in the Environment section, then populates the Infrastructure Definition fields from the provisioner outputs with <+provisioner.KEY> expressions. In later execution steps, reference the outputs with the fully qualified step-output path. For the provisioner step below (identifier ProvisionInfra) in the stage with identifier ShellScriptDeployDynamic, the namespace output is <+pipeline.stages.ShellScriptDeployDynamic.spec.provisioner.steps.ProvisionInfra.output.namespace>.

Map script outputs

Once you have added dynamic provisioning to the Environment section of the stage, you must map specific script outputs to the required Harness Infrastructure Definition used by the stage.

Each deployment type maps different script outputs to its Infrastructure Definition settings. The following table shows the settings to map for each infrastructure type:

Infra type

Infra settings that require mapping

Kubernetes Direct

Namespace, Release Name (optional)

Kubernetes GCP

Namespace, Cluster, Release Name (optional)

Kubernetes Azure

Namespace, Cluster

Kubernetes AWS

Namespace, Cluster, Release Name (optional)

Physical Data Center

Host Array Path, Host Attributes

SSH and WinRM on AWS

Region, Tags

SSH and WinRM on Azure

Subscription Id, Resource Group, Tags

Azure Web App

Subscription, Resource Group

Google Cloud Functions

Region, Project

AWS Lambda

Region

AWS ECS

Region, Cluster

Tanzu Application Services

Organization, Space

Serverless.com AWS Lambda

Region, Stage

For the setup steps for your deployment type, go to Dynamic provisioning by deployment type.

Dynamic provisioning by deployment type

Each deployment type maps different script outputs to the Harness infrastructure settings in the pipeline stage.

For some deployment types, the full pipeline YAML is given here for your reference. You can set up the other deployment types the same way, using these examples as a reference.

In each example, replace the project, organization, service, environment, and infrastructure identifiers with your own.

Pipeline YAML - Azure Web App

The execution step in this example is an on-delegate ShellScript step that prints the dynamically provisioned outputs. It stands in for a real AzureSlotDeployment step so you can verify provisioning end to end without a live Azure Web App. Replace it with your actual AzureSlotDeployment step when you deploy to a real web app.

Reference provisioner outputs outside the Infrastructure Definition with the fully qualified path. In this example, the subscriptionId output is <+pipeline.stages.AzureWebAppDeploy.spec.provisioner.steps.shellprovision.output.subscriptionId>. The <+provisioner.KEY> shorthand resolves only inside the Infrastructure Definition mapping.

Pipeline YAML - AWS SAM
Pipeline YAML - AWS ECS
Pipeline YAML - AWS Lambda
Pipeline YAML - Native Helm

Reference provisioner outputs outside the Infrastructure Definition with the fully qualified path. In this example, the namespace output is <+pipeline.stages.HelmDeploy.spec.provisioner.steps.K8s_Shell_Provisioner.output.namespace>. The <+provisioner.KEY> shorthand resolves only inside the Infrastructure Definition mapping.

Pipeline YAML - Google Cloud Functions
Pipeline YAML - Serverless.com framework for AWS Lambda
Pipeline YAML - Tanzu Application Services

Reference provisioner outputs outside the Infrastructure Definition with the fully qualified path. In this example, the organization output is <+pipeline.stages.s1.spec.provisioner.steps.TAS_Infrastructure_Provisioner.output.organization>. The <+provisioner.KEY> shorthand resolves only inside the Infrastructure Definition mapping.

Pipeline YAML - SSH on AWS

The execution step in this example is an on-delegate ShellScript step that prints the dynamically provisioned outputs and the resolved hosts. It stands in for a real SSH Command step so you can verify provisioning end to end without reachable target VMs. Replace it with your actual SSH Command deploy step when you target live instances.

Reference provisioner outputs outside the Infrastructure Definition with the fully qualified path. In this example, the region output is <+pipeline.stages.SSHDeploy.spec.provisioner.steps.ShellScriptProvision_1.output.region>. The <+provisioner.KEY> shorthand resolves only inside the Infrastructure Definition mapping.

Pipeline YAML - WinRM on AWS

Provisioner output path variable

Harness automatically injects the $PROVISIONER_OUTPUT_PATH environment variable into every Shell Script Provision step. Use this variable to write your script's JSON output so it can be referenced in later pipeline steps. It is available only in the Shell Script Provision step, not in a regular Shell Script step.

For example, this script writes a JSON object to $PROVISIONER_OUTPUT_PATH:

Harness captures this JSON automatically. Later pipeline steps reference individual fields with the fully qualified step-output path. For an ad hoc step in the Execution section, the path is <+pipeline.stages.<STAGE_ID>.spec.execution.steps.<STEP_ID>.output.server>, where <STAGE_ID> and <STEP_ID> are the identifiers of your stage and Shell Script Provision step. For a dynamic step in the Environment section, the path is <+pipeline.stages.<STAGE_ID>.spec.provisioner.steps.<STEP_ID>.output.server>. The <+provisioner.KEY> shorthand resolves only inside the Infrastructure Definition mapping.

View provisioner outputs

After a Shell Script Provision step runs, Harness captures the JSON written to $PROVISIONER_OUTPUT_PATH and makes the outputs available in the pipeline.

When the step starts, the log includes a message similar to the following:

The path shown in the log is an example. Do not rely on a specific file location. Always write your JSON output to $PROVISIONER_OUTPUT_PATH.

After the step completes, select the Output tab to view the values Harness captured from the JSON written to $PROVISIONER_OUTPUT_PATH.

To reference an output in a later pipeline step, copy its Output Name from the Output tab. For example:


Rollback support

Shell Script provisioning does not provide built-in rollback like the Terraform or AWS CloudFormation provisioners.


Next steps

You have learned how Shell Script provisioning works and how to map its outputs to the Infrastructure Definition. Continue with the following:

Last updated

Was this helpful?