Running your program on refresh and destroy
By default, pulumi refresh and pulumi destroy do not execute your program. They operate on stack configuration and the resources already recorded in state. The --run-program flag opts in to running your program first, so the operation sees whatever your program computes at runtime — provider credentials, dynamic resources, or updated provider inputs.
Reach for --run-program whenever the values that refresh or destroy depend on are produced by code rather than persisted in state. The two most common situations are dynamic credentials and provider upgrades.
Refreshing or destroying with expired credentials
Most cloud credentials are short-lived: OIDC-issued tokens and STS session credentials expire on the order of minutes to hours, and credentials brokered through a secrets manager are often similarly time-bound. When pulumi up runs, the program fetches a fresh credential and Pulumi records the resulting provider configuration in state. The credential is not re-fetched on later operations.
A few hours or days later, running pulumi refresh or pulumi destroy reuses that recorded provider configuration. The token has expired, the operation fails, and the failure looks like an auth error from the cloud rather than a stale-credential problem.
Add --run-program to re-run your program so the provider gets a fresh credential:
pulumi refresh --run-program
pulumi destroy --run-program
Removing spurious diffs after a provider upgrade
Major-version provider releases typically change resource schemas: property names and types shift, deprecated fields disappear, and the inputs the provider expects look different from what is currently in state. Running pulumi refresh after a major provider update without running the program can surface spurious diffs that reflect schema differences rather than real drift in the cloud.
Running the program gives the new provider the inputs it needs to compute a clean diff between your program’s intent and the cloud state. After upgrading a provider’s major version, run:
pulumi up --refresh --run-program
The AWS provider 6.x → 7.x migration guide prescribes exactly this command for that reason. The same pattern applies to any provider upgrade where the schema changes — Azure, GCP, Kubernetes, or any other.
Using the flag
--run-program is accepted by pulumi refresh, pulumi destroy, and by pulumi up and pulumi preview when they perform a refresh step (--refresh):
pulumi refresh --run-program
pulumi destroy --run-program
pulumi up --refresh --run-program
pulumi preview --refresh --run-program
To set it once per shell or in CI, use the equivalent environment variable:
export PULUMI_RUN_PROGRAM=true
See Pulumi CLI environment variables for the full list.
Related uses
- Resource hooks. Delete hooks require
--run-programonpulumi destroy— without it, Pulumi cannot register the hooks before deletion and the operation fails. See Deletions and delete hooks. - Dynamic providers. Programs that use dynamic providers need the program to run so Pulumi can load the provider’s implementation from your code.
See also
pulumi refresh— CLI reference.pulumi destroy— CLI reference.- Improved refresh and destroy experience for Pulumi IaC — original announcement, with extended examples.
- Resource hooks — when delete hooks force the use of
--run-program.
Thank you for your feedback!
If you have a question about how to use Pulumi, reach out in Community Slack.
Open an issue on GitHub to report a problem or suggest an improvement.