Pulumi’s drift detection is actually a proactive mechanism that catches when your deployed infrastructure diverges from its desired state, not just a passive report.

Let’s see it in action. Imagine we have a simple Pulumi program that provisions an AWS S3 bucket:

import pulumi
import pulumi_aws as aws

bucket = aws.s3.Bucket("my-example-bucket")

pulumi.export("bucket_name", bucket.id)

We deploy this using pulumi up. Pulumi records the state of my-example-bucket in its state file. Now, suppose someone manually changes a setting on this S3 bucket outside of Pulumi, like enabling versioning:

Manual S3 Bucket Versioning Change

When you run pulumi up again, Pulumi performs drift detection before it even considers making any changes. It compares the actual state of the my-example-bucket resource in AWS with the state recorded in its Pulumi state file.

Here’s what you’d see:

Previewing update (dev)

     Type                 Name             Plan       Info
+    pulumi:pulumi:Stack  my-project-dev   created
aws:s3/bucket:Bucket  my-example-bucket  updated    4 changes

Pulumi highlights that my-example-bucket will be updated. If you drill down into the changes, you’ll see something like this:

Diagnostics:
  pulumi:resource:aws:s3/bucket:Bucket (my-example-bucket):
    ~ replace "versioning" from "Suspended" to "Enabled"

This ~ replace indicates a difference Pulumi detected. It knows that the versioning property is no longer Suspended (as per its state file) but is actually Enabled in the cloud. Pulumi doesn’t just tell you there’s drift; it tells you what drifted.

The mental model Pulumi builds is that of a desired state. Your Pulumi program is the source of truth for that desired state. When you run pulumi up, Pulumi orchestrates a two-phase process:

  1. Read Current State: Pulumi queries the cloud provider for the actual current state of all resources managed by the stack.
  2. Compare and Diff: It compares this actual state with the desired state stored in its state file (which is derived from your last successful pulumi up).
  3. Generate Update Plan: Based on the diff, it constructs a plan of what actions (create, update, delete, replace) are needed to bring the actual state in line with the desired state.

Crucially, Pulumi doesn’t assume the cloud state matches its state file. It verifies. This verification is the drift detection. If you’ve disabled versioning in your Pulumi program, but it’s enabled in AWS, Pulumi will propose to disable it. If you’ve enabled versioning in Pulumi and it’s disabled in AWS, Pulumi will propose to enable it.

The levers you control are your Pulumi program’s resource definitions. Every property you define for a resource is a part of the desired state. If a property can be mutated in the cloud provider’s console or via another tool, Pulumi will detect that divergence.

Most people focus on the "what changed" aspect of the diff. What’s less obvious is that Pulumi’s drift detection doesn’t care about the order or timing of changes. It simply compares the current reality with the target reality. So, if you have multiple resources that drift, Pulumi will flag them all in the preview, and then it will execute its update plan based on the resource dependencies, regardless of how the drift occurred.

The next challenge you’ll face is handling drift caused by external automation or compliance tools.

Want structured learning?

Take the full Pulumi course →