What the agent does
The agent clones the module into its own cloud sandbox and reads every versions.tf, because a published module declares the providers it accepts in more than one place. In terraform-aws-modules/terraform-aws-vpc, the root versions.tf asks for hashicorp/aws >= 6.28 with required_version = ">= 1.0", and so do modules/flow-log, modules/vpc-endpoints, wrappers and each directory under examples, some of them with required_version = ">= 1.5.7". The constraints are floors, not pins, and .gitignore excludes .terraform.lock.hcl, so there is no lockfile to bump. Upgrading here means testing against the newest provider and moving the floor only when the module needs it.
It runs terraform init -upgrade in the root and in each example (simple, complete, ipv6-dualstack, ipam, network-acls and the rest), records the provider version each one resolves, and then reads the provider changelog from the old floor up to that version. It searches the 74 resource blocks in main.tf, the 5 in vpc-flow-logs.tf and the submodules for arguments the changelog deprecates or removes, and fixes each one in the module. When a fix needs an argument that only exists in a newer provider, the agent raises the floor in every versions.tf that declares it, so the root module and its submodules never disagree.
Next it runs the checks the repository already defines. .pre-commit-config.yaml (pre-commit-terraform v1.108.1) runs terraform_fmt, terraform_wrapper_module_for_each, terraform_docs, terraform_tflint with a list of rules such as terraform_required_providers and terraform_documented_variables, and terraform_validate. .github/workflows/pre-commit.yml runs them twice, on the minimum and the maximum Terraform version that clowdhaus/terraform-min-max finds, with tflint v0.64.0 and terraform-docs v0.24.0. The agent runs terraform fmt -check -recursive, terraform validate in each example and the same pre-commit hooks in the sandbox.
The prompt also asks for terraform test. This module has no .tftest.hcl files, so the agent says so instead of claiming a test pass, and lists terraform test as not run. Any bump that breaks validation or a hook and has no clean fix is left out of the pull request with the error and the reason.
Start it with one API call
POST https://api.prix.dev/o/{org}/sessions with this body:
{
"agent": "claude",
"input": "Upgrade the providers in this Terraform module. Read every versions.tf (root, modules/, wrappers/ and examples/) and run terraform init -upgrade in each to find the newest provider versions the constraints allow. Read each provider's changelog from the current minimum to that version, fix every deprecated or removed argument the module uses, and raise the minimum version in every versions.tf that declares the provider only where a fix needs it. Run terraform fmt -check -recursive, terraform validate in every example, the pre-commit hooks in .pre-commit-config.yaml, and terraform test if any .tftest.hcl files exist. Leave out any upgrade that breaks them and say why. Open a pull request with one line per provider: old minimum, new minimum or unchanged, the version tested, and each argument fixed.",
"resources": [
{
"url": "https://github.com/your-org/your-module"
}
]
}- Get an API key. In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
- Send the request. POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
- Read what came back. Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.
What comes back
What comes back is a pull request on a new branch. It holds the argument fixes in main.tf, vpc-flow-logs.tf or the submodules, the raised version constraints in each versions.tf that needed one, and whatever terraform_docs regenerated in the README files as a result. The description has one line per provider with the old floor, the new floor or unchanged, and the version the examples were validated against, then the list of fixes and any bump left out with its error.
The checks are the repository's own pre-commit workflow on the minimum and maximum Terraform versions, the same hooks the agent ran. The session's transcript keeps every terraform init -upgrade, validate and pre-commit run with its output, so a reviewer can see which provider version each example resolved.
Before merging, a reviewer checks that a raised floor is justified by a fix in the same diff, since raising it forces every caller of the module to upgrade too. They read each argument change for a behavior change the changelog mentions, because terraform validate proves the configuration is well formed, not that a plan against a real account changes nothing.
Run it on every Monday morning
The AWS provider releases often, so a weekly run keeps the module ahead of deprecations without anyone reading changelogs by hand. A scheduled job can send this request every Monday for each module repository, with an Idempotency-Key built from the repository and the week so a retried request returns the run already started.
With a webhook URL on the API key, Rush posts run.completed or run.failed when the run's turn finishes. Your handler reads the session from session_url and posts the pull request link to the channel that owns the module, or does nothing when the run found no change worth making.
The use case this job follows, with its automation and trigger: Upgrade dependencies weekly.
Why run it on Rush?
Provider upgrades need a clean plugin cache: terraform init -upgrade downloads each provider fresh, and a laptop's ~/.terraform.d or an old .terraform directory can hide a version mismatch. In a Rush sandbox the agent installs Terraform, tflint and terraform-docs at the versions the workflow names and initialises every example from nothing.
A bot that opens one red pull request per version bump gets ignored. Here the agent does what a reviewer would do first, reading the changelog and validating each example, and the transcript keeps every command's output as the record. Several module repositories can run at once, each in its own sandbox.
Frequently asked questions
Does it need AWS credentials?
No. terraform init, fmt, validate, tflint and terraform-docs all run without credentials. The agent does not run plan or apply against an account unless you ask and give it credentials.
Why not just pin the newest provider version?
A reusable module should accept the widest range of providers it works with, so callers can choose their own versions in their lockfiles. The agent raises the minimum only when a fix requires it, and tests against the newest version.
My module has no terraform test files. Is that a problem?
The upgrade still runs, but terraform test has nothing to execute, and the pull request says so. You can ask in a follow-up for plan-mode tests in a tests/ directory, which run without credentials using mocked providers.
Will it work with OpenTofu?
Name OpenTofu in the prompt and the agent runs tofu init -upgrade and tofu validate instead. Provider sources and constraints read the same way in both.