Repository: hashicorp/terraform-provider-azuread

Issue:
`azuread_group_role_management_policy` unset `approval_stage` causes constant drift
<!---
Please note the following potential times when an issue might be in Terraform core:

* [Configuration Language](https://www.terraform.io/docs/configuration/index.html) or resource ordering issues
* [State](https://www.terraform.io/docs/state/index.html) and [State Backend](https://www.terraform.io/docs/backends/index.html) issues
* [Provisioner](https://www.terraform.io/docs/provisioners/index.html) issues
* [Registry](https://registry.terraform.io/) issues
* Spans resources across multiple providers

If you are running into one of these scenarios, we recommend opening an issue in the [Terraform core repository](https://github.com/hashicorp/terraform/) instead.
--->

<!--- Please keep this note for the community --->

### Community Note

* Please vote on this issue by adding a 👍 [reaction](https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) 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

<!--- Thank you for keeping this note for the community --->

### Terraform (and AzureAD Provider) Version

```
Terraform v1.5.7
on windows_amd64
+ provider registry.terraform.io/env0/env0 v1.18.7
+ provider registry.terraform.io/hashicorp/azuread v2.49.1
+ provider registry.terraform.io/hashicorp/azurerm v3.103.1
+ provider registry.terraform.io/hashicorp/random v3.6.2
+ provider registry.terraform.io/hashicorp/tfe v0.55.0
+ provider registry.terraform.io/hashicorp/time v0.7.2
+ provider registry.terraform.io/hashicorp/vault v3.8.2
+ provider registry.terraform.io/integrations/github v6.2.1
```

### Affected Resource(s)

<!--- Please list the affected resources and data sources. --->

* `azuread_group_role_management_policy`

### Terraform Configuration Files

<!--- Information about code formatting: https://help.github.com/articles/basic-writing-and-formatting-syntax/#quoting-code --->

```hcl
resource "azuread_group_role_management_policy" "groups" {
  group_id = "xxxxx-xxxxx-xxxxx-xxxx"
  role_id  = "member"

  active_assignment_rules {
    expiration_required                = true
    expire_after                       = "P30D"
    require_justification              = true
    require_multifactor_authentication = true
    require_ticket_info                = false
  }

  eligible_assignment_rules {
    expiration_required = false
    expire_after        = "P365D"
  }

  activation_rules {
    maximum_duration                   = "PT12H"
    require_approval                   = false
    require_justification              = true
    require_multifactor_authentication = true
    require_ticket_info                = true
  }
}
```

### Debug Output

<!---
Please provide a link to a GitHub Gist containing the complete debug output. Please do NOT paste the debug output in the issue; just paste a link to the Gist.

To obtain the debug output, see the [Terraform documentation on debugging](https://www.terraform.io/docs/internals/debugging.html).
--->

### Panic Output

<!--- If Terraform produced a panic, please provide a link to a GitHub Gist containing the output of the `crash.log`. --->

### Expected Behavior

Resource should not show changes

### Actual Behavior

Resource shows changes on every apply.
In Terraform Cloud, this doesn't show what is going to be changed, just `4 unchanged attributes hidden` and `4 unchanged blocks hidden`.

As a CLI run, it shows the `activation_rules.approval_stage` being removed:
```
  # module.this.azuread_group_role_management_policy.groups["data_admins"] will be updated in-place
  ~ resource "azuread_group_role_management_policy" "groups" {
        id           = "Group_663174af-0098-4588-87a4-1d10577e22f2_5b6ae689-0d59-41be-b172-3f07be7bff57"
        # (4 unchanged attributes hidden)

      ~ activation_rules {
            # (5 unchanged attributes hidden)

          - approval_stage {
            }
        }

        # (3 unchanged blocks hidden)
    }
```

### Steps to Reproduce

<!--- Please list the steps required to reproduce the issue. --->

1. `terraform apply`
2. Run the apply again and you will see resource shows changes

I have tried adding an empty `approval_stage` block but that requires a `primary_approver` which cannot be empty either.

### Important Factoids

<!--- Are there anything atypical about your accounts that we should know? For example: Running in a Azure China/Germany/Government? --->

### References

<!---
Information about referencing Github Issues: https://help.github.com/articles/basic-writing-and-formatting-syntax/#referencing-issues-and-pull-requests

Are there any other GitHub issues (open or closed) or pull requests that should be linked here? Such as vendor documentation?
--->



Hints from issue comments:
@paul-hugill: Probably having the same issue with the newly released `azurerm_role_management_policy` resource as well, both when using v3.108.0, at least I'm having the same `empty` changes plans every time.

I can open an issue on that provider as well and mention this if desired.@manicminer: Thanks @paul-hugill, if you can open an issue for AzureRM that'd be appreciated 👍 @sunevnuahs: We are experiencing the same issue with this resource with azuread v3.0.2.

We initially had an approval_stage (group as primary approver) set in the member policy, but as this was not required we removed it so that the approval_stage is not there at all when activation_rules.require_approval is false (using dynamic blocks).

The plan/apply went fine and removed this, however we now experience this constant update when planning.

As a workaround we can keep activation_rules.require_approval but define a approval_stage to a primary_approver (singleUser or groupMembers) that effectively does nothing as approval is not required.  The user or group does not really matter as they will not be approving anything for this policy.
This at least stops the annoyance of the proposed change in the plan.

Situation is not ideal as why should we need to set and approver on a policy that does not require one.


Having just read the [issue ](https://github.com/hashicorp/terraform-provider-azurerm/issues/26377)for azurerm_role_management_policyI see the comment from JWilkinsonMB (https://github.com/hashicorp/terraform-provider-azurerm/issues/26377#issuecomment-2423683251) is essentially the same as the proposed workaround here.

@christopher-pope: Has there been any update on this? We're encountering this issue too with azuread v3.1.0.@alienm16: I confirm that last version of azuread provider contunue to have this probleme, Requiere_approval is not set or set to false, the terraform plan see a drift each time because the missing approval_stage/primary_approver block.

For now, the only workaround i have found is to use this:

  approval_stage {
      primary_approver {
        object_id = azuread_group.this.object_id
        type = "groupMembers"
      }
    }

I reuse my PIM Group to be the approver, I see it in the GUI, but with require_approval = false, I don't need approval, but it's not a good config, it's a workaround.  

Please make a correction to the azuread provider!

Solution patch:
diff --git a/internal/services/policies/group_role_management_policy_resource.go b/internal/services/policies/group_role_management_policy_resource.go
index f3f6cd73..961018dd 100644
--- a/internal/services/policies/group_role_management_policy_resource.go
+++ b/internal/services/policies/group_role_management_policy_resource.go
@@ -220,6 +220,7 @@ func (r GroupRoleManagementPolicyResource) Arguments() map[string]*pluginsdk.Sch
 						Description: "The approval stages for the activation",
 						Type:        pluginsdk.TypeList,
 						Optional:    true,
+						Computed:    true,
 						MaxItems:    1,
 						Elem: &pluginsdk.Resource{
 							Schema: map[string]*pluginsdk.Schema{



Test patch:
diff --git a/internal/services/policies/group_role_management_policy_resource_test.go b/internal/services/policies/group_role_management_policy_resource_test.go
index f301b674..24cbd338 100644
--- a/internal/services/policies/group_role_management_policy_resource_test.go
+++ b/internal/services/policies/group_role_management_policy_resource_test.go
@@ -21,6 +21,22 @@ import (
 
 type GroupRoleManagementPolicyResource struct{}
 
+func TestGroupRoleManagementPolicy_activationRules(t *testing.T) {
+	data := acceptance.BuildTestData(t, "azuread_group_role_management_policy", "test")
+	r := GroupRoleManagementPolicyResource{}
+
+	// Ignore the dangling resource post-test as the policy remains while the group is in a pending deletion state
+	data.ResourceTestIgnoreDangling(t, r, []acceptance.TestStep{
+		{
+			Config: r.activationRules(data),
+			Check: acceptance.ComposeTestCheckFunc(
+				check.That(data.ResourceName).ExistsInAzure(r),
+			),
+		},
+		data.ImportStep(),
+	})
+}
+
 func TestGroupRoleManagementPolicy_member(t *testing.T) {
 	data := acceptance.BuildTestData(t, "azuread_group_role_management_policy", "test")
 	r := GroupRoleManagementPolicyResource{}
@@ -86,6 +102,26 @@ func (GroupRoleManagementPolicyResource) Exists(ctx context.Context, clients *cl
 	return pointer.To(true), nil
 }
 
+func (GroupRoleManagementPolicyResource) activationRules(data acceptance.TestData) string {
+	return fmt.Sprintf(`
+provider "azuread" {}
+
+resource "azuread_group" "this" {
+  display_name     = "PAM Basic Test %[1]s"
+  security_enabled = true
+}
+
+resource "azuread_group_role_management_policy" "test" {
+  group_id = azuread_group.this.object_id
+  role_id  = "member"
+
+  activation_rules {
+    maximum_duration = "PT12H"
+  }
+}
+`, data.RandomString)
+}
+
 func (GroupRoleManagementPolicyResource) member(data acceptance.TestData) string {
 	return fmt.Sprintf(`
 provider "azuread" {}