-
Notifications
You must be signed in to change notification settings - Fork 301
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Identity Governance roles and assignments
- Loading branch information
1 parent
dbad923
commit 34dc70f
Showing
8 changed files
with
482 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
--- | ||
subcategory: "Identity Governance" | ||
--- | ||
|
||
# Data Source: azuread_access_package_catalog_role | ||
|
||
Gets information about an access package catalog role. | ||
|
||
## API Permissions | ||
|
||
The following API permissions are required in order to use this data source. | ||
|
||
When authenticated with a service principal, this data source requires one of the following application roles: `EntitlementManagement.Read.All` or `Directory.Read.All` | ||
|
||
When authenticated with a user principal, this data source does not require any additional roles. | ||
|
||
## Example Usage (by Group Display Name) | ||
|
||
*Look up by display name* | ||
```terraform | ||
data "azuread_access_package_catalog_role" "example" { | ||
display_name = "Catalog owner" | ||
} | ||
``` | ||
|
||
*Look up by object ID* | ||
```terraform | ||
data "azuread_access_package_catalog_role" "example" { | ||
object_id = "ae79f266-94d4-4dab-b730-feca7e132178" | ||
} | ||
``` | ||
|
||
## Argument Reference | ||
|
||
The following arguments are supported: | ||
|
||
* `display_name` - (Optional) Specifies the display name of the role. | ||
* `object_id` - (Optional) Specifies the object ID of the role. | ||
|
||
~> One of `display_name` or `object_id` must be specified. | ||
|
||
## Attributes Reference | ||
|
||
The following attributes are exported: | ||
|
||
* `description` - The description of the role. | ||
* `display_name` - The display name of the role. | ||
* `object_id` - The object ID of the role. | ||
* `template_id` - The object ID of the role. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
--- | ||
subcategory: "Identity Governance" | ||
--- | ||
|
||
# Resource: azuread_access_package_catalog_role_assignment | ||
|
||
Manages a single catalog role assignment within Azure Active Directory. | ||
|
||
## API Permissions | ||
|
||
The following API permissions are required in order to use this resource. | ||
|
||
When authenticated with a service principal, this resource requires one of the following application roles: `EntitlementManagement.ReadWrite.All` or `Directory.ReadWrite.All` | ||
|
||
When authenticated with a user principal, this resource requires one of the following directory roles: `Identity Governance administrator` or `Global Administrator` | ||
|
||
## Example Usage | ||
|
||
```terraform | ||
data "azuread_user" "example" { | ||
user_principal_name = "[email protected]" | ||
} | ||
resource "azuread_access_package_catalog_role" "example" { | ||
display_name = "Catalog owner" | ||
} | ||
resource "azuread_access_package_catalog" "example" { | ||
display_name = "example-access-package-catalog" | ||
description = "Example access package catalog" | ||
} | ||
resource "azuread_access_package_catalog_role_assignment" "example" { | ||
role_id = azuread_access_package_catalog_role.example.object_id | ||
principal_object_id = data.azuread_user.example.object_id | ||
catalog_id = azuread_access_package_catalog.example.id | ||
} | ||
``` | ||
|
||
|
||
## Argument Reference | ||
|
||
The following arguments are supported: | ||
|
||
* `catalog_id` - (Required) The ID of the Catalog this role assignment will be scoped to. Changing this forces a new resource to be created. | ||
* `principal_object_id` - (Required) The object ID of the principal for you want to create a role assignment. Supported object types are Users, Groups or Service Principals. Changing this forces a new resource to be created. | ||
* `role_id` - (Required) The object ID of the catalog role you want to assign. Changing this forces a new resource to be created. | ||
|
||
## Attributes Reference | ||
|
||
In addition to all arguments above, the following attributes are exported: | ||
|
||
*No additional attributes are exported* | ||
|
||
## Import | ||
|
||
Catalog role assignments can be imported using the ID of the assignment, e.g. | ||
|
||
```shell | ||
terraform import azuread_access_package_catalog_role_assignment.test 00000000-0000-0000-0000-000000000000 | ||
``` |
127 changes: 127 additions & 0 deletions
127
internal/services/identitygovernance/access_package_catalog_role_assignment_resource.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
package identitygovernance | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"fmt" | ||
"log" | ||
"net/http" | ||
"strings" | ||
"time" | ||
|
||
"github.com/hashicorp/go-uuid" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
"github.com/hashicorp/terraform-provider-azuread/internal/clients" | ||
"github.com/hashicorp/terraform-provider-azuread/internal/tf" | ||
"github.com/hashicorp/terraform-provider-azuread/internal/utils" | ||
"github.com/hashicorp/terraform-provider-azuread/internal/validate" | ||
"github.com/manicminer/hamilton/msgraph" | ||
"github.com/manicminer/hamilton/odata" | ||
) | ||
|
||
func accessPackageCatalogRoleAssignmentResource() *schema.Resource { | ||
return &schema.Resource{ | ||
CreateContext: accessPackageCatalogRoleAssignmentResourceCreate, | ||
ReadContext: accessPackageCatalogRoleAssignmentResourceRead, | ||
DeleteContext: accessPackageCatalogRoleRoleAssignmentResourceDelete, | ||
|
||
Timeouts: &schema.ResourceTimeout{ | ||
Create: schema.DefaultTimeout(5 * time.Minute), | ||
Read: schema.DefaultTimeout(5 * time.Minute), | ||
Update: schema.DefaultTimeout(5 * time.Minute), | ||
Delete: schema.DefaultTimeout(5 * time.Minute), | ||
}, | ||
|
||
Importer: tf.ValidateResourceIDPriorToImport(func(id string) error { | ||
if _, err := uuid.ParseUUID(id); err != nil { | ||
return fmt.Errorf("specified ID (%q) is not valid: %s", id, err) | ||
} | ||
return nil | ||
}), | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"role_id": { | ||
Description: "The object ID of the catalog role for this assignment", | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
ValidateDiagFunc: validate.UUID, | ||
}, | ||
|
||
"principal_object_id": { | ||
Description: "The object ID of the member principal", | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
ValidateDiagFunc: validate.UUID, | ||
}, | ||
|
||
"catalog_id": { | ||
Description: "The unique ID of the access package catalog.", | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
ValidateDiagFunc: validate.UUID, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func accessPackageCatalogRoleAssignmentResourceCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
client := meta.(*clients.Client).IdentityGovernance.AccessPackageCatalogRoleAssignmentsClient | ||
|
||
catalogId := d.Get("catalog_id").(string) | ||
principalId := d.Get("principal_object_id").(string) | ||
roleId := d.Get("role_id").(string) | ||
|
||
properties := msgraph.UnifiedRoleAssignment{ | ||
DirectoryScopeId: utils.String("/"), | ||
PrincipalId: utils.String(principalId), | ||
RoleDefinitionId: utils.String(roleId), | ||
AppScopeId: utils.String("/AccessPackageCatalog/" + catalogId), | ||
} | ||
|
||
assignment, status, err := client.Create(ctx, properties) | ||
if err != nil { | ||
return tf.ErrorDiagF(err, "Assigning catalog role %q to directory principal %q on catalog %q, received %d with error: %+v", roleId, principalId, catalogId, status, err) | ||
} | ||
if assignment == nil || assignment.ID() == nil { | ||
return tf.ErrorDiagF(errors.New("returned role assignment ID was nil"), "API Error") | ||
} | ||
|
||
d.SetId(*assignment.ID()) | ||
return accessPackageCatalogRoleAssignmentResourceRead(ctx, d, meta) | ||
} | ||
|
||
func accessPackageCatalogRoleAssignmentResourceRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
client := meta.(*clients.Client).IdentityGovernance.AccessPackageCatalogRoleAssignmentsClient | ||
|
||
id := d.Id() | ||
assignment, status, err := client.Get(ctx, id, odata.Query{}) | ||
if err != nil { | ||
if status == http.StatusNotFound { | ||
log.Printf("[DEBUG] Assignment with ID %q was not found - removing from state", id) | ||
d.SetId("") | ||
return nil | ||
} | ||
return tf.ErrorDiagF(err, "Retrieving role assignment %q", id) | ||
} | ||
|
||
catalogId := strings.TrimPrefix(*assignment.AppScopeId, "/AccessPackageCatalog/") | ||
|
||
tf.Set(d, "catalog_id", utils.String(catalogId)) | ||
tf.Set(d, "principal_object_id", assignment.PrincipalId) | ||
tf.Set(d, "role_id", assignment.RoleDefinitionId) | ||
|
||
return nil | ||
} | ||
|
||
func accessPackageCatalogRoleRoleAssignmentResourceDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
client := meta.(*clients.Client).IdentityGovernance.AccessPackageCatalogRoleAssignmentsClient | ||
|
||
if _, err := client.Delete(ctx, d.Id()); err != nil { | ||
return tf.ErrorDiagF(err, "Deleting role assignment %q: %+v", d.Id(), err) | ||
} | ||
return nil | ||
} |
75 changes: 75 additions & 0 deletions
75
internal/services/identitygovernance/access_package_catalog_role_assignment_resource_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package identitygovernance_test | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"net/http" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform" | ||
"github.com/hashicorp/terraform-provider-azuread/internal/acceptance" | ||
"github.com/hashicorp/terraform-provider-azuread/internal/acceptance/check" | ||
"github.com/hashicorp/terraform-provider-azuread/internal/clients" | ||
"github.com/hashicorp/terraform-provider-azuread/internal/utils" | ||
"github.com/manicminer/hamilton/odata" | ||
) | ||
|
||
type AccessPackageCatalogRoleAssignmentResource struct{} | ||
|
||
func TestAccAccessPackageCatalogRoleAssignmentResource_basic(t *testing.T) { | ||
data := acceptance.BuildTestData(t, "azuread_access_package_catalog_role_assignment", "test") | ||
r := AccessPackageCatalogRoleAssignmentResource{} | ||
|
||
data.DataSourceTest(t, []resource.TestStep{ | ||
{ | ||
Config: r.basic(data), | ||
Check: resource.ComposeTestCheckFunc( | ||
check.That(data.ResourceName).ExistsInAzure(r), | ||
check.That(data.ResourceName).Key("catalog_id").IsUuid(), | ||
check.That(data.ResourceName).Key("principal_object_id").IsUuid(), | ||
check.That(data.ResourceName).Key("role_id").Exists(), | ||
), | ||
}, | ||
}) | ||
} | ||
|
||
func (r AccessPackageCatalogRoleAssignmentResource) Exists(ctx context.Context, clients *clients.Client, state *terraform.InstanceState) (*bool, error) { | ||
client := clients.IdentityGovernance.AccessPackageCatalogRoleAssignmentsClient | ||
client.BaseClient.DisableRetries = true | ||
|
||
if _, status, err := client.Get(ctx, state.ID, odata.Query{}); err != nil { | ||
if status == http.StatusNotFound { | ||
return utils.Bool(false), nil | ||
} | ||
return nil, fmt.Errorf("failed to retrieve directory role assignment %q: %+v", state.ID, err) | ||
} | ||
|
||
return utils.Bool(true), nil | ||
} | ||
|
||
func (AccessPackageCatalogRoleAssignmentResource) basic(data acceptance.TestData) string { | ||
return fmt.Sprintf(` | ||
%[1]s | ||
data "azuread_access_package_catalog_role" "test" { | ||
display_name = "Catalog owner" | ||
} | ||
data "azuread_domains" "test" { | ||
only_initial = true | ||
} | ||
resource "azuread_user" "test" { | ||
user_principal_name = "acctestUser'%[2]d@${data.azuread_domains.test.domains.0.domain_name}" | ||
display_name = "acctestUser-%[2]d" | ||
password = "%[3]s" | ||
} | ||
resource "azuread_access_package_catalog_role_assignment" "test" { | ||
role_id = data.azuread_access_package_catalog_role.test.object_id | ||
catalog_id = azuread_access_package_catalog.test.id | ||
principal_object_id = azuread_user.test.object_id | ||
} | ||
`, AccessPackageCatalogResource{}.basic(data), data.RandomInteger, data.RandomPassword) | ||
} |
Oops, something went wrong.