Skip to content

okta_request_condition: activate failure during Create orphans the created condition (not saved to state, duplicate on retry) #2899

Description

@exitcode0

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request.
  • Please do not leave +1 or me too comments, they generate extra noise for issue followers and do not help prioritize the request.
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment.

Terraform Version & Okta Provider Version(s)

Terraform v1.12.1
on linux_amd64

  • provider registry.terraform.io/okta/okta v6.10.0

The same defect is present on master / v6.13.0 (see analysis below).

Affected Resource(s)

  • okta_request_condition

Can this be done in the Admin UI?

Yes

Can this be done in the actual API call?

Yes (create + activate both work individually; the bug is in how the provider handles a failure between them)

Customer Information

Organization Name: (redacted — large paid enterprise org, happy to share privately)
Paid Customer: yes

Terraform Configuration

resource "okta_request_condition" "example" {
  resource_id          = "0oaXXXXXXXXXXXXXXXXX" # app ID
  name                 = "Self service access request"
  approval_sequence_id = "68XXXXXXXXXXXXXXXXXXXXXX"
  status               = "ACTIVE"

  requester_settings {
    type = "GROUPS"
    ids {
      id = "00gXXXXXXXXXXXXXXXXX"
    }
  }

  access_scope_settings {
    type = "GROUPS"
    ids {
      id = "00gYYYYYYYYYYYYYYYYY"
    }
    ids {
      id = "00gZZZZZZZZZZZZZZZZZ"
    }
  }
  # priority not set (computed)
}

Debug Output

Debug logs are not available from the CI run where this occurred. The failure is fully explained by code inspection (see Actual Behavior); the apply failed with the provider error:

Error activating Request condition

Could not activate Request condition after creation: ...

Expected Behavior

If Create fails partway through (the condition was created via the POST but a follow-up call such as activation failed), the provider should persist the created condition's ID to state before returning the error. Terraform would then track the resource (marked tainted) and the next apply would replace it, instead of leaving an unmanaged duplicate behind.

Per the plugin framework resource create documentation, any state saved in the Create response is preserved even when error diagnostics are returned, precisely to handle partially-created resources.

Actual Behavior

Create in okta/services/governance/resource_request_condition.go makes two API calls when the configuration sets status = "ACTIVE":

  1. CreateResourceRequestConditionV2 (POST) — the Okta API creates the condition as an INACTIVE draft (line 205 at v6.10.0)
  2. ActivateResourceRequestConditionV2 (lines 215–227 at v6.10.0)

resp.State.Set is only called once, at the very end of Create (line 235). If the activate call fails, the error path returns without ever setting state:

// Activate the condition if status is set to ACTIVE
if !data.Status.IsNull() && data.Status.ValueString() == "ACTIVE" {
    requestConditionResp, _, err = r.OktaGovernanceClient.OktaGovernanceSDKClient().
        RequestConditionsAPI.ActivateResourceRequestConditionV2(ctx,
        data.ResourceId.ValueString(),
        requestConditionResp.GetId()).Execute()
    if err != nil {
        resp.Diagnostics.AddError(
            "Error activating Request condition",
            "Could not activate Request condition after creation: "+err.Error(),
        )
        return // <-- condition already exists in Okta, but its ID is never saved to state
    }
}

Because no state was set, Terraform records nothing for the resource. The condition exists in Okta as an orphaned INACTIVE draft, and the next terraform apply creates a second condition — leaving a duplicate request condition on the app, one of them unmanaged and INACTIVE.

We hit this in production: a CI apply in a rate-limited org failed on the activate call (the provider's HTTP transport retries 429s a finite number of times, then gives up with giving up after N attempt(s)). The retry apply succeeded and created a second condition, leaving the first one orphaned on the app (INACTIVE, with an API-assigned priority). The orphan had to be found and deleted manually.

On master / v6.13.0 the same window exists, and a second one was added: the follow-up priority PATCH (UpdateResourceRequestConditionV2, added between the activate call and resp.State.Set) also returns on error without saving state, so a priority-PATCH failure orphans the condition the same way.

Steps to reproduce

  1. Configure an okta_request_condition with status = "ACTIVE" (see configuration above).
  2. Arrange for the activation call to fail after the create POST succeeds. Easiest deterministic repro: intercept POST .../request-conditions/{conditionId}/lifecycle/activate with a proxy and return HTTP 429 (or any 5xx) repeatedly until the transport gives up. In the real world this happens organically in orgs under API rate-limit pressure.
  3. terraform apply — fails with "Error activating Request condition".
  4. Observe: the condition exists in Okta (INACTIVE draft) but terraform state list shows no entry for it.
  5. terraform apply again — a second, duplicate condition is created; the first remains orphaned.

Important Factoids

  • The suggested fix is to call resp.State.Set with at least id and resource_id immediately after the create POST succeeds, before the activate (and, on master, priority PATCH) calls. A mid-Create failure then taints the resource instead of orphaning it.
  • The orphaned condition's INACTIVE status is what pins the failure to the activate step: the POST had succeeded, activation never did.
  • Nothing atypical about authentication: standard service-account (API token) auth.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions