> 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/infrastructure-as-code-management/platform/iacm-pipelines/operations-overview/drift-detection-operations-overview.md).

# Drift Detection

{% @harness-package-selector/package-selector platforms="%5B%7B%22label%22%3A%22Approval%20Step%22%2C%22slug%22%3A%22approval-step%22%2C%22path%22%3A%22infrastructure-as-code-management%2Fplatform%2Fiacm-pipelines%2Foperations-overview%2Fapproval-step-operations-overview%22%7D%2C%7B%22label%22%3A%22Queue%20Step%22%2C%22slug%22%3A%22queue-step%22%2C%22path%22%3A%22infrastructure-as-code-management%2Fplatform%2Fiacm-pipelines%2Foperations-overview%2Fqueue-step-operations-overview%22%7D%2C%7B%22label%22%3A%22Drift%20Detection%22%2C%22slug%22%3A%22drift-detection%22%2C%22path%22%3A%22infrastructure-as-code-management%2Fplatform%2Fiacm-pipelines%2Foperations-overview%2Fdrift-detection-operations-overview%22%7D%2C%7B%22label%22%3A%22PR%20Automation%22%2C%22slug%22%3A%22pr-automation%22%2C%22path%22%3A%22infrastructure-as-code-management%2Fplatform%2Fiacm-pipelines%2Foperations-overview%2Fpr-automation-operations-overview%22%7D%5D" selectedPlatform="drift-detection" %}

Drift occurs when the actual resources in your cloud environment differ from those defined in your OpenTofu or Terraform state file. This usually happens when someone makes manual changes, for example, modifying a resource directly in the cloud console instead of updating it through code.

Harness IaCM helps detect and highlight these discrepancies, enabling you to quickly reconcile the real infrastructure with your configuration. This is typically done using a provisioning pipeline, which ensures that your Git-based configuration is the source of truth.

{% hint style="info" %}
**EXAMPLE: DETECTING MANUALLY CREATED RESOURCES**

Suppose you have a pipeline that provisions an **SQS queue**. The pipeline runs `init`, `plan`, and `apply`, and the queue is successfully created. Later, someone manually adds an **EC2 instance** in the same environment. When you re-run the pipeline or execute a **Detect Drift** operation, Harness identifies that the EC2 instance is not in your code or state and flags it as drift.

As an operator, you have a few options:

* **Import** the EC2 instance into your state file if you want to manage it as code.
* **Delete** it if it was created unintentionally.
* **Ignore** it if it is a known but unmanaged resource.

If you want to reconcile the state without applying pending configuration changes, use a `plan-refresh-only` step.
{% endhint %}

### Detect drift <a href="#detect-drift" id="detect-drift"></a>

To detect drift, follow these steps:

1. Create a Pipeline with an Infrastructure as Code Management stage, as described in [Provision workspace](/infrastructure-as-code-management/platform/workspaces/provision-workspace.md).
2. Choose a Workspace or set it as a runtime input.
3. Select **Detect Drift** when prompted to choose an operation.

![Drift detection pipeline operation](/files/mCO1DZWBLV9MOpcvfzE2)

4. To schedule drift detection regularly, define a [cron trigger for the pipeline](/harness-ai/use-harness-platform/triggers/schedule-pipelines-using-cron-triggers.md).

### Review drift details <a href="#review-drift-details" id="review-drift-details"></a>

When drift is detected, the pipeline fails and highlights the affected resources. You can review drift details in your pipeline and workspace.

#### In the pipeline <a href="#in-the-pipeline" id="in-the-pipeline"></a>

Go to the **Resources** tab. The **Drift Changes** section outlines all resources where drift was detected. Click a resource to see which attributes have changed.

![Drift detected in pipeline resources tab](/files/6Y9rB44dzJUi6frAalMI)

#### In the workspace <a href="#in-the-workspace" id="in-the-workspace"></a>

Drifted resources are also visible in the Workspace view. Under the **Resources** tab, look for resources marked as **Drifted**.

![Drifted resources in workspace view](/files/DvZsrCGkeS7hbbXRm3PU)

Click a resource to view its drifted attributes.

![Drifted resource attributes](/files/DluPB5onFa5UBjzspmBZ)

#### Detect drift using YAML <a href="#detect-drift-using-yaml" id="detect-drift-using-yaml"></a>

You can also run drift detection by configuring a plugin step in your pipeline YAML. This is useful when you are customizing pipeline execution outside the UI.

```yaml
- step:
    name: Drift or Refresh
    identifier: drift_or_refresh
    type: Plugin
    spec:
      connectorRef: <your_tofu_or_terraform_image_connector>
      image: plugins/harness-tofu # or plugins/harness-terraform
      settings:
        command: detect-drift # plan-refresh-only
      environmentVariables:
        PLUGIN_WORKSPACE: <your_workspace_id>
```

### Detect drift during provisioning <a href="#detect-drift-during-provisioning" id="detect-drift-during-provisioning"></a>

Harness IaCM can also detect drift during provisioning. If a provisioning pipeline identifies drift, that information is displayed in the **Approval** step and the **Resources** tab.

![Drift detected during provisioning](/files/AoYZL5hV2OPaopM0affX)

### Resolve drift <a href="#resolve-drift" id="resolve-drift"></a>

To promote best practices, always treat your IaC repository as the source of truth. If drift occurs, consider the following options:

* **Reconcile the infrastructure** using a provision pipeline to bring resources back in sync.
* **Use plan-refresh-only** to refresh the state without applying new configuration changes.
* **Manually import or delete** the drifted resources depending on your intent.
* **Remediate with the agent** from the workspace [Insights](/infrastructure-as-code-management/platform/workspaces/insights.md) tab. Go to the [IaCM Remediation Agent](/infrastructure-as-code-management/platform/workspaces/remediation-agent.md) to reconcile drift with a generated pull request.

{% hint style="info" %}
**WHEN TO USE PLAN-REFRESH-ONLY**

Use `plan-refresh-only` if there are drifted resources in your environment, but your code also has unreviewed changes. This ensures only the state is updated to match the real environment, without applying unrelated code updates.
{% endhint %}

#### Resolve drift using plan-refresh-only <a href="#resolve-drift-using-plan-refresh-only" id="resolve-drift-using-plan-refresh-only"></a>

This pipeline shows how to handle drift without applying pending changes:

![Plan refresh only pipeline](/files/OYZYXyP9mz0fjRTwXq2m)

{% hint style="info" %}
**OPENTOFU DRIFT VS PLAN BEHAVIOR**

OpenTofu and Terraform handle `drift` and `plan` operations differently.

**For drift detection:** Harness runs `tofu plan -refresh-only` to find changes made outside of OpenTofu, including metadata like `updated_at` values.

**For regular planning:** The `tofu plan` command (and corresponding Harness step) only reports differences between your configuration and infrastructure. If your config matches the current state, **OpenTofu will report no changes needed**, even if metadata values changed.

In short: Drift detection finds all external changes, while planning only focuses on changes relevant to bringing your infrastructure in line with your configuration.
{% endhint %}
