Terramate Cloud seamlessly integrates with Terramate CLI and offers features such as better Pull Request Previews, Observability, Asset Management, Policies, Alerts and Notifications, Drift Management and more that help teams collaborate better.
To use Terramate Cloud, you must sync data from Terramate CLI to Terramate Cloud for operations such as previews, deployments and drift checks. For example, the following command creates plan files called drift.tfplan
in all available stacks and syncs those plans to Terramate Cloud. It explicitly marks the data sync as a drift detection workflow, meaning if any plans contain diffs (which means that your live infrastructure has drifted away from your desired configuration), Terramate Cloud will process them as drifts and relate them to your stacks in Terramate Cloud.
terramate run \
--sync-drift-status \
--terraform-plan-file=drift.tfplan \
--continue-on-error \
--parallel 5 \
-- \
terraform plan -out drift.tfplan -detailed-exitcode -lock=false
Here’s a quick overview of the data that will be synced to Terramate Cloud whenever you decide to sync pull requests, deployments or drift detection workflows:
Plans are always sanitized locally by Terramate CLI before being synced and processed to Terramate Cloud. We filter out all sensitive values, such as secrets and credentials, that might be persisted in your plan files. For a detailed overview, see the Security and Data Access Overview section of the documentation.
If you want to learn more about how Terramate CLI and Terramate Cloud work under the hood, we advise you to read the How it Works section in our documentation.
Now that we have learned about Terramate CLI and Terramate Cloud fundamentals, let’s understand how drift detection works in Terramate.
There are two primary ways in Terramate to detect drift:
Let’s look at both options in detail, understand their use cases and see how we can configure them.
This runs scheduled drift detection jobs in your CI/CD. You can configure different workflows and intervals for stacks, environments, etc. We recommend running a drift check in all relevant stacks at least once every 24 hours. For example, the following GitHub Actions workflow runs a drift detection job in all stacks at 2:00 AM daily.
name: Scheduled Terraform Drift Detection
on:
schedule:
- cron: '0 2 * * *'
jobs:
drift-detection:
name: Check Drift
permissions:
id-token: write
contents: read
pull-requests: read
checks: read
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.head_ref }}
fetch-depth: 0
- name: Install Terramate
uses: terramate-io/terramate-action@v1
- name: Install Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: 1.7.4
terraform_wrapper: false
- name: Configure AWS credentials via OIDC
if: steps.list.outputs.stdout
uses: aws-actions/configure-aws-credentials@v2
with:
aws-region: 'CHANGEME: AWS REGION'
role-to-assume: 'CHANGEME: IAM ROLE ARN'
- name: Run Terraform init on all stacks
id: init
run: terramate run -- terraform init
- name: Run drift detection
id: drift
run: |
terramate run \
--sync-drift-status \
--terraform-plan-file=drift.tfplan \
--continue-on-error \
--parallel 5 \
-- \
terraform plan -out drift.tfplan -detailed-exitcode -lock=false
env:
GITHUB_TOKEN: ${{ github.token }}
Like the workflow above, our documentation includes blueprints for GitLab CI/CD, BitBucket Pipelines and others.
We recommend you run drift detection health checks for all stacks deployed with, e.g., terraform apply
, tofu apply
, or terragrunt apply
after a successful or failed deployment
For successful deployments, the drift detection health check guarantees that the infrastructure resources don’t drift right away—which often happens with auto scalers that scale up and down right after a deployment.
For failed deployments, the drift detection health check will create a new plan, which is extremely helpful in the case of partially applied deployments. This will help your team understand what part of the desired configuration has been successfully applied and what part is missing. We will dive into this further later in this article.
For example, the following GitHub Actions workflow shows a deployment pipeline with a drift detection health check after each deployment.
name: Terraform Deployment
on:
push:
branches:
- main
jobs:
deploy:
name: Deploy Terraform changes in changed Terramate stacks
permissions:
id-token: write
contents: read
pull-requests: read
checks: read
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install Terramate
uses: terramate-io/terramate-action@v1
- name: Install Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: 1.7.4
terraform_wrapper: false
- name: List changed stacks
id: list
run: terramate list --changed
- name: Configure AWS credentials via OIDC
if: steps.list.outputs.stdout
uses: aws-actions/configure-aws-credentials@v2
with:
aws-region: 'CHANGEME: AWS REGION'
role-to-assume: 'CHANGEME: IAM ROLE ARN'
- name: Run Terraform init in each changed stacks
if: steps.list.outputs.stdout
run: |
terramate run \
--changed \
-- \
terraform init
- name: Create Terraform plan on changed stacks
if: steps.list.outputs.stdout
run: |
terramate run \
--changed \
-- \
terraform plan -lock-timeout=5m -out out.tfplan
- name: Apply planned changes on changed stacks
if: steps.list.outputs.stdout
run: |
terramate run \
--changed \
--sync-deployment \
--terraform-plan-file=out.tfplan \
-- \
terraform apply -input=false -auto-approve -lock-timeout=5m out.tfplan
env:
GITHUB_TOKEN: ${{ github.token }}
- name: Run drift detection
if: steps.list.outputs.stdout && ! cancelled() && steps.apply.outcome != 'skipped'
run: |
terramate run \
--changed \
--sync-drift-status \
--terraform-plan-file=drift.tfplan \
-- \
terraform plan -out drift.tfplan -detailed-exitcode
env:
GITHUB_TOKEN: ${{ github.token }}
By looking at the workflow, you will see that Terramate CLI orchestrates the terraform apply
command in all stacks that contain changes (hence the --changed
flag) and syncs the operation as a deployment to Terramate Cloud. After the deployment, Terramate will orchestrate the terraform plan
command in exactly the same stacks and sync those as a drift detection health check to Terramate Cloud.
Now that we have learned how Terramate could be used to run scheduled drift detection workflows and how to check the integrity of deployments with drift detection health checks after a successful or failed deployment, let’s look at how Terramate Cloud helps you manage drift efficiently.
Whenever you sync plans that contain diffs and thus indicate a drift with the --sync-drift-status
flag, Terramate Cloud will do the following things:
drifted
.Let’s address each action in more detail below.
In the stacks detail view in Terramate Cloud, you can review each stack's drift in detail. For example, the following screenshot shows a stack used to manage the settings for a GitHub repository using Terraform. The drift indicates that a branch protection configuration was changed outside of Terraform.
It also shows you:
unhealthy
Since you can sync data from multiple repositories and even from multiple VCS accounts and organizations, it is ideal to keep a holistic overview of all your infrastructure managed with IaC in a single place.
Having a single dashboard allowing us to keep track of drift is great, but often, having an overview only is not actionable for teams. For example, how do I know which person is responsible for remediating this drift? How can I keep up to date on newly detected drift or whenever a drift is being resolved?
Because of this, we’ve added Alerts to Terramate Cloud. Alerts help teams assign and manage incidents such as failed deployments and drift to individuals and teams, allowing you to effectively manage such events without losing track.
Alerts automatically assign the relevant individuals and teams to new incidents and integrate seamlessly with the Slack Bot Integration. This allows you to directly inform users in your Slack workspace about alerts assigned to them and about continuous updates for previously created and assigned alerts.
Remediating Drift with Terramate
Terramate CLI and Terramate Cloud help you detect drift with scheduled workflows, alerts, and Slack notifications, but how can we use both to remediate drift so that we can keep our infrastructure drift-free?
Reconciling drift means we overwrite changes to our live infrastructure outside of Terraform. This is typically done by running another application, e.g., terraform apply
or tofu apply
. With Terramate, you can easily query your Terramate Cloud Organization for drifted
stacks, allowing you to filter all stacks in a repository.
Running commands such as terraform apply
on drifted
stacks
One way to reconcile drift is to run commands such as terraform apply
in all drifted stacks using Terramate CLI.
terramate run --status=drifted -- terraform apply
Adding a change trigger for all drifted stacks to be considered by the change detection in the CI/CD run
When running Terramate in automation, you often configure deployment pipelines that use Terramate's change detection to only deploy stacks that contain changes. To reconcile stacks using the normal Pull Request flow, it’s recommended to mark the relevant stacks as triggered
using Change Tiggers so that they will be considered in the next CI run even though they don’t contain any changes.
terramate experimental trigger --status=drifted
The status
filter argument can also be combined with other filters such as change detection, tags and directories, allowing you to filter the graph of orchestrated stacks in an advanced manner, e.g.:
terramate run \
--filter drifted \ # accepts 'drifted', 'failed' and 'unhealthy'
--chidr stacks/prod \
--tags terraform \
--changed \
--parallel 5 \
-- \
terraform apply
A common way of remediating drift is to automatically reconcile it once it is detected with commands such as terraform apply
or tofu apply
. Add a reconciliation step to the drift detection workflow discussed earlier in this guide to achieve this.
The following workflow will automatically run terraform apply
on all stacks that contain drift right and that a tag reconcile
at 2:00 AM daily.
name: Scheduled Terraform Drift Detection and Reconciliation
on:
schedule:
- cron: '0 2 * * *'
jobs:
drift-detection:
name: Check Drift
permissions:
id-token: write
contents: read
pull-requests: read
checks: read
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.head_ref }}
fetch-depth: 0
- name: Install Terramate
uses: terramate-io/terramate-action@v1
- name: Install Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: 1.7.4
terraform_wrapper: false
- name: Configure AWS credentials via OIDC
if: steps.list.outputs.stdout
uses: aws-actions/configure-aws-credentials@v2
with:
aws-region: 'CHANGEME: AWS REGION'
role-to-assume: 'CHANGEME: IAM ROLE ARN'
- name: Run Terraform init on all stacks
id: init
run: terramate run -- terraform init
- name: Run drift detection
id: drift
run: |
terramate run \
--sync-drift-status \
--terraform-plan-file=drift.tfplan \
--continue-on-error \
--parallel 5 \
-- \
terraform plan -out drift.tfplan -detailed-exitcode -lock=false
env:
GITHUB_TOKEN: ${{ github.token }}
- name: Reconcile Drift
id: reconcile-drift
run: |
terramate run \
--status=drifted \
--tags=reconcile \
--sync-deployment \
--terraform-plan-file=drift.tfplan \
--continue-on-error \
--parallel 5 \
-- \
terraform apply -input=false -auto-approve -lock-timeout=5m drift.tfplan
env:
GITHUB_TOKEN: ${{ github.token }}
This will add a reconcile
drift step to the scheduled drift detection workflow, running a deployment on all stacks marked as drifted and tagged with reconcile
right after the drift detection step.
Automated reconciliation is usually advisable for all stacks that manage production infrastructure, especially for mission-critical services.
Congratulations. You just learned a lot about how to detect, manage and remediate drift in your Terraform, OpenTofu and Terragrunt projects using Terramate CLI and Terramate Cloud. Use alerts, orchestration, drift detection, cloud sync and others to keep your infrastructure drift-free while preserving full control and flexibility.
Feel free to join the Terramate Community on Discord if you have any questions or to book a demo to learn more about how Terramate can help you manage drift in your Infrastructure as Code projects.