terraform-provider-azuread icon indicating copy to clipboard operation
terraform-provider-azuread copied to clipboard

azuread_directory_role_eligibility_schedule_request resources disappear and can't be recreated

Open garretth9 opened this issue 4 months ago • 7 comments

Community Note

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

Terraform (and AzureAD Provider) Version

Terraform v1.5.7 on darwin_arm64

  • provider registry.terraform.io/hashicorp/azuread v2.45.0

Affected Resource(s)

  • azuread_directory_role_eligibility_schedule_request

Terraform Configuration Files

data "azuread_user" "example" {
  user_principal_name = "[email protected]"
}

resource "azuread_directory_role" "example" {
  display_name = "Application Administrator"
}

resource "azuread_directory_role_eligibility_schedule_request" "example" {
  role_definition_id = azuread_directory_role.example.template_id
  principal_id       = azuread_user.example.object_id
  directory_scope_id = "/"
  justification      = "Example"
}

Debug Output

Panic Output

Expected Behavior

The role eligibility assignment should be created, and in the absence of any other changes being made should remain indefinitely.

Actual Behavior

The role eligibility assignment is created but within a month or two (not positive on the exact duration), the Schedule Request seems to automatically expire and disappear. This leads terraform to attempt to recreate it on the next run, but as the actual role assignment still exists it results in an error similar to the below

│ Error: Eligibility schedule request for role "45xxx3c5-c802-45c6-b32a-1d70xxx1e86e" to principal "8e2xxe56-bacf-4c8d-87e6-5de5xxx8a453", received 400 with error: RoleEligibilityScheduleRequestClient.BaseClient.Post(): unexpected status 400 with OData error: RoleAssignmentExists: The Role assignment already exists.
│ 
│   with azuread_directory_role_eligibility_schedule_request.example,
│   on groups.tf line 70, in resource "azuread_directory_role_eligibility_schedule_request" "example":
│   70: resource "azuread_directory_role_eligibility_schedule_request" "example" {
│ 
│ RoleEligibilityScheduleRequestClient.BaseClient.Post(): unexpected status
│ 400 with OData error: RoleAssignmentExists: The Role assignment already
│ exists.

Steps to Reproduce

  1. terraform apply
  2. wait a month or two
  3. terraform apply

I'm not sure this is an issue with the resource itself per se, but given that the behavior of Entra seems to be

  1. User creates an eligibility schedule request
  2. An eligible role assignment is created FROM this schedule request
  3. The request eventually rolls off leaving the assignment behind

I do wonder whether it's even useful to have this as a resource in the provider. Perhaps there's a way to skip step 1 and create the schedule request directly? or alternately once the request is created in terraform have it tie the resource ID to the actual eligible role assignment somehow instead of tying it to the schedule request, which seems to not be a permanent resource?

Important Factoids

References

  • #0000

garretth9 avatar Feb 08 '24 14:02 garretth9

Did a test of this and the eligibility schedule request was created with no end time, i.e. "End Time -> Permanent" in "PIM -> Eligible assignments" in the Azure portal.

Given that I don't see how this can be an issue with the TF provider. Most likely the request was removed manually.

nbaju1 avatar Feb 09 '24 10:02 nbaju1

Perhaps I wasn’t clear on the issue. All of my role aaasignments are still present, the problem is that when terraform refreshed the state it no longer sees the eligibility REQUESTS in our tenant, so it tries to recreate the resources. This then fails because the role assignment the request is trying to create already exists.

There doesn’t seem to be a direct correlation between the eligibility request resource terraform is creating and the actual eligible role assignment in Entra.

What I THINK is happening is that the role eligibility schedule request is the equivalent of the form you fill out on the portal saying “I want to assign eligibility for this role for this duration”, and creating that resource causes Entra to create a separate resource for the actual role assignment. Eventually Entra cleans up those old requests (for us it took a couple months), but the actual role assignments remained since I requested they be permanent.

On Fri, Feb 9, 2024 at 5:44 AM Anders Julton @.***> wrote:

Did a test of this and the eligibility schedule request was created with no end time, i.e. "End Time -> Permanent" in "PIM -> Eligible assignments" in the Azure portal.

Given that I don't see how this can be an issue with the TF provider. Most likely the request was removed manually.

— Reply to this email directly, view it on GitHub https://github.com/hashicorp/terraform-provider-azuread/issues/1306#issuecomment-1935697217, or unsubscribe https://github.com/notifications/unsubscribe-auth/AL5CX62MP2D6QAL2ZBPHFFDYSX4ZDAVCNFSM6AAAAABC73CHDGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSMZVGY4TOMRRG4 . You are receiving this because you authored the thread.Message ID: @.***>

garretth9 avatar Feb 09 '24 22:02 garretth9

To add some more detail, i believe the issue here has to do with the distinction between a roleEligibilitySchedule and a roleEligibilityScheduleRequest. It looks like when you create an eligible role assignment using an eligibilityScheduleRequest the Schedule itself is created with the permanent lifespan that was requested, but the eligibilityScheduleRequest itself appears to have a separate lifecycle.

When i search with powershell using the Get-MgRoleManagementDirectoryRoleEligibilitySchedule cmdlet i still see my eligible role assignments with a status of "provisioned", however when i search with the Get-MgRoleManagementDirectoryRoleEligibilityScheduleRequest the requests all show a status of "Revoked" The same problem happened after roughly the same duration in both our production and test tenants. I'm the only one managing role managements in our test tenant so i know for a fact no manual action was done to remove them.

The eligible assignments were deployed using terraform near the end of December, and i was deploying new eligible role assignments with this template successfully until a couple weeks ago. Then when i tried to update it again yesterday the requests had all rolled off and terraform wanted to recreate them all. So i suspect the requests have a one month lifecycle, but i'm not positive.

Unfortunately that means if you want to try and replicate it i think you'll have to deploy the resources and wait a month or so then try generating a new plan, you should see that the role assignments are still there but terraform thinks the schedule requests need to be recreated, which will fail.

garretth9 avatar Feb 10 '24 00:02 garretth9

I agree, seems like Entra has separate resources for the request and the actual schedule. Checked in our test tenant and most requests were Revoked, while the schedules were Provisioned. I'm not savvy enough in Go or Terraform to understand how the check to see if a request needs to be recreated is made, but if the status field on the roleEligibilityScheduleRequests object is the one being checked, then this will cause unnecessary attempts to recreate the resource when it automatically changes to Revoked. Note that I haven't tested myself to see if it automatically changes, but from what @garretth9 reports and the status in our tentant this seems likely.

The only way, using the MS Graph API at least, to create a schedule is to create the request. There is no POST method for the schedule resource.

A solution might be to change the read resource method in the provider to look at the schedule rather than the request to determine if the request must be recreated.

Refs: Request: https://learn.microsoft.com/en-us/graph/api/resources/unifiedroleeligibilityschedulerequest?view=graph-rest-1.0 Schedule: https://learn.microsoft.com/en-us/graph/api/resources/unifiedroleeligibilityschedule?view=graph-rest-1.0

nbaju1 avatar Feb 16 '24 09:02 nbaju1

Looking in my environment today i see that all of the "revoked" schedule requests have now completely vanished. It really seems like the only path forward to make this resource even viable for use is to somehow link it to the created schedule instead of the request.

In fact, i'd go a step further and say it might be more appropriate to

  1. remove the azuread_directory_role_eligibility_schedule_request resource entirely
  2. replace it with an azuread_directory_role_eligibility_schedule resource
  3. have the provider logic manage the steps of creating a schedule request and linking the terraform resource to the id of the created schedule instead of the schedule request so we can actually see if the schedule needs to be recreated

In any case it doesn't seem particularly useful to have the terraform state pointing to a resource that is going to self-destruct automatically

garretth9 avatar Feb 23 '24 14:02 garretth9

Just to give this some additionnal light, I also have the same issue as mentionned here. The request actually expires but the assignment is still active.

Darkfogel avatar Mar 27 '24 18:03 Darkfogel

  1. remove the azuread_directory_role_eligibility_schedule_request resource entirely
  2. replace it with an azuread_directory_role_eligibility_schedule resource
  3. have the provider logic manage the steps of creating a schedule request and linking the terraform resource to the id of the created schedule instead of the schedule request so we can actually see if the schedule needs to be recreated

I agree with these proposed changes. First, we need to add client implementation related to eligibility schedules in the Go Graph API SDK (Hamilton).

kenchan0130 avatar Apr 02 '24 03:04 kenchan0130