Skip to content

fix(terraform): keep prior state when the proxy rejects a virtual key update - #40540

Open
devin-ai-integration[bot] wants to merge 1 commit into
mainfrom
litellm_terraform_key_update_partial
Open

devin-ai-integration[bot] wants to merge 1 commit into
mainfrom
litellm_terraform_key_update_partial

Conversation

@devin-ai-integration

Copy link
Copy Markdown
Contributor

TLDR

Problem this solves:

How it solves it:

User Flow

Before: an operator editing a litellm_key gets a rejected update that still looks applied on the next plan

  1. They set budget_duration = "bad" on their litellm_key and run terraform apply
  2. The provider sends POST http://localhost:4000/key/update and gets 400 Invalid budget_duration 'bad', apply prints the error
  3. The state file now holds budget_duration = "bad" anyway
  4. terraform plan reports "No changes", so the broken value is never revisited

After: the same rejection leaves state untouched so the diff keeps showing up

  1. They set budget_duration = "bad" on their litellm_key and run terraform apply
  2. The provider sends POST http://localhost:4000/key/update and gets 400 Invalid budget_duration 'bad', apply prints the error
  3. The state file still holds the previous budget_duration
  4. terraform plan still shows the pending change, so the operator can correct it

Relevant issues

Linear ticket

Pre-Submission checklist

  • I have added meaningful tests
  • The handful of test files covering my change pass locally, e.g. uv run pytest tests/test_litellm/<your_test_file>.py -v. Leave the suites (make test-unit-*, make test-unit) to CI: it finishes in ~15 minutes where a laptop takes an hour or more
  • My PR passes all required CI/CD checks (e.g., lint, schema.d.ts sync check, etc.)
  • My PR's scope is as isolated as possible; it only solves 1 specific problem
  • I have received a Greptile Confidence Score of at least 4/5 before requesting a maintainer review (Greptile reviews automatically once the PR is opened; only comment @greptileai to re-request a review after pushing changes)

Screenshots / Proof of Fix

The regression test drives the real provider update path against an HTTP server that answers /key/update with the proxy's 400, then inspects the resulting state

Before (69245fe)

  1. cd terraform/provider && go test ./litellm/ -run TestResourceKeyUpdateFailureKeepsPriorState -v
  2. Output:
2026/09/10 04:13:29 Making POST request to http://127.0.0.1:35755/key/update with body:
{"aliases":{},"blocked":false,"budget_duration":"bad","key":"[REDACTED]","key_alias":"demo","model_max_budget":{},"models":["fake-model"],"permissions":{},"team_id":""}
2026/09/10 04:13:29 Response status: 400
2026/09/10 04:13:29 Response body: {"error":{"message":"Invalid budget_duration 'bad'"}}
--- FAIL: TestResourceKeyUpdateFailureKeepsPriorState (0.00s)
    resource_key_test.go:356: failed update persisted budget_duration="bad" into state, want it absent
FAIL

After (2cf6f47)

  1. cd terraform/provider && gofmt -l . && go vet ./... && go test ./...
  2. Output:
ok  	github.com/BerriAI/terraform-provider-litellm/litellm	5.093s
ok  	github.com/BerriAI/terraform-provider-litellm/tools/endpointaudit	0.003s

Type

🐛 Bug Fix

Caveats (if any)

Low

Link to Devin session: https://app.devin.ai/sessions/ec91c5ef3b2c4b7793fc1b346b989b12
Open in Devin Desktop: https://app.devin.ai/desktop/session/ec91c5ef3b2c4b7793fc1b346b989b12?variant=devin
Requested by: @yassin-berriai

… update

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@greptile-apps

greptile-apps Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR enables Terraform partial-state handling when a virtual-key update fails, preventing rejected planned values from replacing the prior state

  • The change is limited to the UpdateKey error path
  • Successful updates retain the existing read-after-update behavior
  • No security issues or repository-rule violations were identified

Confidence Score: 5/5

The PR appears safe to merge and correctly preserves prior state after failed virtual-key updates

The partial-state call is made before returning the update diagnostic, while the successful update path remains unchanged

Important Files Changed

Filename Overview
terraform/provider/litellm/resource_key.go Preserves prior Terraform state when the proxy rejects or fails a virtual-key update

Reviews (1): Last reviewed commit: "fix(terraform): keep prior state when th..." | Re-trigger Greptile

@codecov

codecov Bot commented Sep 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@yuneng-berri
yuneng-berri deleted the branch main September 13, 2026 04:51
@yuneng-berri yuneng-berri reopened this Sep 13, 2026
@devin-ai-integration
devin-ai-integration Bot changed the base branch from litellm_internal_staging to main September 23, 2026 14:37

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants