> 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/provision-infrastructure/terraform-infra/rollback-provisioned-infra-with-the-terraform-rollback-step.md).

# Rollback Infrastructure with the Terraform Rollback step

Configure the Terraform Rollback step to revert infrastructure to the previous successful state.

The Terraform Rollback step rolls back your provisioned infrastructure to the previous successful state when a deployment fails. It uses the Terraform state from the last successful deployment to revert infrastructure changes.

This topic explains how to configure the Terraform Rollback step in your deployment pipeline.

***

## What you will learn from this topic

* How to configure the [Terraform Rollback step](#configure-the-terraform-rollback-step) to handle failed deployments.
* How to use [Provisioner Identifiers](#provisioner-identifier) to link Rollback steps to infrastructure provisioned by Apply steps.
* How [Terraform rollback works](#how-terraform-rollback-works) and when it can be performed.
* What [rollback limitations](#rollback-limitations) exist based on Terraform state.

***

## Before you begin

* **Harness project access**: View, Create/Edit, and Execute permissions on Pipelines and Environments. For more information, refer to [RBAC in Harness](https://developer.harness.io/docs/platform/role-based-access-control/rbac-in-harness) to configure roles.
* **Terraform or OpenTofu installed on delegate**: Terraform or OpenTofu must be installed on the delegate to execute Terraform commands. For more information, refer to [Build custom delegate images with third-party tools](https://developer.harness.io/docs/platform/delegates/install-delegates/build-custom-delegate-images-with-third-party-tools) to install Terraform.
* **Provisioner Identifier**: You need the Provisioner Identifier from the Terraform Apply step that provisioned the infrastructure you want to roll back. For more information, refer to [Terraform Apply step](/continuous-delivery/use-continuous-delivery/provision-infrastructure/terraform-infra/run-a-terraform-plan-with-the-terraform-apply-step.md).
* **Previous successful state**: Rollback requires at least one successful Terraform Apply execution to have a previous state to revert to.
* **Understanding of Terraform concepts**: This guide assumes familiarity with Terraform workspaces, backends, modules, and state files. For more information, refer to [Terraform documentation](https://developer.hashicorp.com/terraform/docs).

***

## How Terraform rollback works

When rollback is performed, Harness rolls back the provisioned infrastructure to the previous successful version of the Terraform state using the Terraform configuration from the latest successful deployment with a matching **Provisioner Identifier**.

Harness performs a hard rollback to the exact version of the state from the previous successful deployment. It does not increment the serial number in the Terraform state file.

Harness determines what to rollback using the **Provisioner Identifier**. The Provisioner Identifier is a unique label that links Terraform Plan, Apply, and Rollback steps to the same configuration.

### Rollback limitations

**Module deployment scenario:**

If you deployed two modules successfully (module1 and module2), then tried to deploy module3 but it failed, Harness will roll back to the successful state of module1 and module2.

However, if module3 succeeds and you now have module1, module2, and module3 deployed, and the next deployment fails, the rollback will only roll back to the Terraform state with module3 deployed. Module1 and module2 were not in the previous Terraform state, so the rollback excludes them.

**State storage requirement:**

Rollback is not possible if you run the Terraform Apply step with the **Skip state storage** option enabled and no Terraform backend is configured in your Terraform files. Using the Rollback step in such a scenario is an incorrect setup and might cause an unexpected result.

***

## Configure the Terraform Rollback step

You can add the Terraform Rollback step in the following **Rollback** sections within your **Deploy** stage:

* **Dynamic Provisioning Rollback**: Add it in the **Infrastructure** > **Dynamic Provisioning** > **Rollback** section if you provisioned infrastructure dynamically in the same stage.
* **Execution Rollback**: Add it in the **Execution** > **Rollback** section to roll back infrastructure provisioned in the execution steps.

***

## Basic settings

Configure the following basic settings for the Terraform Rollback step.

### Name

In **Name**, enter a name for the step (for example, **rollback**).

The name is important because you can use it in [expressions](https://developer.harness.io/docs/platform/variables-and-expressions/harness-variables) to refer to settings in this step.

### Timeout

In **Timeout**, enter how long Harness should wait to complete the Terraform Rollback step before failing it.

### Provisioner Identifier

In **Provisioner Identifier**, enter the same Provisioner Identifier you used in the Terraform Plan and Apply steps.

The Provisioner Identifier enables Harness to locate the Terraform state from the previous successful deployment and revert to that state.

{% hint style="warning" %}
**Provisioner Identifier scope**

The Provisioner Identifier is project-wide. You can reference it across pipelines in the same project. Coordinate with your team to ensure identifiers are unique and not reused across pipelines to avoid conflicts.
{% endhint %}

When rollback succeeds, view the execution logs in the pipeline execution details page to confirm the state was reverted.

***

## Command line options

{% hint style="info" %}
**Currently, the command line options feature is behind the feature flag `CDS_TERRAFORM_CLI_OPTIONS_NG`. Contact** [**Harness Support**](mailto:support@harness.io) **to enable the feature.**
{% endhint %}

This setting allows you to set the Terraform CLI options for Terraform commands depending on the Terraform step type.

For example: `-lock=false`, `-lock-timeout=0s`.

### Skip Terraform refresh

The Terraform refresh command will not run when this setting is selected.

***

## Advanced settings

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

* [Delegate Selector](https://developer.harness.io/docs/platform/delegates/manage-delegates/select-delegates-with-selectors)
* [Conditional Execution](https://developer.harness.io/docs/platform/pipelines/step-skip-condition-settings)
* [Failure Strategy](https://developer.harness.io/docs/platform/pipelines/failure-handling/define-a-failure-strategy-on-stages-and-steps)
* [Looping Strategy](https://developer.harness.io/docs/platform/pipelines/looping-strategies/looping-strategies-matrix-repeat-and-parallelism)
* [Policy Enforcement](https://developer.harness.io/docs/platform/governance/policy-as-code/harness-governance-overview)

***

## YAML example

<details>

<summary>Terraform Rollback step YAML</summary>

**In provisioner rollbackSteps (automatic on failure):**

```yaml
provisioner:
  steps:
    - step:
        type: TerraformPlan
        name: Terraform Plan
        identifier: Terraform_Plan
        spec:
          provisionerIdentifier: my_terraform_provisioner
          # ... configuration ...
    
    - step:
        type: TerraformApply
        name: Terraform Apply
        identifier: Terraform_Apply
        spec:
          provisionerIdentifier: my_terraform_provisioner
          configuration:
            type: InheritFromPlan
          delegateSelectors:
            - my-delegate-selector
  
  rollbackSteps:
    - step:
        type: TerraformRollback
        name: Rollback Terraform
        identifier: Terraform_Rollback
        spec:
          provisionerIdentifier: my_terraform_provisioner
          delegateSelectors:
            - my-delegate-selector
        timeout: 10m
```

**In execution rollbackSteps (on deployment failure):**

```yaml
execution:
  steps:
    - step:
        type: K8sRollingDeploy
        name: Rolling Deployment
        identifier: Rolling_Deployment
        # ... deployment configuration ...
  
  rollbackSteps:
    - step:
        type: TerraformRollback
        name: Rollback Infrastructure
        identifier: Rollback_Infrastructure
        spec:
          provisionerIdentifier: my_terraform_provisioner
          delegateSelectors:
            - my-delegate-selector
        timeout: 10m
```

**Key configuration:**

* `provisionerIdentifier`: Must match the identifier used in Terraform Plan/Apply steps - this links the rollback to the correct Terraform state
* **Provisioner rollbackSteps**: Executes if any step in the provisioner section fails (e.g., Terraform Apply fails)
* **Execution rollbackSteps**: Executes if deployment fails after infrastructure provisioning succeeds
* `delegateSelectors`: Use same selector as Plan/Apply for consistency
* Rollback reverts to the last successful Terraform state before the current Apply

</details>

***

## Troubleshooting

<details>

<summary>Terraform rollback fails with state mismatch error</summary>

Verify the Provisioner Identifier matches the Apply step that created the infrastructure. Check that a previous successful Terraform state exists for the rollback to target.

</details>

<details>

<summary>Permission denied when rolling back infrastructure with Terraform Rollback step</summary>

Verify the connector used in the rollback step has permissions to modify the target resources. Check cloud provider IAM roles and policies.

</details>

<details>

<summary>Terraform rollback step cannot find previous successful state</summary>

Check that the Terraform Apply step completed successfully at least once before the rollback. Verify state storage is configured and accessible. Rollback requires a previous successful state to revert to.

</details>

<details>

<summary>Rollback step shows Provisioner Identifier mismatch</summary>

Ensure the Provisioner Identifier in the Rollback step exactly matches the identifier used in the Terraform Plan and Apply steps. Check for typos or case sensitivity issues.

</details>

***

## Next steps

* [Terraform Apply step](/continuous-delivery/use-continuous-delivery/provision-infrastructure/terraform-infra/run-a-terraform-plan-with-the-terraform-apply-step.md): Understand the Apply workflow that rollback reverts.
* [Terraform Destroy step](/continuous-delivery/use-continuous-delivery/provision-infrastructure/terraform-infra/remove-provisioned-infra-with-terraform-destroy.md): Permanently remove provisioned infrastructure.
* [Terraform provisioning overview](/continuous-delivery/use-continuous-delivery/provision-infrastructure/terraform-infra/terraform-provisioning-with-harness.md): Understand the complete provisioning workflow.

{% @harness-feedback/feedback %}
