Pulumi Watch lets you iterate on your infrastructure code as if it were application code, seeing changes reflected in your cloud environment almost instantly.
Let’s see it in action. Imagine you’re deploying a simple AWS S3 bucket.
import pulumi
import pulumi_aws as aws
# Create an AWS resource (S3 bucket)
bucket = aws.s3.Bucket("my-bucket")
# Export the name of the bucket
pulumi.export("bucket_name", bucket.id)
Now, you want to add versioning to this bucket. You modify your code:
import pulumi
import pulumi_aws as aws
# Create an AWS resource (S3 bucket)
bucket = aws.s3.Bucket("my-bucket",
versioning=aws.s3.BucketVersioningArgs(
enabled=True,
))
# Export the name of the bucket
pulumi.export("bucket_name", bucket.id)
Normally, you’d run pulumi up again and wait for the full deployment. With pulumi watch, you just run pulumi watch in your terminal in the same directory as your Pulumi project. Then, save your modified Python file. Within seconds, Pulumi detects the change, plans the update, and applies it. You’ll see output in your pulumi watch terminal showing the change being applied, and if you check your AWS console, the bucket will now have versioning enabled.
This works by pulumi watch constantly monitoring your project’s source files. When it detects a modification, it triggers a Pulumi deployment lifecycle. This isn’t just a pulumi preview followed by a pulumi up; it’s a more intelligent process. Pulumi analyzes the delta between your desired state (the code you just saved) and the current state of your infrastructure in the cloud. It then calculates the minimal set of changes required to reconcile these states, performing only those specific updates. This dramatically speeds up the feedback loop for infrastructure development.
The core problem Pulumi Watch solves is the friction in traditional Infrastructure as Code (IaC) workflows. Historically, making a change meant editing code, committing, pushing, waiting for a CI/CD pipeline, and then observing the result. This could take minutes to hours. Pulumi Watch brings this down to seconds, enabling an iterative development style akin to front-end or back-end application development. You can experiment with configurations, test new resource properties, or fix errors much faster.
Under the hood, pulumi watch leverages Pulumi’s engine. It sets up a file watcher for your project’s source files, including your Pulumi program code, any configuration files, and even related assets like Dockerfiles or docker-compose.yml if they are part of your deployment. When a change is detected, pulumi watch orchestrates a pulumi preview to show you what will change, and then automatically proceeds with pulumi up if the preview is successful and you haven’t configured it to pause. You can control this behavior with flags like --on-event preview or --on-event destroy.
The exact levers you control are primarily through your Pulumi program itself. You define resources and their properties. pulumi watch is the mechanism for rapidly applying changes to those definitions. However, you can influence its behavior. For instance, pulumi watch -p 1000 (where 1000 is milliseconds) sets a debounce interval, preventing rapid, back-to-back updates if you save files very quickly. You can also specify which files to watch if you don’t want pulumi watch to monitor everything in your project directory.
The most common pattern is to simply run pulumi watch and then edit your code. Pulumi will automatically detect the changes and perform the update. However, it’s important to understand that pulumi watch is not a replacement for robust CI/CD pipelines. It’s a development-time tool. For production deployments, you’ll still rely on your established pipelines for consistent, repeatable, and auditable deployments across different environments.
One aspect that often surprises developers is how pulumi watch handles resource replacement. If you change a property that necessitates replacing a resource (e.g., changing the instance type of an EC2 instance), pulumi watch will, by default, attempt to perform this replacement. This means the old resource is destroyed and a new one is created, which can lead to brief downtime for that specific service. You can see this clearly in the pulumi up output that pulumi watch drives. For critical resources where downtime is unacceptable even during development, you might consider updating properties that don’t require replacement, or using more advanced Pulumi features like import to manage existing infrastructure during such transitions.
The next logical step after mastering rapid iteration with pulumi watch is understanding how to manage secrets within your infrastructure code.