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

Add support for PIM Group management #1327

Merged
merged 57 commits into from
May 8, 2024
Merged
Show file tree
Hide file tree
Changes from 48 commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
0e3b0cc
Enable typed resources for identitygovernance
oWretch Feb 29, 2024
b14959b
Create `azuread_privileged_access_group_assignment_schedule_request`
oWretch Feb 29, 2024
003e26d
Handle deletion of requests in all states
oWretch Mar 1, 2024
cccc742
Initial test creation
oWretch Mar 3, 2024
f72d4ee
Handle case where the request comes back failed from Entra
oWretch Mar 3, 2024
11408d5
Create azuread_privileged_access_group_eligibility_schedule_request
oWretch Mar 3, 2024
b27b94e
Create tests for azuread_privileged_access_group_eligibility_schedule…
oWretch Mar 3, 2024
236a7b0
Enable typed resources for Policies
oWretch Mar 4, 2024
f6ac361
Create clients
oWretch Mar 4, 2024
dc2facb
Initial resource for PAM Group policies
oWretch Mar 4, 2024
7b1a840
Initial CRUD functions
oWretch Mar 4, 2024
8beaa4f
Correct schema errors
oWretch Mar 4, 2024
bb74378
Fix Create function
oWretch Mar 4, 2024
7ddb94e
Fix ID issues
oWretch Mar 4, 2024
07cc7c2
Add parsing for role policies
oWretch Mar 4, 2024
f163e04
Finish migrating settings into blocks
oWretch Mar 4, 2024
08b6a3d
Rename AllowPermanent to ExpirationRequired
oWretch Mar 4, 2024
1dbc70a
Update policy build code to actually work
oWretch Mar 4, 2024
66ac6af
Read now works also
oWretch Mar 4, 2024
d370422
Update parameter requirements
oWretch Mar 4, 2024
7fcfbce
Rename all resource etc with Group prefix
oWretch Mar 4, 2024
2acc9de
We have working tests
oWretch Mar 5, 2024
8dede21
Add documentation
oWretch Mar 5, 2024
65c7657
Rename `approval_stages` to `approval_stage`
oWretch Mar 5, 2024
2a655fe
Ensure all additional_recipients blocks have an item
oWretch Mar 5, 2024
a6b7c04
Rename base `object_id` to `group_id`
oWretch Mar 5, 2024
78ac258
Update primary_approver block to better match the underlying API
oWretch Mar 5, 2024
0fd0004
Fix duplicate `approval_stages` being saved in the state file
oWretch Mar 5, 2024
2dd6c6a
Allow `additional_recipients` to be an empty list
oWretch Mar 5, 2024
1318798
Convert Lists to Sets where order doesn't matter
oWretch Mar 5, 2024
43f03a5
DRY processing notification settings
oWretch Mar 5, 2024
5598a54
Reverse nesting of notification blocks to match the GUI layout
oWretch Mar 6, 2024
07037ad
Update Import section of the documentation
oWretch Mar 6, 2024
9902481
Merge branch 'refs/heads/f/pim-group-eligible-schedule' into f/pim-gr…
oWretch Mar 6, 2024
c57208f
Merge branch 'refs/heads/f/pim-group-assign-schedule' into f/pim-groups
oWretch Mar 6, 2024
d409233
Fix naming issues after merge
oWretch Mar 6, 2024
3f079cc
Ensure all validation functions are ValidateDiagFuncs
oWretch Mar 6, 2024
0c66c13
Catch error where no valid expiry defined
oWretch Mar 6, 2024
78ce8d2
Combine common code for schedule requests
oWretch Mar 7, 2024
44aec6d
Better validation of start and expiry dates
oWretch Mar 7, 2024
2edafda
Centralise schedule resource build
oWretch Mar 7, 2024
bb2237b
Suppress diff on the start date
oWretch Mar 7, 2024
1dd653f
Update read functions to find the lastest request version
oWretch Mar 16, 2024
832971c
Correct ordering of arguments in documentation
oWretch Mar 21, 2024
a0f4dff
Bump `hamilton` to v0.67.0
oWretch Apr 1, 2024
c1d6e25
Make Group Role Management documentation clearer
oWretch Apr 4, 2024
1681630
Add full validation function for role management policy IDs
oWretch Apr 4, 2024
0bd0aef
Create custom importer for group role management policy
oWretch Apr 4, 2024
f71d75f
Move to managing schedules rather than requests
oWretch Apr 8, 2024
a4a0726
Handle the change in ID for policies when updated
oWretch Apr 8, 2024
a71fe54
Fix golint errors
oWretch Apr 30, 2024
fcc6044
add basis for a data source to retrieve group role management policy …
iwarapter Apr 30, 2024
ef8f613
Correct notification rule example
oWretch May 7, 2024
9f53c2d
identitygovernance: don't mark as gone when we've actively destroyed …
manicminer May 8, 2024
2af400c
data.azuread_group_role_management_policy: fix up acceptance test
manicminer May 8, 2024
8c2cdfe
doc fixups
manicminer May 8, 2024
4e071f8
make generate
manicminer May 8, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 152 additions & 0 deletions docs/resources/group_role_management_policy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
---
subcategory: "Policies"
---

# Resource: azuread_group_role_management_policy

Manage a role policy for an Azure AD group.

## API Permissions

The following API permissions are required in order to use this resource.

When authenticated with a service principal, this resource requires the `RoleManagementPolicy.ReadWrite.AzureADGroup` Microsoft Graph API permissions.

When authenticated with a user principal, this resource requires `Global Administrator` directory role, or the `Privileged Role Administrator` role in Identity Governance.

## Example Usage

```terraform
resource "azuread_group" "example" {
display_name = "group-name"
security_enabled = true
}

resource "azuread_user" "member" {
user_principal_name = "[email protected]"
display_name = "J. Doe"
mail_nickname = "jdoe"
password = "SecretP@sswd99!"
}

resource "azuread_group_role_management_policy" "example" {
group_id = azuread_group.example.id
assignment_type = "member"

active_assignment_rules {
expire_after = "P365D"
}

eligible_assignment_rules {
expiration_required = false
}

notification_rules {
approver_notifications {
eligible_assignments {
notification_level = "Critical"
default_recipients = false
additional_recipients = [
"[email protected]",
"[email protected]",
]
}
}
}
}
```

## Argument Reference

* `activation_rules` - (Optional) An `activation_rules` block as defined below.
* `active_assignment_rules` - (Optional) An `active_assignment_rules` block as defined below.
* `assignment_type` - (Required) The type of assignment this policy coveres. Can be either `member` or `owner`.
* `eligible_assignment_rules` - (Optional) An `eligible_assignment_rules` block as defined below.
* `group_id` - (Required) The ID of the Azure AD group for which the policy applies.
* `notification_rules` - (Optional) A `notification_rules` block as defined below.

---

An `activation_rules` block supports the following:

* `approval_stage` - (Optional) An `approval_stage` block as defined below.
* `maximum_duration` - (Optional) The maximum length of time an activated role can be valid, in an IS)8601 Duration format (e.g. `PT8H`). Valid range is `PT30M` to `PT23H30M`, in 30 minute increments, or `PT1D`.
* `require_approval` - (Optional) Is approval required for activation. If `true` an `approval_stage` block must be provided.
* `require_justification` - (Optional) Is a justification required during activation of the role.
* `require_multifactor_authentication` - (Optional) Is multi-factor authentication required to activate the role. Conflicts with `required_conditional_access_authentication_context`.
* `require_ticket_info` - (Optional) Is ticket information requrired during activation of the role.
* `required_conditional_access_authentication_context` - (Optional) The Entra ID Conditional Access context that must be present for activation. Conflicts with `require_multifactor_authentication`.

---

An `active_assignment_rules` block supports the following:

* `expiration_required` - (Optional) Must an assignment have an expiry date. `false` allows permanent assignment.
* `expire_after` - (Optional) The maximum length of time an assignment can be valid, as an ISO8601 duration. Permitted values: `P15D`, `P30D`, `P90D`, `P180D`, or `P365D`.
* `require_justification` - (Optional) Is a justification required to create new assignments.
* `require_multifactor_authentication` - (Optional) Is multi-factor authentication required to create new assignments.
* `require_ticket_info` - (Optional) Is ticket information required to create new assignments.

One of `expiration_required` or `expire_after` must be provided.

---

An `approval_stage` block supports the following:

* One or more `primary_approver` blocks as defined below.

---

An `eligible_assignment_rules` block supports the following:

* `expiration_required`- Must an assignment have an expiry date. `false` allows permanent assignment.
* `expire_after` - The maximum length of time an assignment can be valid, as an ISO8601 duration. Permitted values: `P15D`, `P30D`, `P90D`, `P180D`, or `P365D`.

One of `expiration_required` or `expire_after` must be provided.

---

A `notification_rules` block supports the following:

* `active_assignments` - (Optional) A `notification_target` block as defined below to configure notfications on active role assignments.
* `eligible_activations` - (Optional) A `notification_target` block as defined below for configuring notifications on activation of eligible role.
* `eligible_assignments` - (Optional) A `notification_target` block as defined below to configure notification on eligible role assignments.

At least one `notification_target` block must be provided.

---

A `notification_settings` block supports the following:

* `additional_recipients` - (Optional) A list of additional email addresses that will receive these notifications.
* `default_recipients` - (Required) Should the default recipients receive these notifications.
* `notification_level` - (Required) What level of notifications should be sent. Options are `All` or `Critical`.

---

A `notification_target` block supports the following:

* `admin_notifications` - (Optional) A `notification_settings` block as defined above.
* `approver_notifications` - (Optional) A `notification_settings` block as defined above.
* `assignee_notifications` - (Optional) A `notification_settings` block as defined above.

At least one `notification_settings` block must be provided.

---

A `primary_approver` block supports the following:

* `object_id` - (Required) The ID of the object which will act as an approver.
* `type` - (Required) The type of object acting as an approver. Possible options are `singleUser` and `groupMembers`.

## Attributes Reference

In addition to all arguments above, the following attributes are exported:

* `id` (String) The ID of this policy.
* `display_name` (String) The display name of this policy.
* `description` (String) The description of this policy.

## Import

Because these policies are created automatically by Entra ID, they will auto-import on first use.
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
---
subcategory: "Identity Governance"
---

# Resource: azuread_privileged_access_group_assignment_schedule_request
oWretch marked this conversation as resolved.
Show resolved Hide resolved

Manages an active assignment to a privileged access group.

## API Permissions

The following API permissions are required in order to use this resource.

When authenticated with a service principal, this resource requires the `PrivilegedAssignmentSchedule.ReadWrite.AzureADGroup` Microsoft Graph API permissions.

When authenticated with a user principal, this resource requires `Global Administrator` directory role, or the `Privileged Role Administrator` role in Identity Governance.

## Example Usage

```terraform
resource "azuread_group" "example" {
display_name = "group-name"
security_enabled = true
}

resource "azuread_user" "member" {
user_principal_name = "[email protected]"
display_name = "J. Doe"
mail_nickname = "jdoe"
password = "SecretP@sswd99!"
}

resource "azuread_privileged_access_group_assignment_schedule_request" "example" {
group_id = azuread_group.pim.id
principal_id = azuread_user.member.id
assignment_type = "member"
duration = "P30D"
justification = "as requested"
}
```

## Argument Reference

- `group_id` (Required) The Object ID of the Azure AD group to which the principal will be assigned.
- `principal_id` (Required) The Object ID of the principal to be assigned to the above group. Can be either a user or a group.
- `assignment_type` (Required) The type of assignment to the group. Can be either `member` or `owner`.
- `justification` (Optional) The justification for this assignment. May be required by the role policy.
- `ticket_number` (Optional) The ticket number in the ticket system approving this assignment. May be required by the role policy.
- `ticket_system` (Optional) The ticket system containing the ticket number approving this assignment. May be required by the role policy.
- `start_date` (Optional) The date from which this assignment is valid, formatted as an RFC3339 date string (e.g. 2018-01-01T01:02:03Z). If not provided, the assignment is immediately valid.
- `expiration_date` (Optional) The date that this assignment expires, formatted as an RFC3339 date string (e.g. 2018-01-01T01:02:03Z).
- `duration` (Optional) The duration that this assignment is valid for, formatted as an ISO8601 duration (e.g. P30D for 30 days, PT3H for three hours).
- `permanent_assignment` (Optional) Is this assigment permanently valid.

At least one of `expiration_date`, `duration`, or `permanent_assignment` must be supplied. The role policy may limit the maximum duration which can be supplied.

## Attributes Reference

In addition to all arguments above, the following attributes are exported:

- `id` (String) The ID of this request.
- `status` (String) The provisioning status of this request.
- `target_schedule_id` (String) The ID of this schedule created by this request.

## Import

An assignment schedule can be imported using the ID, e.g.

```shell
terraform import azuread_privileged_access_group_assignment_schedule_request.example 00000000-0000-0000-0000-000000000000
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
---
subcategory: "Identity Governance"
---

# Resource: azuread_privileged_access_group_eligibility_schedule_request
oWretch marked this conversation as resolved.
Show resolved Hide resolved

Manages an eligible assignment to a privileged access group.

## API Permissions

The following API permissions are required in order to use this resource.

When authenticated with a service principal, this resource requires the `PrivilegedEligibilitySchedule.ReadWrite.AzureADGroup` Microsoft Graph API permissions.

When authenticated with a user principal, this resource requires `Global Administrator` directory role, or the `Privileged Role Administrator` role in Identity Governance.

## Example Usage

```terraform
resource "azuread_group" "example" {
display_name = "group-name"
security_enabled = true
}

resource "azuread_user" "member" {
user_principal_name = "[email protected]"
display_name = "J. Doe"
mail_nickname = "jdoe"
password = "SecretP@sswd99!"
}

resource "azuread_privileged_access_group_eligibility_schedule_request" "example" {
group_id = azuread_group.pim.id
principal_id = azuread_user.member.id
assignment_type = "member"
duration = "P30D"
justification = "as requested"
}
```

## Argument Reference

- `group_id` (Required) The Object ID of the Azure AD group to which the principal will be assigned.
- `principal_id` (Required) The Object ID of the principal to be assigned to the above group. Can be either a user or a group.
- `assignment_type` (Required) The type of assignment to the group. Can be either `member` or `owner`.
- `justification` (Optional) The justification for this assignment. May be required by the role policy.
- `ticket_number` (Optional) The ticket number in the ticket system approving this assignment. May be required by the role policy.
- `ticket_system` (Optional) The ticket system containing the ticket number approving this assignment. May be required by the role policy.
- `start_date` (Optional) The date from which this assignment is valid, formatted as an RFC3339 date string (e.g. 2018-01-01T01:02:03Z). If not provided, the assignment is immediately valid.
- `expiration_date` (Optional) The date that this assignment expires, formatted as an RFC3339 date string (e.g. 2018-01-01T01:02:03Z).
- `duration` (Optional) The duration that this assignment is valid for, formatted as an ISO8601 duration (e.g. P30D for 30 days, PT3H for three hours).
- `permanent_assignment` (Optional) Is this assigment permanently valid.

At least one of `expiration_date`, `duration`, or `permanent_assignment` must be supplied. The role policy may limit the maximum duration which can be supplied.

## Attributes Reference

In addition to all arguments above, the following attributes are exported:

- `id` (String) The ID of this request.
- `status` (String) The provisioning status of this request.
- `target_schedule_id` (String) The ID of this schedule created by this request.

## Import

An assignment schedule can be imported using the ID, e.g.

```shell
terraform import azuread_privileged_access_group_eligibility_schedule_request.example 00000000-0000-0000-0000-000000000000
```
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ require (
github.com/hashicorp/go-uuid v1.0.3
github.com/hashicorp/terraform-plugin-sdk/v2 v2.29.0
github.com/hashicorp/terraform-plugin-testing v1.5.1
github.com/manicminer/hamilton v0.66.0
github.com/manicminer/hamilton v0.67.0
golang.org/x/text v0.14.0
)

Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/manicminer/hamilton v0.66.0 h1:pJPlaf32wMZBCArX1U5QC0YqR3vnJoc4crTuigLy0og=
github.com/manicminer/hamilton v0.66.0/go.mod h1:u80g9rPtJpCG7EC0iayttt8UfeAp6jknClixgZGE950=
github.com/manicminer/hamilton v0.67.0 h1:hG3tPunQCGcgP2Nx0+lwW+Swu9MXOs4JGospakK79pY=
github.com/manicminer/hamilton v0.67.0/go.mod h1:u80g9rPtJpCG7EC0iayttt8UfeAp6jknClixgZGE950=
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
Expand Down
2 changes: 2 additions & 0 deletions internal/provider/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ func SupportedTypedServices() []sdk.TypedServiceRegistration {
applications.Registration{},
directoryroles.Registration{},
domains.Registration{},
policies.Registration{},
identitygovernance.Registration{},
serviceprincipals.Registration{},
}
}
Expand Down
42 changes: 26 additions & 16 deletions internal/services/identitygovernance/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@ import (
)

type Client struct {
AccessPackageAssignmentPolicyClient *msgraph.AccessPackageAssignmentPolicyClient
AccessPackageCatalogClient *msgraph.AccessPackageCatalogClient
AccessPackageCatalogRoleAssignmentsClient *msgraph.EntitlementRoleAssignmentsClient
AccessPackageCatalogRoleClient *msgraph.EntitlementRoleDefinitionsClient
AccessPackageClient *msgraph.AccessPackageClient
AccessPackageResourceClient *msgraph.AccessPackageResourceClient
AccessPackageResourceRequestClient *msgraph.AccessPackageResourceRequestClient
AccessPackageResourceRoleScopeClient *msgraph.AccessPackageResourceRoleScopeClient
AccessPackageAssignmentPolicyClient *msgraph.AccessPackageAssignmentPolicyClient
AccessPackageCatalogClient *msgraph.AccessPackageCatalogClient
AccessPackageCatalogRoleAssignmentsClient *msgraph.EntitlementRoleAssignmentsClient
AccessPackageCatalogRoleClient *msgraph.EntitlementRoleDefinitionsClient
AccessPackageClient *msgraph.AccessPackageClient
AccessPackageResourceClient *msgraph.AccessPackageResourceClient
AccessPackageResourceRequestClient *msgraph.AccessPackageResourceRequestClient
AccessPackageResourceRoleScopeClient *msgraph.AccessPackageResourceRoleScopeClient
PrivilegedAccessGroupAssignmentScheduleRequestsClient *msgraph.PrivilegedAccessGroupAssignmentScheduleRequestsClient
PrivilegedAccessGroupEligibilityScheduleRequestsClient *msgraph.PrivilegedAccessGroupEligibilityScheduleRequestsClient
}

func NewClient(o *common.ClientOptions) *Client {
Expand Down Expand Up @@ -54,14 +56,22 @@ func NewClient(o *common.ClientOptions) *Client {
o.ConfigureClient(&accessPackageResourceRoleScopeClient.BaseClient)
accessPackageResourceRoleScopeClient.BaseClient.ApiVersion = msgraph.VersionBeta

privilegedAccessGroupAssignmentScheduleRequestsClient := msgraph.NewPrivilegedAccessGroupAssignmentScheduleRequestsClient()
o.ConfigureClient(&privilegedAccessGroupAssignmentScheduleRequestsClient.BaseClient)

privilegedAccessGroupEligibilityScheduleRequestsClient := msgraph.NewPrivilegedAccessGroupEligibilityScheduleRequestsClient()
o.ConfigureClient(&privilegedAccessGroupEligibilityScheduleRequestsClient.BaseClient)

return &Client{
AccessPackageAssignmentPolicyClient: accessPackageAssignmentPolicyClient,
AccessPackageCatalogClient: accessPackageCatalogClient,
AccessPackageCatalogRoleAssignmentsClient: accessPackageCatalogRoleAssignmentsClient,
AccessPackageCatalogRoleClient: accessPackageCatalogRoleClient,
AccessPackageClient: accessPackageClient,
AccessPackageResourceClient: accessPackageResourceClient,
AccessPackageResourceRequestClient: accessPackageResourceRequestClient,
AccessPackageResourceRoleScopeClient: accessPackageResourceRoleScopeClient,
AccessPackageAssignmentPolicyClient: accessPackageAssignmentPolicyClient,
AccessPackageCatalogClient: accessPackageCatalogClient,
AccessPackageCatalogRoleAssignmentsClient: accessPackageCatalogRoleAssignmentsClient,
AccessPackageCatalogRoleClient: accessPackageCatalogRoleClient,
AccessPackageClient: accessPackageClient,
AccessPackageResourceClient: accessPackageResourceClient,
AccessPackageResourceRequestClient: accessPackageResourceRequestClient,
AccessPackageResourceRoleScopeClient: accessPackageResourceRoleScopeClient,
PrivilegedAccessGroupAssignmentScheduleRequestsClient: privilegedAccessGroupAssignmentScheduleRequestsClient,
PrivilegedAccessGroupEligibilityScheduleRequestsClient: privilegedAccessGroupEligibilityScheduleRequestsClient,
}
}
15 changes: 15 additions & 0 deletions internal/services/identitygovernance/helpers/test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package helpers

import (
"time"

"github.com/hashicorp/terraform-plugin-testing/terraform"
"github.com/hashicorp/terraform-provider-azuread/internal/acceptance"
)

func SleepCheck(d time.Duration) acceptance.TestCheckFunc {
return func(s *terraform.State) error {
time.Sleep(d)
return nil
}
}
Loading