Skip to main content
By the end of this tutorial, you will have set up Kosli to track authorized Terraform changes and detect when an unauthorized change slips through.
This tutorial focuses on detecting changes made by bypassing the approved Terraform process (e.g. a developer running terraform apply directly from their machine). Detecting is a separate concern covered by Terraform drift detection.

Prerequisites

Setup

export KOSLI_ORG=<your-personal-kosli-org-name>
export KOSLI_API_TOKEN=<your-api-token>
Clone the tutorial repository:
git clone https://github.com/kosli-dev/iac-changes-tutorial.git
cd iac-changes-tutorial

Create a Kosli flow

Create a Kosli flow to represent the approved process for Terraform changes. Using keeps things simple for this tutorial:
kosli create flow tf-tutorial --use-empty-template

Make and track an authorized change

In production, an authorized change goes through CI. In this tutorial, you run those commands locally to simulate the process.
Begin a trail to represent a single authorized change:
kosli begin trail authorized-1 --flow=tf-tutorial
Optionally, scan your Terraform config for security issues and attest the output to Kosli:
snyk iac test main.tf --sarif-file-output=sarif.json
kosli attest snyk --name=security --flow=tf-tutorial --trail=authorized-1 --scan-results=sarif.json
Create a Terraform plan, save it to a file, and attest it to Kosli:
terraform init
terraform plan -out=tf.plan
kosli attest generic --name=tf-plan --flow=tf-tutorial --trail=authorized-1 --attachments=tf.plan
Apply the plan and attest the resulting as an artifact. Kosli calculates a fingerprint from the state file contents — this fingerprint is how it later detects unauthorized changes:
This tutorial uses a local state file for simplicity. In production, the state file is typically stored in cloud storage (e.g. AWS S3) and you would download it after the authorized change. Note that --build-url and --commit-url are set to placeholder URLs here — in CI these are set automatically.
terraform apply -auto-approve tf.plan
kosli attest artifact terraform.tfstate --name=state-file --artifact-type=file --flow=tf-tutorial --trail=authorized-1 \
   --build-url=https://example.com --commit-url=https://example.com --commit=HEAD

Monitor the state file

To detect unauthorized changes, Kosli monitors the state file for changes by tracking it in an environment. Create a server environment:
kosli create env terraform-state --type=server
Report the current state file to the environment:
In production, configure environment reporting to run periodically or on state file changes. See reporting AWS environments if you use S3 as your Terraform backend.
kosli snapshot path terraform-state --name=tf-state --path=terraform.tfstate
Check the latest snapshot:
kosli get snapshot terraform-state
You should see:
COMMIT   ARTIFACT                                                                       FLOW         COMPLIANCE     RUNNING_SINCE  REPLICAS
d881b2f  Name: tf-state                                                                 tf-tutorial  NON-COMPLIANT  28 minutes ago   1
         Fingerprint: a57667a7b921b91d438631afa1a1fe35300b4da909a19d2b61196580f30f1d0c
The FLOW column shows tf-tutorial — Kosli has provenance for this change. In the Kosli UI under Environments > terraform-state, the artifact shows as compliant.
Environment shows an authorized change

Introduce an unauthorized change

Simulate an unauthorized change by modifying line 6 of main.tf — change random_pet_result to random_pet_name — then apply directly without going through the approved process:
terraform apply --auto-approve
Report the updated state file to Kosli:
In production this step is not needed — environment reporting runs automatically on change or on a schedule.
kosli snapshot path terraform-state --name=tf-state --path=terraform.tfstate
Check the snapshot again:
kosli get snapshot terraform-state
You should see:
COMMIT  ARTIFACT                                                                       FLOW  COMPLIANCE     RUNNING_SINCE   REPLICAS
N/A     Name: tf-state                                                                 N/A   NON-COMPLIANT  8 minutes ago  1
        Fingerprint: edd93dcde27718ed493222ceb218275655555f3f3bfefa95628c599e678ac325
The FLOW is now N/A — Kosli has no provenance for this state file fingerprint. It was not attested through any known flow, which means the change was unauthorized. The environment page reflects this:
Environment shows an unauthorized change

What you’ve accomplished

You have used Kosli to track authorized Terraform changes and detect an unauthorized one. By fingerprinting the Terraform state file and comparing it against attested artifacts, Kosli can tell whether a running infrastructure state came from an approved process or not. From here you can:
  • Set up alerts and automated responses when unauthorized changes are detected using Kosli actions
  • See how to report S3-backed state files automatically in the Report AWS environments tutorial
Last modified on March 11, 2026