Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

azuread_directory_role_eligibility_schedule_request resources disappear and can't be recreated #1306

Open
garretth9 opened this issue Feb 8, 2024 · 8 comments

Comments

@garretth9
Copy link

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 = "jdoe@hashicorp.com"
}

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
@nbaju1
Copy link

nbaju1 commented Feb 9, 2024

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.

@garretth9
Copy link
Author

garretth9 commented Feb 9, 2024 via email

@garretth9
Copy link
Author

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.

@nbaju1
Copy link

nbaju1 commented Feb 16, 2024

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

@garretth9
Copy link
Author

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

@Darkfogel
Copy link

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.

@kenchan0130
Copy link
Contributor

  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).

@Darkfogel
Copy link

@manicminer Would that issue be the same one that was happening in the azurerm provider that you fixed in PR #25956?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants