Skip to content

fix(objectstorage): retry enabling the project on 409 conflict - #1645

Open
FabianHardt wants to merge 1 commit into
stackitcloud:mainfrom
FabianHardt:objectstorage-retry-enable-conflict
Open

fix(objectstorage): retry enabling the project on 409 conflict#1645
FabianHardt wants to merge 1 commit into
stackitcloud:mainfrom
FabianHardt:objectstorage-retry-enable-conflict

Conversation

@FabianHardt

Copy link
Copy Markdown

Problem

stackit_objectstorage_bucket, stackit_objectstorage_credential and
stackit_objectstorage_credentials_group each enable object storage for the
project before creating their own object. When two of them are created in the
same apply and nothing forces an order, Terraform runs them in parallel and the
API rejects the losing call:

Error: Enabling object storage project before creation: failed to create object
storage project: 409 Conflict  ([{project.create_conflict Two concurrent calls
try to create the same project}]), status code 409

The apply fails although nothing is actually wrong — the competing call enables
the project a moment later.

Minimal reproducer (both resources in one config, no reference between them):

resource "stackit_objectstorage_bucket" "b" {
  project_id = var.project_id
  name       = "some-bucket"
}

resource "stackit_objectstorage_credentials_group" "g" {
  project_id = var.project_id
  name       = "some-group"
}

The comment in enableProject already assumes idempotency — "Creation will
also be successful if the project is already enabled"
— which holds for
sequential calls but not for concurrent ones.

Change

enableProject retries on 409 and leaves every other error untouched. An
apply no longer depends on the order in which Terraform happens to start the
resources.

depends_on works around it today, but that requires knowing about an implicit
API call the resource documentation does not mention — the error message points
at object storage projects, not at a missing dependency.

The retry is deliberately narrow rather than utils.RetryRequest: that helper
also retries errors which are not GenericOpenAPIError, which would slow the
existing unit tests down.

Tests

Added to credentialsgroup/resource_test.go:

  • TestEnableProjectRetriesOnConflict — succeeds immediately, one conflict then
    success, and conflicts until the attempts are used up; asserts the number of
    API calls in each case
  • TestEnableProjectDoesNotRetryOtherErrors — a 403 must fail on the first
    attempt

The retry delay is a package variable so tests can shorten it.

go test ./stackit/internal/services/objectstorage/...   -> ok (all packages)
gofmt -l / go vet                                       -> clean

Note

The three copies of enableProject are identical; I kept the duplication to
keep the diff reviewable. Happy to extract it into
objectstorage/utils instead if you prefer.

bucket, credential and credentials group each enable object storage for the
project before creating their own object. When two of them are created in the
same apply, Terraform runs them in parallel and the API rejects the losing
call:

  Error: Enabling object storage project before creation: failed to create
  object storage project: 409 Conflict
  ([{project.create_conflict Two concurrent calls try to create the same
  project}]), status code 409

The apply fails, although nothing is wrong - the competing call enables the
project a moment later. The comment in enableProject already assumed the call
to be idempotent ("Creation will also be successful if the project is already
enabled"), which holds for sequential calls but not for concurrent ones.

enableProject now retries on 409 and leaves every other error untouched, so an
apply no longer depends on the order in which Terraform happens to start the
resources. Users can work around it today with depends_on, but that requires
knowing about an implicit call that the resource documentation does not
mention.

The retry is deliberately narrow rather than utils.RetryRequest: that helper
also retries errors that are not API errors, which would slow down the
existing unit tests.

Signed-off-by: Fabian Hardt <fabian.hardt@opitz-consulting.com>
@FabianHardt
FabianHardt requested a review from a team as a code owner August 2, 2026 09:43
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.

1 participant