From 4bea691fc63d014d938f0f550d5159e6352bdb60 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Wed, 22 Jan 2025 08:33:36 +0200 Subject: [PATCH 01/54] initial commit --- .../pim-role-assignment/README.md | 194 ++++++++++++++++++ .../pim-role-assignment/main.bicep | 155 ++++++++++++++ .../pim-role-assignment/main.json | 57 +++++ .../modules/definitions.bicep | 46 +++++ .../modules/management-group.bicep | 91 ++++++++ .../modules/resource-group.bicep | 85 ++++++++ .../modules/subscription.bicep | 82 ++++++++ .../tests/e2e/mg.defaults/dependencies.bicep | 13 ++ .../tests/e2e/mg.defaults/main.test.bicep | 70 +++++++ .../tests/e2e/waf-aligned/main.test.bicep | 48 +++++ .../pim-role-assignment/version.json | 7 + 11 files changed, 848 insertions(+) create mode 100644 avm/ptn/authorization/pim-role-assignment/README.md create mode 100644 avm/ptn/authorization/pim-role-assignment/main.bicep create mode 100644 avm/ptn/authorization/pim-role-assignment/main.json create mode 100644 avm/ptn/authorization/pim-role-assignment/modules/definitions.bicep create mode 100644 avm/ptn/authorization/pim-role-assignment/modules/management-group.bicep create mode 100644 avm/ptn/authorization/pim-role-assignment/modules/resource-group.bicep create mode 100644 avm/ptn/authorization/pim-role-assignment/modules/subscription.bicep create mode 100644 avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/dependencies.bicep create mode 100644 avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep create mode 100644 avm/ptn/authorization/pim-role-assignment/tests/e2e/waf-aligned/main.test.bicep create mode 100644 avm/ptn/authorization/pim-role-assignment/version.json diff --git a/avm/ptn/authorization/pim-role-assignment/README.md b/avm/ptn/authorization/pim-role-assignment/README.md new file mode 100644 index 0000000000..172facef4a --- /dev/null +++ b/avm/ptn/authorization/pim-role-assignment/README.md @@ -0,0 +1,194 @@ +# `[Authorization/PimRoleAssignment]` + + + +## Navigation + +- [Resource Types](#Resource-Types) +- [Usage examples](#Usage-examples) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Data Collection](#Data-Collection) + +## Resource Types + +_None_ + +## Usage examples + +The following section provides usage examples for the module, which were used to validate and deploy the module successfully. For a full reference, please review the module's test folder in its repository. + +>**Note**: Each example lists all the required parameters first, followed by the rest - each in alphabetical order. + +>**Note**: To reference the module, please use the following syntax `br/public:avm/ptn/authorization/pim-role-assignment:`. + +- [Defaults](#example-1-defaults) +- [Waf-Aligned](#example-2-waf-aligned) + +### Example 1: _Defaults_ + +
+ +via Bicep module + +```bicep +module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:' = { + name: 'pimRoleAssignmentDeployment' + params: { + // Required parameters + name: 'apradef001' + // Non-required parameters + location: '' + } +} +``` + +
+

+ +

+ +via JSON parameters file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "apradef001" + }, + // Non-required parameters + "location": { + "value": "" + } + } +} +``` + +
+

+ +

+ +via Bicep parameters file + +```bicep-params +using 'br/public:avm/ptn/authorization/pim-role-assignment:' + +// Required parameters +param name = 'apradef001' +// Non-required parameters +param location = '' +``` + +
+

+ +### Example 2: _Waf-Aligned_ + +

+ +via Bicep module + +```bicep +module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:' = { + name: 'pimRoleAssignmentDeployment' + params: { + // Required parameters + name: 'aprawaf001' + // Non-required parameters + location: '' + } +} +``` + +
+

+ +

+ +via JSON parameters file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "aprawaf001" + }, + // Non-required parameters + "location": { + "value": "" + } + } +} +``` + +
+

+ +

+ +via Bicep parameters file + +```bicep-params +using 'br/public:avm/ptn/authorization/pim-role-assignment:' + +// Required parameters +param name = 'aprawaf001' +// Non-required parameters +param location = '' +``` + +
+

+ +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-name) | string | Name of the resource to create. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | +| [`location`](#parameter-location) | string | Location for all Resources. | + +### Parameter: `name` + +Name of the resource to create. + +- Required: Yes +- Type: string + +### Parameter: `enableTelemetry` + +Enable/Disable usage telemetry for module. + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `location` + +Location for all Resources. + +- Required: No +- Type: string +- Default: `[resourceGroup().location]` + +## Outputs + +_None_ + +## Data Collection + +The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. diff --git a/avm/ptn/authorization/pim-role-assignment/main.bicep b/avm/ptn/authorization/pim-role-assignment/main.bicep new file mode 100644 index 0000000000..9e1dff6625 --- /dev/null +++ b/avm/ptn/authorization/pim-role-assignment/main.bicep @@ -0,0 +1,155 @@ +metadata name = '' +metadata description = '' + +targetScope = 'managementGroup' + +import { requestTypeType, scheduleInfoType, scheduleInfoExpirationType, ticketInfoType } from 'modules/definitions.bicep' + +@sys.description('Required. You can provide either the display name of the role definition (must be configured in the variable `builtInRoleNames`), or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.') +param roleDefinitionIdOrName string + +@sys.description('Required. The Principal or Object ID of the Security Principal (User, Group, Service Principal, Managed Identity).') +param principalId string + +@sys.description('Optional. Name of the Resource Group to assign the RBAC role to. If Resource Group name is provided, and Subscription ID is provided, the module deploys at resource group level, therefore assigns the provided RBAC role to the resource group.') +param resourceGroupName string = '' + +@sys.description('Optional. Subscription ID of the subscription to assign the RBAC role to. If no Resource Group name is provided, the module deploys at subscription level, therefore assigns the provided RBAC role to the subscription.') +param subscriptionId string = '' + +@sys.description('Optional. Group ID of the Management Group to assign the RBAC role to. If not provided, will use the current scope for deployment.') +param managementGroupId string = managementGroup().name + +@sys.description('Optional. Location deployment metadata.') +param location string = deployment().location + +@sys.description('Optional. The justification for the role eligibility.') +param justification string = '' + +@sys.description('Required. The type of the role assignment eligibility request.') +param requestType requestTypeType + +@sys.description('Optional. The resultant role eligibility assignment id or the role eligibility assignment id being updated.') +param targetRoleEligibilityScheduleId string = '' + +@sys.description('Optional. The role eligibility assignment instance id being updated.') +param targetRoleEligibilityScheduleInstanceId string = '' + +@sys.description('Optional. Ticket Info of the role eligibility.') +param ticketInfo ticketInfoType? + +@sys.description('Optional. Schedule info of the role eligibility assignment.') +param scheduleInfo scheduleInfoType + +@sys.description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to.') +param condition string = '' + +@sys.description('Optional. Version of the condition. Currently accepted value is "2.0".') +@allowed([ + '2.0' +]) +param conditionVersion string = '2.0' + +@sys.description('Optional. Enable/Disable usage telemetry for module.') +param enableTelemetry bool = true + +// ============== // +// Resources // +// ============== // + +#disable-next-line no-deployments-resources +resource avmTelemetry 'Microsoft.Resources/deployments@2024-03-01' = if (enableTelemetry) { + name: '46d3xbcp.ptn.authorization-pimroleassignment.${replace('-..--..-', '.', '-')}.${substring(uniqueString(deployment().name, location), 0, 4)}' + properties: { + mode: 'Incremental' + template: { + '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' + contentVersion: '1.0.0.0' + resources: [] + outputs: { + telemetry: { + type: 'String' + value: 'For more information, see https://aka.ms/avm/TelemetryInfo' + } + } + } + } + location: location +} + +module roleAssignment_mg 'modules/management-group.bicep' = if (empty(subscriptionId) && empty(resourceGroupName)) { + name: '${uniqueString(deployment().name, location)}-PimRoleAssignment-MG-Module' + scope: managementGroup(managementGroupId) + params: { + roleDefinitionIdOrName: roleDefinitionIdOrName + principalId: principalId + managementGroupId: managementGroupId + requestType: requestType + justification: justification + targetRoleEligibilityScheduleId: targetRoleEligibilityScheduleId + targetRoleEligibilityScheduleInstanceId: targetRoleEligibilityScheduleInstanceId + ticketInfo: ticketInfo + conditionVersion: conditionVersion + condition: !empty(condition) ? condition : '' + scheduleInfo: scheduleInfo + } +} + +/* +module roleAssignment_sub 'modules/subscription.bicep' = if (!empty(subscriptionId) && empty(resourceGroupName)) { + name: '${uniqueString(deployment().name, location)}-RoleAssignment-Sub-Module' + scope: subscription(subscriptionId) + params: { + roleDefinitionIdOrName: roleDefinitionIdOrName + principalId: principalId + subscriptionId: subscriptionId + description: !empty(description) ? description : '' + principalType: !empty(principalType) ? principalType : '' + delegatedManagedIdentityResourceId: !empty(delegatedManagedIdentityResourceId) + ? delegatedManagedIdentityResourceId + : '' + conditionVersion: conditionVersion + condition: !empty(condition) ? condition : '' + } +} + +module roleAssignment_rg 'modules/resource-group.bicep' = if (!empty(resourceGroupName) && !empty(subscriptionId)) { + name: '${uniqueString(deployment().name, location)}-RoleAssignment-RG-Module' + scope: resourceGroup(subscriptionId, resourceGroupName) + params: { + roleDefinitionIdOrName: roleDefinitionIdOrName + principalId: principalId + subscriptionId: subscriptionId + resourceGroupName: resourceGroupName + description: !empty(description) ? description : '' + principalType: !empty(principalType) ? principalType : '' + delegatedManagedIdentityResourceId: !empty(delegatedManagedIdentityResourceId) + ? delegatedManagedIdentityResourceId + : '' + conditionVersion: conditionVersion + condition: !empty(condition) ? condition : '' + } +} + + +@sys.description('The GUID of the Role Assignment.') +output name string = empty(subscriptionId) && empty(resourceGroupName) + ? roleAssignment_mg.outputs.name + : (!empty(subscriptionId) && empty(resourceGroupName) + ? roleAssignment_sub.outputs.name + : roleAssignment_rg.outputs.name) + +@sys.description('The resource ID of the Role Assignment.') +output resourceId string = empty(subscriptionId) && empty(resourceGroupName) + ? roleAssignment_mg.outputs.resourceId + : (!empty(subscriptionId) && empty(resourceGroupName) + ? roleAssignment_sub.outputs.resourceId + : roleAssignment_rg.outputs.resourceId) + +@sys.description('The scope this Role Assignment applies to.') +output scope string = empty(subscriptionId) && empty(resourceGroupName) + ? roleAssignment_mg.outputs.scope + : (!empty(subscriptionId) && empty(resourceGroupName) + ? roleAssignment_sub.outputs.scope + : roleAssignment_rg.outputs.scope) +*/ diff --git a/avm/ptn/authorization/pim-role-assignment/main.json b/avm/ptn/authorization/pim-role-assignment/main.json new file mode 100644 index 0000000000..ee978d2e98 --- /dev/null +++ b/avm/ptn/authorization/pim-role-assignment/main.json @@ -0,0 +1,57 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.32.4.45862", + "templateHash": "17114577725154327600" + }, + "name": "", + "description": "" + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the resource to create." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all Resources." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + }, + "resources": [ + { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2024-03-01", + "name": "[format('46d3xbcp.[[REPLACE WITH TELEMETRY IDENTIFIER]].{0}.{1}', replace('-..--..-', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + } + ] +} \ No newline at end of file diff --git a/avm/ptn/authorization/pim-role-assignment/modules/definitions.bicep b/avm/ptn/authorization/pim-role-assignment/modules/definitions.bicep new file mode 100644 index 0000000000..95c9dcf61f --- /dev/null +++ b/avm/ptn/authorization/pim-role-assignment/modules/definitions.bicep @@ -0,0 +1,46 @@ +// ================ // +// Definitions // +// ================ // + +@export() +@sys.description('Optional. The request type of the role assignment.') +type requestTypeType = + | 'AdminAssign' + | 'AdminExtend' + | 'AdminRemove' + | 'AdminRenew' + | 'AdminUpdate' + | 'SelfActivate' + | 'SelfDeactivate' + | 'SelfExtend' + | 'SelfRenew' + +@export() +type scheduleInfoType = { + @sys.description('Optional. The expiry information for the role eligibility.') + expiration: scheduleInfoExpirationType? + + @sys.description('Optional. Start DateTime of the role eligibility assignment.') + startDateTime: string? +} + +@export() +type scheduleInfoExpirationType = { + @sys.description('Optional. Duration of the role eligibility assignment in TimeSpan format.') + duration: string? + + @sys.description('Optional. End DateTime of the role eligibility assignment.') + endDateTime: string? + + @sys.description('Optional. Type of the role eligibility assignment expiration.') + type: 'AfterDateTime' | 'AfterDuration' | 'NoExpiration'? +} + +@export() +type ticketInfoType = { + @sys.description('Optional. The ticket number for the role eligibility assignment.') + ticketNumber: string? + + @sys.description('Optional. The ticket system name for the role eligibility assignment.') + ticketSystem: string? +}? diff --git a/avm/ptn/authorization/pim-role-assignment/modules/management-group.bicep b/avm/ptn/authorization/pim-role-assignment/modules/management-group.bicep new file mode 100644 index 0000000000..eb7abf4541 --- /dev/null +++ b/avm/ptn/authorization/pim-role-assignment/modules/management-group.bicep @@ -0,0 +1,91 @@ +metadata name = 'Role Assignments (Management Group scope)' +metadata description = 'This module deploys a PIM Role Assignment at a Management Group scope.' + +targetScope = 'managementGroup' + +import { requestTypeType, scheduleInfoType, scheduleInfoExpirationType, ticketInfoType } from 'definitions.bicep' + +@sys.description('Required. You can provide either the display name of the role definition (must be configured in the variable `builtInRoleNames`), or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.') +param roleDefinitionIdOrName string + +@sys.description('Required. The Principal or Object ID of the Security Principal (User, Group, Service Principal, Managed Identity).') +param principalId string + +@sys.description('Optional. Group ID of the Management Group to assign the RBAC role to. If not provided, will use the current scope for deployment.') +param managementGroupId string = managementGroup().name + +@sys.description('Optional. The justification for the role eligibility.') +param justification string = '' + +@sys.description('Required. The type of the role assignment eligibility request.') +param requestType requestTypeType + +@sys.description('Optional. The resultant role eligibility assignment id or the role eligibility assignment id being updated.') +param targetRoleEligibilityScheduleId string = '' + +@sys.description('Optional. The role eligibility assignment instance id being updated.') +param targetRoleEligibilityScheduleInstanceId string = '' + +@sys.description('Optional. Ticket Info of the role eligibility.') +param ticketInfo ticketInfoType? + +@sys.description('Optional. Schedule info of the role eligibility assignment.') +param scheduleInfo scheduleInfoType + +@sys.description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to.') +param condition string = '' + +@sys.description('Optional. Version of the condition. Currently accepted value is "2.0".') +@allowed([ + '2.0' +]) +param conditionVersion string = '2.0' + +var builtInRoleNames = { + Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') + Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') + Reader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + 'Resource Policy Contributor': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '36243c78-bf99-498c-9df9-86d9f8d28608' + ) + 'Role Based Access Control Administrator': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'f58310d9-a9f6-439a-9e8d-f62e7b41a168' + ) + 'User Access Administrator': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9' + ) + 'Management Group Reader': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'ac63b705-f282-497d-ac71-919bf39d939d' + ) +} + +var roleDefinitionIdVar = (builtInRoleNames[?roleDefinitionIdOrName] ?? roleDefinitionIdOrName) + +resource pimRoleAssignment 'Microsoft.Authorization/roleEligibilityScheduleRequests@2022-04-01-preview' = { + name: guid(managementGroupId, roleDefinitionIdVar, principalId) + properties: { + principalId: principalId + requestType: requestType + roleDefinitionId: roleDefinitionIdVar + condition: !empty(condition) ? condition : null + conditionVersion: !empty(conditionVersion) && !empty(condition) ? conditionVersion : null + justification: justification + scheduleInfo: scheduleInfo + targetRoleEligibilityScheduleId: targetRoleEligibilityScheduleId + targetRoleEligibilityScheduleInstanceId: targetRoleEligibilityScheduleInstanceId + ticketInfo: ticketInfo + } +} + +@sys.description('The GUID of the Role Assignment.') +output name string = pimRoleAssignment.name + +@sys.description('The resource ID of the Role Assignment.') +output resourceId string = pimRoleAssignment.id + +@sys.description('The scope this Role Assignment applies to.') +output scope string = az.resourceId('Microsoft.Management/managementGroups', managementGroupId) diff --git a/avm/ptn/authorization/pim-role-assignment/modules/resource-group.bicep b/avm/ptn/authorization/pim-role-assignment/modules/resource-group.bicep new file mode 100644 index 0000000000..c73d5d07f5 --- /dev/null +++ b/avm/ptn/authorization/pim-role-assignment/modules/resource-group.bicep @@ -0,0 +1,85 @@ +metadata name = 'Role Assignments (Resource Group scope)' +metadata description = 'This module deploys a Role Assignment at a Resource Group scope.' + +targetScope = 'resourceGroup' + +@sys.description('Required. You can provide either the display name of the role definition (must be configured in the variable `builtInRoleNames`), or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.') +param roleDefinitionIdOrName string + +@sys.description('Required. The Principal or Object ID of the Security Principal (User, Group, Service Principal, Managed Identity).') +param principalId string + +@sys.description('Optional. Name of the Resource Group to assign the RBAC role to. If not provided, will use the current scope for deployment.') +param resourceGroupName string = resourceGroup().name + +@sys.description('Optional. Subscription ID of the subscription to assign the RBAC role to. If not provided, will use the current scope for deployment.') +param subscriptionId string = subscription().subscriptionId + +@sys.description('Optional. The description of the role assignment.') +param description string = '' + +@sys.description('Optional. ID of the delegated managed identity resource.') +param delegatedManagedIdentityResourceId string = '' + +@sys.description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to.') +param condition string = '' + +@sys.description('Optional. Version of the condition. Currently accepted value is "2.0".') +@allowed([ + '2.0' +]) +param conditionVersion string = '2.0' + +@sys.description('Optional. The principal type of the assigned principal ID.') +@allowed([ + 'ServicePrincipal' + 'Group' + 'User' + 'ForeignGroup' + 'Device' + '' +]) +param principalType string + +var builtInRoleNames = { + Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') + Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') + Reader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + 'Role Based Access Control Administrator': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'f58310d9-a9f6-439a-9e8d-f62e7b41a168' + ) + 'User Access Administrator': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9' + ) +} + +var roleDefinitionIdVar = (builtInRoleNames[?roleDefinitionIdOrName] ?? roleDefinitionIdOrName) + +resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(subscriptionId, resourceGroupName, roleDefinitionIdVar, principalId) + properties: { + roleDefinitionId: roleDefinitionIdVar + principalId: principalId + description: !empty(description) ? description : null + principalType: !empty(principalType) ? any(principalType) : null + delegatedManagedIdentityResourceId: !empty(delegatedManagedIdentityResourceId) + ? delegatedManagedIdentityResourceId + : null + conditionVersion: !empty(conditionVersion) && !empty(condition) ? conditionVersion : null + condition: !empty(condition) ? condition : null + } +} + +@sys.description('The GUID of the Role Assignment.') +output name string = roleAssignment.name + +@sys.description('The resource ID of the Role Assignment.') +output resourceId string = roleAssignment.id + +@sys.description('The name of the resource group the role assignment was applied at.') +output resourceGroupName string = resourceGroup().name + +@sys.description('The scope this Role Assignment applies to.') +output scope string = resourceGroup().id diff --git a/avm/ptn/authorization/pim-role-assignment/modules/subscription.bicep b/avm/ptn/authorization/pim-role-assignment/modules/subscription.bicep new file mode 100644 index 0000000000..1142912b4c --- /dev/null +++ b/avm/ptn/authorization/pim-role-assignment/modules/subscription.bicep @@ -0,0 +1,82 @@ +metadata name = 'Role Assignments (Subscription scope)' +metadata description = 'This module deploys a Role Assignment at a Subscription scope.' + +targetScope = 'subscription' + +@sys.description('Required. You can provide either the display name of the role definition (must be configured in the variable `builtInRoleNames`), or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.') +param roleDefinitionIdOrName string + +@sys.description('Required. The Principal or Object ID of the Security Principal (User, Group, Service Principal, Managed Identity).') +param principalId string + +@sys.description('Optional. Subscription ID of the subscription to assign the RBAC role to. If not provided, will use the current scope for deployment.') +param subscriptionId string = subscription().subscriptionId + +@sys.description('Optional. The description of the role assignment.') +param description string = '' + +@sys.description('Optional. ID of the delegated managed identity resource.') +param delegatedManagedIdentityResourceId string = '' + +@sys.description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to.') +param condition string = '' + +@sys.description('Optional. Version of the condition. Currently accepted value is "2.0".') +@allowed([ + '2.0' +]) +param conditionVersion string = '2.0' + +@sys.description('Optional. The principal type of the assigned principal ID.') +@allowed([ + 'ServicePrincipal' + 'Group' + 'User' + 'ForeignGroup' + 'Device' + '' +]) +param principalType string = '' + +var builtInRoleNames = { + Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') + Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') + Reader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + 'Role Based Access Control Administrator': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'f58310d9-a9f6-439a-9e8d-f62e7b41a168' + ) + 'User Access Administrator': subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9' + ) +} + +var roleDefinitionIdVar = (builtInRoleNames[?roleDefinitionIdOrName] ?? roleDefinitionIdOrName) + +resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(subscriptionId, roleDefinitionIdVar, principalId) + properties: { + roleDefinitionId: roleDefinitionIdVar + principalId: principalId + description: !empty(description) ? description : null + principalType: !empty(principalType) ? any(principalType) : null + delegatedManagedIdentityResourceId: !empty(delegatedManagedIdentityResourceId) + ? delegatedManagedIdentityResourceId + : null + conditionVersion: !empty(conditionVersion) && !empty(condition) ? conditionVersion : null + condition: !empty(condition) ? condition : null + } +} + +@sys.description('The GUID of the Role Assignment.') +output name string = roleAssignment.name + +@sys.description('The resource ID of the Role Assignment.') +output resourceId string = roleAssignment.id + +@sys.description('The name of the resource group the role assignment was applied at.') +output subscriptionName string = subscription().displayName + +@sys.description('The scope this Role Assignment applies to.') +output scope string = subscription().id diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/dependencies.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/dependencies.bicep new file mode 100644 index 0000000000..d367770432 --- /dev/null +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/dependencies.bicep @@ -0,0 +1,13 @@ +@description('Optional. The location to deploy resources to.') +param location string = resourceGroup().location + +@description('Required. The name of the Managed Identity to create.') +param managedIdentityName string + +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: managedIdentityName + location: location +} + +@description('The principal ID of the created Managed Identity.') +output managedIdentityPrincipalId string = managedIdentity.properties.principalId diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep new file mode 100644 index 0000000000..f9be6a9ad0 --- /dev/null +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep @@ -0,0 +1,70 @@ +targetScope = 'managementGroup' +metadata name = 'PIM Role Assignments (Management Group scope)' +metadata description = 'This module deploys a PIM Role Assignment at a Management Group scope using minimal parameters.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-authorization.roleassignments-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'pimmgmin' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +@description('Optional. Subscription ID of the subscription to assign the RBAC role to. If no Resource Group name is provided, the module deploys at subscription level, therefore assigns the provided RBAC role to the subscription.') +param subscriptionId string = '#_subscriptionId_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +/*module resourceGroup 'br/public:avm/res/resources/resource-group:0.2.3' = { + scope: subscription('${subscriptionId}') + name: '${uniqueString(deployment().name, resourceLocation)}-resourceGroup' + params: { + name: resourceGroupName + location: resourceLocation + } +} + +module nestedDependencies 'dependencies.bicep' = { + scope: az.resourceGroup(subscriptionId, resourceGroupName) + name: '${uniqueString(deployment().name, resourceLocation)}-${serviceShort}-nestedDependencies' + params: { + managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' + location: resourceLocation + } + dependsOn: [ + resourceGroup + ] +}*/ + +// ============== // +// Test Execution // +// ============== // + +module testDeployment '../../../main.bicep' = { + name: '${uniqueString(deployment().name)}-test-${serviceShort}' + params: { + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + roleDefinitionIdOrName: 'Resource Policy Contributor' + requestType: 'AdminAssign' + scheduleInfo: { + expiration: { + type: 'AfterDuration' + duration: 'P1H' + } + } + location: resourceLocation + } +} diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/waf-aligned/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/waf-aligned/main.test.bicep new file mode 100644 index 0000000000..2970d5f024 --- /dev/null +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/waf-aligned/main.test.bicep @@ -0,0 +1,48 @@ +targetScope = 'subscription' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +// e.g., for a module 'network/private-endpoint' you could use 'dep-dev-network.privateendpoints-${serviceShort}-rg' +param resourceGroupName string = 'dep-${namePrefix}---${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +// e.g., for a module 'network/private-endpoint' you could use 'npe' as a prefix and then 'waf' as a suffix for the waf-aligned test +param serviceShort string = 'aprawaf' + +@description('Optional. A token to inject into the name of each resource. This value can be automatically injected by the CI.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: resourceLocation +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + // You parameters go here + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + } + } +] diff --git a/avm/ptn/authorization/pim-role-assignment/version.json b/avm/ptn/authorization/pim-role-assignment/version.json new file mode 100644 index 0000000000..8def869ede --- /dev/null +++ b/avm/ptn/authorization/pim-role-assignment/version.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.1", + "pathFilters": [ + "./main.json" + ] +} From 900a0308f6d618782084efacf212c26eb2fd8119 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Thu, 23 Jan 2025 14:06:28 +0200 Subject: [PATCH 02/54] feat: Update PIM Role Assignment metadata and descriptions for clarity --- .../modules/definitions.bicep | 2 +- .../modules/management-group.bicep | 10 +-- .../modules/resource-group.bicep | 62 +++++++++-------- .../modules/subscription.bicep | 66 ++++++++++--------- 4 files changed, 74 insertions(+), 66 deletions(-) diff --git a/avm/ptn/authorization/pim-role-assignment/modules/definitions.bicep b/avm/ptn/authorization/pim-role-assignment/modules/definitions.bicep index 95c9dcf61f..c4d9a1d470 100644 --- a/avm/ptn/authorization/pim-role-assignment/modules/definitions.bicep +++ b/avm/ptn/authorization/pim-role-assignment/modules/definitions.bicep @@ -26,7 +26,7 @@ type scheduleInfoType = { @export() type scheduleInfoExpirationType = { - @sys.description('Optional. Duration of the role eligibility assignment in TimeSpan format.') + @sys.description('Optional. Duration of the role eligibility assignment in TimeSpan format. Example: P365D, P2H') duration: string? @sys.description('Optional. End DateTime of the role eligibility assignment.') diff --git a/avm/ptn/authorization/pim-role-assignment/modules/management-group.bicep b/avm/ptn/authorization/pim-role-assignment/modules/management-group.bicep index eb7abf4541..c00d3eabf2 100644 --- a/avm/ptn/authorization/pim-role-assignment/modules/management-group.bicep +++ b/avm/ptn/authorization/pim-role-assignment/modules/management-group.bicep @@ -1,4 +1,4 @@ -metadata name = 'Role Assignments (Management Group scope)' +metadata name = ' PIM Role Assignments (Management Group scope)' metadata description = 'This module deploys a PIM Role Assignment at a Management Group scope.' targetScope = 'managementGroup' @@ -69,8 +69,8 @@ resource pimRoleAssignment 'Microsoft.Authorization/roleEligibilityScheduleReque name: guid(managementGroupId, roleDefinitionIdVar, principalId) properties: { principalId: principalId - requestType: requestType roleDefinitionId: roleDefinitionIdVar + requestType: requestType condition: !empty(condition) ? condition : null conditionVersion: !empty(conditionVersion) && !empty(condition) ? conditionVersion : null justification: justification @@ -81,11 +81,11 @@ resource pimRoleAssignment 'Microsoft.Authorization/roleEligibilityScheduleReque } } -@sys.description('The GUID of the Role Assignment.') +@sys.description('The GUID of the PIM Role Assignment.') output name string = pimRoleAssignment.name -@sys.description('The resource ID of the Role Assignment.') +@sys.description('The resource ID of the PIM Role Assignment.') output resourceId string = pimRoleAssignment.id -@sys.description('The scope this Role Assignment applies to.') +@sys.description('The scope this PIM Role Assignment applies to.') output scope string = az.resourceId('Microsoft.Management/managementGroups', managementGroupId) diff --git a/avm/ptn/authorization/pim-role-assignment/modules/resource-group.bicep b/avm/ptn/authorization/pim-role-assignment/modules/resource-group.bicep index c73d5d07f5..d20466b3c3 100644 --- a/avm/ptn/authorization/pim-role-assignment/modules/resource-group.bicep +++ b/avm/ptn/authorization/pim-role-assignment/modules/resource-group.bicep @@ -1,8 +1,10 @@ -metadata name = 'Role Assignments (Resource Group scope)' -metadata description = 'This module deploys a Role Assignment at a Resource Group scope.' +metadata name = 'PIM Role Assignments (Resource Group scope)' +metadata description = 'This module deploys a PIM Role Assignment at a Resource Group scope.' targetScope = 'resourceGroup' +import { requestTypeType, scheduleInfoType, scheduleInfoExpirationType, ticketInfoType } from 'definitions.bicep' + @sys.description('Required. You can provide either the display name of the role definition (must be configured in the variable `builtInRoleNames`), or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.') param roleDefinitionIdOrName string @@ -15,11 +17,23 @@ param resourceGroupName string = resourceGroup().name @sys.description('Optional. Subscription ID of the subscription to assign the RBAC role to. If not provided, will use the current scope for deployment.') param subscriptionId string = subscription().subscriptionId -@sys.description('Optional. The description of the role assignment.') -param description string = '' +@sys.description('Optional. The justification for the role eligibility.') +param justification string = '' + +@sys.description('Required. The type of the role assignment eligibility request.') +param requestType requestTypeType + +@sys.description('Optional. The resultant role eligibility assignment id or the role eligibility assignment id being updated.') +param targetRoleEligibilityScheduleId string = '' + +@sys.description('Optional. The role eligibility assignment instance id being updated.') +param targetRoleEligibilityScheduleInstanceId string = '' -@sys.description('Optional. ID of the delegated managed identity resource.') -param delegatedManagedIdentityResourceId string = '' +@sys.description('Optional. Ticket Info of the role eligibility.') +param ticketInfo ticketInfoType? + +@sys.description('Optional. Schedule info of the role eligibility assignment.') +param scheduleInfo scheduleInfoType @sys.description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to.') param condition string = '' @@ -30,17 +44,6 @@ param condition string = '' ]) param conditionVersion string = '2.0' -@sys.description('Optional. The principal type of the assigned principal ID.') -@allowed([ - 'ServicePrincipal' - 'Group' - 'User' - 'ForeignGroup' - 'Device' - '' -]) -param principalType string - var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') @@ -57,29 +60,30 @@ var builtInRoleNames = { var roleDefinitionIdVar = (builtInRoleNames[?roleDefinitionIdOrName] ?? roleDefinitionIdOrName) -resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { +resource pimRoleAssignment 'Microsoft.Authorization/roleEligibilityScheduleRequests@2022-04-01-preview' = { name: guid(subscriptionId, resourceGroupName, roleDefinitionIdVar, principalId) properties: { roleDefinitionId: roleDefinitionIdVar principalId: principalId - description: !empty(description) ? description : null - principalType: !empty(principalType) ? any(principalType) : null - delegatedManagedIdentityResourceId: !empty(delegatedManagedIdentityResourceId) - ? delegatedManagedIdentityResourceId - : null + requestType: requestType conditionVersion: !empty(conditionVersion) && !empty(condition) ? conditionVersion : null condition: !empty(condition) ? condition : null + justification: justification + scheduleInfo: scheduleInfo + targetRoleEligibilityScheduleId: targetRoleEligibilityScheduleId + targetRoleEligibilityScheduleInstanceId: targetRoleEligibilityScheduleInstanceId + ticketInfo: ticketInfo } } -@sys.description('The GUID of the Role Assignment.') -output name string = roleAssignment.name +@sys.description('The GUID of the PIM Role Assignment.') +output name string = pimRoleAssignment.name -@sys.description('The resource ID of the Role Assignment.') -output resourceId string = roleAssignment.id +@sys.description('The resource ID of the PIM Role Assignment.') +output resourceId string = pimRoleAssignment.id -@sys.description('The name of the resource group the role assignment was applied at.') +@sys.description('The name of the resource group the PIM role assignment was applied at.') output resourceGroupName string = resourceGroup().name -@sys.description('The scope this Role Assignment applies to.') +@sys.description('The scope this PIM Role Assignment applies to.') output scope string = resourceGroup().id diff --git a/avm/ptn/authorization/pim-role-assignment/modules/subscription.bicep b/avm/ptn/authorization/pim-role-assignment/modules/subscription.bicep index 1142912b4c..69d0bc0402 100644 --- a/avm/ptn/authorization/pim-role-assignment/modules/subscription.bicep +++ b/avm/ptn/authorization/pim-role-assignment/modules/subscription.bicep @@ -1,8 +1,10 @@ -metadata name = 'Role Assignments (Subscription scope)' -metadata description = 'This module deploys a Role Assignment at a Subscription scope.' +metadata name = 'PIM Role Assignments (Subscription scope)' +metadata description = 'This module deploys a PIM Role Assignment at a Subscription scope.' targetScope = 'subscription' +import { requestTypeType, scheduleInfoType, scheduleInfoExpirationType, ticketInfoType } from 'definitions.bicep' + @sys.description('Required. You can provide either the display name of the role definition (must be configured in the variable `builtInRoleNames`), or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.') param roleDefinitionIdOrName string @@ -12,11 +14,23 @@ param principalId string @sys.description('Optional. Subscription ID of the subscription to assign the RBAC role to. If not provided, will use the current scope for deployment.') param subscriptionId string = subscription().subscriptionId -@sys.description('Optional. The description of the role assignment.') -param description string = '' +@sys.description('Optional. The justification for the role eligibility.') +param justification string = '' + +@sys.description('Required. The type of the role assignment eligibility request.') +param requestType requestTypeType + +@sys.description('Optional. The resultant role eligibility assignment id or the role eligibility assignment id being updated.') +param targetRoleEligibilityScheduleId string = '' -@sys.description('Optional. ID of the delegated managed identity resource.') -param delegatedManagedIdentityResourceId string = '' +@sys.description('Optional. The role eligibility assignment instance id being updated.') +param targetRoleEligibilityScheduleInstanceId string = '' + +@sys.description('Optional. Ticket Info of the role eligibility.') +param ticketInfo ticketInfoType? + +@sys.description('Optional. Schedule info of the role eligibility assignment.') +param scheduleInfo scheduleInfoType @sys.description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to.') param condition string = '' @@ -27,17 +41,6 @@ param condition string = '' ]) param conditionVersion string = '2.0' -@sys.description('Optional. The principal type of the assigned principal ID.') -@allowed([ - 'ServicePrincipal' - 'Group' - 'User' - 'ForeignGroup' - 'Device' - '' -]) -param principalType string = '' - var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') @@ -54,29 +57,30 @@ var builtInRoleNames = { var roleDefinitionIdVar = (builtInRoleNames[?roleDefinitionIdOrName] ?? roleDefinitionIdOrName) -resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { +resource pimRoleAssignment 'Microsoft.Authorization/roleEligibilityScheduleRequests@2022-04-01-preview' = { name: guid(subscriptionId, roleDefinitionIdVar, principalId) properties: { - roleDefinitionId: roleDefinitionIdVar principalId: principalId - description: !empty(description) ? description : null - principalType: !empty(principalType) ? any(principalType) : null - delegatedManagedIdentityResourceId: !empty(delegatedManagedIdentityResourceId) - ? delegatedManagedIdentityResourceId - : null - conditionVersion: !empty(conditionVersion) && !empty(condition) ? conditionVersion : null + roleDefinitionId: roleDefinitionIdVar + requestType: requestType condition: !empty(condition) ? condition : null + conditionVersion: !empty(conditionVersion) && !empty(condition) ? conditionVersion : null + justification: justification + scheduleInfo: scheduleInfo + targetRoleEligibilityScheduleId: targetRoleEligibilityScheduleId + targetRoleEligibilityScheduleInstanceId: targetRoleEligibilityScheduleInstanceId + ticketInfo: ticketInfo } } -@sys.description('The GUID of the Role Assignment.') -output name string = roleAssignment.name +@sys.description('The GUID of the PIM Role Assignment.') +output name string = pimRoleAssignment.name -@sys.description('The resource ID of the Role Assignment.') -output resourceId string = roleAssignment.id +@sys.description('The resource ID of the PIM Role Assignment.') +output resourceId string = pimRoleAssignment.id -@sys.description('The name of the resource group the role assignment was applied at.') +@sys.description('The name of the resource group the PIM role assignment was applied at.') output subscriptionName string = subscription().displayName -@sys.description('The scope this Role Assignment applies to.') +@sys.description('The scope this PIM Role Assignment applies to.') output scope string = subscription().id From bf2e2d872fb714b5183cadd1cf0ca9360ed56a80 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Thu, 23 Jan 2025 14:54:54 +0200 Subject: [PATCH 03/54] feat: Refactor PIM Role Assignment tests by removing obsolete dependencies and adding new test modules for various scopes --- .../pim-role-assignment/main.bicep | 35 +++++----- .../tests/e2e/mg.defaults/dependencies.bicep | 13 ---- .../tests/e2e/mg.defaults/main.test.bicep | 45 ++----------- .../tests/e2e/mg.max/main.test.bicep | 41 ++++++++++++ .../tests/e2e/rg.default/main.test.bicep | 56 ++++++++++++++++ .../tests/e2e/rg.max/main.test.bicep | 64 +++++++++++++++++++ .../tests/e2e/sub.default/main.test.bicep | 36 +++++++++++ .../tests/e2e/sub.max/main.test.bicep | 42 ++++++++++++ .../tests/e2e/waf-aligned/main.test.bicep | 48 -------------- 9 files changed, 260 insertions(+), 120 deletions(-) delete mode 100644 avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/dependencies.bicep create mode 100644 avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep create mode 100644 avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep create mode 100644 avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep create mode 100644 avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep create mode 100644 avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.max/main.test.bicep delete mode 100644 avm/ptn/authorization/pim-role-assignment/tests/e2e/waf-aligned/main.test.bicep diff --git a/avm/ptn/authorization/pim-role-assignment/main.bicep b/avm/ptn/authorization/pim-role-assignment/main.bicep index 9e1dff6625..50a899225f 100644 --- a/avm/ptn/authorization/pim-role-assignment/main.bicep +++ b/avm/ptn/authorization/pim-role-assignment/main.bicep @@ -95,61 +95,60 @@ module roleAssignment_mg 'modules/management-group.bicep' = if (empty(subscripti } } -/* module roleAssignment_sub 'modules/subscription.bicep' = if (!empty(subscriptionId) && empty(resourceGroupName)) { - name: '${uniqueString(deployment().name, location)}-RoleAssignment-Sub-Module' + name: '${uniqueString(deployment().name, location)}-PimRoleAssignment-Sub-Module' scope: subscription(subscriptionId) params: { roleDefinitionIdOrName: roleDefinitionIdOrName principalId: principalId subscriptionId: subscriptionId - description: !empty(description) ? description : '' - principalType: !empty(principalType) ? principalType : '' - delegatedManagedIdentityResourceId: !empty(delegatedManagedIdentityResourceId) - ? delegatedManagedIdentityResourceId - : '' + requestType: requestType + justification: justification + targetRoleEligibilityScheduleId: targetRoleEligibilityScheduleId + targetRoleEligibilityScheduleInstanceId: targetRoleEligibilityScheduleInstanceId + ticketInfo: ticketInfo conditionVersion: conditionVersion condition: !empty(condition) ? condition : '' + scheduleInfo: scheduleInfo } } module roleAssignment_rg 'modules/resource-group.bicep' = if (!empty(resourceGroupName) && !empty(subscriptionId)) { - name: '${uniqueString(deployment().name, location)}-RoleAssignment-RG-Module' + name: '${uniqueString(deployment().name, location)}-PimRoleAssignment-RG-Module' scope: resourceGroup(subscriptionId, resourceGroupName) params: { roleDefinitionIdOrName: roleDefinitionIdOrName principalId: principalId subscriptionId: subscriptionId resourceGroupName: resourceGroupName - description: !empty(description) ? description : '' - principalType: !empty(principalType) ? principalType : '' - delegatedManagedIdentityResourceId: !empty(delegatedManagedIdentityResourceId) - ? delegatedManagedIdentityResourceId - : '' + requestType: requestType + justification: justification + targetRoleEligibilityScheduleId: targetRoleEligibilityScheduleId + targetRoleEligibilityScheduleInstanceId: targetRoleEligibilityScheduleInstanceId + ticketInfo: ticketInfo conditionVersion: conditionVersion condition: !empty(condition) ? condition : '' + scheduleInfo: scheduleInfo } } - -@sys.description('The GUID of the Role Assignment.') +@sys.description('The GUID of the PIM Role Assignment.') output name string = empty(subscriptionId) && empty(resourceGroupName) ? roleAssignment_mg.outputs.name : (!empty(subscriptionId) && empty(resourceGroupName) ? roleAssignment_sub.outputs.name : roleAssignment_rg.outputs.name) -@sys.description('The resource ID of the Role Assignment.') +@sys.description('The resource ID of the PIM Role Assignment.') output resourceId string = empty(subscriptionId) && empty(resourceGroupName) ? roleAssignment_mg.outputs.resourceId : (!empty(subscriptionId) && empty(resourceGroupName) ? roleAssignment_sub.outputs.resourceId : roleAssignment_rg.outputs.resourceId) -@sys.description('The scope this Role Assignment applies to.') +@sys.description('The scope this PIM Role Assignment applies to.') output scope string = empty(subscriptionId) && empty(resourceGroupName) ? roleAssignment_mg.outputs.scope : (!empty(subscriptionId) && empty(resourceGroupName) ? roleAssignment_sub.outputs.scope : roleAssignment_rg.outputs.scope) -*/ diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/dependencies.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/dependencies.bicep deleted file mode 100644 index d367770432..0000000000 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/dependencies.bicep +++ /dev/null @@ -1,13 +0,0 @@ -@description('Optional. The location to deploy resources to.') -param location string = resourceGroup().location - -@description('Required. The name of the Managed Identity to create.') -param managedIdentityName string - -resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location -} - -@description('The principal ID of the created Managed Identity.') -output managedIdentityPrincipalId string = managedIdentity.properties.principalId diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep index f9be6a9ad0..198ff48f8b 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep @@ -1,54 +1,17 @@ targetScope = 'managementGroup' -metadata name = 'PIM Role Assignments (Management Group scope)' +metadata name = ' PIM Role Assignments (Management Group scope)' metadata description = 'This module deploys a PIM Role Assignment at a Management Group scope using minimal parameters.' // ========== // // Parameters // // ========== // -@description('Optional. The name of the resource group to deploy for testing purposes.') -@maxLength(90) -param resourceGroupName string = 'dep-${namePrefix}-authorization.roleassignments-${serviceShort}-rg' - @description('Optional. The location to deploy resources to.') param resourceLocation string = deployment().location @description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') param serviceShort string = 'pimmgmin' -@description('Optional. A token to inject into the name of each resource.') -param namePrefix string = '#_namePrefix_#' - -@description('Optional. Subscription ID of the subscription to assign the RBAC role to. If no Resource Group name is provided, the module deploys at subscription level, therefore assigns the provided RBAC role to the subscription.') -param subscriptionId string = '#_subscriptionId_#' - -// ============ // -// Dependencies // -// ============ // - -// General resources -// ================= -/*module resourceGroup 'br/public:avm/res/resources/resource-group:0.2.3' = { - scope: subscription('${subscriptionId}') - name: '${uniqueString(deployment().name, resourceLocation)}-resourceGroup' - params: { - name: resourceGroupName - location: resourceLocation - } -} - -module nestedDependencies 'dependencies.bicep' = { - scope: az.resourceGroup(subscriptionId, resourceGroupName) - name: '${uniqueString(deployment().name, resourceLocation)}-${serviceShort}-nestedDependencies' - params: { - managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' - location: resourceLocation - } - dependsOn: [ - resourceGroup - ] -}*/ - // ============== // // Test Execution // // ============== // @@ -56,15 +19,15 @@ module nestedDependencies 'dependencies.bicep' = { module testDeployment '../../../main.bicep' = { name: '${uniqueString(deployment().name)}-test-${serviceShort}' params: { - principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalId: '' roleDefinitionIdOrName: 'Resource Policy Contributor' requestType: 'AdminAssign' + location: resourceLocation scheduleInfo: { expiration: { - type: 'AfterDuration' duration: 'P1H' + type: 'AfterDuration' } } - location: resourceLocation } } diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep new file mode 100644 index 0000000000..6b57e3aa63 --- /dev/null +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep @@ -0,0 +1,41 @@ +targetScope = 'managementGroup' +metadata name = 'PIM Role Assignments (Management Group scope)' +metadata description = 'This module deploys a PIM Role Assignment at a Management Group scope using common parameters.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'pimmgmax' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============== // +// Test Execution // +// ============== // + +module testDeployment '../../../main.bicep' = { + name: '${uniqueString(deployment().name)}-test-${namePrefix}-${serviceShort}' + params: { + principalId: '' + roleDefinitionIdOrName: 'Resource Policy Contributor' + requestType: 'AdminAssign' + location: resourceLocation + scheduleInfo: { + expiration: { + type: 'AfterDateTime' + } + startDateTime: '2025-01-23T12:39:44Z' + } + justification: 'Justification for the role eligibility' + ticketInfo: { + ticketNumber: '123456' + ticketSystem: 'system1' + } + } +} diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep new file mode 100644 index 0000000000..36c219db00 --- /dev/null +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep @@ -0,0 +1,56 @@ +targetScope = 'managementGroup' +metadata name = 'PIM Role Assignments (Resource Group scope)' +metadata description = 'This module deploys a PIM Role Assignment at a Resource Group scope using minimal parameters.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'pimrgmin' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-authorization.pimroleassignments-${serviceShort}-rg' + +@description('Optional. Subscription ID of the subscription to assign the RBAC role to. If no Resource Group name is provided, the module deploys at subscription level, therefore assigns the provided RBAC role to the subscription.') +param subscriptionId string = '#_subscriptionId_#' + +// General resources +// ================= +module resourceGroup 'br/public:avm/res/resources/resource-group:0.2.3' = { + scope: subscription('${subscriptionId}') + name: '${uniqueString(deployment().name, resourceLocation)}-resourceGroup' + params: { + name: resourceGroupName + location: resourceLocation + } +} + +// ============== // +// Test Execution // +// ============== // + +module testDeployment '../../../main.bicep' = { + name: '${uniqueString(deployment().name)}-test-${serviceShort}' + params: { + principalId: '' + roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11' + location: resourceLocation + subscriptionId: subscriptionId + resourceGroupName: resourceGroup.outputs.name + requestType: 'AdminAssign' + scheduleInfo: { + expiration: { + duration: 'P1H' + type: 'AfterDuration' + } + } + } +} diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep new file mode 100644 index 0000000000..c70785e063 --- /dev/null +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep @@ -0,0 +1,64 @@ +targetScope = 'managementGroup' +metadata name = 'PIM Role Assignments (Resource Group)' +metadata description = 'This module deploys a PIM Role Assignment at a Resource Group scope using common parameters.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'pimrgmax' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-authorization.pimroleassignments-${serviceShort}-rg' + +@description('Optional. Subscription ID of the subscription to assign the RBAC role to. If no Resource Group name is provided, the module deploys at subscription level, therefore assigns the provided RBAC role to the subscription.') +param subscriptionId string = '#_subscriptionId_#' + +@description('Optional. The dateTime of the role assignment eligibility.') +param startTime string = utcNow() + +// General resources +// ================= +module resourceGroup 'br/public:avm/res/resources/resource-group:0.2.3' = { + scope: subscription('${subscriptionId}') + name: '${uniqueString(deployment().name, resourceLocation)}-resourceGroup' + params: { + name: resourceGroupName + location: resourceLocation + } +} + +// ============== // +// Test Execution // +// ============== // + +module testDeployment '../../../main.bicep' = { + name: '${uniqueString(deployment().name)}-test-${serviceShort}' + params: { + principalId: '' + roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11' + location: resourceLocation + subscriptionId: subscriptionId + resourceGroupName: resourceGroup.outputs.name + requestType: 'AdminAssign' + scheduleInfo: { + expiration: { + type: 'AfterDateTime' + } + startDateTime: startTime + } + justification: 'Justification for role eligibility' + ticketInfo: { + ticketNumber: '32423' + ticketSystem: 'system12' + } + } +} diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep new file mode 100644 index 0000000000..b4ec05ab3e --- /dev/null +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep @@ -0,0 +1,36 @@ +targetScope = 'managementGroup' +metadata name = 'PIM Role Assignments (Subscription scope)' +metadata description = 'This module deploys a PIM Role Assignment at a Subscription scope using minimal parameters.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'pimsubmin' + +@description('Optional. Subscription ID of the subscription to assign the RBAC role to. If no Resource Group name is provided, the module deploys at subscription level, therefore assigns the provided RBAC role to the subscription.') +param subscriptionId string = '#_subscriptionId_#' + +// ============== // +// Test Execution // +// ============== // + +module testDeployment '../../../main.bicep' = { + name: '${uniqueString(deployment().name)}-test-${serviceShort}' + params: { + principalId: '' + roleDefinitionIdOrName: subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + 'acdd72a7-3385-48ef-bd42-f606fba81ae7' + ) + subscriptionId: subscriptionId + requestType: 'AdminAssign' + scheduleInfo: { + expiration: { + duration: 'P1H' + type: 'AfterDuration' + } + } + } +} diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.max/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.max/main.test.bicep new file mode 100644 index 0000000000..59121ab655 --- /dev/null +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.max/main.test.bicep @@ -0,0 +1,42 @@ +targetScope = 'managementGroup' +metadata name = 'PIM Role Assignments (Subscription scope)' +metadata description = 'This module deploys a PIM Role Assignment at a Subscription scope using common parameters.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'pimsubmax' + +@description('Optional. Subscription ID of the subscription to assign the RBAC role to. If no Resource Group name is provided, the module deploys at subscription level, therefore assigns the provided RBAC role to the subscription.') +param subscriptionId string = '#_subscriptionId_#' + +// ============== // +// Test Execution // +// ============== // + +module testDeployment '../../../main.bicep' = { + name: '${uniqueString(deployment().name)}-test-${serviceShort}' + params: { + principalId: '' + roleDefinitionIdOrName: 'Reader' + requestType: 'AdminAssign' + scheduleInfo: { + expiration: { + duration: 'P1H' + type: 'AfterDuration' + } + } + justification: 'Justification for role assignment' + ticketInfo: { + ticketNumber: '21312' + ticketSystem: ' System2' + } + location: resourceLocation + subscriptionId: subscriptionId + } +} diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/waf-aligned/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/waf-aligned/main.test.bicep deleted file mode 100644 index 2970d5f024..0000000000 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/waf-aligned/main.test.bicep +++ /dev/null @@ -1,48 +0,0 @@ -targetScope = 'subscription' - -// ========== // -// Parameters // -// ========== // - -@description('Optional. The name of the resource group to deploy for testing purposes.') -@maxLength(90) -// e.g., for a module 'network/private-endpoint' you could use 'dep-dev-network.privateendpoints-${serviceShort}-rg' -param resourceGroupName string = 'dep-${namePrefix}---${serviceShort}-rg' - -@description('Optional. The location to deploy resources to.') -param resourceLocation string = deployment().location - -@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') -// e.g., for a module 'network/private-endpoint' you could use 'npe' as a prefix and then 'waf' as a suffix for the waf-aligned test -param serviceShort string = 'aprawaf' - -@description('Optional. A token to inject into the name of each resource. This value can be automatically injected by the CI.') -param namePrefix string = '#_namePrefix_#' - -// ============ // -// Dependencies // -// ============ // - -// General resources -// ================= -resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { - name: resourceGroupName - location: resourceLocation -} - -// ============== // -// Test Execution // -// ============== // - -@batchSize(1) -module testDeployment '../../../main.bicep' = [ - for iteration in ['init', 'idem']: { - scope: resourceGroup - name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' - params: { - // You parameters go here - name: '${namePrefix}${serviceShort}001' - location: resourceLocation - } - } -] From c7afd063a8ff96cf89ea06dcb084fc8ba79b764e Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Thu, 23 Jan 2025 15:14:02 +0200 Subject: [PATCH 04/54] feat: Add GitHub Actions workflow for PIM Role Assignment authorization --- ....ptn.authorization.pim-role-assignment.yml | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 .github/workflows/avm.ptn.authorization.pim-role-assignment.yml diff --git a/.github/workflows/avm.ptn.authorization.pim-role-assignment.yml b/.github/workflows/avm.ptn.authorization.pim-role-assignment.yml new file mode 100644 index 0000000000..0d33d510eb --- /dev/null +++ b/.github/workflows/avm.ptn.authorization.pim-role-assignment.yml @@ -0,0 +1,88 @@ +name: "avm.ptn.authorization.pim-role-assignment" + +on: + workflow_dispatch: + inputs: + staticValidation: + type: boolean + description: "Execute static validation" + required: false + default: true + deploymentValidation: + type: boolean + description: "Execute deployment validation" + required: false + default: true + removeDeployment: + type: boolean + description: "Remove deployed module" + required: false + default: true + customLocation: + type: string + description: "Default location overwrite (e.g., eastus)" + required: false + push: + branches: + - main + paths: + - ".github/actions/templates/avm-**" + - ".github/workflows/avm.template.module.yml" + - ".github/workflows/avm.ptn.authorization.pim-role-assignment.yml" + - "avm/ptn/authorization/pim-role-assignment/**" + - "utilities/pipelines/**" + - "!utilities/pipelines/platform/**" + - "!*/**/README.md" + +env: + modulePath: "avm/ptn/authorization/pim-role-assignment" + workflowPath: ".github/workflows/avm.ptn.authorization.pim-role-assignment.yml" + +concurrency: + group: ${{ github.workflow }} + +jobs: + ########################### + # Initialize pipeline # + ########################### + job_initialize_pipeline: + runs-on: ubuntu-latest + name: "Initialize pipeline" + steps: + - name: "Checkout" + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: "Set input parameters to output variables" + id: get-workflow-param + uses: ./.github/actions/templates/avm-getWorkflowInput + with: + workflowPath: "${{ env.workflowPath}}" + - name: "Get module test file paths" + id: get-module-test-file-paths + uses: ./.github/actions/templates/avm-getModuleTestFiles + with: + modulePath: "${{ env.modulePath }}" + outputs: + workflowInput: ${{ steps.get-workflow-param.outputs.workflowInput }} + moduleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.moduleTestFilePaths }} + psRuleModuleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.psRuleModuleTestFilePaths }} + modulePath: "${{ env.modulePath }}" + + ############################## + # Call reusable workflow # + ############################## + call-workflow-passing-data: + name: "Run" + permissions: + id-token: write # For OIDC + contents: write # For release tags + needs: + - job_initialize_pipeline + uses: ./.github/workflows/avm.template.module.yml + with: + workflowInput: "${{ needs.job_initialize_pipeline.outputs.workflowInput }}" + moduleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.moduleTestFilePaths }}" + psRuleModuleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.psRuleModuleTestFilePaths }}" + modulePath: "${{ needs.job_initialize_pipeline.outputs.modulePath}}" + secrets: inherit From 20b0564b624b59c5b3fe3f5b569eb2c065720bf3 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Thu, 23 Jan 2025 16:38:17 +0200 Subject: [PATCH 05/54] feat: Add userPrincipalId parameter to test Bicep files for tenant-specific role assignments --- .../tests/e2e/mg.defaults/main.test.bicep | 6 +++++- .../pim-role-assignment/tests/e2e/mg.max/main.test.bicep | 6 +++++- .../tests/e2e/rg.default/main.test.bicep | 6 +++++- .../pim-role-assignment/tests/e2e/rg.max/main.test.bicep | 6 +++++- .../tests/e2e/sub.default/main.test.bicep | 6 +++++- .../pim-role-assignment/tests/e2e/sub.max/main.test.bicep | 6 +++++- 6 files changed, 30 insertions(+), 6 deletions(-) diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep index 198ff48f8b..ed10e4ce1f 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep @@ -12,6 +12,10 @@ param resourceLocation string = deployment().location @description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') param serviceShort string = 'pimmgmin' +@description('Required. Principle ID of the user. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'userPrinicipalId\'.') +@secure() +param userPrinicipalId string = '' + // ============== // // Test Execution // // ============== // @@ -19,7 +23,7 @@ param serviceShort string = 'pimmgmin' module testDeployment '../../../main.bicep' = { name: '${uniqueString(deployment().name)}-test-${serviceShort}' params: { - principalId: '' + principalId: userPrinicipalId roleDefinitionIdOrName: 'Resource Policy Contributor' requestType: 'AdminAssign' location: resourceLocation diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep index 6b57e3aa63..bd69afe4b3 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep @@ -15,6 +15,10 @@ param serviceShort string = 'pimmgmax' @description('Optional. A token to inject into the name of each resource.') param namePrefix string = '#_namePrefix_#' +@description('Required. Principle ID of the user. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'userPrinicipalId\'.') +@secure() +param userPrinicipalId string = '' + // ============== // // Test Execution // // ============== // @@ -22,7 +26,7 @@ param namePrefix string = '#_namePrefix_#' module testDeployment '../../../main.bicep' = { name: '${uniqueString(deployment().name)}-test-${namePrefix}-${serviceShort}' params: { - principalId: '' + principalId: userPrinicipalId roleDefinitionIdOrName: 'Resource Policy Contributor' requestType: 'AdminAssign' location: resourceLocation diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep index 36c219db00..24752c76f6 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep @@ -22,6 +22,10 @@ param resourceGroupName string = 'dep-${namePrefix}-authorization.pimroleassignm @description('Optional. Subscription ID of the subscription to assign the RBAC role to. If no Resource Group name is provided, the module deploys at subscription level, therefore assigns the provided RBAC role to the subscription.') param subscriptionId string = '#_subscriptionId_#' +@description('Required. Principle ID of the user. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'userPrinicipalId\'.') +@secure() +param userPrinicipalId string = '' + // General resources // ================= module resourceGroup 'br/public:avm/res/resources/resource-group:0.2.3' = { @@ -40,7 +44,7 @@ module resourceGroup 'br/public:avm/res/resources/resource-group:0.2.3' = { module testDeployment '../../../main.bicep' = { name: '${uniqueString(deployment().name)}-test-${serviceShort}' params: { - principalId: '' + principalId: userPrinicipalId roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11' location: resourceLocation subscriptionId: subscriptionId diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep index c70785e063..01dd6fccf1 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep @@ -25,6 +25,10 @@ param subscriptionId string = '#_subscriptionId_#' @description('Optional. The dateTime of the role assignment eligibility.') param startTime string = utcNow() +@description('Required. Principle ID of the user. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'userPrinicipalId\'.') +@secure() +param userPrinicipalId string = '' + // General resources // ================= module resourceGroup 'br/public:avm/res/resources/resource-group:0.2.3' = { @@ -43,7 +47,7 @@ module resourceGroup 'br/public:avm/res/resources/resource-group:0.2.3' = { module testDeployment '../../../main.bicep' = { name: '${uniqueString(deployment().name)}-test-${serviceShort}' params: { - principalId: '' + principalId: userPrinicipalId roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11' location: resourceLocation subscriptionId: subscriptionId diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep index b4ec05ab3e..1db381008c 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep @@ -12,6 +12,10 @@ param serviceShort string = 'pimsubmin' @description('Optional. Subscription ID of the subscription to assign the RBAC role to. If no Resource Group name is provided, the module deploys at subscription level, therefore assigns the provided RBAC role to the subscription.') param subscriptionId string = '#_subscriptionId_#' +@description('Required. Principle ID of the user. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'userPrinicipalId\'.') +@secure() +param userPrinicipalId string = '' + // ============== // // Test Execution // // ============== // @@ -19,7 +23,7 @@ param subscriptionId string = '#_subscriptionId_#' module testDeployment '../../../main.bicep' = { name: '${uniqueString(deployment().name)}-test-${serviceShort}' params: { - principalId: '' + principalId: userPrinicipalId roleDefinitionIdOrName: subscriptionResourceId( 'Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7' diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.max/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.max/main.test.bicep index 59121ab655..3ee5ea1a7e 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.max/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.max/main.test.bicep @@ -15,6 +15,10 @@ param serviceShort string = 'pimsubmax' @description('Optional. Subscription ID of the subscription to assign the RBAC role to. If no Resource Group name is provided, the module deploys at subscription level, therefore assigns the provided RBAC role to the subscription.') param subscriptionId string = '#_subscriptionId_#' +@description('Required. Principle ID of the user. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'userPrinicipalId\'.') +@secure() +param userPrinicipalId string = '' + // ============== // // Test Execution // // ============== // @@ -22,7 +26,7 @@ param subscriptionId string = '#_subscriptionId_#' module testDeployment '../../../main.bicep' = { name: '${uniqueString(deployment().name)}-test-${serviceShort}' params: { - principalId: '' + principalId: userPrinicipalId roleDefinitionIdOrName: 'Reader' requestType: 'AdminAssign' scheduleInfo: { From edd59248ffe969c4aff9ad198f10fb4a2ba24f43 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Thu, 23 Jan 2025 16:45:13 +0200 Subject: [PATCH 06/54] feat: Add PIM Role Assignment to issue template for better tracking --- .github/ISSUE_TEMPLATE/avm_module_issue.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/ISSUE_TEMPLATE/avm_module_issue.yml b/.github/ISSUE_TEMPLATE/avm_module_issue.yml index 0c32aa15a1..2048e0846b 100644 --- a/.github/ISSUE_TEMPLATE/avm_module_issue.yml +++ b/.github/ISSUE_TEMPLATE/avm_module_issue.yml @@ -41,6 +41,7 @@ body: - "avm/ptn/aca-lza/hosting-environment" - "avm/ptn/ai-platform/baseline" - "avm/ptn/app/container-job-toolkit" + - "avm/ptn/authorization/pim-role-assignment" - "avm/ptn/authorization/policy-assignment" - "avm/ptn/authorization/policy-exemption" - "avm/ptn/authorization/resource-role-assignment" From 8b441d6b32dd377de3f943741ba6a5a3e72ae56e Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Thu, 23 Jan 2025 16:48:46 +0200 Subject: [PATCH 07/54] feat: Implement new logging mechanism for improved error tracking --- .../pim-role-assignment/README.md | 777 ++++++++++- .../pim-role-assignment/main.json | 1156 ++++++++++++++++- 2 files changed, 1903 insertions(+), 30 deletions(-) diff --git a/avm/ptn/authorization/pim-role-assignment/README.md b/avm/ptn/authorization/pim-role-assignment/README.md index 172facef4a..a973a4d60d 100644 --- a/avm/ptn/authorization/pim-role-assignment/README.md +++ b/avm/ptn/authorization/pim-role-assignment/README.md @@ -12,7 +12,9 @@ ## Resource Types -_None_ +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Authorization/roleEligibilityScheduleRequests` | [2022-04-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01-preview/roleEligibilityScheduleRequests) | ## Usage examples @@ -22,10 +24,224 @@ The following section provides usage examples for the module, which were used to >**Note**: To reference the module, please use the following syntax `br/public:avm/ptn/authorization/pim-role-assignment:`. -- [Defaults](#example-1-defaults) -- [Waf-Aligned](#example-2-waf-aligned) +- [ PIM Role Assignments (Management Group scope)](#example-1-pim-role-assignments-management-group-scope) +- [PIM Role Assignments (Management Group scope)](#example-2-pim-role-assignments-management-group-scope) +- [PIM Role Assignments (Resource Group scope)](#example-3-pim-role-assignments-resource-group-scope) +- [PIM Role Assignments (Resource Group)](#example-4-pim-role-assignments-resource-group) +- [PIM Role Assignments (Subscription scope)](#example-5-pim-role-assignments-subscription-scope) +- [PIM Role Assignments (Subscription scope)](#example-6-pim-role-assignments-subscription-scope) + +### Example 1: _ PIM Role Assignments (Management Group scope)_ + +This module deploys a PIM Role Assignment at a Management Group scope using minimal parameters. + + +

+ +via Bicep module + +```bicep +module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:' = { + name: 'pimRoleAssignmentDeployment' + params: { + // Required parameters + principalId: '' + requestType: 'AdminAssign' + roleDefinitionIdOrName: 'Resource Policy Contributor' + scheduleInfo: { + expiration: { + duration: 'P1H' + type: 'AfterDuration' + } + } + // Non-required parameters + location: '' + } +} +``` + +
+

+ +

+ +via JSON parameters file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "principalId": { + "value": "" + }, + "requestType": { + "value": "AdminAssign" + }, + "roleDefinitionIdOrName": { + "value": "Resource Policy Contributor" + }, + "scheduleInfo": { + "value": { + "expiration": { + "duration": "P1H", + "type": "AfterDuration" + } + } + }, + // Non-required parameters + "location": { + "value": "" + } + } +} +``` + +
+

+ +

+ +via Bicep parameters file + +```bicep-params +using 'br/public:avm/ptn/authorization/pim-role-assignment:' + +// Required parameters +param principalId = '' +param requestType = 'AdminAssign' +param roleDefinitionIdOrName = 'Resource Policy Contributor' +param scheduleInfo = { + expiration: { + duration: 'P1H' + type: 'AfterDuration' + } +} +// Non-required parameters +param location = '' +``` + +
+

+ +### Example 2: _PIM Role Assignments (Management Group scope)_ + +This module deploys a PIM Role Assignment at a Management Group scope using common parameters. + + +

+ +via Bicep module + +```bicep +module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:' = { + name: 'pimRoleAssignmentDeployment' + params: { + // Required parameters + principalId: '' + requestType: 'AdminAssign' + roleDefinitionIdOrName: 'Resource Policy Contributor' + scheduleInfo: { + expiration: { + type: 'AfterDateTime' + } + startDateTime: '2025-01-23T12:39:44Z' + } + // Non-required parameters + justification: 'Justification for the role eligibility' + location: '' + ticketInfo: { + ticketNumber: '123456' + ticketSystem: 'system1' + } + } +} +``` + +
+

+ +

+ +via JSON parameters file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "principalId": { + "value": "" + }, + "requestType": { + "value": "AdminAssign" + }, + "roleDefinitionIdOrName": { + "value": "Resource Policy Contributor" + }, + "scheduleInfo": { + "value": { + "expiration": { + "type": "AfterDateTime" + }, + "startDateTime": "2025-01-23T12:39:44Z" + } + }, + // Non-required parameters + "justification": { + "value": "Justification for the role eligibility" + }, + "location": { + "value": "" + }, + "ticketInfo": { + "value": { + "ticketNumber": "123456", + "ticketSystem": "system1" + } + } + } +} +``` + +
+

+ +

+ +via Bicep parameters file + +```bicep-params +using 'br/public:avm/ptn/authorization/pim-role-assignment:' + +// Required parameters +param principalId = '' +param requestType = 'AdminAssign' +param roleDefinitionIdOrName = 'Resource Policy Contributor' +param scheduleInfo = { + expiration: { + type: 'AfterDateTime' + } + startDateTime: '2025-01-23T12:39:44Z' +} +// Non-required parameters +param justification = 'Justification for the role eligibility' +param location = '' +param ticketInfo = { + ticketNumber: '123456' + ticketSystem: 'system1' +} +``` + +
+

+ +### Example 3: _PIM Role Assignments (Resource Group scope)_ + +This module deploys a PIM Role Assignment at a Resource Group scope using minimal parameters. -### Example 1: _Defaults_

@@ -36,9 +252,19 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:' + requestType: 'AdminAssign' + roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11' + scheduleInfo: { + expiration: { + duration: 'P1H' + type: 'AfterDuration' + } + } // Non-required parameters location: '' + resourceGroupName: '' + subscriptionId: '' } } ``` @@ -56,12 +282,32 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:" + }, + "requestType": { + "value": "AdminAssign" + }, + "roleDefinitionIdOrName": { + "value": "/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11" + }, + "scheduleInfo": { + "value": { + "expiration": { + "duration": "P1H", + "type": "AfterDuration" + } + } }, // Non-required parameters "location": { "value": "" + }, + "resourceGroupName": { + "value": "" + }, + "subscriptionId": { + "value": "" } } } @@ -78,15 +324,28 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:' // Required parameters -param name = 'apradef001' +param principalId = '' +param requestType = 'AdminAssign' +param roleDefinitionIdOrName = '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11' +param scheduleInfo = { + expiration: { + duration: 'P1H' + type: 'AfterDuration' + } +} // Non-required parameters param location = '' +param resourceGroupName = '' +param subscriptionId = '' ```

-### Example 2: _Waf-Aligned_ +### Example 4: _PIM Role Assignments (Resource Group)_ + +This module deploys a PIM Role Assignment at a Resource Group scope using common parameters. +

@@ -97,9 +356,24 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:' + requestType: 'AdminAssign' + roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11' + scheduleInfo: { + expiration: { + type: 'AfterDateTime' + } + startDateTime: '' + } // Non-required parameters + justification: 'Justification for role eligibility' location: '' + resourceGroupName: '' + subscriptionId: '' + ticketInfo: { + ticketNumber: '32423' + ticketSystem: 'system12' + } } } ``` @@ -117,12 +391,41 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:" + }, + "requestType": { + "value": "AdminAssign" + }, + "roleDefinitionIdOrName": { + "value": "/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11" + }, + "scheduleInfo": { + "value": { + "expiration": { + "type": "AfterDateTime" + }, + "startDateTime": "" + } }, // Non-required parameters + "justification": { + "value": "Justification for role eligibility" + }, "location": { "value": "" + }, + "resourceGroupName": { + "value": "" + }, + "subscriptionId": { + "value": "" + }, + "ticketInfo": { + "value": { + "ticketNumber": "32423", + "ticketSystem": "system12" + } } } } @@ -139,9 +442,236 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:' // Required parameters -param name = 'aprawaf001' +param principalId = '' +param requestType = 'AdminAssign' +param roleDefinitionIdOrName = '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11' +param scheduleInfo = { + expiration: { + type: 'AfterDateTime' + } + startDateTime: '' +} // Non-required parameters +param justification = 'Justification for role eligibility' param location = '' +param resourceGroupName = '' +param subscriptionId = '' +param ticketInfo = { + ticketNumber: '32423' + ticketSystem: 'system12' +} +``` + +
+

+ +### Example 5: _PIM Role Assignments (Subscription scope)_ + +This module deploys a PIM Role Assignment at a Subscription scope using minimal parameters. + + +

+ +via Bicep module + +```bicep +module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:' = { + name: 'pimRoleAssignmentDeployment' + params: { + // Required parameters + principalId: '' + requestType: 'AdminAssign' + roleDefinitionIdOrName: '' + scheduleInfo: { + expiration: { + duration: 'P1H' + type: 'AfterDuration' + } + } + // Non-required parameters + subscriptionId: '' + } +} +``` + +
+

+ +

+ +via JSON parameters file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "principalId": { + "value": "" + }, + "requestType": { + "value": "AdminAssign" + }, + "roleDefinitionIdOrName": { + "value": "" + }, + "scheduleInfo": { + "value": { + "expiration": { + "duration": "P1H", + "type": "AfterDuration" + } + } + }, + // Non-required parameters + "subscriptionId": { + "value": "" + } + } +} +``` + +
+

+ +

+ +via Bicep parameters file + +```bicep-params +using 'br/public:avm/ptn/authorization/pim-role-assignment:' + +// Required parameters +param principalId = '' +param requestType = 'AdminAssign' +param roleDefinitionIdOrName = '' +param scheduleInfo = { + expiration: { + duration: 'P1H' + type: 'AfterDuration' + } +} +// Non-required parameters +param subscriptionId = '' +``` + +
+

+ +### Example 6: _PIM Role Assignments (Subscription scope)_ + +This module deploys a PIM Role Assignment at a Subscription scope using common parameters. + + +

+ +via Bicep module + +```bicep +module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:' = { + name: 'pimRoleAssignmentDeployment' + params: { + // Required parameters + principalId: '' + requestType: 'AdminAssign' + roleDefinitionIdOrName: 'Reader' + scheduleInfo: { + expiration: { + duration: 'P1H' + type: 'AfterDuration' + } + } + // Non-required parameters + justification: 'Justification for role assignment' + location: '' + subscriptionId: '' + ticketInfo: { + ticketNumber: '21312' + ticketSystem: ' System2' + } + } +} +``` + +
+

+ +

+ +via JSON parameters file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "principalId": { + "value": "" + }, + "requestType": { + "value": "AdminAssign" + }, + "roleDefinitionIdOrName": { + "value": "Reader" + }, + "scheduleInfo": { + "value": { + "expiration": { + "duration": "P1H", + "type": "AfterDuration" + } + } + }, + // Non-required parameters + "justification": { + "value": "Justification for role assignment" + }, + "location": { + "value": "" + }, + "subscriptionId": { + "value": "" + }, + "ticketInfo": { + "value": { + "ticketNumber": "21312", + "ticketSystem": " System2" + } + } + } +} +``` + +
+

+ +

+ +via Bicep parameters file + +```bicep-params +using 'br/public:avm/ptn/authorization/pim-role-assignment:' + +// Required parameters +param principalId = '' +param requestType = 'AdminAssign' +param roleDefinitionIdOrName = 'Reader' +param scheduleInfo = { + expiration: { + duration: 'P1H' + type: 'AfterDuration' + } +} +// Non-required parameters +param justification = 'Justification for role assignment' +param location = '' +param subscriptionId = '' +param ticketInfo = { + ticketNumber: '21312' + ticketSystem: ' System2' +} ```
@@ -153,22 +683,84 @@ param location = '' | Parameter | Type | Description | | :-- | :-- | :-- | -| [`name`](#parameter-name) | string | Name of the resource to create. | +| [`principalId`](#parameter-principalid) | string | The Principal or Object ID of the Security Principal (User, Group, Service Principal, Managed Identity). | +| [`requestType`](#parameter-requesttype) | string | The type of the role assignment eligibility request. | +| [`roleDefinitionIdOrName`](#parameter-roledefinitionidorname) | string | You can provide either the display name of the role definition (must be configured in the variable `builtInRoleNames`), or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. | **Optional parameters** | Parameter | Type | Description | | :-- | :-- | :-- | +| [`condition`](#parameter-condition) | string | The conditions on the role assignment. This limits the resources it can be assigned to. | +| [`conditionVersion`](#parameter-conditionversion) | string | Version of the condition. Currently accepted value is "2.0". | | [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | -| [`location`](#parameter-location) | string | Location for all Resources. | +| [`justification`](#parameter-justification) | string | The justification for the role eligibility. | +| [`location`](#parameter-location) | string | Location deployment metadata. | +| [`managementGroupId`](#parameter-managementgroupid) | string | Group ID of the Management Group to assign the RBAC role to. If not provided, will use the current scope for deployment. | +| [`resourceGroupName`](#parameter-resourcegroupname) | string | Name of the Resource Group to assign the RBAC role to. If Resource Group name is provided, and Subscription ID is provided, the module deploys at resource group level, therefore assigns the provided RBAC role to the resource group. | +| [`scheduleInfo`](#parameter-scheduleinfo) | object | Schedule info of the role eligibility assignment. | +| [`subscriptionId`](#parameter-subscriptionid) | string | Subscription ID of the subscription to assign the RBAC role to. If no Resource Group name is provided, the module deploys at subscription level, therefore assigns the provided RBAC role to the subscription. | +| [`targetRoleEligibilityScheduleId`](#parameter-targetroleeligibilityscheduleid) | string | The resultant role eligibility assignment id or the role eligibility assignment id being updated. | +| [`targetRoleEligibilityScheduleInstanceId`](#parameter-targetroleeligibilityscheduleinstanceid) | string | The role eligibility assignment instance id being updated. | +| [`ticketInfo`](#parameter-ticketinfo) | object | Ticket Info of the role eligibility. | + +### Parameter: `principalId` + +The Principal or Object ID of the Security Principal (User, Group, Service Principal, Managed Identity). + +- Required: Yes +- Type: string + +### Parameter: `requestType` -### Parameter: `name` +The type of the role assignment eligibility request. -Name of the resource to create. +- Required: Yes +- Type: string +- Allowed: + ```Bicep + [ + 'AdminAssign' + 'AdminExtend' + 'AdminRemove' + 'AdminRenew' + 'AdminUpdate' + 'SelfActivate' + 'SelfDeactivate' + 'SelfExtend' + 'SelfRenew' + ] + ``` + +### Parameter: `roleDefinitionIdOrName` + +You can provide either the display name of the role definition (must be configured in the variable `builtInRoleNames`), or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. - Required: Yes - Type: string +### Parameter: `condition` + +The conditions on the role assignment. This limits the resources it can be assigned to. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `conditionVersion` + +Version of the condition. Currently accepted value is "2.0". + +- Required: No +- Type: string +- Default: `'2.0'` +- Allowed: + ```Bicep + [ + '2.0' + ] + ``` + ### Parameter: `enableTelemetry` Enable/Disable usage telemetry for module. @@ -177,17 +769,162 @@ Enable/Disable usage telemetry for module. - Type: bool - Default: `True` +### Parameter: `justification` + +The justification for the role eligibility. + +- Required: No +- Type: string +- Default: `''` + ### Parameter: `location` -Location for all Resources. +Location deployment metadata. + +- Required: No +- Type: string +- Default: `[deployment().location]` + +### Parameter: `managementGroupId` + +Group ID of the Management Group to assign the RBAC role to. If not provided, will use the current scope for deployment. + +- Required: No +- Type: string +- Default: `[managementGroup().name]` + +### Parameter: `resourceGroupName` + +Name of the Resource Group to assign the RBAC role to. If Resource Group name is provided, and Subscription ID is provided, the module deploys at resource group level, therefore assigns the provided RBAC role to the resource group. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `scheduleInfo` + +Schedule info of the role eligibility assignment. + +- Required: Yes +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`expiration`](#parameter-scheduleinfoexpiration) | object | The expiry information for the role eligibility. | +| [`startDateTime`](#parameter-scheduleinfostartdatetime) | string | Start DateTime of the role eligibility assignment. | + +### Parameter: `scheduleInfo.expiration` + +The expiry information for the role eligibility. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`duration`](#parameter-scheduleinfoexpirationduration) | string | Duration of the role eligibility assignment in TimeSpan format. Example: P365D, P2H | +| [`endDateTime`](#parameter-scheduleinfoexpirationenddatetime) | string | End DateTime of the role eligibility assignment. | +| [`type`](#parameter-scheduleinfoexpirationtype) | string | Type of the role eligibility assignment expiration. | + +### Parameter: `scheduleInfo.expiration.duration` + +Duration of the role eligibility assignment in TimeSpan format. Example: P365D, P2H + +- Required: No +- Type: string + +### Parameter: `scheduleInfo.expiration.endDateTime` + +End DateTime of the role eligibility assignment. + +- Required: No +- Type: string + +### Parameter: `scheduleInfo.expiration.type` + +Type of the role eligibility assignment expiration. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'AfterDateTime' + 'AfterDuration' + 'NoExpiration' + ] + ``` + +### Parameter: `scheduleInfo.startDateTime` + +Start DateTime of the role eligibility assignment. + +- Required: No +- Type: string + +### Parameter: `subscriptionId` + +Subscription ID of the subscription to assign the RBAC role to. If no Resource Group name is provided, the module deploys at subscription level, therefore assigns the provided RBAC role to the subscription. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `targetRoleEligibilityScheduleId` + +The resultant role eligibility assignment id or the role eligibility assignment id being updated. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `targetRoleEligibilityScheduleInstanceId` + +The role eligibility assignment instance id being updated. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `ticketInfo` + +Ticket Info of the role eligibility. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`ticketNumber`](#parameter-ticketinfoticketnumber) | string | The ticket number for the role eligibility assignment. | +| [`ticketSystem`](#parameter-ticketinfoticketsystem) | string | The ticket system name for the role eligibility assignment. | + +### Parameter: `ticketInfo.ticketNumber` + +The ticket number for the role eligibility assignment. + +- Required: No +- Type: string + +### Parameter: `ticketInfo.ticketSystem` + +The ticket system name for the role eligibility assignment. - Required: No - Type: string -- Default: `[resourceGroup().location]` ## Outputs -_None_ +| Output | Type | Description | +| :-- | :-- | :-- | +| `name` | string | The GUID of the PIM Role Assignment. | +| `resourceId` | string | The resource ID of the PIM Role Assignment. | +| `scope` | string | The scope this PIM Role Assignment applies to. | ## Data Collection diff --git a/avm/ptn/authorization/pim-role-assignment/main.json b/avm/ptn/authorization/pim-role-assignment/main.json index ee978d2e98..c68cddd8c2 100644 --- a/avm/ptn/authorization/pim-role-assignment/main.json +++ b/avm/ptn/authorization/pim-role-assignment/main.json @@ -1,27 +1,219 @@ { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "$schema": "https://schema.management.azure.com/schemas/2019-08-01/managementGroupDeploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.32.4.45862", - "templateHash": "17114577725154327600" + "templateHash": "2264747261940316043" }, "name": "", "description": "" }, + "definitions": { + "requestTypeType": { + "type": "string", + "allowedValues": [ + "AdminAssign", + "AdminExtend", + "AdminRemove", + "AdminRenew", + "AdminUpdate", + "SelfActivate", + "SelfDeactivate", + "SelfExtend", + "SelfRenew" + ], + "metadata": { + "description": "Optional. The request type of the role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "modules/definitions.bicep" + } + } + }, + "scheduleInfoExpirationType": { + "type": "object", + "properties": { + "duration": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Duration of the role eligibility assignment in TimeSpan format. Example: P365D, P2H" + } + }, + "endDateTime": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. End DateTime of the role eligibility assignment." + } + }, + "type": { + "type": "string", + "allowedValues": [ + "AfterDateTime", + "AfterDuration", + "NoExpiration" + ], + "nullable": true, + "metadata": { + "description": "Optional. Type of the role eligibility assignment expiration." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "modules/definitions.bicep" + } + } + }, + "scheduleInfoType": { + "type": "object", + "properties": { + "expiration": { + "$ref": "#/definitions/scheduleInfoExpirationType", + "nullable": true, + "metadata": { + "description": "Optional. The expiry information for the role eligibility." + } + }, + "startDateTime": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Start DateTime of the role eligibility assignment." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "modules/definitions.bicep" + } + } + }, + "ticketInfoType": { + "type": "object", + "properties": { + "ticketNumber": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The ticket number for the role eligibility assignment." + } + }, + "ticketSystem": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The ticket system name for the role eligibility assignment." + } + } + }, + "nullable": true, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "modules/definitions.bicep" + } + } + } + }, "parameters": { - "name": { + "roleDefinitionIdOrName": { "type": "string", "metadata": { - "description": "Required. Name of the resource to create." + "description": "Required. You can provide either the display name of the role definition (must be configured in the variable `builtInRoleNames`), or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The Principal or Object ID of the Security Principal (User, Group, Service Principal, Managed Identity)." + } + }, + "resourceGroupName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Name of the Resource Group to assign the RBAC role to. If Resource Group name is provided, and Subscription ID is provided, the module deploys at resource group level, therefore assigns the provided RBAC role to the resource group." + } + }, + "subscriptionId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Subscription ID of the subscription to assign the RBAC role to. If no Resource Group name is provided, the module deploys at subscription level, therefore assigns the provided RBAC role to the subscription." + } + }, + "managementGroupId": { + "type": "string", + "defaultValue": "[managementGroup().name]", + "metadata": { + "description": "Optional. Group ID of the Management Group to assign the RBAC role to. If not provided, will use the current scope for deployment." } }, "location": { "type": "string", - "defaultValue": "[resourceGroup().location]", + "defaultValue": "[deployment().location]", "metadata": { - "description": "Optional. Location for all Resources." + "description": "Optional. Location deployment metadata." + } + }, + "justification": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The justification for the role eligibility." + } + }, + "requestType": { + "$ref": "#/definitions/requestTypeType", + "metadata": { + "description": "Required. The type of the role assignment eligibility request." + } + }, + "targetRoleEligibilityScheduleId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The resultant role eligibility assignment id or the role eligibility assignment id being updated." + } + }, + "targetRoleEligibilityScheduleInstanceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The role eligibility assignment instance id being updated." + } + }, + "ticketInfo": { + "$ref": "#/definitions/ticketInfoType", + "nullable": true, + "metadata": { + "description": "Optional. Ticket Info of the role eligibility." + } + }, + "scheduleInfo": { + "$ref": "#/definitions/scheduleInfoType", + "metadata": { + "description": "Optional. Schedule info of the role eligibility assignment." + } + }, + "condition": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to." + } + }, + "conditionVersion": { + "type": "string", + "defaultValue": "2.0", + "allowedValues": [ + "2.0" + ], + "metadata": { + "description": "Optional. Version of the condition. Currently accepted value is \"2.0\"." } }, "enableTelemetry": { @@ -32,12 +224,12 @@ } } }, - "resources": [ - { + "resources": { + "avmTelemetry": { "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.[[REPLACE WITH TELEMETRY IDENTIFIER]].{0}.{1}', replace('-..--..-', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.ptn.authorization-pimroleassignment.{0}.{1}', replace('-..--..-', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -51,7 +243,951 @@ } } } + }, + "location": "[parameters('location')]" + }, + "roleAssignment_mg": { + "condition": "[and(empty(parameters('subscriptionId')), empty(parameters('resourceGroupName')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-PimRoleAssignment-MG-Module', uniqueString(deployment().name, parameters('location')))]", + "scope": "[format('Microsoft.Management/managementGroups/{0}', parameters('managementGroupId'))]", + "location": "[deployment().location]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "roleDefinitionIdOrName": { + "value": "[parameters('roleDefinitionIdOrName')]" + }, + "principalId": { + "value": "[parameters('principalId')]" + }, + "managementGroupId": { + "value": "[parameters('managementGroupId')]" + }, + "requestType": { + "value": "[parameters('requestType')]" + }, + "justification": { + "value": "[parameters('justification')]" + }, + "targetRoleEligibilityScheduleId": { + "value": "[parameters('targetRoleEligibilityScheduleId')]" + }, + "targetRoleEligibilityScheduleInstanceId": { + "value": "[parameters('targetRoleEligibilityScheduleInstanceId')]" + }, + "ticketInfo": { + "value": "[parameters('ticketInfo')]" + }, + "conditionVersion": { + "value": "[parameters('conditionVersion')]" + }, + "condition": "[if(not(empty(parameters('condition'))), createObject('value', parameters('condition')), createObject('value', ''))]", + "scheduleInfo": { + "value": "[parameters('scheduleInfo')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-08-01/managementGroupDeploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.32.4.45862", + "templateHash": "10603070821192131693" + }, + "name": " PIM Role Assignments (Management Group scope)", + "description": "This module deploys a PIM Role Assignment at a Management Group scope." + }, + "definitions": { + "requestTypeType": { + "type": "string", + "allowedValues": [ + "AdminAssign", + "AdminExtend", + "AdminRemove", + "AdminRenew", + "AdminUpdate", + "SelfActivate", + "SelfDeactivate", + "SelfExtend", + "SelfRenew" + ], + "metadata": { + "description": "Optional. The request type of the role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "definitions.bicep" + } + } + }, + "scheduleInfoExpirationType": { + "type": "object", + "properties": { + "duration": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Duration of the role eligibility assignment in TimeSpan format. Example: P365D, P2H" + } + }, + "endDateTime": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. End DateTime of the role eligibility assignment." + } + }, + "type": { + "type": "string", + "allowedValues": [ + "AfterDateTime", + "AfterDuration", + "NoExpiration" + ], + "nullable": true, + "metadata": { + "description": "Optional. Type of the role eligibility assignment expiration." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "definitions.bicep" + } + } + }, + "scheduleInfoType": { + "type": "object", + "properties": { + "expiration": { + "$ref": "#/definitions/scheduleInfoExpirationType", + "nullable": true, + "metadata": { + "description": "Optional. The expiry information for the role eligibility." + } + }, + "startDateTime": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Start DateTime of the role eligibility assignment." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "definitions.bicep" + } + } + }, + "ticketInfoType": { + "type": "object", + "properties": { + "ticketNumber": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The ticket number for the role eligibility assignment." + } + }, + "ticketSystem": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The ticket system name for the role eligibility assignment." + } + } + }, + "nullable": true, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "definitions.bicep" + } + } + } + }, + "parameters": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. You can provide either the display name of the role definition (must be configured in the variable `builtInRoleNames`), or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The Principal or Object ID of the Security Principal (User, Group, Service Principal, Managed Identity)." + } + }, + "managementGroupId": { + "type": "string", + "defaultValue": "[managementGroup().name]", + "metadata": { + "description": "Optional. Group ID of the Management Group to assign the RBAC role to. If not provided, will use the current scope for deployment." + } + }, + "justification": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The justification for the role eligibility." + } + }, + "requestType": { + "$ref": "#/definitions/requestTypeType", + "metadata": { + "description": "Required. The type of the role assignment eligibility request." + } + }, + "targetRoleEligibilityScheduleId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The resultant role eligibility assignment id or the role eligibility assignment id being updated." + } + }, + "targetRoleEligibilityScheduleInstanceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The role eligibility assignment instance id being updated." + } + }, + "ticketInfo": { + "$ref": "#/definitions/ticketInfoType", + "nullable": true, + "metadata": { + "description": "Optional. Ticket Info of the role eligibility." + } + }, + "scheduleInfo": { + "$ref": "#/definitions/scheduleInfoType", + "metadata": { + "description": "Optional. Schedule info of the role eligibility assignment." + } + }, + "condition": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to." + } + }, + "conditionVersion": { + "type": "string", + "defaultValue": "2.0", + "allowedValues": [ + "2.0" + ], + "metadata": { + "description": "Optional. Version of the condition. Currently accepted value is \"2.0\"." + } + } + }, + "variables": { + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", + "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", + "Management Group Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ac63b705-f282-497d-ac71-919bf39d939d')]" + }, + "roleDefinitionIdVar": "[coalesce(tryGet(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), parameters('roleDefinitionIdOrName'))]" + }, + "resources": { + "pimRoleAssignment": { + "type": "Microsoft.Authorization/roleEligibilityScheduleRequests", + "apiVersion": "2022-04-01-preview", + "name": "[guid(parameters('managementGroupId'), variables('roleDefinitionIdVar'), parameters('principalId'))]", + "properties": { + "principalId": "[parameters('principalId')]", + "roleDefinitionId": "[variables('roleDefinitionIdVar')]", + "requestType": "[parameters('requestType')]", + "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", + "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", + "justification": "[parameters('justification')]", + "scheduleInfo": "[parameters('scheduleInfo')]", + "targetRoleEligibilityScheduleId": "[parameters('targetRoleEligibilityScheduleId')]", + "targetRoleEligibilityScheduleInstanceId": "[parameters('targetRoleEligibilityScheduleInstanceId')]", + "ticketInfo": "[parameters('ticketInfo')]" + } + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The GUID of the PIM Role Assignment." + }, + "value": "[guid(parameters('managementGroupId'), variables('roleDefinitionIdVar'), parameters('principalId'))]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the PIM Role Assignment." + }, + "value": "[extensionResourceId(managementGroup().id, 'Microsoft.Authorization/roleEligibilityScheduleRequests', guid(parameters('managementGroupId'), variables('roleDefinitionIdVar'), parameters('principalId')))]" + }, + "scope": { + "type": "string", + "metadata": { + "description": "The scope this PIM Role Assignment applies to." + }, + "value": "[resourceId('Microsoft.Management/managementGroups', parameters('managementGroupId'))]" + } + } + } + } + }, + "roleAssignment_sub": { + "condition": "[and(not(empty(parameters('subscriptionId'))), empty(parameters('resourceGroupName')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-PimRoleAssignment-Sub-Module', uniqueString(deployment().name, parameters('location')))]", + "subscriptionId": "[parameters('subscriptionId')]", + "location": "[deployment().location]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "roleDefinitionIdOrName": { + "value": "[parameters('roleDefinitionIdOrName')]" + }, + "principalId": { + "value": "[parameters('principalId')]" + }, + "subscriptionId": { + "value": "[parameters('subscriptionId')]" + }, + "requestType": { + "value": "[parameters('requestType')]" + }, + "justification": { + "value": "[parameters('justification')]" + }, + "targetRoleEligibilityScheduleId": { + "value": "[parameters('targetRoleEligibilityScheduleId')]" + }, + "targetRoleEligibilityScheduleInstanceId": { + "value": "[parameters('targetRoleEligibilityScheduleInstanceId')]" + }, + "ticketInfo": { + "value": "[parameters('ticketInfo')]" + }, + "conditionVersion": { + "value": "[parameters('conditionVersion')]" + }, + "condition": "[if(not(empty(parameters('condition'))), createObject('value', parameters('condition')), createObject('value', ''))]", + "scheduleInfo": { + "value": "[parameters('scheduleInfo')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.32.4.45862", + "templateHash": "10664267379889324239" + }, + "name": "PIM Role Assignments (Subscription scope)", + "description": "This module deploys a PIM Role Assignment at a Subscription scope." + }, + "definitions": { + "requestTypeType": { + "type": "string", + "allowedValues": [ + "AdminAssign", + "AdminExtend", + "AdminRemove", + "AdminRenew", + "AdminUpdate", + "SelfActivate", + "SelfDeactivate", + "SelfExtend", + "SelfRenew" + ], + "metadata": { + "description": "Optional. The request type of the role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "definitions.bicep" + } + } + }, + "scheduleInfoExpirationType": { + "type": "object", + "properties": { + "duration": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Duration of the role eligibility assignment in TimeSpan format. Example: P365D, P2H" + } + }, + "endDateTime": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. End DateTime of the role eligibility assignment." + } + }, + "type": { + "type": "string", + "allowedValues": [ + "AfterDateTime", + "AfterDuration", + "NoExpiration" + ], + "nullable": true, + "metadata": { + "description": "Optional. Type of the role eligibility assignment expiration." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "definitions.bicep" + } + } + }, + "scheduleInfoType": { + "type": "object", + "properties": { + "expiration": { + "$ref": "#/definitions/scheduleInfoExpirationType", + "nullable": true, + "metadata": { + "description": "Optional. The expiry information for the role eligibility." + } + }, + "startDateTime": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Start DateTime of the role eligibility assignment." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "definitions.bicep" + } + } + }, + "ticketInfoType": { + "type": "object", + "properties": { + "ticketNumber": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The ticket number for the role eligibility assignment." + } + }, + "ticketSystem": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The ticket system name for the role eligibility assignment." + } + } + }, + "nullable": true, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "definitions.bicep" + } + } + } + }, + "parameters": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. You can provide either the display name of the role definition (must be configured in the variable `builtInRoleNames`), or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The Principal or Object ID of the Security Principal (User, Group, Service Principal, Managed Identity)." + } + }, + "subscriptionId": { + "type": "string", + "defaultValue": "[subscription().subscriptionId]", + "metadata": { + "description": "Optional. Subscription ID of the subscription to assign the RBAC role to. If not provided, will use the current scope for deployment." + } + }, + "justification": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The justification for the role eligibility." + } + }, + "requestType": { + "$ref": "#/definitions/requestTypeType", + "metadata": { + "description": "Required. The type of the role assignment eligibility request." + } + }, + "targetRoleEligibilityScheduleId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The resultant role eligibility assignment id or the role eligibility assignment id being updated." + } + }, + "targetRoleEligibilityScheduleInstanceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The role eligibility assignment instance id being updated." + } + }, + "ticketInfo": { + "$ref": "#/definitions/ticketInfoType", + "nullable": true, + "metadata": { + "description": "Optional. Ticket Info of the role eligibility." + } + }, + "scheduleInfo": { + "$ref": "#/definitions/scheduleInfoType", + "metadata": { + "description": "Optional. Schedule info of the role eligibility assignment." + } + }, + "condition": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to." + } + }, + "conditionVersion": { + "type": "string", + "defaultValue": "2.0", + "allowedValues": [ + "2.0" + ], + "metadata": { + "description": "Optional. Version of the condition. Currently accepted value is \"2.0\"." + } + } + }, + "variables": { + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + }, + "roleDefinitionIdVar": "[coalesce(tryGet(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), parameters('roleDefinitionIdOrName'))]" + }, + "resources": { + "pimRoleAssignment": { + "type": "Microsoft.Authorization/roleEligibilityScheduleRequests", + "apiVersion": "2022-04-01-preview", + "name": "[guid(parameters('subscriptionId'), variables('roleDefinitionIdVar'), parameters('principalId'))]", + "properties": { + "principalId": "[parameters('principalId')]", + "roleDefinitionId": "[variables('roleDefinitionIdVar')]", + "requestType": "[parameters('requestType')]", + "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", + "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", + "justification": "[parameters('justification')]", + "scheduleInfo": "[parameters('scheduleInfo')]", + "targetRoleEligibilityScheduleId": "[parameters('targetRoleEligibilityScheduleId')]", + "targetRoleEligibilityScheduleInstanceId": "[parameters('targetRoleEligibilityScheduleInstanceId')]", + "ticketInfo": "[parameters('ticketInfo')]" + } + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The GUID of the PIM Role Assignment." + }, + "value": "[guid(parameters('subscriptionId'), variables('roleDefinitionIdVar'), parameters('principalId'))]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the PIM Role Assignment." + }, + "value": "[subscriptionResourceId('Microsoft.Authorization/roleEligibilityScheduleRequests', guid(parameters('subscriptionId'), variables('roleDefinitionIdVar'), parameters('principalId')))]" + }, + "subscriptionName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the PIM role assignment was applied at." + }, + "value": "[subscription().displayName]" + }, + "scope": { + "type": "string", + "metadata": { + "description": "The scope this PIM Role Assignment applies to." + }, + "value": "[subscription().id]" + } + } + } } + }, + "roleAssignment_rg": { + "condition": "[and(not(empty(parameters('resourceGroupName'))), not(empty(parameters('subscriptionId'))))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-PimRoleAssignment-RG-Module', uniqueString(deployment().name, parameters('location')))]", + "subscriptionId": "[parameters('subscriptionId')]", + "resourceGroup": "[parameters('resourceGroupName')]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "roleDefinitionIdOrName": { + "value": "[parameters('roleDefinitionIdOrName')]" + }, + "principalId": { + "value": "[parameters('principalId')]" + }, + "subscriptionId": { + "value": "[parameters('subscriptionId')]" + }, + "resourceGroupName": { + "value": "[parameters('resourceGroupName')]" + }, + "requestType": { + "value": "[parameters('requestType')]" + }, + "justification": { + "value": "[parameters('justification')]" + }, + "targetRoleEligibilityScheduleId": { + "value": "[parameters('targetRoleEligibilityScheduleId')]" + }, + "targetRoleEligibilityScheduleInstanceId": { + "value": "[parameters('targetRoleEligibilityScheduleInstanceId')]" + }, + "ticketInfo": { + "value": "[parameters('ticketInfo')]" + }, + "conditionVersion": { + "value": "[parameters('conditionVersion')]" + }, + "condition": "[if(not(empty(parameters('condition'))), createObject('value', parameters('condition')), createObject('value', ''))]", + "scheduleInfo": { + "value": "[parameters('scheduleInfo')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.32.4.45862", + "templateHash": "6536365610380375961" + }, + "name": "PIM Role Assignments (Resource Group scope)", + "description": "This module deploys a PIM Role Assignment at a Resource Group scope." + }, + "definitions": { + "requestTypeType": { + "type": "string", + "allowedValues": [ + "AdminAssign", + "AdminExtend", + "AdminRemove", + "AdminRenew", + "AdminUpdate", + "SelfActivate", + "SelfDeactivate", + "SelfExtend", + "SelfRenew" + ], + "metadata": { + "description": "Optional. The request type of the role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "definitions.bicep" + } + } + }, + "scheduleInfoExpirationType": { + "type": "object", + "properties": { + "duration": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Duration of the role eligibility assignment in TimeSpan format. Example: P365D, P2H" + } + }, + "endDateTime": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. End DateTime of the role eligibility assignment." + } + }, + "type": { + "type": "string", + "allowedValues": [ + "AfterDateTime", + "AfterDuration", + "NoExpiration" + ], + "nullable": true, + "metadata": { + "description": "Optional. Type of the role eligibility assignment expiration." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "definitions.bicep" + } + } + }, + "scheduleInfoType": { + "type": "object", + "properties": { + "expiration": { + "$ref": "#/definitions/scheduleInfoExpirationType", + "nullable": true, + "metadata": { + "description": "Optional. The expiry information for the role eligibility." + } + }, + "startDateTime": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Start DateTime of the role eligibility assignment." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "definitions.bicep" + } + } + }, + "ticketInfoType": { + "type": "object", + "properties": { + "ticketNumber": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The ticket number for the role eligibility assignment." + } + }, + "ticketSystem": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The ticket system name for the role eligibility assignment." + } + } + }, + "nullable": true, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "definitions.bicep" + } + } + } + }, + "parameters": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. You can provide either the display name of the role definition (must be configured in the variable `builtInRoleNames`), or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The Principal or Object ID of the Security Principal (User, Group, Service Principal, Managed Identity)." + } + }, + "resourceGroupName": { + "type": "string", + "defaultValue": "[resourceGroup().name]", + "metadata": { + "description": "Optional. Name of the Resource Group to assign the RBAC role to. If not provided, will use the current scope for deployment." + } + }, + "subscriptionId": { + "type": "string", + "defaultValue": "[subscription().subscriptionId]", + "metadata": { + "description": "Optional. Subscription ID of the subscription to assign the RBAC role to. If not provided, will use the current scope for deployment." + } + }, + "justification": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The justification for the role eligibility." + } + }, + "requestType": { + "$ref": "#/definitions/requestTypeType", + "metadata": { + "description": "Required. The type of the role assignment eligibility request." + } + }, + "targetRoleEligibilityScheduleId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The resultant role eligibility assignment id or the role eligibility assignment id being updated." + } + }, + "targetRoleEligibilityScheduleInstanceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The role eligibility assignment instance id being updated." + } + }, + "ticketInfo": { + "$ref": "#/definitions/ticketInfoType", + "nullable": true, + "metadata": { + "description": "Optional. Ticket Info of the role eligibility." + } + }, + "scheduleInfo": { + "$ref": "#/definitions/scheduleInfoType", + "metadata": { + "description": "Optional. Schedule info of the role eligibility assignment." + } + }, + "condition": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to." + } + }, + "conditionVersion": { + "type": "string", + "defaultValue": "2.0", + "allowedValues": [ + "2.0" + ], + "metadata": { + "description": "Optional. Version of the condition. Currently accepted value is \"2.0\"." + } + } + }, + "variables": { + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + }, + "roleDefinitionIdVar": "[coalesce(tryGet(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), parameters('roleDefinitionIdOrName'))]" + }, + "resources": { + "pimRoleAssignment": { + "type": "Microsoft.Authorization/roleEligibilityScheduleRequests", + "apiVersion": "2022-04-01-preview", + "name": "[guid(parameters('subscriptionId'), parameters('resourceGroupName'), variables('roleDefinitionIdVar'), parameters('principalId'))]", + "properties": { + "roleDefinitionId": "[variables('roleDefinitionIdVar')]", + "principalId": "[parameters('principalId')]", + "requestType": "[parameters('requestType')]", + "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", + "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", + "justification": "[parameters('justification')]", + "scheduleInfo": "[parameters('scheduleInfo')]", + "targetRoleEligibilityScheduleId": "[parameters('targetRoleEligibilityScheduleId')]", + "targetRoleEligibilityScheduleInstanceId": "[parameters('targetRoleEligibilityScheduleInstanceId')]", + "ticketInfo": "[parameters('ticketInfo')]" + } + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The GUID of the PIM Role Assignment." + }, + "value": "[guid(parameters('subscriptionId'), parameters('resourceGroupName'), variables('roleDefinitionIdVar'), parameters('principalId'))]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the PIM Role Assignment." + }, + "value": "[resourceId('Microsoft.Authorization/roleEligibilityScheduleRequests', guid(parameters('subscriptionId'), parameters('resourceGroupName'), variables('roleDefinitionIdVar'), parameters('principalId')))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the PIM role assignment was applied at." + }, + "value": "[resourceGroup().name]" + }, + "scope": { + "type": "string", + "metadata": { + "description": "The scope this PIM Role Assignment applies to." + }, + "value": "[resourceGroup().id]" + } + } + } + } + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The GUID of the PIM Role Assignment." + }, + "value": "[if(and(empty(parameters('subscriptionId')), empty(parameters('resourceGroupName'))), reference('roleAssignment_mg').outputs.name.value, if(and(not(empty(parameters('subscriptionId'))), empty(parameters('resourceGroupName'))), reference('roleAssignment_sub').outputs.name.value, reference('roleAssignment_rg').outputs.name.value))]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the PIM Role Assignment." + }, + "value": "[if(and(empty(parameters('subscriptionId')), empty(parameters('resourceGroupName'))), reference('roleAssignment_mg').outputs.resourceId.value, if(and(not(empty(parameters('subscriptionId'))), empty(parameters('resourceGroupName'))), reference('roleAssignment_sub').outputs.resourceId.value, reference('roleAssignment_rg').outputs.resourceId.value))]" + }, + "scope": { + "type": "string", + "metadata": { + "description": "The scope this PIM Role Assignment applies to." + }, + "value": "[if(and(empty(parameters('subscriptionId')), empty(parameters('resourceGroupName'))), reference('roleAssignment_mg').outputs.scope.value, if(and(not(empty(parameters('subscriptionId'))), empty(parameters('resourceGroupName'))), reference('roleAssignment_sub').outputs.scope.value, reference('roleAssignment_rg').outputs.scope.value))]" } - ] + } } \ No newline at end of file From 3f4a279c1c6ac1acdc0524a5a3c3a7436a1e7205 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Thu, 23 Jan 2025 16:53:10 +0200 Subject: [PATCH 08/54] feat: Update README and Bicep files to clarify scheduleInfo parameter as required and improve descriptions --- .../pim-role-assignment/README.md | 130 +++++++++--------- .../pim-role-assignment/main.bicep | 2 +- .../pim-role-assignment/main.json | 18 +-- .../modules/definitions.bicep | 2 +- 4 files changed, 76 insertions(+), 76 deletions(-) diff --git a/avm/ptn/authorization/pim-role-assignment/README.md b/avm/ptn/authorization/pim-role-assignment/README.md index a973a4d60d..40b3b1c87b 100644 --- a/avm/ptn/authorization/pim-role-assignment/README.md +++ b/avm/ptn/authorization/pim-role-assignment/README.md @@ -686,6 +686,7 @@ param ticketInfo = { | [`principalId`](#parameter-principalid) | string | The Principal or Object ID of the Security Principal (User, Group, Service Principal, Managed Identity). | | [`requestType`](#parameter-requesttype) | string | The type of the role assignment eligibility request. | | [`roleDefinitionIdOrName`](#parameter-roledefinitionidorname) | string | You can provide either the display name of the role definition (must be configured in the variable `builtInRoleNames`), or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. | +| [`scheduleInfo`](#parameter-scheduleinfo) | object | Schedule info of the role eligibility assignment. | **Optional parameters** @@ -698,7 +699,6 @@ param ticketInfo = { | [`location`](#parameter-location) | string | Location deployment metadata. | | [`managementGroupId`](#parameter-managementgroupid) | string | Group ID of the Management Group to assign the RBAC role to. If not provided, will use the current scope for deployment. | | [`resourceGroupName`](#parameter-resourcegroupname) | string | Name of the Resource Group to assign the RBAC role to. If Resource Group name is provided, and Subscription ID is provided, the module deploys at resource group level, therefore assigns the provided RBAC role to the resource group. | -| [`scheduleInfo`](#parameter-scheduleinfo) | object | Schedule info of the role eligibility assignment. | | [`subscriptionId`](#parameter-subscriptionid) | string | Subscription ID of the subscription to assign the RBAC role to. If no Resource Group name is provided, the module deploys at subscription level, therefore assigns the provided RBAC role to the subscription. | | [`targetRoleEligibilityScheduleId`](#parameter-targetroleeligibilityscheduleid) | string | The resultant role eligibility assignment id or the role eligibility assignment id being updated. | | [`targetRoleEligibilityScheduleInstanceId`](#parameter-targetroleeligibilityscheduleinstanceid) | string | The role eligibility assignment instance id being updated. | @@ -739,68 +739,6 @@ You can provide either the display name of the role definition (must be configur - Required: Yes - Type: string -### Parameter: `condition` - -The conditions on the role assignment. This limits the resources it can be assigned to. - -- Required: No -- Type: string -- Default: `''` - -### Parameter: `conditionVersion` - -Version of the condition. Currently accepted value is "2.0". - -- Required: No -- Type: string -- Default: `'2.0'` -- Allowed: - ```Bicep - [ - '2.0' - ] - ``` - -### Parameter: `enableTelemetry` - -Enable/Disable usage telemetry for module. - -- Required: No -- Type: bool -- Default: `True` - -### Parameter: `justification` - -The justification for the role eligibility. - -- Required: No -- Type: string -- Default: `''` - -### Parameter: `location` - -Location deployment metadata. - -- Required: No -- Type: string -- Default: `[deployment().location]` - -### Parameter: `managementGroupId` - -Group ID of the Management Group to assign the RBAC role to. If not provided, will use the current scope for deployment. - -- Required: No -- Type: string -- Default: `[managementGroup().name]` - -### Parameter: `resourceGroupName` - -Name of the Resource Group to assign the RBAC role to. If Resource Group name is provided, and Subscription ID is provided, the module deploys at resource group level, therefore assigns the provided RBAC role to the resource group. - -- Required: No -- Type: string -- Default: `''` - ### Parameter: `scheduleInfo` Schedule info of the role eligibility assignment. @@ -826,13 +764,13 @@ The expiry information for the role eligibility. | Parameter | Type | Description | | :-- | :-- | :-- | -| [`duration`](#parameter-scheduleinfoexpirationduration) | string | Duration of the role eligibility assignment in TimeSpan format. Example: P365D, P2H | +| [`duration`](#parameter-scheduleinfoexpirationduration) | string | Duration of the role eligibility assignment in TimeSpan format. Example: P365D, P2H. | | [`endDateTime`](#parameter-scheduleinfoexpirationenddatetime) | string | End DateTime of the role eligibility assignment. | | [`type`](#parameter-scheduleinfoexpirationtype) | string | Type of the role eligibility assignment expiration. | ### Parameter: `scheduleInfo.expiration.duration` -Duration of the role eligibility assignment in TimeSpan format. Example: P365D, P2H +Duration of the role eligibility assignment in TimeSpan format. Example: P365D, P2H. - Required: No - Type: string @@ -866,6 +804,68 @@ Start DateTime of the role eligibility assignment. - Required: No - Type: string +### Parameter: `condition` + +The conditions on the role assignment. This limits the resources it can be assigned to. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `conditionVersion` + +Version of the condition. Currently accepted value is "2.0". + +- Required: No +- Type: string +- Default: `'2.0'` +- Allowed: + ```Bicep + [ + '2.0' + ] + ``` + +### Parameter: `enableTelemetry` + +Enable/Disable usage telemetry for module. + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `justification` + +The justification for the role eligibility. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `location` + +Location deployment metadata. + +- Required: No +- Type: string +- Default: `[deployment().location]` + +### Parameter: `managementGroupId` + +Group ID of the Management Group to assign the RBAC role to. If not provided, will use the current scope for deployment. + +- Required: No +- Type: string +- Default: `[managementGroup().name]` + +### Parameter: `resourceGroupName` + +Name of the Resource Group to assign the RBAC role to. If Resource Group name is provided, and Subscription ID is provided, the module deploys at resource group level, therefore assigns the provided RBAC role to the resource group. + +- Required: No +- Type: string +- Default: `''` + ### Parameter: `subscriptionId` Subscription ID of the subscription to assign the RBAC role to. If no Resource Group name is provided, the module deploys at subscription level, therefore assigns the provided RBAC role to the subscription. diff --git a/avm/ptn/authorization/pim-role-assignment/main.bicep b/avm/ptn/authorization/pim-role-assignment/main.bicep index 50a899225f..2884e545a4 100644 --- a/avm/ptn/authorization/pim-role-assignment/main.bicep +++ b/avm/ptn/authorization/pim-role-assignment/main.bicep @@ -38,7 +38,7 @@ param targetRoleEligibilityScheduleInstanceId string = '' @sys.description('Optional. Ticket Info of the role eligibility.') param ticketInfo ticketInfoType? -@sys.description('Optional. Schedule info of the role eligibility assignment.') +@sys.description('Required. Schedule info of the role eligibility assignment.') param scheduleInfo scheduleInfoType @sys.description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to.') diff --git a/avm/ptn/authorization/pim-role-assignment/main.json b/avm/ptn/authorization/pim-role-assignment/main.json index c68cddd8c2..09b67e743e 100644 --- a/avm/ptn/authorization/pim-role-assignment/main.json +++ b/avm/ptn/authorization/pim-role-assignment/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.32.4.45862", - "templateHash": "2264747261940316043" + "templateHash": "17896703325979208691" }, "name": "", "description": "" @@ -39,7 +39,7 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Duration of the role eligibility assignment in TimeSpan format. Example: P365D, P2H" + "description": "Optional. Duration of the role eligibility assignment in TimeSpan format. Example: P365D, P2H." } }, "endDateTime": { @@ -196,7 +196,7 @@ "scheduleInfo": { "$ref": "#/definitions/scheduleInfoType", "metadata": { - "description": "Optional. Schedule info of the role eligibility assignment." + "description": "Required. Schedule info of the role eligibility assignment." } }, "condition": { @@ -299,7 +299,7 @@ "_generator": { "name": "bicep", "version": "0.32.4.45862", - "templateHash": "10603070821192131693" + "templateHash": "3472269945089695290" }, "name": " PIM Role Assignments (Management Group scope)", "description": "This module deploys a PIM Role Assignment at a Management Group scope." @@ -332,7 +332,7 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Duration of the role eligibility assignment in TimeSpan format. Example: P365D, P2H" + "description": "Optional. Duration of the role eligibility assignment in TimeSpan format. Example: P365D, P2H." } }, "endDateTime": { @@ -599,7 +599,7 @@ "_generator": { "name": "bicep", "version": "0.32.4.45862", - "templateHash": "10664267379889324239" + "templateHash": "777676517902942222" }, "name": "PIM Role Assignments (Subscription scope)", "description": "This module deploys a PIM Role Assignment at a Subscription scope." @@ -632,7 +632,7 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Duration of the role eligibility assignment in TimeSpan format. Example: P365D, P2H" + "description": "Optional. Duration of the role eligibility assignment in TimeSpan format. Example: P365D, P2H." } }, "endDateTime": { @@ -907,7 +907,7 @@ "_generator": { "name": "bicep", "version": "0.32.4.45862", - "templateHash": "6536365610380375961" + "templateHash": "16754171039560483844" }, "name": "PIM Role Assignments (Resource Group scope)", "description": "This module deploys a PIM Role Assignment at a Resource Group scope." @@ -940,7 +940,7 @@ "type": "string", "nullable": true, "metadata": { - "description": "Optional. Duration of the role eligibility assignment in TimeSpan format. Example: P365D, P2H" + "description": "Optional. Duration of the role eligibility assignment in TimeSpan format. Example: P365D, P2H." } }, "endDateTime": { diff --git a/avm/ptn/authorization/pim-role-assignment/modules/definitions.bicep b/avm/ptn/authorization/pim-role-assignment/modules/definitions.bicep index c4d9a1d470..ce8793fda5 100644 --- a/avm/ptn/authorization/pim-role-assignment/modules/definitions.bicep +++ b/avm/ptn/authorization/pim-role-assignment/modules/definitions.bicep @@ -26,7 +26,7 @@ type scheduleInfoType = { @export() type scheduleInfoExpirationType = { - @sys.description('Optional. Duration of the role eligibility assignment in TimeSpan format. Example: P365D, P2H') + @sys.description('Optional. Duration of the role eligibility assignment in TimeSpan format. Example: P365D, P2H.') duration: string? @sys.description('Optional. End DateTime of the role eligibility assignment.') From dceb7d1477b84caeda6a998dceee15f562735856 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Thu, 23 Jan 2025 16:58:04 +0200 Subject: [PATCH 09/54] feat: Update CODEOWNERS to include new role assignment paths for improved ownership tracking --- .github/CODEOWNERS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 8fc0458129..d1c68efad1 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -6,6 +6,8 @@ /avm/ptn/aca-lza/hosting-environment/ @Azure/avm-ptn-acalza-hostingenvironment-module-owners-bicep @Azure/avm-module-reviewers-bicep /avm/ptn/ai-platform/baseline/ @Azure/avm-ptn-aiplatform-baseline-module-owners-bicep @Azure/avm-module-reviewers-bicep /avm/ptn/app/container-job-toolkit/ @Azure/avm-ptn-app-containerjobtoolkit-module-owners-bicep @Azure/avm-module-reviewers-bicep +/avm/ptn/authorization/role-assignment/ @Azure/avm-ptn-authorization-roleassignment-module-owners-bicep @Azure/avm-module-reviewers-bicep +/avm/ptn/authorization/pim-role-assignment/ @Azure/avm-ptn-authorization-pimroleassignment-module-owners-bicep @Azure/avm-module-reviewers-bicep /avm/ptn/authorization/policy-assignment/ @Azure/avm-ptn-authorization-policyassignment-module-owners-bicep @Azure/avm-module-reviewers-bicep /avm/ptn/authorization/policy-exemption/ @Azure/avm-ptn-authorization-policyexemption-module-owners-bicep @Azure/avm-module-reviewers-bicep /avm/ptn/authorization/resource-role-assignment/ @Azure/avm-ptn-authorization-resourceroleassignment-module-owners-bicep @Azure/avm-module-reviewers-bicep From 50762c64e14a53b748a4c263f7008975171fab94 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Thu, 23 Jan 2025 17:01:29 +0200 Subject: [PATCH 10/54] feat: Add namePrefix parameter to Bicep test files for resource naming flexibility --- .../tests/e2e/mg.defaults/main.test.bicep | 5 ++++- .../tests/e2e/sub.default/main.test.bicep | 5 ++++- .../pim-role-assignment/tests/e2e/sub.max/main.test.bicep | 5 ++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep index ed10e4ce1f..a1497c1629 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep @@ -12,6 +12,9 @@ param resourceLocation string = deployment().location @description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') param serviceShort string = 'pimmgmin' +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + @description('Required. Principle ID of the user. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'userPrinicipalId\'.') @secure() param userPrinicipalId string = '' @@ -21,7 +24,7 @@ param userPrinicipalId string = '' // ============== // module testDeployment '../../../main.bicep' = { - name: '${uniqueString(deployment().name)}-test-${serviceShort}' + name: '${uniqueString(deployment().name)}-test-${serviceShort}-${namePrefix}' params: { principalId: userPrinicipalId roleDefinitionIdOrName: 'Resource Policy Contributor' diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep index 1db381008c..dd40de15fa 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep @@ -9,6 +9,9 @@ metadata description = 'This module deploys a PIM Role Assignment at a Subscript @description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') param serviceShort string = 'pimsubmin' +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + @description('Optional. Subscription ID of the subscription to assign the RBAC role to. If no Resource Group name is provided, the module deploys at subscription level, therefore assigns the provided RBAC role to the subscription.') param subscriptionId string = '#_subscriptionId_#' @@ -21,7 +24,7 @@ param userPrinicipalId string = '' // ============== // module testDeployment '../../../main.bicep' = { - name: '${uniqueString(deployment().name)}-test-${serviceShort}' + name: '${uniqueString(deployment().name)}-test-${serviceShort}-${namePrefix}' params: { principalId: userPrinicipalId roleDefinitionIdOrName: subscriptionResourceId( diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.max/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.max/main.test.bicep index 3ee5ea1a7e..1f7cae84db 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.max/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.max/main.test.bicep @@ -12,6 +12,9 @@ param resourceLocation string = deployment().location @description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') param serviceShort string = 'pimsubmax' +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + @description('Optional. Subscription ID of the subscription to assign the RBAC role to. If no Resource Group name is provided, the module deploys at subscription level, therefore assigns the provided RBAC role to the subscription.') param subscriptionId string = '#_subscriptionId_#' @@ -24,7 +27,7 @@ param userPrinicipalId string = '' // ============== // module testDeployment '../../../main.bicep' = { - name: '${uniqueString(deployment().name)}-test-${serviceShort}' + name: '${uniqueString(deployment().name)}-test-${serviceShort}-${namePrefix}' params: { principalId: userPrinicipalId roleDefinitionIdOrName: 'Reader' From 4d9fee80f8b67bc40ac0297a008dee240c3d17a3 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Thu, 23 Jan 2025 20:44:56 +0200 Subject: [PATCH 11/54] feat: Update roleDefinitionIdOrName from 'Resource Policy Contributor' to 'Contributor' for consistency across documentation and tests --- .../authorization/pim-role-assignment/README.md | 12 ++++++------ .../authorization/pim-role-assignment/main.json | 16 ++++++++-------- .../tests/e2e/mg.max/main.test.bicep | 2 +- .../tests/e2e/rg.max/main.test.bicep | 2 +- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/avm/ptn/authorization/pim-role-assignment/README.md b/avm/ptn/authorization/pim-role-assignment/README.md index 40b3b1c87b..845a70fcd9 100644 --- a/avm/ptn/authorization/pim-role-assignment/README.md +++ b/avm/ptn/authorization/pim-role-assignment/README.md @@ -141,7 +141,7 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:' requestType: 'AdminAssign' - roleDefinitionIdOrName: 'Resource Policy Contributor' + roleDefinitionIdOrName: 'Contributor' scheduleInfo: { expiration: { type: 'AfterDateTime' @@ -179,7 +179,7 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:' // Required parameters param principalId = '' param requestType = 'AdminAssign' -param roleDefinitionIdOrName = 'Resource Policy Contributor' +param roleDefinitionIdOrName = 'Contributor' param scheduleInfo = { expiration: { type: 'AfterDateTime' @@ -358,7 +358,7 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:' requestType: 'AdminAssign' - roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11' + roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7' scheduleInfo: { expiration: { type: 'AfterDateTime' @@ -398,7 +398,7 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:' // Required parameters param principalId = '' param requestType = 'AdminAssign' -param roleDefinitionIdOrName = '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11' +param roleDefinitionIdOrName = '/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7' param scheduleInfo = { expiration: { type: 'AfterDateTime' diff --git a/avm/ptn/authorization/pim-role-assignment/main.json b/avm/ptn/authorization/pim-role-assignment/main.json index 09b67e743e..8e5fbb3d69 100644 --- a/avm/ptn/authorization/pim-role-assignment/main.json +++ b/avm/ptn/authorization/pim-role-assignment/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "17896703325979208691" + "version": "0.33.13.18514", + "templateHash": "1554994413761275960" }, "name": "", "description": "" @@ -298,8 +298,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "3472269945089695290" + "version": "0.33.13.18514", + "templateHash": "13148321770832829527" }, "name": " PIM Role Assignments (Management Group scope)", "description": "This module deploys a PIM Role Assignment at a Management Group scope." @@ -598,8 +598,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "777676517902942222" + "version": "0.33.13.18514", + "templateHash": "7566590888966202430" }, "name": "PIM Role Assignments (Subscription scope)", "description": "This module deploys a PIM Role Assignment at a Subscription scope." @@ -906,8 +906,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "16754171039560483844" + "version": "0.33.13.18514", + "templateHash": "5557911543551567745" }, "name": "PIM Role Assignments (Resource Group scope)", "description": "This module deploys a PIM Role Assignment at a Resource Group scope." diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep index bd69afe4b3..d55a66a6d2 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep @@ -27,7 +27,7 @@ module testDeployment '../../../main.bicep' = { name: '${uniqueString(deployment().name)}-test-${namePrefix}-${serviceShort}' params: { principalId: userPrinicipalId - roleDefinitionIdOrName: 'Resource Policy Contributor' + roleDefinitionIdOrName: 'Contributor' requestType: 'AdminAssign' location: resourceLocation scheduleInfo: { diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep index 01dd6fccf1..c19c0e4f73 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep @@ -48,7 +48,7 @@ module testDeployment '../../../main.bicep' = { name: '${uniqueString(deployment().name)}-test-${serviceShort}' params: { principalId: userPrinicipalId - roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11' + roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7' location: resourceLocation subscriptionId: subscriptionId resourceGroupName: resourceGroup.outputs.name From 0e59e83922eaeadd927a69007f9b3c1326f63e80 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Sun, 2 Feb 2025 11:21:39 +0200 Subject: [PATCH 12/54] feat: Enhance PIM role assignment module with eligible role support and updated metadata --- .../pim-role-assignment/main.bicep | 26 ++++-- .../modules/definitions.bicep | 60 ++++++++----- .../modules/management-group.bicep | 86 +++++++++++++++++-- .../modules/resource-group.bicep | 86 +++++++++++++++++-- .../modules/subscription.bicep | 86 +++++++++++++++++-- .../tests/e2e/mg.defaults/main.test.bicep | 22 +++-- 6 files changed, 305 insertions(+), 61 deletions(-) diff --git a/avm/ptn/authorization/pim-role-assignment/main.bicep b/avm/ptn/authorization/pim-role-assignment/main.bicep index 2884e545a4..2bf9e8de25 100644 --- a/avm/ptn/authorization/pim-role-assignment/main.bicep +++ b/avm/ptn/authorization/pim-role-assignment/main.bicep @@ -3,7 +3,7 @@ metadata description = '' targetScope = 'managementGroup' -import { requestTypeType, scheduleInfoType, scheduleInfoExpirationType, ticketInfoType } from 'modules/definitions.bicep' +import { requestTypeType, ticketInfoType, pimRoleAssignmentTypeType } from 'modules/definitions.bicep' @sys.description('Required. You can provide either the display name of the role definition (must be configured in the variable `builtInRoleNames`), or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.') param roleDefinitionIdOrName string @@ -23,6 +23,9 @@ param managementGroupId string = managementGroup().name @sys.description('Optional. Location deployment metadata.') param location string = deployment().location +@description('Required. The type of the PIM role assignment whether its active or eligible.') +param pimRoleAssignmentType pimRoleAssignmentTypeType + @sys.description('Optional. The justification for the role eligibility.') param justification string = '' @@ -35,12 +38,15 @@ param targetRoleEligibilityScheduleId string = '' @sys.description('Optional. The role eligibility assignment instance id being updated.') param targetRoleEligibilityScheduleInstanceId string = '' +@sys.description('Optional. The resultant role assignment schedule id or the role assignment schedule id being updated.') +param targetRoleAssignmentScheduleId string = '' + +@sys.description('Optional. The role assignment schedule instance id being updated.') +param targetRoleAssignmentScheduleInstanceId string = '' + @sys.description('Optional. Ticket Info of the role eligibility.') param ticketInfo ticketInfoType? -@sys.description('Required. Schedule info of the role eligibility assignment.') -param scheduleInfo scheduleInfoType - @sys.description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to.') param condition string = '' @@ -88,14 +94,16 @@ module roleAssignment_mg 'modules/management-group.bicep' = if (empty(subscripti justification: justification targetRoleEligibilityScheduleId: targetRoleEligibilityScheduleId targetRoleEligibilityScheduleInstanceId: targetRoleEligibilityScheduleInstanceId + targetRoleAssignmentScheduleId: targetRoleAssignmentScheduleId + targetRoleAssignmentScheduleInstanceId: targetRoleAssignmentScheduleInstanceId ticketInfo: ticketInfo conditionVersion: conditionVersion condition: !empty(condition) ? condition : '' - scheduleInfo: scheduleInfo + pimRoleAssignmentType: pimRoleAssignmentType } } -module roleAssignment_sub 'modules/subscription.bicep' = if (!empty(subscriptionId) && empty(resourceGroupName)) { +/*module roleAssignment_sub 'modules/subscription.bicep' = if (!empty(subscriptionId) && empty(resourceGroupName)) { name: '${uniqueString(deployment().name, location)}-PimRoleAssignment-Sub-Module' scope: subscription(subscriptionId) params: { @@ -109,7 +117,7 @@ module roleAssignment_sub 'modules/subscription.bicep' = if (!empty(subscription ticketInfo: ticketInfo conditionVersion: conditionVersion condition: !empty(condition) ? condition : '' - scheduleInfo: scheduleInfo + pimRoleAssignmentType: pimRoleAssignmentType } } @@ -128,7 +136,7 @@ module roleAssignment_rg 'modules/resource-group.bicep' = if (!empty(resourceGro ticketInfo: ticketInfo conditionVersion: conditionVersion condition: !empty(condition) ? condition : '' - scheduleInfo: scheduleInfo + pimRoleAssignmentType: pimRoleAssignmentType } } @@ -152,3 +160,5 @@ output scope string = empty(subscriptionId) && empty(resourceGroupName) : (!empty(subscriptionId) && empty(resourceGroupName) ? roleAssignment_sub.outputs.scope : roleAssignment_rg.outputs.scope) + + */ diff --git a/avm/ptn/authorization/pim-role-assignment/modules/definitions.bicep b/avm/ptn/authorization/pim-role-assignment/modules/definitions.bicep index ce8793fda5..9fd5ec81c1 100644 --- a/avm/ptn/authorization/pim-role-assignment/modules/definitions.bicep +++ b/avm/ptn/authorization/pim-role-assignment/modules/definitions.bicep @@ -16,31 +16,51 @@ type requestTypeType = | 'SelfRenew' @export() -type scheduleInfoType = { - @sys.description('Optional. The expiry information for the role eligibility.') - expiration: scheduleInfoExpirationType? +type ticketInfoType = { + @sys.description('Optional. The ticket number for the role eligibility assignment.') + ticketNumber: string? - @sys.description('Optional. Start DateTime of the role eligibility assignment.') - startDateTime: string? -} + @sys.description('Optional. The ticket system name for the role eligibility assignment.') + ticketSystem: string? +}? @export() -type scheduleInfoExpirationType = { - @sys.description('Optional. Duration of the role eligibility assignment in TimeSpan format. Example: P365D, P2H.') - duration: string? +@discriminator('roleAssignmentType') +type pimRoleAssignmentTypeType = pimActiveRoleAssignmentType | pimEligibleRoleAssignmentType - @sys.description('Optional. End DateTime of the role eligibility assignment.') - endDateTime: string? +type pimActiveRoleAssignmentType = { + roleAssignmentType: 'Active' + linkedRoleEligibilityScheduleId: string? + targetRoleAssignmentScheduleId: string? + targetRoleAssignmentScheduleInstanceId: string? + scheduleInfo: roleAssignmentScheduleType +} - @sys.description('Optional. Type of the role eligibility assignment expiration.') - type: 'AfterDateTime' | 'AfterDuration' | 'NoExpiration'? +type pimEligibleRoleAssignmentType = { + roleAssignmentType: 'Eligible' + targetRoleEligibilityScheduleId: string? + targetRoleEligibilityScheduleInstanceId: string? + scheduleInfo: roleAssignmentScheduleType } -@export() -type ticketInfoType = { - @sys.description('Optional. The ticket number for the role eligibility assignment.') - ticketNumber: string? +@discriminator('durationType') +type roleAssignmentScheduleType = + | permenantRoleAssignmentScheduleType + | timeBoundDurationRoleAssignmentScheduleType + | timeBoundDateTimeRoleAssignmentScheduleType - @sys.description('Optional. The ticket system name for the role eligibility assignment.') - ticketSystem: string? -}? +type permenantRoleAssignmentScheduleType = { + durationType: 'NoExpiration' +} + +type timeBoundDurationRoleAssignmentScheduleType = { + durationType: 'AfterDuration' + duration: string + startTime: string +} + +type timeBoundDateTimeRoleAssignmentScheduleType = { + durationType: 'AfterDateTime' + endDateTime: string + startTime: string +} diff --git a/avm/ptn/authorization/pim-role-assignment/modules/management-group.bicep b/avm/ptn/authorization/pim-role-assignment/modules/management-group.bicep index c00d3eabf2..e6bb21414a 100644 --- a/avm/ptn/authorization/pim-role-assignment/modules/management-group.bicep +++ b/avm/ptn/authorization/pim-role-assignment/modules/management-group.bicep @@ -3,7 +3,7 @@ metadata description = 'This module deploys a PIM Role Assignment at a Managemen targetScope = 'managementGroup' -import { requestTypeType, scheduleInfoType, scheduleInfoExpirationType, ticketInfoType } from 'definitions.bicep' +import { requestTypeType, pimRoleAssignmentTypeType, ticketInfoType } from 'definitions.bicep' @sys.description('Required. You can provide either the display name of the role definition (must be configured in the variable `builtInRoleNames`), or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.') param roleDefinitionIdOrName string @@ -14,6 +14,9 @@ param principalId string @sys.description('Optional. Group ID of the Management Group to assign the RBAC role to. If not provided, will use the current scope for deployment.') param managementGroupId string = managementGroup().name +@description('Required. The type of the PIM role assignment whether its active or eligible.') +param pimRoleAssignmentType pimRoleAssignmentTypeType + @sys.description('Optional. The justification for the role eligibility.') param justification string = '' @@ -26,12 +29,15 @@ param targetRoleEligibilityScheduleId string = '' @sys.description('Optional. The role eligibility assignment instance id being updated.') param targetRoleEligibilityScheduleInstanceId string = '' +@sys.description('Optional. The resultant role assignment schedule id or the role assignment schedule id being updated.') +param targetRoleAssignmentScheduleId string = '' + +@sys.description('Optional. The role assignment schedule instance id being updated.') +param targetRoleAssignmentScheduleInstanceId string = '' + @sys.description('Optional. Ticket Info of the role eligibility.') param ticketInfo ticketInfoType? -@sys.description('Optional. Schedule info of the role eligibility assignment.') -param scheduleInfo scheduleInfoType - @sys.description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to.') param condition string = '' @@ -65,7 +71,7 @@ var builtInRoleNames = { var roleDefinitionIdVar = (builtInRoleNames[?roleDefinitionIdOrName] ?? roleDefinitionIdOrName) -resource pimRoleAssignment 'Microsoft.Authorization/roleEligibilityScheduleRequests@2022-04-01-preview' = { +resource pimEligibleRoleAssignment 'Microsoft.Authorization/roleEligibilityScheduleRequests@2022-04-01-preview' = if (pimRoleAssignmentType.roleAssignmentType == 'Eligible') { name: guid(managementGroupId, roleDefinitionIdVar, principalId) properties: { principalId: principalId @@ -74,18 +80,82 @@ resource pimRoleAssignment 'Microsoft.Authorization/roleEligibilityScheduleReque condition: !empty(condition) ? condition : null conditionVersion: !empty(conditionVersion) && !empty(condition) ? conditionVersion : null justification: justification - scheduleInfo: scheduleInfo targetRoleEligibilityScheduleId: targetRoleEligibilityScheduleId targetRoleEligibilityScheduleInstanceId: targetRoleEligibilityScheduleInstanceId ticketInfo: ticketInfo + scheduleInfo: pimRoleAssignmentType.scheduleInfo.durationType == 'NoExpiration' + ? { + expiration: { + type: 'NoExpiration' + } + } + : pimRoleAssignmentType.scheduleInfo.durationType == 'AfterDuration' + ? { + expiration: { + type: 'AfterDuration' + duration: pimRoleAssignmentType.scheduleInfo.duration + } + startDateTime: pimRoleAssignmentType.scheduleInfo.startTime + } + : pimRoleAssignmentType.scheduleInfo.durationType == 'AfterDateTime' + ? { + expiration: { + type: 'AfterDateTime' + endDateTime: pimRoleAssignmentType.scheduleInfo.endDateTime + } + startDateTime: pimRoleAssignmentType.scheduleInfo.startTime + } + : null + } +} + +resource pimActiveRoleAssignment 'Microsoft.Authorization/roleAssignmentScheduleRequests@2022-04-01-preview' = if (pimRoleAssignmentType.roleAssignmentType == 'Active') { + name: guid(managementGroupId, roleDefinitionIdVar, principalId) + properties: { + principalId: principalId + roleDefinitionId: roleDefinitionIdVar + requestType: requestType + condition: !empty(condition) ? condition : null + conditionVersion: !empty(conditionVersion) && !empty(condition) ? conditionVersion : null + justification: justification + targetRoleAssignmentScheduleId: targetRoleAssignmentScheduleId + targetRoleAssignmentScheduleInstanceId: targetRoleAssignmentScheduleInstanceId + ticketInfo: ticketInfo + scheduleInfo: pimRoleAssignmentType.scheduleInfo.durationType == 'NoExpiration' + ? { + expiration: { + type: 'NoExpiration' + } + } + : pimRoleAssignmentType.scheduleInfo.durationType == 'AfterDuration' + ? { + expiration: { + type: 'AfterDuration' + duration: pimRoleAssignmentType.scheduleInfo.duration + } + startDateTime: pimRoleAssignmentType.scheduleInfo.startTime + } + : pimRoleAssignmentType.scheduleInfo.durationType == 'AfterDateTime' + ? { + expiration: { + type: 'AfterDateTime' + endDateTime: pimRoleAssignmentType.scheduleInfo.endDateTime + } + startDateTime: pimRoleAssignmentType.scheduleInfo.startTime + } + : null } } @sys.description('The GUID of the PIM Role Assignment.') -output name string = pimRoleAssignment.name +output name string = pimRoleAssignmentType.roleAssignmentType == 'Eligible' + ? pimEligibleRoleAssignment.name + : pimActiveRoleAssignment.name @sys.description('The resource ID of the PIM Role Assignment.') -output resourceId string = pimRoleAssignment.id +output resourceId string = pimRoleAssignmentType.roleAssignmentType == 'Eligible' + ? pimEligibleRoleAssignment.id + : pimActiveRoleAssignment.id @sys.description('The scope this PIM Role Assignment applies to.') output scope string = az.resourceId('Microsoft.Management/managementGroups', managementGroupId) diff --git a/avm/ptn/authorization/pim-role-assignment/modules/resource-group.bicep b/avm/ptn/authorization/pim-role-assignment/modules/resource-group.bicep index d20466b3c3..d9dc00c6a9 100644 --- a/avm/ptn/authorization/pim-role-assignment/modules/resource-group.bicep +++ b/avm/ptn/authorization/pim-role-assignment/modules/resource-group.bicep @@ -3,7 +3,7 @@ metadata description = 'This module deploys a PIM Role Assignment at a Resource targetScope = 'resourceGroup' -import { requestTypeType, scheduleInfoType, scheduleInfoExpirationType, ticketInfoType } from 'definitions.bicep' +import { requestTypeType, pimRoleAssignmentTypeType, ticketInfoType } from 'definitions.bicep' @sys.description('Required. You can provide either the display name of the role definition (must be configured in the variable `builtInRoleNames`), or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.') param roleDefinitionIdOrName string @@ -17,6 +17,9 @@ param resourceGroupName string = resourceGroup().name @sys.description('Optional. Subscription ID of the subscription to assign the RBAC role to. If not provided, will use the current scope for deployment.') param subscriptionId string = subscription().subscriptionId +@description('Required. The type of the PIM role assignment whether its active or eligible.') +param pimRoleAssignmentType pimRoleAssignmentTypeType + @sys.description('Optional. The justification for the role eligibility.') param justification string = '' @@ -29,12 +32,15 @@ param targetRoleEligibilityScheduleId string = '' @sys.description('Optional. The role eligibility assignment instance id being updated.') param targetRoleEligibilityScheduleInstanceId string = '' +@sys.description('Optional. The resultant role assignment schedule id or the role assignment schedule id being updated.') +param targetRoleAssignmentScheduleId string = '' + +@sys.description('Optional. The role assignment schedule instance id being updated.') +param targetRoleAssignmentScheduleInstanceId string = '' + @sys.description('Optional. Ticket Info of the role eligibility.') param ticketInfo ticketInfoType? -@sys.description('Optional. Schedule info of the role eligibility assignment.') -param scheduleInfo scheduleInfoType - @sys.description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to.') param condition string = '' @@ -60,7 +66,7 @@ var builtInRoleNames = { var roleDefinitionIdVar = (builtInRoleNames[?roleDefinitionIdOrName] ?? roleDefinitionIdOrName) -resource pimRoleAssignment 'Microsoft.Authorization/roleEligibilityScheduleRequests@2022-04-01-preview' = { +resource pimEligibleRoleAssignment 'Microsoft.Authorization/roleEligibilityScheduleRequests@2022-04-01-preview' = if (pimRoleAssignmentType.roleAssignmentType == 'Eligible') { name: guid(subscriptionId, resourceGroupName, roleDefinitionIdVar, principalId) properties: { roleDefinitionId: roleDefinitionIdVar @@ -69,18 +75,82 @@ resource pimRoleAssignment 'Microsoft.Authorization/roleEligibilityScheduleReque conditionVersion: !empty(conditionVersion) && !empty(condition) ? conditionVersion : null condition: !empty(condition) ? condition : null justification: justification - scheduleInfo: scheduleInfo targetRoleEligibilityScheduleId: targetRoleEligibilityScheduleId targetRoleEligibilityScheduleInstanceId: targetRoleEligibilityScheduleInstanceId ticketInfo: ticketInfo + scheduleInfo: pimRoleAssignmentType.scheduleInfo.durationType == 'NoExpiration' + ? { + expiration: { + type: 'NoExpiration' + } + } + : pimRoleAssignmentType.scheduleInfo.durationType == 'AfterDuration' + ? { + expiration: { + type: 'AfterDuration' + duration: pimRoleAssignmentType.scheduleInfo.duration + } + startDateTime: pimRoleAssignmentType.scheduleInfo.startTime + } + : pimRoleAssignmentType.scheduleInfo.durationType == 'AfterDateTime' + ? { + expiration: { + type: 'AfterDateTime' + endDateTime: pimRoleAssignmentType.scheduleInfo.endDateTime + } + startDateTime: pimRoleAssignmentType.scheduleInfo.startTime + } + : null + } +} + +resource pimActiveRoleAssignment 'Microsoft.Authorization/roleAssignmentScheduleRequests@2022-04-01-preview' = if (pimRoleAssignmentType.roleAssignmentType == 'Active') { + name: guid(subscriptionId, resourceGroupName, roleDefinitionIdVar, principalId) + properties: { + roleDefinitionId: roleDefinitionIdVar + principalId: principalId + requestType: requestType + conditionVersion: !empty(conditionVersion) && !empty(condition) ? conditionVersion : null + condition: !empty(condition) ? condition : null + justification: justification + targetRoleAssignmentScheduleId: targetRoleAssignmentScheduleId + targetRoleAssignmentScheduleInstanceId: targetRoleAssignmentScheduleInstanceId + ticketInfo: ticketInfo + scheduleInfo: pimRoleAssignmentType.scheduleInfo.durationType == 'NoExpiration' + ? { + expiration: { + type: 'NoExpiration' + } + } + : pimRoleAssignmentType.scheduleInfo.durationType == 'AfterDuration' + ? { + expiration: { + type: 'AfterDuration' + duration: pimRoleAssignmentType.scheduleInfo.duration + } + startDateTime: pimRoleAssignmentType.scheduleInfo.startTime + } + : pimRoleAssignmentType.scheduleInfo.durationType == 'AfterDateTime' + ? { + expiration: { + type: 'AfterDateTime' + endDateTime: pimRoleAssignmentType.scheduleInfo.endDateTime + } + startDateTime: pimRoleAssignmentType.scheduleInfo.startTime + } + : null } } @sys.description('The GUID of the PIM Role Assignment.') -output name string = pimRoleAssignment.name +output name string = pimRoleAssignmentType.roleAssignmentType == 'Eligible' + ? pimEligibleRoleAssignment.name + : pimActiveRoleAssignment.name @sys.description('The resource ID of the PIM Role Assignment.') -output resourceId string = pimRoleAssignment.id +output resourceId string = pimRoleAssignmentType.roleAssignmentType == 'Eligible' + ? pimEligibleRoleAssignment.id + : pimActiveRoleAssignment.id @sys.description('The name of the resource group the PIM role assignment was applied at.') output resourceGroupName string = resourceGroup().name diff --git a/avm/ptn/authorization/pim-role-assignment/modules/subscription.bicep b/avm/ptn/authorization/pim-role-assignment/modules/subscription.bicep index 69d0bc0402..ca2b62166d 100644 --- a/avm/ptn/authorization/pim-role-assignment/modules/subscription.bicep +++ b/avm/ptn/authorization/pim-role-assignment/modules/subscription.bicep @@ -3,7 +3,7 @@ metadata description = 'This module deploys a PIM Role Assignment at a Subscript targetScope = 'subscription' -import { requestTypeType, scheduleInfoType, scheduleInfoExpirationType, ticketInfoType } from 'definitions.bicep' +import { requestTypeType, pimRoleAssignmentTypeType, ticketInfoType } from 'definitions.bicep' @sys.description('Required. You can provide either the display name of the role definition (must be configured in the variable `builtInRoleNames`), or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.') param roleDefinitionIdOrName string @@ -14,6 +14,9 @@ param principalId string @sys.description('Optional. Subscription ID of the subscription to assign the RBAC role to. If not provided, will use the current scope for deployment.') param subscriptionId string = subscription().subscriptionId +@description('Required. The type of the PIM role assignment whether its active or eligible.') +param pimRoleAssignmentType pimRoleAssignmentTypeType + @sys.description('Optional. The justification for the role eligibility.') param justification string = '' @@ -26,12 +29,15 @@ param targetRoleEligibilityScheduleId string = '' @sys.description('Optional. The role eligibility assignment instance id being updated.') param targetRoleEligibilityScheduleInstanceId string = '' +@sys.description('Optional. The resultant role assignment schedule id or the role assignment schedule id being updated.') +param targetRoleAssignmentScheduleId string = '' + +@sys.description('Optional. The role assignment schedule instance id being updated.') +param targetRoleAssignmentScheduleInstanceId string = '' + @sys.description('Optional. Ticket Info of the role eligibility.') param ticketInfo ticketInfoType? -@sys.description('Optional. Schedule info of the role eligibility assignment.') -param scheduleInfo scheduleInfoType - @sys.description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to.') param condition string = '' @@ -57,7 +63,7 @@ var builtInRoleNames = { var roleDefinitionIdVar = (builtInRoleNames[?roleDefinitionIdOrName] ?? roleDefinitionIdOrName) -resource pimRoleAssignment 'Microsoft.Authorization/roleEligibilityScheduleRequests@2022-04-01-preview' = { +resource pimEligibleRoleAssignment 'Microsoft.Authorization/roleEligibilityScheduleRequests@2022-04-01-preview' = if (pimRoleAssignmentType.roleAssignmentType == 'Eligible') { name: guid(subscriptionId, roleDefinitionIdVar, principalId) properties: { principalId: principalId @@ -66,18 +72,82 @@ resource pimRoleAssignment 'Microsoft.Authorization/roleEligibilityScheduleReque condition: !empty(condition) ? condition : null conditionVersion: !empty(conditionVersion) && !empty(condition) ? conditionVersion : null justification: justification - scheduleInfo: scheduleInfo targetRoleEligibilityScheduleId: targetRoleEligibilityScheduleId targetRoleEligibilityScheduleInstanceId: targetRoleEligibilityScheduleInstanceId ticketInfo: ticketInfo + scheduleInfo: pimRoleAssignmentType.scheduleInfo.durationType == 'NoExpiration' + ? { + expiration: { + type: 'NoExpiration' + } + } + : pimRoleAssignmentType.scheduleInfo.durationType == 'AfterDuration' + ? { + expiration: { + type: 'AfterDuration' + duration: pimRoleAssignmentType.scheduleInfo.duration + } + startDateTime: pimRoleAssignmentType.scheduleInfo.startTime + } + : pimRoleAssignmentType.scheduleInfo.durationType == 'AfterDateTime' + ? { + expiration: { + type: 'AfterDateTime' + endDateTime: pimRoleAssignmentType.scheduleInfo.endDateTime + } + startDateTime: pimRoleAssignmentType.scheduleInfo.startTime + } + : null + } +} + +resource pimActiveRoleAssignment 'Microsoft.Authorization/roleAssignmentScheduleRequests@2022-04-01-preview' = if (pimRoleAssignmentType.roleAssignmentType == 'Active') { + name: guid(subscriptionId, roleDefinitionIdVar, principalId) + properties: { + principalId: principalId + roleDefinitionId: roleDefinitionIdVar + requestType: requestType + condition: !empty(condition) ? condition : null + conditionVersion: !empty(conditionVersion) && !empty(condition) ? conditionVersion : null + justification: justification + targetRoleAssignmentScheduleId: targetRoleAssignmentScheduleId + targetRoleAssignmentScheduleInstanceId: targetRoleAssignmentScheduleInstanceId + ticketInfo: ticketInfo + scheduleInfo: pimRoleAssignmentType.scheduleInfo.durationType == 'NoExpiration' + ? { + expiration: { + type: 'NoExpiration' + } + } + : pimRoleAssignmentType.scheduleInfo.durationType == 'AfterDuration' + ? { + expiration: { + type: 'AfterDuration' + duration: pimRoleAssignmentType.scheduleInfo.duration + } + startDateTime: pimRoleAssignmentType.scheduleInfo.startTime + } + : pimRoleAssignmentType.scheduleInfo.durationType == 'AfterDateTime' + ? { + expiration: { + type: 'AfterDateTime' + endDateTime: pimRoleAssignmentType.scheduleInfo.endDateTime + } + startDateTime: pimRoleAssignmentType.scheduleInfo.startTime + } + : null } } @sys.description('The GUID of the PIM Role Assignment.') -output name string = pimRoleAssignment.name +output name string = pimRoleAssignmentType.roleAssignmentType == 'Eligible' + ? pimEligibleRoleAssignment.name + : pimActiveRoleAssignment.name @sys.description('The resource ID of the PIM Role Assignment.') -output resourceId string = pimRoleAssignment.id +output resourceId string = pimRoleAssignmentType.roleAssignmentType == 'Eligible' + ? pimEligibleRoleAssignment.id + : pimActiveRoleAssignment.id @sys.description('The name of the resource group the PIM role assignment was applied at.') output subscriptionName string = subscription().displayName diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep index a1497c1629..e247271f2e 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep @@ -1,6 +1,6 @@ targetScope = 'managementGroup' -metadata name = ' PIM Role Assignments (Management Group scope)' -metadata description = 'This module deploys a PIM Role Assignment at a Management Group scope using minimal parameters.' +metadata name = ' PIM Eligible Role Assignments (Management Group scope)' +metadata description = 'This module deploys a PIM Eligible Role Assignment at a Management Group scope using minimal parameters.' // ========== // // Parameters // @@ -19,6 +19,8 @@ param namePrefix string = '#_namePrefix_#' @secure() param userPrinicipalId string = '' +param startDateTime string = utcNow() + // ============== // // Test Execution // // ============== // @@ -26,15 +28,17 @@ param userPrinicipalId string = '' module testDeployment '../../../main.bicep' = { name: '${uniqueString(deployment().name)}-test-${serviceShort}-${namePrefix}' params: { + pimRoleAssignmentType: { + roleAssignmentType: 'Eligible' + scheduleInfo: { + duration: 'P10D' + durationType: 'AfterDuration' + startTime: startDateTime + } + } principalId: userPrinicipalId - roleDefinitionIdOrName: 'Resource Policy Contributor' requestType: 'AdminAssign' + roleDefinitionIdOrName: 'User Access Administrator' location: resourceLocation - scheduleInfo: { - expiration: { - duration: 'P1H' - type: 'AfterDuration' - } - } } } From a3f29c26199399d21217399c88c76162e40da8b2 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Sun, 2 Feb 2025 11:27:17 +0200 Subject: [PATCH 13/54] feat: Add optional start date parameter for role assignment and enhance resource removal logic --- .../pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep | 1 + .../resourceRemoval/helper/Invoke-ResourceRemoval.ps1 | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep index e247271f2e..7a2d2ab2b2 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep @@ -19,6 +19,7 @@ param namePrefix string = '#_namePrefix_#' @secure() param userPrinicipalId string = '' +@description('Optional. The start date and time for the role assignment. Defaults to the current date and time.') param startDateTime string = utcNow() // ============== // diff --git a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 index 758d270459..64b6008e88 100644 --- a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 +++ b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 @@ -105,6 +105,10 @@ function Invoke-ResourceRemoval { $null = $roleAssignmentsOnScope | Where-Object { $_.RoleAssignmentId -eq $ResourceId } | Remove-AzRoleAssignment break } + 'Microsoft.Authorization/roleEligibilityScheduleRequests' { + $null = Remove-AzResource -ResourceId $ResourceId -Force -ErrorAction 'Stop' + break + } 'Microsoft.RecoveryServices/vaults' { # Pre-Removal # ----------- From c138874ee2fffff69c8d46fa2b2f77caeb0d46ec Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Sun, 2 Feb 2025 11:29:32 +0200 Subject: [PATCH 14/54] feat: Update role definition in e2e test to use Resource Policy Contributor --- .../pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep index 7a2d2ab2b2..9df7297709 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep @@ -39,7 +39,7 @@ module testDeployment '../../../main.bicep' = { } principalId: userPrinicipalId requestType: 'AdminAssign' - roleDefinitionIdOrName: 'User Access Administrator' + roleDefinitionIdOrName: 'Resource Policy Contributor' location: resourceLocation } } From 5986dff31415fd745373bdc8f958322a0704c36e Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Sun, 2 Feb 2025 12:17:08 +0200 Subject: [PATCH 15/54] fix: Correct serviceShort parameter value in e2e test configuration --- .../pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep index 9df7297709..6ee29f524a 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep @@ -10,7 +10,7 @@ metadata description = 'This module deploys a PIM Eligible Role Assignment at a param resourceLocation string = deployment().location @description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') -param serviceShort string = 'pimmgmin' +param serviceShort string = 'pimgmin' @description('Optional. A token to inject into the name of each resource.') param namePrefix string = '#_namePrefix_#' From 54a0851ff918765f2d9aa18527e911d869f766a7 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Sun, 2 Feb 2025 12:23:29 +0200 Subject: [PATCH 16/54] fix: Update requestType from 'AdminAssign' to 'AdminUpdate' in e2e test configuration --- .../pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep index 6ee29f524a..30d2e953e1 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep @@ -38,7 +38,7 @@ module testDeployment '../../../main.bicep' = { } } principalId: userPrinicipalId - requestType: 'AdminAssign' + requestType: 'AdminUpdate' roleDefinitionIdOrName: 'Resource Policy Contributor' location: resourceLocation } From f49d5f1aa71cc23ef59cabc165e7fb074f7521f6 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Sun, 2 Feb 2025 12:40:12 +0200 Subject: [PATCH 17/54] fix: Update requestType to 'AdminAssign' and roleDefinitionIdOrName in e2e test configuration --- .../pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep index 30d2e953e1..ff204b5d7d 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep @@ -38,8 +38,8 @@ module testDeployment '../../../main.bicep' = { } } principalId: userPrinicipalId - requestType: 'AdminUpdate' - roleDefinitionIdOrName: 'Resource Policy Contributor' + requestType: 'AdminAssign' + roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/18d7d88d-d35e-4fb5-a5c3-7773c20a72d9' location: resourceLocation } } From e1ba129a8e9172b1c3096cce932be31917a119b0 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Sun, 2 Feb 2025 14:03:45 +0200 Subject: [PATCH 18/54] feat: Enhance PIM role assignment logic with active and eligible types, add start and end date parameters --- .../pim-role-assignment/README.md | 411 ++++--- .../pim-role-assignment/main.json | 1046 ++++++----------- .../modules/definitions.bicep | 29 + .../tests/e2e/mg.max/main.test.bicep | 17 +- .../tests/e2e/rg.default/main.test.bicep | 20 +- .../tests/e2e/rg.max/main.test.bicep | 21 +- .../tests/e2e/sub.default/main.test.bicep | 17 +- .../tests/e2e/sub.max/main.test.bicep | 12 +- .../helper/Invoke-ResourceRemoval.ps1 | 4 + 9 files changed, 664 insertions(+), 913 deletions(-) diff --git a/avm/ptn/authorization/pim-role-assignment/README.md b/avm/ptn/authorization/pim-role-assignment/README.md index 845a70fcd9..af77f755a8 100644 --- a/avm/ptn/authorization/pim-role-assignment/README.md +++ b/avm/ptn/authorization/pim-role-assignment/README.md @@ -14,6 +14,7 @@ | Resource Type | API Version | | :-- | :-- | +| `Microsoft.Authorization/roleAssignmentScheduleRequests` | [2022-04-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01-preview/roleAssignmentScheduleRequests) | | `Microsoft.Authorization/roleEligibilityScheduleRequests` | [2022-04-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01-preview/roleEligibilityScheduleRequests) | ## Usage examples @@ -24,16 +25,16 @@ The following section provides usage examples for the module, which were used to >**Note**: To reference the module, please use the following syntax `br/public:avm/ptn/authorization/pim-role-assignment:`. -- [ PIM Role Assignments (Management Group scope)](#example-1-pim-role-assignments-management-group-scope) -- [PIM Role Assignments (Management Group scope)](#example-2-pim-role-assignments-management-group-scope) -- [PIM Role Assignments (Resource Group scope)](#example-3-pim-role-assignments-resource-group-scope) -- [PIM Role Assignments (Resource Group)](#example-4-pim-role-assignments-resource-group) -- [PIM Role Assignments (Subscription scope)](#example-5-pim-role-assignments-subscription-scope) -- [PIM Role Assignments (Subscription scope)](#example-6-pim-role-assignments-subscription-scope) +- [ PIM Eligible Role Assignments (Management Group scope)](#example-1-pim-eligible-role-assignments-management-group-scope) +- [PIM Active Role Assignments (Management Group scope)](#example-2-pim-active-role-assignments-management-group-scope) +- [PIM Eligible Role Assignments (Resource Group scope)](#example-3-pim-eligible-role-assignments-resource-group-scope) +- [PIM Active Role Assignments (Resource Group)](#example-4-pim-active-role-assignments-resource-group) +- [PIM Eligible Role Assignments (Subscription scope)](#example-5-pim-eligible-role-assignments-subscription-scope) +- [PIM Active permenant Role Assignments (Subscription scope)](#example-6-pim-active-permenant-role-assignments-subscription-scope) -### Example 1: _ PIM Role Assignments (Management Group scope)_ +### Example 1: _ PIM Eligible Role Assignments (Management Group scope)_ -This module deploys a PIM Role Assignment at a Management Group scope using minimal parameters. +This module deploys a PIM Eligible Role Assignment at a Management Group scope using minimal parameters.
@@ -45,15 +46,17 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:' - requestType: 'AdminAssign' - roleDefinitionIdOrName: 'Resource Policy Contributor' - scheduleInfo: { - expiration: { - duration: 'P1H' - type: 'AfterDuration' + pimRoleAssignmentType: { + roleAssignmentType: 'Eligible' + scheduleInfo: { + duration: 'P10D' + durationType: 'AfterDuration' + startTime: '' } } + principalId: '' + requestType: 'AdminAssign' + roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/18d7d88d-d35e-4fb5-a5c3-7773c20a72d9' // Non-required parameters location: '' } @@ -73,6 +76,16 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:" + } + } + }, "principalId": { "value": "" }, @@ -80,15 +93,7 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:' // Required parameters -param principalId = '' -param requestType = 'AdminAssign' -param roleDefinitionIdOrName = 'Resource Policy Contributor' -param scheduleInfo = { - expiration: { - duration: 'P1H' - type: 'AfterDuration' +param pimRoleAssignmentType = { + roleAssignmentType: 'Eligible' + scheduleInfo: { + duration: 'P10D' + durationType: 'AfterDuration' + startTime: '' } } +param principalId = '' +param requestType = 'AdminAssign' +param roleDefinitionIdOrName = '/providers/Microsoft.Authorization/roleDefinitions/18d7d88d-d35e-4fb5-a5c3-7773c20a72d9' // Non-required parameters param location = '' ``` @@ -125,9 +132,9 @@ param location = ''

-### Example 2: _PIM Role Assignments (Management Group scope)_ +### Example 2: _PIM Active Role Assignments (Management Group scope)_ -This module deploys a PIM Role Assignment at a Management Group scope using common parameters. +This module deploys a PIM Active Role Assignment at a Management Group scope using common parameters.

@@ -139,15 +146,17 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:' + } + } principalId: '' requestType: 'AdminAssign' roleDefinitionIdOrName: 'Contributor' - scheduleInfo: { - expiration: { - type: 'AfterDateTime' - } - startDateTime: '2025-01-23T12:39:44Z' - } // Non-required parameters justification: 'Justification for the role eligibility' location: '' @@ -172,6 +181,16 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:" + } + } + }, "principalId": { "value": "" }, @@ -181,14 +200,6 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:' // Required parameters +param pimRoleAssignmentType = { + roleAssignmentType: 'Active' + scheduleInfo: { + duration: 'P10D' + durationType: 'AfterDuration' + startTime: '' + } +} param principalId = '' param requestType = 'AdminAssign' param roleDefinitionIdOrName = 'Contributor' -param scheduleInfo = { - expiration: { - type: 'AfterDateTime' - } - startDateTime: '2025-01-23T12:39:44Z' -} // Non-required parameters param justification = 'Justification for the role eligibility' param location = '' @@ -238,9 +251,9 @@ param ticketInfo = {

-### Example 3: _PIM Role Assignments (Resource Group scope)_ +### Example 3: _PIM Eligible Role Assignments (Resource Group scope)_ -This module deploys a PIM Role Assignment at a Resource Group scope using minimal parameters. +This module deploys a PIM Eligible Role Assignment at a Resource Group scope using minimal parameters.

@@ -252,15 +265,17 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:' + startTime: '' + } + } principalId: '' requestType: 'AdminAssign' roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11' - scheduleInfo: { - expiration: { - duration: 'P1H' - type: 'AfterDuration' - } - } // Non-required parameters location: '' resourceGroupName: '' @@ -282,6 +297,16 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:", + "startTime": "" + } + } + }, "principalId": { "value": "" }, @@ -291,14 +316,6 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:" @@ -324,15 +341,17 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:' // Required parameters +param pimRoleAssignmentType = { + roleAssignmentType: 'Eligible' + scheduleInfo: { + durationType: 'AfterDateTime' + endDateTime: '' + startTime: '' + } +} param principalId = '' param requestType = 'AdminAssign' param roleDefinitionIdOrName = '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11' -param scheduleInfo = { - expiration: { - duration: 'P1H' - type: 'AfterDuration' - } -} // Non-required parameters param location = '' param resourceGroupName = '' @@ -342,9 +361,9 @@ param subscriptionId = ''

-### Example 4: _PIM Role Assignments (Resource Group)_ +### Example 4: _PIM Active Role Assignments (Resource Group)_ -This module deploys a PIM Role Assignment at a Resource Group scope using common parameters. +This module deploys a PIM Active Role Assignment at a Resource Group scope using common parameters.

@@ -356,15 +375,17 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:' + startTime: '' + } + } principalId: '' requestType: 'AdminAssign' roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7' - scheduleInfo: { - expiration: { - type: 'AfterDateTime' - } - startDateTime: '' - } // Non-required parameters justification: 'Justification for role eligibility' location: '' @@ -391,6 +412,16 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:", + "startTime": "" + } + } + }, "principalId": { "value": "" }, @@ -400,14 +431,6 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:" - } - }, // Non-required parameters "justification": { "value": "Justification for role eligibility" @@ -442,15 +465,17 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:' // Required parameters +param pimRoleAssignmentType = { + roleAssignmentType: 'Active' + scheduleInfo: { + durationType: 'AfterDateTime' + endDateTime: '' + startTime: '' + } +} param principalId = '' param requestType = 'AdminAssign' param roleDefinitionIdOrName = '/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7' -param scheduleInfo = { - expiration: { - type: 'AfterDateTime' - } - startDateTime: '' -} // Non-required parameters param justification = 'Justification for role eligibility' param location = '' @@ -465,9 +490,9 @@ param ticketInfo = {

-### Example 5: _PIM Role Assignments (Subscription scope)_ +### Example 5: _PIM Eligible Role Assignments (Subscription scope)_ -This module deploys a PIM Role Assignment at a Subscription scope using minimal parameters. +This module deploys a PIM Eligible Role Assignment at a Subscription scope using minimal parameters.

@@ -479,15 +504,17 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:' + } + } principalId: '' requestType: 'AdminAssign' roleDefinitionIdOrName: '' - scheduleInfo: { - expiration: { - duration: 'P1H' - type: 'AfterDuration' - } - } // Non-required parameters subscriptionId: '' } @@ -507,6 +534,16 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:" + } + } + }, "principalId": { "value": "" }, @@ -516,14 +553,6 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:" }, - "scheduleInfo": { - "value": { - "expiration": { - "duration": "P1H", - "type": "AfterDuration" - } - } - }, // Non-required parameters "subscriptionId": { "value": "" @@ -543,15 +572,17 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:' // Required parameters +param pimRoleAssignmentType = { + roleAssignmentType: 'Eligible' + scheduleInfo: { + duration: 'P10D' + durationType: 'AfterDuration' + startTime: '' + } +} param principalId = '' param requestType = 'AdminAssign' param roleDefinitionIdOrName = '' -param scheduleInfo = { - expiration: { - duration: 'P1H' - type: 'AfterDuration' - } -} // Non-required parameters param subscriptionId = '' ``` @@ -559,9 +590,9 @@ param subscriptionId = ''

-### Example 6: _PIM Role Assignments (Subscription scope)_ +### Example 6: _PIM Active permenant Role Assignments (Subscription scope)_ -This module deploys a PIM Role Assignment at a Subscription scope using common parameters. +This module deploys a PIM Active permenant Role Assignment at a Subscription scope using common parameters.

@@ -573,15 +604,15 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:' requestType: 'AdminAssign' roleDefinitionIdOrName: 'Reader' - scheduleInfo: { - expiration: { - duration: 'P1H' - type: 'AfterDuration' - } - } // Non-required parameters justification: 'Justification for role assignment' location: '' @@ -607,6 +638,14 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:" }, @@ -616,14 +655,6 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:' // Required parameters +param pimRoleAssignmentType = { + roleAssignmentType: 'Active' + scheduleInfo: { + durationType: 'NoExpiration' + } +} param principalId = '' param requestType = 'AdminAssign' param roleDefinitionIdOrName = 'Reader' -param scheduleInfo = { - expiration: { - duration: 'P1H' - type: 'AfterDuration' - } -} // Non-required parameters param justification = 'Justification for role assignment' param location = '' @@ -683,10 +714,10 @@ param ticketInfo = { | Parameter | Type | Description | | :-- | :-- | :-- | +| [`pimRoleAssignmentType`](#parameter-pimroleassignmenttype) | object | The type of the PIM role assignment whether its active or eligible. | | [`principalId`](#parameter-principalid) | string | The Principal or Object ID of the Security Principal (User, Group, Service Principal, Managed Identity). | | [`requestType`](#parameter-requesttype) | string | The type of the role assignment eligibility request. | | [`roleDefinitionIdOrName`](#parameter-roledefinitionidorname) | string | You can provide either the display name of the role definition (must be configured in the variable `builtInRoleNames`), or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. | -| [`scheduleInfo`](#parameter-scheduleinfo) | object | Schedule info of the role eligibility assignment. | **Optional parameters** @@ -700,10 +731,19 @@ param ticketInfo = { | [`managementGroupId`](#parameter-managementgroupid) | string | Group ID of the Management Group to assign the RBAC role to. If not provided, will use the current scope for deployment. | | [`resourceGroupName`](#parameter-resourcegroupname) | string | Name of the Resource Group to assign the RBAC role to. If Resource Group name is provided, and Subscription ID is provided, the module deploys at resource group level, therefore assigns the provided RBAC role to the resource group. | | [`subscriptionId`](#parameter-subscriptionid) | string | Subscription ID of the subscription to assign the RBAC role to. If no Resource Group name is provided, the module deploys at subscription level, therefore assigns the provided RBAC role to the subscription. | +| [`targetRoleAssignmentScheduleId`](#parameter-targetroleassignmentscheduleid) | string | The resultant role assignment schedule id or the role assignment schedule id being updated. | +| [`targetRoleAssignmentScheduleInstanceId`](#parameter-targetroleassignmentscheduleinstanceid) | string | The role assignment schedule instance id being updated. | | [`targetRoleEligibilityScheduleId`](#parameter-targetroleeligibilityscheduleid) | string | The resultant role eligibility assignment id or the role eligibility assignment id being updated. | | [`targetRoleEligibilityScheduleInstanceId`](#parameter-targetroleeligibilityscheduleinstanceid) | string | The role eligibility assignment instance id being updated. | | [`ticketInfo`](#parameter-ticketinfo) | object | Ticket Info of the role eligibility. | +### Parameter: `pimRoleAssignmentType` + +The type of the PIM role assignment whether its active or eligible. + +- Required: Yes +- Type: object + ### Parameter: `principalId` The Principal or Object ID of the Security Principal (User, Group, Service Principal, Managed Identity). @@ -739,71 +779,6 @@ You can provide either the display name of the role definition (must be configur - Required: Yes - Type: string -### Parameter: `scheduleInfo` - -Schedule info of the role eligibility assignment. - -- Required: Yes -- Type: object - -**Optional parameters** - -| Parameter | Type | Description | -| :-- | :-- | :-- | -| [`expiration`](#parameter-scheduleinfoexpiration) | object | The expiry information for the role eligibility. | -| [`startDateTime`](#parameter-scheduleinfostartdatetime) | string | Start DateTime of the role eligibility assignment. | - -### Parameter: `scheduleInfo.expiration` - -The expiry information for the role eligibility. - -- Required: No -- Type: object - -**Optional parameters** - -| Parameter | Type | Description | -| :-- | :-- | :-- | -| [`duration`](#parameter-scheduleinfoexpirationduration) | string | Duration of the role eligibility assignment in TimeSpan format. Example: P365D, P2H. | -| [`endDateTime`](#parameter-scheduleinfoexpirationenddatetime) | string | End DateTime of the role eligibility assignment. | -| [`type`](#parameter-scheduleinfoexpirationtype) | string | Type of the role eligibility assignment expiration. | - -### Parameter: `scheduleInfo.expiration.duration` - -Duration of the role eligibility assignment in TimeSpan format. Example: P365D, P2H. - -- Required: No -- Type: string - -### Parameter: `scheduleInfo.expiration.endDateTime` - -End DateTime of the role eligibility assignment. - -- Required: No -- Type: string - -### Parameter: `scheduleInfo.expiration.type` - -Type of the role eligibility assignment expiration. - -- Required: No -- Type: string -- Allowed: - ```Bicep - [ - 'AfterDateTime' - 'AfterDuration' - 'NoExpiration' - ] - ``` - -### Parameter: `scheduleInfo.startDateTime` - -Start DateTime of the role eligibility assignment. - -- Required: No -- Type: string - ### Parameter: `condition` The conditions on the role assignment. This limits the resources it can be assigned to. @@ -874,6 +849,22 @@ Subscription ID of the subscription to assign the RBAC role to. If no Resource G - Type: string - Default: `''` +### Parameter: `targetRoleAssignmentScheduleId` + +The resultant role assignment schedule id or the role assignment schedule id being updated. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `targetRoleAssignmentScheduleInstanceId` + +The role assignment schedule instance id being updated. + +- Required: No +- Type: string +- Default: `''` + ### Parameter: `targetRoleEligibilityScheduleId` The resultant role eligibility assignment id or the role eligibility assignment id being updated. @@ -920,11 +911,7 @@ The ticket system name for the role eligibility assignment. ## Outputs -| Output | Type | Description | -| :-- | :-- | :-- | -| `name` | string | The GUID of the PIM Role Assignment. | -| `resourceId` | string | The resource ID of the PIM Role Assignment. | -| `scope` | string | The scope this PIM Role Assignment applies to. | +_None_ ## Data Collection diff --git a/avm/ptn/authorization/pim-role-assignment/main.json b/avm/ptn/authorization/pim-role-assignment/main.json index 8e5fbb3d69..4e546affef 100644 --- a/avm/ptn/authorization/pim-role-assignment/main.json +++ b/avm/ptn/authorization/pim-role-assignment/main.json @@ -5,60 +5,69 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "1554994413761275960" + "version": "0.33.93.31351", + "templateHash": "2945332709067203601" }, "name": "", "description": "" }, "definitions": { - "requestTypeType": { - "type": "string", - "allowedValues": [ - "AdminAssign", - "AdminExtend", - "AdminRemove", - "AdminRenew", - "AdminUpdate", - "SelfActivate", - "SelfDeactivate", - "SelfExtend", - "SelfRenew" - ], + "_1.permenantRoleAssignmentScheduleType": { + "type": "object", + "properties": { + "durationType": { + "type": "string", + "allowedValues": [ + "NoExpiration" + ], + "metadata": { + "description": "Required. The type of the duration." + } + } + }, "metadata": { - "description": "Optional. The request type of the role assignment.", "__bicep_imported_from!": { "sourceTemplate": "modules/definitions.bicep" } } }, - "scheduleInfoExpirationType": { + "_1.pimActiveRoleAssignmentType": { "type": "object", "properties": { - "duration": { + "roleAssignmentType": { + "type": "string", + "allowedValues": [ + "Active" + ], + "metadata": { + "description": "Required. The type of the role assignment." + } + }, + "linkedRoleEligibilityScheduleId": { "type": "string", "nullable": true, "metadata": { - "description": "Optional. Duration of the role eligibility assignment in TimeSpan format. Example: P365D, P2H." + "description": "Optional. The linked role eligibility schedule id - to activate an eligibility." } }, - "endDateTime": { + "targetRoleAssignmentScheduleId": { "type": "string", "nullable": true, "metadata": { - "description": "Optional. End DateTime of the role eligibility assignment." + "description": "Optional. The resultant role assignment schedule id or the role assignment schedule id being updated." } }, - "type": { + "targetRoleAssignmentScheduleInstanceId": { "type": "string", - "allowedValues": [ - "AfterDateTime", - "AfterDuration", - "NoExpiration" - ], "nullable": true, "metadata": { - "description": "Optional. Type of the role eligibility assignment expiration." + "description": "Optional. The role assignment schedule instance id being updated." + } + }, + "scheduleInfo": { + "$ref": "#/definitions/_1.roleAssignmentScheduleType", + "metadata": { + "description": "Required. The schedule information for the role assignment." } } }, @@ -68,25 +77,165 @@ } } }, - "scheduleInfoType": { + "_1.pimEligibleRoleAssignmentType": { "type": "object", "properties": { - "expiration": { - "$ref": "#/definitions/scheduleInfoExpirationType", + "roleAssignmentType": { + "type": "string", + "allowedValues": [ + "Eligible" + ], + "metadata": { + "description": "Required. The type of the role assignment." + } + }, + "targetRoleEligibilityScheduleId": { + "type": "string", "nullable": true, "metadata": { - "description": "Optional. The expiry information for the role eligibility." + "description": "Optional. The resultant role eligibility schedule id or the role eligibility schedule id being updated." } }, - "startDateTime": { + "targetRoleEligibilityScheduleInstanceId": { "type": "string", "nullable": true, "metadata": { - "description": "Optional. Start DateTime of the role eligibility assignment." + "description": "Optional. The role eligibility assignment instance id being updated." + } + }, + "scheduleInfo": { + "$ref": "#/definitions/_1.roleAssignmentScheduleType", + "metadata": { + "description": "Required. The schedule information for the role assignment." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "modules/definitions.bicep" + } + } + }, + "_1.roleAssignmentScheduleType": { + "type": "object", + "discriminator": { + "propertyName": "durationType", + "mapping": { + "NoExpiration": { + "$ref": "#/definitions/_1.permenantRoleAssignmentScheduleType" + }, + "AfterDuration": { + "$ref": "#/definitions/_1.timeBoundDurationRoleAssignmentScheduleType" + }, + "AfterDateTime": { + "$ref": "#/definitions/_1.timeBoundDateTimeRoleAssignmentScheduleType" + } + } + }, + "metadata": { + "description": "Optional. The schedule information for the role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "modules/definitions.bicep" + } + } + }, + "_1.timeBoundDateTimeRoleAssignmentScheduleType": { + "type": "object", + "properties": { + "durationType": { + "type": "string", + "allowedValues": [ + "AfterDateTime" + ], + "metadata": { + "description": "Required. The type of the duration." + } + }, + "endDateTime": { + "type": "string", + "metadata": { + "description": "Required. The end date and time for the role assignment." + } + }, + "startTime": { + "type": "string", + "metadata": { + "description": "Required. The start date and time for the role assignment." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "modules/definitions.bicep" + } + } + }, + "_1.timeBoundDurationRoleAssignmentScheduleType": { + "type": "object", + "properties": { + "durationType": { + "type": "string", + "allowedValues": [ + "AfterDuration" + ], + "metadata": { + "description": "Required. The type of the duration." + } + }, + "duration": { + "type": "string", + "metadata": { + "description": "Required. The duration for the role assignment." + } + }, + "startTime": { + "type": "string", + "metadata": { + "description": "Required. The start time for the role assignment." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "modules/definitions.bicep" + } + } + }, + "pimRoleAssignmentTypeType": { + "type": "object", + "discriminator": { + "propertyName": "roleAssignmentType", + "mapping": { + "Active": { + "$ref": "#/definitions/_1.pimActiveRoleAssignmentType" + }, + "Eligible": { + "$ref": "#/definitions/_1.pimEligibleRoleAssignmentType" } } }, "metadata": { + "description": "Optional. The type of the PIM role assignment whether its active or eligible.", + "__bicep_imported_from!": { + "sourceTemplate": "modules/definitions.bicep" + } + } + }, + "requestTypeType": { + "type": "string", + "allowedValues": [ + "AdminAssign", + "AdminExtend", + "AdminRemove", + "AdminRenew", + "AdminUpdate", + "SelfActivate", + "SelfDeactivate", + "SelfExtend", + "SelfRenew" + ], + "metadata": { + "description": "Optional. The request type of the role assignment.", "__bicep_imported_from!": { "sourceTemplate": "modules/definitions.bicep" } @@ -159,6 +308,12 @@ "description": "Optional. Location deployment metadata." } }, + "pimRoleAssignmentType": { + "$ref": "#/definitions/pimRoleAssignmentTypeType", + "metadata": { + "description": "Required. The type of the PIM role assignment whether its active or eligible." + } + }, "justification": { "type": "string", "defaultValue": "", @@ -186,6 +341,20 @@ "description": "Optional. The role eligibility assignment instance id being updated." } }, + "targetRoleAssignmentScheduleId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The resultant role assignment schedule id or the role assignment schedule id being updated." + } + }, + "targetRoleAssignmentScheduleInstanceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The role assignment schedule instance id being updated." + } + }, "ticketInfo": { "$ref": "#/definitions/ticketInfoType", "nullable": true, @@ -193,12 +362,6 @@ "description": "Optional. Ticket Info of the role eligibility." } }, - "scheduleInfo": { - "$ref": "#/definitions/scheduleInfoType", - "metadata": { - "description": "Required. Schedule info of the role eligibility assignment." - } - }, "condition": { "type": "string", "defaultValue": "", @@ -280,6 +443,12 @@ "targetRoleEligibilityScheduleInstanceId": { "value": "[parameters('targetRoleEligibilityScheduleInstanceId')]" }, + "targetRoleAssignmentScheduleId": { + "value": "[parameters('targetRoleAssignmentScheduleId')]" + }, + "targetRoleAssignmentScheduleInstanceId": { + "value": "[parameters('targetRoleAssignmentScheduleInstanceId')]" + }, "ticketInfo": { "value": "[parameters('ticketInfo')]" }, @@ -287,8 +456,8 @@ "value": "[parameters('conditionVersion')]" }, "condition": "[if(not(empty(parameters('condition'))), createObject('value', parameters('condition')), createObject('value', ''))]", - "scheduleInfo": { - "value": "[parameters('scheduleInfo')]" + "pimRoleAssignmentType": { + "value": "[parameters('pimRoleAssignmentType')]" } }, "template": { @@ -298,60 +467,69 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "13148321770832829527" + "version": "0.33.93.31351", + "templateHash": "2970460738165571757" }, "name": " PIM Role Assignments (Management Group scope)", "description": "This module deploys a PIM Role Assignment at a Management Group scope." }, "definitions": { - "requestTypeType": { - "type": "string", - "allowedValues": [ - "AdminAssign", - "AdminExtend", - "AdminRemove", - "AdminRenew", - "AdminUpdate", - "SelfActivate", - "SelfDeactivate", - "SelfExtend", - "SelfRenew" - ], + "_1.permenantRoleAssignmentScheduleType": { + "type": "object", + "properties": { + "durationType": { + "type": "string", + "allowedValues": [ + "NoExpiration" + ], + "metadata": { + "description": "Required. The type of the duration." + } + } + }, "metadata": { - "description": "Optional. The request type of the role assignment.", "__bicep_imported_from!": { "sourceTemplate": "definitions.bicep" } } }, - "scheduleInfoExpirationType": { + "_1.pimActiveRoleAssignmentType": { "type": "object", "properties": { - "duration": { + "roleAssignmentType": { + "type": "string", + "allowedValues": [ + "Active" + ], + "metadata": { + "description": "Required. The type of the role assignment." + } + }, + "linkedRoleEligibilityScheduleId": { "type": "string", "nullable": true, "metadata": { - "description": "Optional. Duration of the role eligibility assignment in TimeSpan format. Example: P365D, P2H." + "description": "Optional. The linked role eligibility schedule id - to activate an eligibility." } }, - "endDateTime": { + "targetRoleAssignmentScheduleId": { "type": "string", "nullable": true, "metadata": { - "description": "Optional. End DateTime of the role eligibility assignment." + "description": "Optional. The resultant role assignment schedule id or the role assignment schedule id being updated." } }, - "type": { + "targetRoleAssignmentScheduleInstanceId": { "type": "string", - "allowedValues": [ - "AfterDateTime", - "AfterDuration", - "NoExpiration" - ], "nullable": true, "metadata": { - "description": "Optional. Type of the role eligibility assignment expiration." + "description": "Optional. The role assignment schedule instance id being updated." + } + }, + "scheduleInfo": { + "$ref": "#/definitions/_1.roleAssignmentScheduleType", + "metadata": { + "description": "Required. The schedule information for the role assignment." } } }, @@ -361,21 +539,36 @@ } } }, - "scheduleInfoType": { + "_1.pimEligibleRoleAssignmentType": { "type": "object", "properties": { - "expiration": { - "$ref": "#/definitions/scheduleInfoExpirationType", + "roleAssignmentType": { + "type": "string", + "allowedValues": [ + "Eligible" + ], + "metadata": { + "description": "Required. The type of the role assignment." + } + }, + "targetRoleEligibilityScheduleId": { + "type": "string", "nullable": true, "metadata": { - "description": "Optional. The expiry information for the role eligibility." + "description": "Optional. The resultant role eligibility schedule id or the role eligibility schedule id being updated." } }, - "startDateTime": { + "targetRoleEligibilityScheduleInstanceId": { "type": "string", "nullable": true, "metadata": { - "description": "Optional. Start DateTime of the role eligibility assignment." + "description": "Optional. The role eligibility assignment instance id being updated." + } + }, + "scheduleInfo": { + "$ref": "#/definitions/_1.roleAssignmentScheduleType", + "metadata": { + "description": "Required. The schedule information for the role assignment." } } }, @@ -385,297 +578,82 @@ } } }, - "ticketInfoType": { + "_1.roleAssignmentScheduleType": { + "type": "object", + "discriminator": { + "propertyName": "durationType", + "mapping": { + "NoExpiration": { + "$ref": "#/definitions/_1.permenantRoleAssignmentScheduleType" + }, + "AfterDuration": { + "$ref": "#/definitions/_1.timeBoundDurationRoleAssignmentScheduleType" + }, + "AfterDateTime": { + "$ref": "#/definitions/_1.timeBoundDateTimeRoleAssignmentScheduleType" + } + } + }, + "metadata": { + "description": "Optional. The schedule information for the role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "definitions.bicep" + } + } + }, + "_1.timeBoundDateTimeRoleAssignmentScheduleType": { "type": "object", "properties": { - "ticketNumber": { + "durationType": { "type": "string", - "nullable": true, + "allowedValues": [ + "AfterDateTime" + ], "metadata": { - "description": "Optional. The ticket number for the role eligibility assignment." + "description": "Required. The type of the duration." } }, - "ticketSystem": { + "endDateTime": { "type": "string", - "nullable": true, "metadata": { - "description": "Optional. The ticket system name for the role eligibility assignment." + "description": "Required. The end date and time for the role assignment." + } + }, + "startTime": { + "type": "string", + "metadata": { + "description": "Required. The start date and time for the role assignment." } } }, - "nullable": true, "metadata": { "__bicep_imported_from!": { "sourceTemplate": "definitions.bicep" } } - } - }, - "parameters": { - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. You can provide either the display name of the role definition (must be configured in the variable `builtInRoleNames`), or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." - } - }, - "principalId": { - "type": "string", - "metadata": { - "description": "Required. The Principal or Object ID of the Security Principal (User, Group, Service Principal, Managed Identity)." - } - }, - "managementGroupId": { - "type": "string", - "defaultValue": "[managementGroup().name]", - "metadata": { - "description": "Optional. Group ID of the Management Group to assign the RBAC role to. If not provided, will use the current scope for deployment." - } }, - "justification": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The justification for the role eligibility." - } - }, - "requestType": { - "$ref": "#/definitions/requestTypeType", - "metadata": { - "description": "Required. The type of the role assignment eligibility request." - } - }, - "targetRoleEligibilityScheduleId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The resultant role eligibility assignment id or the role eligibility assignment id being updated." - } - }, - "targetRoleEligibilityScheduleInstanceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The role eligibility assignment instance id being updated." - } - }, - "ticketInfo": { - "$ref": "#/definitions/ticketInfoType", - "nullable": true, - "metadata": { - "description": "Optional. Ticket Info of the role eligibility." - } - }, - "scheduleInfo": { - "$ref": "#/definitions/scheduleInfoType", - "metadata": { - "description": "Optional. Schedule info of the role eligibility assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to." - } - }, - "conditionVersion": { - "type": "string", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition. Currently accepted value is \"2.0\"." - } - } - }, - "variables": { - "builtInRoleNames": { - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Management Group Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ac63b705-f282-497d-ac71-919bf39d939d')]" - }, - "roleDefinitionIdVar": "[coalesce(tryGet(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), parameters('roleDefinitionIdOrName'))]" - }, - "resources": { - "pimRoleAssignment": { - "type": "Microsoft.Authorization/roleEligibilityScheduleRequests", - "apiVersion": "2022-04-01-preview", - "name": "[guid(parameters('managementGroupId'), variables('roleDefinitionIdVar'), parameters('principalId'))]", - "properties": { - "principalId": "[parameters('principalId')]", - "roleDefinitionId": "[variables('roleDefinitionIdVar')]", - "requestType": "[parameters('requestType')]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "justification": "[parameters('justification')]", - "scheduleInfo": "[parameters('scheduleInfo')]", - "targetRoleEligibilityScheduleId": "[parameters('targetRoleEligibilityScheduleId')]", - "targetRoleEligibilityScheduleInstanceId": "[parameters('targetRoleEligibilityScheduleInstanceId')]", - "ticketInfo": "[parameters('ticketInfo')]" - } - } - }, - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The GUID of the PIM Role Assignment." - }, - "value": "[guid(parameters('managementGroupId'), variables('roleDefinitionIdVar'), parameters('principalId'))]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the PIM Role Assignment." - }, - "value": "[extensionResourceId(managementGroup().id, 'Microsoft.Authorization/roleEligibilityScheduleRequests', guid(parameters('managementGroupId'), variables('roleDefinitionIdVar'), parameters('principalId')))]" - }, - "scope": { - "type": "string", - "metadata": { - "description": "The scope this PIM Role Assignment applies to." - }, - "value": "[resourceId('Microsoft.Management/managementGroups', parameters('managementGroupId'))]" - } - } - } - } - }, - "roleAssignment_sub": { - "condition": "[and(not(empty(parameters('subscriptionId'))), empty(parameters('resourceGroupName')))]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PimRoleAssignment-Sub-Module', uniqueString(deployment().name, parameters('location')))]", - "subscriptionId": "[parameters('subscriptionId')]", - "location": "[deployment().location]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "roleDefinitionIdOrName": { - "value": "[parameters('roleDefinitionIdOrName')]" - }, - "principalId": { - "value": "[parameters('principalId')]" - }, - "subscriptionId": { - "value": "[parameters('subscriptionId')]" - }, - "requestType": { - "value": "[parameters('requestType')]" - }, - "justification": { - "value": "[parameters('justification')]" - }, - "targetRoleEligibilityScheduleId": { - "value": "[parameters('targetRoleEligibilityScheduleId')]" - }, - "targetRoleEligibilityScheduleInstanceId": { - "value": "[parameters('targetRoleEligibilityScheduleInstanceId')]" - }, - "ticketInfo": { - "value": "[parameters('ticketInfo')]" - }, - "conditionVersion": { - "value": "[parameters('conditionVersion')]" - }, - "condition": "[if(not(empty(parameters('condition'))), createObject('value', parameters('condition')), createObject('value', ''))]", - "scheduleInfo": { - "value": "[parameters('scheduleInfo')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", - "languageVersion": "2.0", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "7566590888966202430" - }, - "name": "PIM Role Assignments (Subscription scope)", - "description": "This module deploys a PIM Role Assignment at a Subscription scope." - }, - "definitions": { - "requestTypeType": { - "type": "string", - "allowedValues": [ - "AdminAssign", - "AdminExtend", - "AdminRemove", - "AdminRenew", - "AdminUpdate", - "SelfActivate", - "SelfDeactivate", - "SelfExtend", - "SelfRenew" - ], - "metadata": { - "description": "Optional. The request type of the role assignment.", - "__bicep_imported_from!": { - "sourceTemplate": "definitions.bicep" - } - } - }, - "scheduleInfoExpirationType": { + "_1.timeBoundDurationRoleAssignmentScheduleType": { "type": "object", "properties": { - "duration": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Duration of the role eligibility assignment in TimeSpan format. Example: P365D, P2H." - } - }, - "endDateTime": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. End DateTime of the role eligibility assignment." - } - }, - "type": { + "durationType": { "type": "string", "allowedValues": [ - "AfterDateTime", - "AfterDuration", - "NoExpiration" + "AfterDuration" ], - "nullable": true, "metadata": { - "description": "Optional. Type of the role eligibility assignment expiration." + "description": "Required. The type of the duration." } - } - }, - "metadata": { - "__bicep_imported_from!": { - "sourceTemplate": "definitions.bicep" - } - } - }, - "scheduleInfoType": { - "type": "object", - "properties": { - "expiration": { - "$ref": "#/definitions/scheduleInfoExpirationType", - "nullable": true, + }, + "duration": { + "type": "string", "metadata": { - "description": "Optional. The expiry information for the role eligibility." + "description": "Required. The duration for the role assignment." } }, - "startDateTime": { + "startTime": { "type": "string", - "nullable": true, "metadata": { - "description": "Optional. Start DateTime of the role eligibility assignment." + "description": "Required. The start time for the role assignment." } } }, @@ -685,234 +663,26 @@ } } }, - "ticketInfoType": { + "pimRoleAssignmentTypeType": { "type": "object", - "properties": { - "ticketNumber": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The ticket number for the role eligibility assignment." - } - }, - "ticketSystem": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The ticket system name for the role eligibility assignment." + "discriminator": { + "propertyName": "roleAssignmentType", + "mapping": { + "Active": { + "$ref": "#/definitions/_1.pimActiveRoleAssignmentType" + }, + "Eligible": { + "$ref": "#/definitions/_1.pimEligibleRoleAssignmentType" } } }, - "nullable": true, "metadata": { + "description": "Optional. The type of the PIM role assignment whether its active or eligible.", "__bicep_imported_from!": { "sourceTemplate": "definitions.bicep" } } - } - }, - "parameters": { - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. You can provide either the display name of the role definition (must be configured in the variable `builtInRoleNames`), or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." - } - }, - "principalId": { - "type": "string", - "metadata": { - "description": "Required. The Principal or Object ID of the Security Principal (User, Group, Service Principal, Managed Identity)." - } - }, - "subscriptionId": { - "type": "string", - "defaultValue": "[subscription().subscriptionId]", - "metadata": { - "description": "Optional. Subscription ID of the subscription to assign the RBAC role to. If not provided, will use the current scope for deployment." - } - }, - "justification": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The justification for the role eligibility." - } - }, - "requestType": { - "$ref": "#/definitions/requestTypeType", - "metadata": { - "description": "Required. The type of the role assignment eligibility request." - } }, - "targetRoleEligibilityScheduleId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The resultant role eligibility assignment id or the role eligibility assignment id being updated." - } - }, - "targetRoleEligibilityScheduleInstanceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The role eligibility assignment instance id being updated." - } - }, - "ticketInfo": { - "$ref": "#/definitions/ticketInfoType", - "nullable": true, - "metadata": { - "description": "Optional. Ticket Info of the role eligibility." - } - }, - "scheduleInfo": { - "$ref": "#/definitions/scheduleInfoType", - "metadata": { - "description": "Optional. Schedule info of the role eligibility assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to." - } - }, - "conditionVersion": { - "type": "string", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition. Currently accepted value is \"2.0\"." - } - } - }, - "variables": { - "builtInRoleNames": { - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" - }, - "roleDefinitionIdVar": "[coalesce(tryGet(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), parameters('roleDefinitionIdOrName'))]" - }, - "resources": { - "pimRoleAssignment": { - "type": "Microsoft.Authorization/roleEligibilityScheduleRequests", - "apiVersion": "2022-04-01-preview", - "name": "[guid(parameters('subscriptionId'), variables('roleDefinitionIdVar'), parameters('principalId'))]", - "properties": { - "principalId": "[parameters('principalId')]", - "roleDefinitionId": "[variables('roleDefinitionIdVar')]", - "requestType": "[parameters('requestType')]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "justification": "[parameters('justification')]", - "scheduleInfo": "[parameters('scheduleInfo')]", - "targetRoleEligibilityScheduleId": "[parameters('targetRoleEligibilityScheduleId')]", - "targetRoleEligibilityScheduleInstanceId": "[parameters('targetRoleEligibilityScheduleInstanceId')]", - "ticketInfo": "[parameters('ticketInfo')]" - } - } - }, - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The GUID of the PIM Role Assignment." - }, - "value": "[guid(parameters('subscriptionId'), variables('roleDefinitionIdVar'), parameters('principalId'))]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the PIM Role Assignment." - }, - "value": "[subscriptionResourceId('Microsoft.Authorization/roleEligibilityScheduleRequests', guid(parameters('subscriptionId'), variables('roleDefinitionIdVar'), parameters('principalId')))]" - }, - "subscriptionName": { - "type": "string", - "metadata": { - "description": "The name of the resource group the PIM role assignment was applied at." - }, - "value": "[subscription().displayName]" - }, - "scope": { - "type": "string", - "metadata": { - "description": "The scope this PIM Role Assignment applies to." - }, - "value": "[subscription().id]" - } - } - } - } - }, - "roleAssignment_rg": { - "condition": "[and(not(empty(parameters('resourceGroupName'))), not(empty(parameters('subscriptionId'))))]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PimRoleAssignment-RG-Module', uniqueString(deployment().name, parameters('location')))]", - "subscriptionId": "[parameters('subscriptionId')]", - "resourceGroup": "[parameters('resourceGroupName')]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "roleDefinitionIdOrName": { - "value": "[parameters('roleDefinitionIdOrName')]" - }, - "principalId": { - "value": "[parameters('principalId')]" - }, - "subscriptionId": { - "value": "[parameters('subscriptionId')]" - }, - "resourceGroupName": { - "value": "[parameters('resourceGroupName')]" - }, - "requestType": { - "value": "[parameters('requestType')]" - }, - "justification": { - "value": "[parameters('justification')]" - }, - "targetRoleEligibilityScheduleId": { - "value": "[parameters('targetRoleEligibilityScheduleId')]" - }, - "targetRoleEligibilityScheduleInstanceId": { - "value": "[parameters('targetRoleEligibilityScheduleInstanceId')]" - }, - "ticketInfo": { - "value": "[parameters('ticketInfo')]" - }, - "conditionVersion": { - "value": "[parameters('conditionVersion')]" - }, - "condition": "[if(not(empty(parameters('condition'))), createObject('value', parameters('condition')), createObject('value', ''))]", - "scheduleInfo": { - "value": "[parameters('scheduleInfo')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "languageVersion": "2.0", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "5557911543551567745" - }, - "name": "PIM Role Assignments (Resource Group scope)", - "description": "This module deploys a PIM Role Assignment at a Resource Group scope." - }, - "definitions": { "requestTypeType": { "type": "string", "allowedValues": [ @@ -933,66 +703,6 @@ } } }, - "scheduleInfoExpirationType": { - "type": "object", - "properties": { - "duration": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Duration of the role eligibility assignment in TimeSpan format. Example: P365D, P2H." - } - }, - "endDateTime": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. End DateTime of the role eligibility assignment." - } - }, - "type": { - "type": "string", - "allowedValues": [ - "AfterDateTime", - "AfterDuration", - "NoExpiration" - ], - "nullable": true, - "metadata": { - "description": "Optional. Type of the role eligibility assignment expiration." - } - } - }, - "metadata": { - "__bicep_imported_from!": { - "sourceTemplate": "definitions.bicep" - } - } - }, - "scheduleInfoType": { - "type": "object", - "properties": { - "expiration": { - "$ref": "#/definitions/scheduleInfoExpirationType", - "nullable": true, - "metadata": { - "description": "Optional. The expiry information for the role eligibility." - } - }, - "startDateTime": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Start DateTime of the role eligibility assignment." - } - } - }, - "metadata": { - "__bicep_imported_from!": { - "sourceTemplate": "definitions.bicep" - } - } - }, "ticketInfoType": { "type": "object", "properties": { @@ -1032,18 +742,17 @@ "description": "Required. The Principal or Object ID of the Security Principal (User, Group, Service Principal, Managed Identity)." } }, - "resourceGroupName": { + "managementGroupId": { "type": "string", - "defaultValue": "[resourceGroup().name]", + "defaultValue": "[managementGroup().name]", "metadata": { - "description": "Optional. Name of the Resource Group to assign the RBAC role to. If not provided, will use the current scope for deployment." + "description": "Optional. Group ID of the Management Group to assign the RBAC role to. If not provided, will use the current scope for deployment." } }, - "subscriptionId": { - "type": "string", - "defaultValue": "[subscription().subscriptionId]", + "pimRoleAssignmentType": { + "$ref": "#/definitions/pimRoleAssignmentTypeType", "metadata": { - "description": "Optional. Subscription ID of the subscription to assign the RBAC role to. If not provided, will use the current scope for deployment." + "description": "Required. The type of the PIM role assignment whether its active or eligible." } }, "justification": { @@ -1073,6 +782,20 @@ "description": "Optional. The role eligibility assignment instance id being updated." } }, + "targetRoleAssignmentScheduleId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The resultant role assignment schedule id or the role assignment schedule id being updated." + } + }, + "targetRoleAssignmentScheduleInstanceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The role assignment schedule instance id being updated." + } + }, "ticketInfo": { "$ref": "#/definitions/ticketInfoType", "nullable": true, @@ -1080,12 +803,6 @@ "description": "Optional. Ticket Info of the role eligibility." } }, - "scheduleInfo": { - "$ref": "#/definitions/scheduleInfoType", - "metadata": { - "description": "Optional. Schedule info of the role eligibility assignment." - } - }, "condition": { "type": "string", "defaultValue": "", @@ -1109,27 +826,48 @@ "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", + "Management Group Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ac63b705-f282-497d-ac71-919bf39d939d')]" }, "roleDefinitionIdVar": "[coalesce(tryGet(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), parameters('roleDefinitionIdOrName'))]" }, "resources": { - "pimRoleAssignment": { + "pimEligibleRoleAssignment": { + "condition": "[equals(parameters('pimRoleAssignmentType').roleAssignmentType, 'Eligible')]", "type": "Microsoft.Authorization/roleEligibilityScheduleRequests", "apiVersion": "2022-04-01-preview", - "name": "[guid(parameters('subscriptionId'), parameters('resourceGroupName'), variables('roleDefinitionIdVar'), parameters('principalId'))]", + "name": "[guid(parameters('managementGroupId'), variables('roleDefinitionIdVar'), parameters('principalId'))]", "properties": { - "roleDefinitionId": "[variables('roleDefinitionIdVar')]", "principalId": "[parameters('principalId')]", + "roleDefinitionId": "[variables('roleDefinitionIdVar')]", "requestType": "[parameters('requestType')]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", + "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", "justification": "[parameters('justification')]", - "scheduleInfo": "[parameters('scheduleInfo')]", "targetRoleEligibilityScheduleId": "[parameters('targetRoleEligibilityScheduleId')]", "targetRoleEligibilityScheduleInstanceId": "[parameters('targetRoleEligibilityScheduleInstanceId')]", - "ticketInfo": "[parameters('ticketInfo')]" + "ticketInfo": "[parameters('ticketInfo')]", + "scheduleInfo": "[if(equals(parameters('pimRoleAssignmentType').scheduleInfo.durationType, 'NoExpiration'), createObject('expiration', createObject('type', 'NoExpiration')), if(equals(parameters('pimRoleAssignmentType').scheduleInfo.durationType, 'AfterDuration'), createObject('expiration', createObject('type', 'AfterDuration', 'duration', parameters('pimRoleAssignmentType').scheduleInfo.duration), 'startDateTime', parameters('pimRoleAssignmentType').scheduleInfo.startTime), if(equals(parameters('pimRoleAssignmentType').scheduleInfo.durationType, 'AfterDateTime'), createObject('expiration', createObject('type', 'AfterDateTime', 'endDateTime', parameters('pimRoleAssignmentType').scheduleInfo.endDateTime), 'startDateTime', parameters('pimRoleAssignmentType').scheduleInfo.startTime), null())))]" + } + }, + "pimActiveRoleAssignment": { + "condition": "[equals(parameters('pimRoleAssignmentType').roleAssignmentType, 'Active')]", + "type": "Microsoft.Authorization/roleAssignmentScheduleRequests", + "apiVersion": "2022-04-01-preview", + "name": "[guid(parameters('managementGroupId'), variables('roleDefinitionIdVar'), parameters('principalId'))]", + "properties": { + "principalId": "[parameters('principalId')]", + "roleDefinitionId": "[variables('roleDefinitionIdVar')]", + "requestType": "[parameters('requestType')]", + "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", + "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", + "justification": "[parameters('justification')]", + "targetRoleAssignmentScheduleId": "[parameters('targetRoleAssignmentScheduleId')]", + "targetRoleAssignmentScheduleInstanceId": "[parameters('targetRoleAssignmentScheduleInstanceId')]", + "ticketInfo": "[parameters('ticketInfo')]", + "scheduleInfo": "[if(equals(parameters('pimRoleAssignmentType').scheduleInfo.durationType, 'NoExpiration'), createObject('expiration', createObject('type', 'NoExpiration')), if(equals(parameters('pimRoleAssignmentType').scheduleInfo.durationType, 'AfterDuration'), createObject('expiration', createObject('type', 'AfterDuration', 'duration', parameters('pimRoleAssignmentType').scheduleInfo.duration), 'startDateTime', parameters('pimRoleAssignmentType').scheduleInfo.startTime), if(equals(parameters('pimRoleAssignmentType').scheduleInfo.durationType, 'AfterDateTime'), createObject('expiration', createObject('type', 'AfterDateTime', 'endDateTime', parameters('pimRoleAssignmentType').scheduleInfo.endDateTime), 'startDateTime', parameters('pimRoleAssignmentType').scheduleInfo.startTime), null())))]" } } }, @@ -1139,55 +877,25 @@ "metadata": { "description": "The GUID of the PIM Role Assignment." }, - "value": "[guid(parameters('subscriptionId'), parameters('resourceGroupName'), variables('roleDefinitionIdVar'), parameters('principalId'))]" + "value": "[if(equals(parameters('pimRoleAssignmentType').roleAssignmentType, 'Eligible'), guid(parameters('managementGroupId'), variables('roleDefinitionIdVar'), parameters('principalId')), guid(parameters('managementGroupId'), variables('roleDefinitionIdVar'), parameters('principalId')))]" }, "resourceId": { "type": "string", "metadata": { "description": "The resource ID of the PIM Role Assignment." }, - "value": "[resourceId('Microsoft.Authorization/roleEligibilityScheduleRequests', guid(parameters('subscriptionId'), parameters('resourceGroupName'), variables('roleDefinitionIdVar'), parameters('principalId')))]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the resource group the PIM role assignment was applied at." - }, - "value": "[resourceGroup().name]" + "value": "[if(equals(parameters('pimRoleAssignmentType').roleAssignmentType, 'Eligible'), extensionResourceId(managementGroup().id, 'Microsoft.Authorization/roleEligibilityScheduleRequests', guid(parameters('managementGroupId'), variables('roleDefinitionIdVar'), parameters('principalId'))), extensionResourceId(managementGroup().id, 'Microsoft.Authorization/roleAssignmentScheduleRequests', guid(parameters('managementGroupId'), variables('roleDefinitionIdVar'), parameters('principalId'))))]" }, "scope": { "type": "string", "metadata": { "description": "The scope this PIM Role Assignment applies to." }, - "value": "[resourceGroup().id]" + "value": "[resourceId('Microsoft.Management/managementGroups', parameters('managementGroupId'))]" } } } } } - }, - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The GUID of the PIM Role Assignment." - }, - "value": "[if(and(empty(parameters('subscriptionId')), empty(parameters('resourceGroupName'))), reference('roleAssignment_mg').outputs.name.value, if(and(not(empty(parameters('subscriptionId'))), empty(parameters('resourceGroupName'))), reference('roleAssignment_sub').outputs.name.value, reference('roleAssignment_rg').outputs.name.value))]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the PIM Role Assignment." - }, - "value": "[if(and(empty(parameters('subscriptionId')), empty(parameters('resourceGroupName'))), reference('roleAssignment_mg').outputs.resourceId.value, if(and(not(empty(parameters('subscriptionId'))), empty(parameters('resourceGroupName'))), reference('roleAssignment_sub').outputs.resourceId.value, reference('roleAssignment_rg').outputs.resourceId.value))]" - }, - "scope": { - "type": "string", - "metadata": { - "description": "The scope this PIM Role Assignment applies to." - }, - "value": "[if(and(empty(parameters('subscriptionId')), empty(parameters('resourceGroupName'))), reference('roleAssignment_mg').outputs.scope.value, if(and(not(empty(parameters('subscriptionId'))), empty(parameters('resourceGroupName'))), reference('roleAssignment_sub').outputs.scope.value, reference('roleAssignment_rg').outputs.scope.value))]" - } } } \ No newline at end of file diff --git a/avm/ptn/authorization/pim-role-assignment/modules/definitions.bicep b/avm/ptn/authorization/pim-role-assignment/modules/definitions.bicep index 9fd5ec81c1..b3a298420b 100644 --- a/avm/ptn/authorization/pim-role-assignment/modules/definitions.bicep +++ b/avm/ptn/authorization/pim-role-assignment/modules/definitions.bicep @@ -26,41 +26,70 @@ type ticketInfoType = { @export() @discriminator('roleAssignmentType') +@description('Optional. The type of the PIM role assignment whether its active or eligible.') type pimRoleAssignmentTypeType = pimActiveRoleAssignmentType | pimEligibleRoleAssignmentType type pimActiveRoleAssignmentType = { + @description('Required. The type of the role assignment.') roleAssignmentType: 'Active' + + @description('Optional. The linked role eligibility schedule id - to activate an eligibility.') linkedRoleEligibilityScheduleId: string? + + @description('Optional. The resultant role assignment schedule id or the role assignment schedule id being updated.') targetRoleAssignmentScheduleId: string? + + @description('Optional. The role assignment schedule instance id being updated.') targetRoleAssignmentScheduleInstanceId: string? + + @description('Required. The schedule information for the role assignment.') scheduleInfo: roleAssignmentScheduleType } type pimEligibleRoleAssignmentType = { + @description('Required. The type of the role assignment.') roleAssignmentType: 'Eligible' + + @description('Optional. The resultant role eligibility schedule id or the role eligibility schedule id being updated.') targetRoleEligibilityScheduleId: string? + + @description('Optional. The role eligibility assignment instance id being updated.') targetRoleEligibilityScheduleInstanceId: string? + + @description('Required. The schedule information for the role assignment.') scheduleInfo: roleAssignmentScheduleType } @discriminator('durationType') +@description('Optional. The schedule information for the role assignment.') type roleAssignmentScheduleType = | permenantRoleAssignmentScheduleType | timeBoundDurationRoleAssignmentScheduleType | timeBoundDateTimeRoleAssignmentScheduleType type permenantRoleAssignmentScheduleType = { + @description('Required. The type of the duration.') durationType: 'NoExpiration' } type timeBoundDurationRoleAssignmentScheduleType = { + @description('Required. The type of the duration.') durationType: 'AfterDuration' + + @description('Required. The duration for the role assignment.') duration: string + + @description('Required. The start time for the role assignment.') startTime: string } type timeBoundDateTimeRoleAssignmentScheduleType = { + @description('Required. The type of the duration.') durationType: 'AfterDateTime' + + @description('Required. The end date and time for the role assignment.') endDateTime: string + + @description('Required. The start date and time for the role assignment.') startTime: string } diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep index d55a66a6d2..caea0836fa 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep @@ -1,6 +1,6 @@ targetScope = 'managementGroup' -metadata name = 'PIM Role Assignments (Management Group scope)' -metadata description = 'This module deploys a PIM Role Assignment at a Management Group scope using common parameters.' +metadata name = 'PIM Active Role Assignments (Management Group scope)' +metadata description = 'This module deploys a PIM Active Role Assignment at a Management Group scope using common parameters.' // ========== // // Parameters // @@ -19,6 +19,9 @@ param namePrefix string = '#_namePrefix_#' @secure() param userPrinicipalId string = '' +@description('Optional. The start date and time for the role assignment. Defaults to the current date and time.') +param startDateTime string = utcNow() + // ============== // // Test Execution // // ============== // @@ -30,11 +33,13 @@ module testDeployment '../../../main.bicep' = { roleDefinitionIdOrName: 'Contributor' requestType: 'AdminAssign' location: resourceLocation - scheduleInfo: { - expiration: { - type: 'AfterDateTime' + pimRoleAssignmentType: { + roleAssignmentType: 'Active' + scheduleInfo: { + duration: 'P10D' + durationType: 'AfterDuration' + startTime: startDateTime } - startDateTime: '2025-01-23T12:39:44Z' } justification: 'Justification for the role eligibility' ticketInfo: { diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep index 24752c76f6..f706921cfe 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep @@ -1,6 +1,6 @@ targetScope = 'managementGroup' -metadata name = 'PIM Role Assignments (Resource Group scope)' -metadata description = 'This module deploys a PIM Role Assignment at a Resource Group scope using minimal parameters.' +metadata name = 'PIM Eligible Role Assignments (Resource Group scope)' +metadata description = 'This module deploys a PIM Eligible Role Assignment at a Resource Group scope using minimal parameters.' // ========== // // Parameters // @@ -26,6 +26,12 @@ param subscriptionId string = '#_subscriptionId_#' @secure() param userPrinicipalId string = '' +@description('Optional. The start date and time for the role assignment. Defaults to the current date and time.') +param startDateTime string = utcNow() + +@description('Optional. The end date and time for the role assignment. Defaults to one year from the start date and time.') +param endDateTime string = dateTimeAdd(startDateTime, 'P1Y') + // General resources // ================= module resourceGroup 'br/public:avm/res/resources/resource-group:0.2.3' = { @@ -50,10 +56,12 @@ module testDeployment '../../../main.bicep' = { subscriptionId: subscriptionId resourceGroupName: resourceGroup.outputs.name requestType: 'AdminAssign' - scheduleInfo: { - expiration: { - duration: 'P1H' - type: 'AfterDuration' + pimRoleAssignmentType: { + roleAssignmentType: 'Eligible' + scheduleInfo: { + durationType: 'AfterDateTime' + endDateTime: endDateTime + startTime: startDateTime } } } diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep index c19c0e4f73..7f89ef3dbd 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep @@ -1,6 +1,6 @@ targetScope = 'managementGroup' -metadata name = 'PIM Role Assignments (Resource Group)' -metadata description = 'This module deploys a PIM Role Assignment at a Resource Group scope using common parameters.' +metadata name = 'PIM Active Role Assignments (Resource Group)' +metadata description = 'This module deploys a PIM Active Role Assignment at a Resource Group scope using common parameters.' // ========== // // Parameters // @@ -22,8 +22,11 @@ param resourceGroupName string = 'dep-${namePrefix}-authorization.pimroleassignm @description('Optional. Subscription ID of the subscription to assign the RBAC role to. If no Resource Group name is provided, the module deploys at subscription level, therefore assigns the provided RBAC role to the subscription.') param subscriptionId string = '#_subscriptionId_#' -@description('Optional. The dateTime of the role assignment eligibility.') -param startTime string = utcNow() +@description('Optional. The start date and time for the role assignment. Defaults to the current date and time.') +param startDateTime string = utcNow() + +@description('Optional. The end date and time for the role assignment. Defaults to one year from the start date and time.') +param endDateTime string = dateTimeAdd(startDateTime, 'P1Y') @description('Required. Principle ID of the user. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'userPrinicipalId\'.') @secure() @@ -53,11 +56,13 @@ module testDeployment '../../../main.bicep' = { subscriptionId: subscriptionId resourceGroupName: resourceGroup.outputs.name requestType: 'AdminAssign' - scheduleInfo: { - expiration: { - type: 'AfterDateTime' + pimRoleAssignmentType: { + roleAssignmentType: 'Active' + scheduleInfo: { + durationType: 'AfterDateTime' + endDateTime: endDateTime + startTime: startDateTime } - startDateTime: startTime } justification: 'Justification for role eligibility' ticketInfo: { diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep index dd40de15fa..6b5e16e6ad 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep @@ -1,6 +1,6 @@ targetScope = 'managementGroup' -metadata name = 'PIM Role Assignments (Subscription scope)' -metadata description = 'This module deploys a PIM Role Assignment at a Subscription scope using minimal parameters.' +metadata name = 'PIM Eligible Role Assignments (Subscription scope)' +metadata description = 'This module deploys a PIM Eligible Role Assignment at a Subscription scope using minimal parameters.' // ========== // // Parameters // @@ -19,6 +19,9 @@ param subscriptionId string = '#_subscriptionId_#' @secure() param userPrinicipalId string = '' +@description('Optional. The start date and time for the role assignment. Defaults to the current date and time.') +param startDateTime string = utcNow() + // ============== // // Test Execution // // ============== // @@ -33,10 +36,12 @@ module testDeployment '../../../main.bicep' = { ) subscriptionId: subscriptionId requestType: 'AdminAssign' - scheduleInfo: { - expiration: { - duration: 'P1H' - type: 'AfterDuration' + pimRoleAssignmentType: { + roleAssignmentType: 'Eligible' + scheduleInfo: { + duration: 'P10D' + durationType: 'AfterDuration' + startTime: startDateTime } } } diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.max/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.max/main.test.bicep index 1f7cae84db..554ab489b1 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.max/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.max/main.test.bicep @@ -1,6 +1,6 @@ targetScope = 'managementGroup' -metadata name = 'PIM Role Assignments (Subscription scope)' -metadata description = 'This module deploys a PIM Role Assignment at a Subscription scope using common parameters.' +metadata name = 'PIM Active permenant Role Assignments (Subscription scope)' +metadata description = 'This module deploys a PIM Active permenant Role Assignment at a Subscription scope using common parameters.' // ========== // // Parameters // @@ -32,10 +32,10 @@ module testDeployment '../../../main.bicep' = { principalId: userPrinicipalId roleDefinitionIdOrName: 'Reader' requestType: 'AdminAssign' - scheduleInfo: { - expiration: { - duration: 'P1H' - type: 'AfterDuration' + pimRoleAssignmentType: { + roleAssignmentType: 'Active' + scheduleInfo: { + durationType: 'NoExpiration' } } justification: 'Justification for role assignment' diff --git a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 index 64b6008e88..060a4d6454 100644 --- a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 +++ b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 @@ -109,6 +109,10 @@ function Invoke-ResourceRemoval { $null = Remove-AzResource -ResourceId $ResourceId -Force -ErrorAction 'Stop' break } + 'Microsoft.Authorization/roleAssignmentScheduleRequests' { + $null = Remove-AzResource -ResourceId $ResourceId -Force -ErrorAction 'Stop' + break + } 'Microsoft.RecoveryServices/vaults' { # Pre-Removal # ----------- From 96d822952d047dd682afcb67dd2e1dc0b0b9e060 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Mon, 3 Feb 2025 16:11:11 +0200 Subject: [PATCH 19/54] feat: Update justification parameter in e2e tests to 'AVM test' and enhance resource removal logic --- .../tests/e2e/mg.defaults/main.test.bicep | 1 + .../tests/e2e/mg.max/main.test.bicep | 2 +- .../tests/e2e/rg.default/main.test.bicep | 1 + .../tests/e2e/rg.max/main.test.bicep | 2 +- .../tests/e2e/sub.default/main.test.bicep | 1 + .../tests/e2e/sub.max/main.test.bicep | 2 +- .../helper/Invoke-ResourceRemoval.ps1 | 16 +++++++++++++++- 7 files changed, 21 insertions(+), 4 deletions(-) diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep index ff204b5d7d..4a9825dfc1 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep @@ -41,5 +41,6 @@ module testDeployment '../../../main.bicep' = { requestType: 'AdminAssign' roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/18d7d88d-d35e-4fb5-a5c3-7773c20a72d9' location: resourceLocation + justification: 'AVM test' } } diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep index caea0836fa..3e0d168ffa 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep @@ -41,7 +41,7 @@ module testDeployment '../../../main.bicep' = { startTime: startDateTime } } - justification: 'Justification for the role eligibility' + justification: 'AVM test' ticketInfo: { ticketNumber: '123456' ticketSystem: 'system1' diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep index f706921cfe..b8b002c711 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep @@ -64,5 +64,6 @@ module testDeployment '../../../main.bicep' = { startTime: startDateTime } } + justification: 'AVM test' } } diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep index 7f89ef3dbd..84e63b66a5 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep @@ -64,7 +64,7 @@ module testDeployment '../../../main.bicep' = { startTime: startDateTime } } - justification: 'Justification for role eligibility' + justification: 'AVM test' ticketInfo: { ticketNumber: '32423' ticketSystem: 'system12' diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep index 6b5e16e6ad..dff4c9e8a8 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep @@ -44,5 +44,6 @@ module testDeployment '../../../main.bicep' = { startTime: startDateTime } } + justification: 'AVM test' } } diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.max/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.max/main.test.bicep index 554ab489b1..6cb10859b8 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.max/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.max/main.test.bicep @@ -38,7 +38,7 @@ module testDeployment '../../../main.bicep' = { durationType: 'NoExpiration' } } - justification: 'Justification for role assignment' + justification: 'AVM test' ticketInfo: { ticketNumber: '21312' ticketSystem: ' System2' diff --git a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 index 060a4d6454..46805f5ca2 100644 --- a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 +++ b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 @@ -106,7 +106,21 @@ function Invoke-ResourceRemoval { break } 'Microsoft.Authorization/roleEligibilityScheduleRequests' { - $null = Remove-AzResource -ResourceId $ResourceId -Force -ErrorAction 'Stop' + $idElem = $ResourceId.Split('/') + $scope = $idElem[0..($idElem.Count - 5)] -join '/' + $pimRoleAssignment = Get-AzRoleEligibilityScheduleRequest -Scope $scope | Where-Object { $_.Justification -eq 'AVM test' -and $_.Status -eq 'Provisioned' } + $pimRoleAssignmentPrinicpalId = $pimRoleAssignment.PrincipalId + $pimRoleAssignmentRoleDefinitionId = $pimRoleAssignment.RoleDefinitionId + + $guid = New-Guid + $startTime = Get-Date -Format o + $null = New-AzRoleEligibilityScheduleRequest -Name $guid ` + -Scope $scope ` + -ExpirationDuration PT1H ` + -PrincipalId $pimRoleAssignmentPrinicpalId ` + -RequestType AdminRemove ` + -RoleDefinitionId $pimRoleAssignmentRoleDefinitionId ` + -ScheduleInfoStartDateTime $startTime break } 'Microsoft.Authorization/roleAssignmentScheduleRequests' { From 1b794990330496ee093ff8284977a037ffd182e6 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Mon, 3 Feb 2025 16:20:27 +0200 Subject: [PATCH 20/54] feat: Enhance resource removal logic to include role assignment schedule requests with AVM test justification --- .../helper/Invoke-ResourceRemoval.ps1 | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 index 46805f5ca2..6d2870d087 100644 --- a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 +++ b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 @@ -111,7 +111,6 @@ function Invoke-ResourceRemoval { $pimRoleAssignment = Get-AzRoleEligibilityScheduleRequest -Scope $scope | Where-Object { $_.Justification -eq 'AVM test' -and $_.Status -eq 'Provisioned' } $pimRoleAssignmentPrinicpalId = $pimRoleAssignment.PrincipalId $pimRoleAssignmentRoleDefinitionId = $pimRoleAssignment.RoleDefinitionId - $guid = New-Guid $startTime = Get-Date -Format o $null = New-AzRoleEligibilityScheduleRequest -Name $guid ` @@ -124,7 +123,20 @@ function Invoke-ResourceRemoval { break } 'Microsoft.Authorization/roleAssignmentScheduleRequests' { - $null = Remove-AzResource -ResourceId $ResourceId -Force -ErrorAction 'Stop' + $idElem = $ResourceId.Split('/') + $scope = $idElem[0..($idElem.Count - 5)] -join '/' + $pimRoleAssignment = Get-AzRoleAssignmentScheduleRequest -Scope $scope | Where-Object { $_.Justification -eq 'AVM test' -and $_.Status -eq 'Provisioned' } + $pimRoleAssignmentPrinicpalId = $pimRoleAssignment.PrincipalId + $pimRoleAssignmentRoleDefinitionId = $pimRoleAssignment.RoleDefinitionId + $guid = New-Guid + $startTime = Get-Date -Format o + $null = New-AzRoleAssignmentScheduleRequest -Name $guid ` + -Scope $scope ` + -ExpirationDuration PT1H ` + -PrincipalId $pimRoleAssignmentPrinicpalId ` + -RequestType AdminRemove ` + -RoleDefinitionId $pimRoleAssignmentRoleDefinitionId ` + -ScheduleInfoStartDateTime $startTime break } 'Microsoft.RecoveryServices/vaults' { From e67034a9f226448542822134ae9d5d345c216520 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Mon, 3 Feb 2025 17:19:17 +0200 Subject: [PATCH 21/54] fix: Update roleDefinitionIdOrName in e2e test configurations for consistency --- .../pim-role-assignment/tests/e2e/rg.default/main.test.bicep | 2 +- .../pim-role-assignment/tests/e2e/rg.max/main.test.bicep | 2 +- .../pim-role-assignment/tests/e2e/sub.default/main.test.bicep | 2 +- .../pim-role-assignment/tests/e2e/sub.max/main.test.bicep | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep index b8b002c711..fbd24c1c7c 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep @@ -51,7 +51,7 @@ module testDeployment '../../../main.bicep' = { name: '${uniqueString(deployment().name)}-test-${serviceShort}' params: { principalId: userPrinicipalId - roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11' + roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/a8889054-8d42-49c9-bc1c-52486c10e7cd' location: resourceLocation subscriptionId: subscriptionId resourceGroupName: resourceGroup.outputs.name diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep index 84e63b66a5..151613604d 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep @@ -51,7 +51,7 @@ module testDeployment '../../../main.bicep' = { name: '${uniqueString(deployment().name)}-test-${serviceShort}' params: { principalId: userPrinicipalId - roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7' + roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c' location: resourceLocation subscriptionId: subscriptionId resourceGroupName: resourceGroup.outputs.name diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep index dff4c9e8a8..442c79b7bb 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep @@ -32,7 +32,7 @@ module testDeployment '../../../main.bicep' = { principalId: userPrinicipalId roleDefinitionIdOrName: subscriptionResourceId( 'Microsoft.Authorization/roleDefinitions', - 'acdd72a7-3385-48ef-bd42-f606fba81ae7' + 'b24988ac-6180-42a0-ab88-20f7382dd24c' ) subscriptionId: subscriptionId requestType: 'AdminAssign' diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.max/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.max/main.test.bicep index 6cb10859b8..e22a4a230b 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.max/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.max/main.test.bicep @@ -30,7 +30,7 @@ module testDeployment '../../../main.bicep' = { name: '${uniqueString(deployment().name)}-test-${serviceShort}-${namePrefix}' params: { principalId: userPrinicipalId - roleDefinitionIdOrName: 'Reader' + roleDefinitionIdOrName: 'Role Based Access Control Administrator' requestType: 'AdminAssign' pimRoleAssignmentType: { roleAssignmentType: 'Active' From 9a48245c3001d001d42ad7e3ffc532854e4b6285 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Tue, 4 Feb 2025 09:12:17 +0200 Subject: [PATCH 22/54] refactor: Enable role assignment module for subscription when resource group name is empty --- avm/ptn/authorization/pim-role-assignment/main.bicep | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/avm/ptn/authorization/pim-role-assignment/main.bicep b/avm/ptn/authorization/pim-role-assignment/main.bicep index 2bf9e8de25..1199702e57 100644 --- a/avm/ptn/authorization/pim-role-assignment/main.bicep +++ b/avm/ptn/authorization/pim-role-assignment/main.bicep @@ -103,7 +103,7 @@ module roleAssignment_mg 'modules/management-group.bicep' = if (empty(subscripti } } -/*module roleAssignment_sub 'modules/subscription.bicep' = if (!empty(subscriptionId) && empty(resourceGroupName)) { +module roleAssignment_sub 'modules/subscription.bicep' = if (!empty(subscriptionId) && empty(resourceGroupName)) { name: '${uniqueString(deployment().name, location)}-PimRoleAssignment-Sub-Module' scope: subscription(subscriptionId) params: { @@ -160,5 +160,3 @@ output scope string = empty(subscriptionId) && empty(resourceGroupName) : (!empty(subscriptionId) && empty(resourceGroupName) ? roleAssignment_sub.outputs.scope : roleAssignment_rg.outputs.scope) - - */ From 540ab56424551b4d5d57263003bed2d712706620 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Tue, 4 Feb 2025 09:15:26 +0200 Subject: [PATCH 23/54] fix: Update date format for role assignment schedule requests to ISO 8601 --- .../resourceRemoval/helper/Invoke-ResourceRemoval.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 index 6d2870d087..161e2fb5f8 100644 --- a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 +++ b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 @@ -112,7 +112,7 @@ function Invoke-ResourceRemoval { $pimRoleAssignmentPrinicpalId = $pimRoleAssignment.PrincipalId $pimRoleAssignmentRoleDefinitionId = $pimRoleAssignment.RoleDefinitionId $guid = New-Guid - $startTime = Get-Date -Format o + $startTime = Get-Date -Format 'yyyyMMddTHHmmssZ' $null = New-AzRoleEligibilityScheduleRequest -Name $guid ` -Scope $scope ` -ExpirationDuration PT1H ` @@ -129,7 +129,7 @@ function Invoke-ResourceRemoval { $pimRoleAssignmentPrinicpalId = $pimRoleAssignment.PrincipalId $pimRoleAssignmentRoleDefinitionId = $pimRoleAssignment.RoleDefinitionId $guid = New-Guid - $startTime = Get-Date -Format o + $startTime = Get-Date -Format 'yyyyMMddTHHmmssZ' $null = New-AzRoleAssignmentScheduleRequest -Name $guid ` -Scope $scope ` -ExpirationDuration PT1H ` From 8b0469f77c682fc9ee5448afe3ba7a2a9c593cfd Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Tue, 4 Feb 2025 09:19:44 +0200 Subject: [PATCH 24/54] fix: Correct date format in resource removal script to use ISO 8601 --- .../resourceRemoval/helper/Invoke-ResourceRemoval.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 index 161e2fb5f8..6d2870d087 100644 --- a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 +++ b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 @@ -112,7 +112,7 @@ function Invoke-ResourceRemoval { $pimRoleAssignmentPrinicpalId = $pimRoleAssignment.PrincipalId $pimRoleAssignmentRoleDefinitionId = $pimRoleAssignment.RoleDefinitionId $guid = New-Guid - $startTime = Get-Date -Format 'yyyyMMddTHHmmssZ' + $startTime = Get-Date -Format o $null = New-AzRoleEligibilityScheduleRequest -Name $guid ` -Scope $scope ` -ExpirationDuration PT1H ` @@ -129,7 +129,7 @@ function Invoke-ResourceRemoval { $pimRoleAssignmentPrinicpalId = $pimRoleAssignment.PrincipalId $pimRoleAssignmentRoleDefinitionId = $pimRoleAssignment.RoleDefinitionId $guid = New-Guid - $startTime = Get-Date -Format 'yyyyMMddTHHmmssZ' + $startTime = Get-Date -Format o $null = New-AzRoleAssignmentScheduleRequest -Name $guid ` -Scope $scope ` -ExpirationDuration PT1H ` From 70e348168b327f689ad92b565d24e86a27b490f9 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Tue, 4 Feb 2025 09:33:54 +0200 Subject: [PATCH 25/54] fix: Access first element of role assignment schedule requests to retrieve PrincipalId and RoleDefinitionId --- .../resourceRemoval/helper/Invoke-ResourceRemoval.ps1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 index 6d2870d087..d43dac9494 100644 --- a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 +++ b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 @@ -109,8 +109,8 @@ function Invoke-ResourceRemoval { $idElem = $ResourceId.Split('/') $scope = $idElem[0..($idElem.Count - 5)] -join '/' $pimRoleAssignment = Get-AzRoleEligibilityScheduleRequest -Scope $scope | Where-Object { $_.Justification -eq 'AVM test' -and $_.Status -eq 'Provisioned' } - $pimRoleAssignmentPrinicpalId = $pimRoleAssignment.PrincipalId - $pimRoleAssignmentRoleDefinitionId = $pimRoleAssignment.RoleDefinitionId + $pimRoleAssignmentPrinicpalId = $pimRoleAssignment[0].PrincipalId + $pimRoleAssignmentRoleDefinitionId = $pimRoleAssignment[0].RoleDefinitionId $guid = New-Guid $startTime = Get-Date -Format o $null = New-AzRoleEligibilityScheduleRequest -Name $guid ` @@ -126,8 +126,8 @@ function Invoke-ResourceRemoval { $idElem = $ResourceId.Split('/') $scope = $idElem[0..($idElem.Count - 5)] -join '/' $pimRoleAssignment = Get-AzRoleAssignmentScheduleRequest -Scope $scope | Where-Object { $_.Justification -eq 'AVM test' -and $_.Status -eq 'Provisioned' } - $pimRoleAssignmentPrinicpalId = $pimRoleAssignment.PrincipalId - $pimRoleAssignmentRoleDefinitionId = $pimRoleAssignment.RoleDefinitionId + $pimRoleAssignmentPrinicpalId = $pimRoleAssignment[0].PrincipalId + $pimRoleAssignmentRoleDefinitionId = $pimRoleAssignment[0].RoleDefinitionId $guid = New-Guid $startTime = Get-Date -Format o $null = New-AzRoleAssignmentScheduleRequest -Name $guid ` From c61c714f614e78d5139ffed155997ea44c81bc50 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Tue, 4 Feb 2025 09:35:15 +0200 Subject: [PATCH 26/54] fix: Add verbose logging for role assignment removal process --- .../resourceRemoval/helper/Invoke-ResourceRemoval.ps1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 index d43dac9494..c853df66bb 100644 --- a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 +++ b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 @@ -113,6 +113,7 @@ function Invoke-ResourceRemoval { $pimRoleAssignmentRoleDefinitionId = $pimRoleAssignment[0].RoleDefinitionId $guid = New-Guid $startTime = Get-Date -Format o + Write-Verbose "Removing assignment at scope $scope for principal $pimRoleAssignmentPrinicpalId" -Verbose $null = New-AzRoleEligibilityScheduleRequest -Name $guid ` -Scope $scope ` -ExpirationDuration PT1H ` @@ -130,6 +131,7 @@ function Invoke-ResourceRemoval { $pimRoleAssignmentRoleDefinitionId = $pimRoleAssignment[0].RoleDefinitionId $guid = New-Guid $startTime = Get-Date -Format o + Write-Verbose "Removing assignment at scope $scope for principal $pimRoleAssignmentPrinicpalId" -Verbose $null = New-AzRoleAssignmentScheduleRequest -Name $guid ` -Scope $scope ` -ExpirationDuration PT1H ` From 5e2ff708d453e3668088e9cbec821a582b01ebbe Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Tue, 4 Feb 2025 09:48:03 +0200 Subject: [PATCH 27/54] fix: Iterate over role assignment requests to handle multiple assignments during removal --- .../helper/Invoke-ResourceRemoval.ps1 | 56 +++++++++++-------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 index c853df66bb..48e7be0c04 100644 --- a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 +++ b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 @@ -109,36 +109,44 @@ function Invoke-ResourceRemoval { $idElem = $ResourceId.Split('/') $scope = $idElem[0..($idElem.Count - 5)] -join '/' $pimRoleAssignment = Get-AzRoleEligibilityScheduleRequest -Scope $scope | Where-Object { $_.Justification -eq 'AVM test' -and $_.Status -eq 'Provisioned' } - $pimRoleAssignmentPrinicpalId = $pimRoleAssignment[0].PrincipalId - $pimRoleAssignmentRoleDefinitionId = $pimRoleAssignment[0].RoleDefinitionId - $guid = New-Guid - $startTime = Get-Date -Format o - Write-Verbose "Removing assignment at scope $scope for principal $pimRoleAssignmentPrinicpalId" -Verbose - $null = New-AzRoleEligibilityScheduleRequest -Name $guid ` - -Scope $scope ` - -ExpirationDuration PT1H ` - -PrincipalId $pimRoleAssignmentPrinicpalId ` - -RequestType AdminRemove ` - -RoleDefinitionId $pimRoleAssignmentRoleDefinitionId ` - -ScheduleInfoStartDateTime $startTime + if ($pimRoleAssignment) { + $pimRoleAssignment | ForEach-Object { + $pimRoleAssignmentPrinicpalId = $_.PrincipalId + $pimRoleAssignmentRoleDefinitionId = $_.RoleDefinitionId + $guid = New-Guid + $startTime = Get-Date -Format o + Write-Verbose "Removing assignment at scope $scope for principal $pimRoleAssignmentPrinicpalId" -Verbose + $null = New-AzRoleEligibilityScheduleRequest -Name $guid ` + -Scope $scope ` + -ExpirationDuration PT1H ` + -PrincipalId $pimRoleAssignmentPrinicpalId ` + -RequestType AdminRemove ` + -RoleDefinitionId $pimRoleAssignmentRoleDefinitionId ` + -ScheduleInfoStartDateTime $startTime + } + } break } 'Microsoft.Authorization/roleAssignmentScheduleRequests' { $idElem = $ResourceId.Split('/') $scope = $idElem[0..($idElem.Count - 5)] -join '/' $pimRoleAssignment = Get-AzRoleAssignmentScheduleRequest -Scope $scope | Where-Object { $_.Justification -eq 'AVM test' -and $_.Status -eq 'Provisioned' } - $pimRoleAssignmentPrinicpalId = $pimRoleAssignment[0].PrincipalId - $pimRoleAssignmentRoleDefinitionId = $pimRoleAssignment[0].RoleDefinitionId - $guid = New-Guid - $startTime = Get-Date -Format o - Write-Verbose "Removing assignment at scope $scope for principal $pimRoleAssignmentPrinicpalId" -Verbose - $null = New-AzRoleAssignmentScheduleRequest -Name $guid ` - -Scope $scope ` - -ExpirationDuration PT1H ` - -PrincipalId $pimRoleAssignmentPrinicpalId ` - -RequestType AdminRemove ` - -RoleDefinitionId $pimRoleAssignmentRoleDefinitionId ` - -ScheduleInfoStartDateTime $startTime + if ($pimRoleAssignment) { + $pimRoleAssignment | ForEach-Object { + $pimRoleAssignmentPrinicpalId = $_.PrincipalId + $pimRoleAssignmentRoleDefinitionId = $_.RoleDefinitionId + $guid = New-Guid + $startTime = Get-Date -Format o + Write-Verbose "Removing assignment at scope $scope for principal $pimRoleAssignmentPrinicpalId" -Verbose + $null = New-AzRoleAssignmentScheduleRequest -Name $guid ` + -Scope $scope ` + -ExpirationDuration PT1H ` + -PrincipalId $pimRoleAssignmentPrinicpalId ` + -RequestType AdminRemove ` + -RoleDefinitionId $pimRoleAssignmentRoleDefinitionId ` + -ScheduleInfoStartDateTime $startTime + } + } break } 'Microsoft.RecoveryServices/vaults' { From 9601d2ccdb87f95cc832f52b30dce655d30a32b8 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Tue, 4 Feb 2025 10:52:45 +0200 Subject: [PATCH 28/54] fix: Update roleDefinitionIdOrName in test cases for consistency --- .../pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep | 2 +- .../pim-role-assignment/tests/e2e/rg.default/main.test.bicep | 2 +- .../pim-role-assignment/tests/e2e/rg.max/main.test.bicep | 2 +- .../pim-role-assignment/tests/e2e/sub.max/main.test.bicep | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep index 4a9825dfc1..14cf99c72b 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep @@ -39,7 +39,7 @@ module testDeployment '../../../main.bicep' = { } principalId: userPrinicipalId requestType: 'AdminAssign' - roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/18d7d88d-d35e-4fb5-a5c3-7773c20a72d9' + roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/a8889054-8d42-49c9-bc1c-52486c10e7cd' location: resourceLocation justification: 'AVM test' } diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep index fbd24c1c7c..1b18cccb4c 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep @@ -51,7 +51,7 @@ module testDeployment '../../../main.bicep' = { name: '${uniqueString(deployment().name)}-test-${serviceShort}' params: { principalId: userPrinicipalId - roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/a8889054-8d42-49c9-bc1c-52486c10e7cd' + roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c' location: resourceLocation subscriptionId: subscriptionId resourceGroupName: resourceGroup.outputs.name diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep index 151613604d..dfab84af0e 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep @@ -51,7 +51,7 @@ module testDeployment '../../../main.bicep' = { name: '${uniqueString(deployment().name)}-test-${serviceShort}' params: { principalId: userPrinicipalId - roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c' + roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/a8889054-8d42-49c9-bc1c-52486c10e7cd' location: resourceLocation subscriptionId: subscriptionId resourceGroupName: resourceGroup.outputs.name diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.max/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.max/main.test.bicep index e22a4a230b..0933399afa 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.max/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.max/main.test.bicep @@ -30,7 +30,7 @@ module testDeployment '../../../main.bicep' = { name: '${uniqueString(deployment().name)}-test-${serviceShort}-${namePrefix}' params: { principalId: userPrinicipalId - roleDefinitionIdOrName: 'Role Based Access Control Administrator' + roleDefinitionIdOrName: 'Owner' requestType: 'AdminAssign' pimRoleAssignmentType: { roleAssignmentType: 'Active' From 29208ecb0f20a241e46020936e24f62cf6bd30cc Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Tue, 4 Feb 2025 11:09:49 +0200 Subject: [PATCH 29/54] fix: Update roleDefinitionIdOrName values in test cases for accuracy --- .../pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep | 2 +- .../pim-role-assignment/tests/e2e/mg.max/main.test.bicep | 2 +- .../pim-role-assignment/tests/e2e/rg.max/main.test.bicep | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep index 14cf99c72b..f912a22e54 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep @@ -39,7 +39,7 @@ module testDeployment '../../../main.bicep' = { } principalId: userPrinicipalId requestType: 'AdminAssign' - roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/a8889054-8d42-49c9-bc1c-52486c10e7cd' + roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c' location: resourceLocation justification: 'AVM test' } diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep index 3e0d168ffa..e7639c8c5c 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep @@ -30,7 +30,7 @@ module testDeployment '../../../main.bicep' = { name: '${uniqueString(deployment().name)}-test-${namePrefix}-${serviceShort}' params: { principalId: userPrinicipalId - roleDefinitionIdOrName: 'Contributor' + roleDefinitionIdOrName: 'Owner' requestType: 'AdminAssign' location: resourceLocation pimRoleAssignmentType: { diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep index dfab84af0e..55d9a6cf3a 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep @@ -51,7 +51,7 @@ module testDeployment '../../../main.bicep' = { name: '${uniqueString(deployment().name)}-test-${serviceShort}' params: { principalId: userPrinicipalId - roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/a8889054-8d42-49c9-bc1c-52486c10e7cd' + roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635' location: resourceLocation subscriptionId: subscriptionId resourceGroupName: resourceGroup.outputs.name From b0633d2b674e512ab294b75a50946ff9b7531e5d Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Tue, 4 Feb 2025 11:21:56 +0200 Subject: [PATCH 30/54] fix: Update roleDefinitionIdOrName values in test cases to use 'Contributor' --- .../pim-role-assignment/tests/e2e/mg.max/main.test.bicep | 2 +- .../pim-role-assignment/tests/e2e/rg.max/main.test.bicep | 2 +- .../pim-role-assignment/tests/e2e/sub.max/main.test.bicep | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep index e7639c8c5c..3e0d168ffa 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep @@ -30,7 +30,7 @@ module testDeployment '../../../main.bicep' = { name: '${uniqueString(deployment().name)}-test-${namePrefix}-${serviceShort}' params: { principalId: userPrinicipalId - roleDefinitionIdOrName: 'Owner' + roleDefinitionIdOrName: 'Contributor' requestType: 'AdminAssign' location: resourceLocation pimRoleAssignmentType: { diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep index 55d9a6cf3a..151613604d 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep @@ -51,7 +51,7 @@ module testDeployment '../../../main.bicep' = { name: '${uniqueString(deployment().name)}-test-${serviceShort}' params: { principalId: userPrinicipalId - roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635' + roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c' location: resourceLocation subscriptionId: subscriptionId resourceGroupName: resourceGroup.outputs.name diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.max/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.max/main.test.bicep index 0933399afa..00e4951a72 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.max/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.max/main.test.bicep @@ -30,7 +30,7 @@ module testDeployment '../../../main.bicep' = { name: '${uniqueString(deployment().name)}-test-${serviceShort}-${namePrefix}' params: { principalId: userPrinicipalId - roleDefinitionIdOrName: 'Owner' + roleDefinitionIdOrName: 'Contributor' requestType: 'AdminAssign' pimRoleAssignmentType: { roleAssignmentType: 'Active' From bbe845218e1d8c79a20dbf6dec18b7942857cfbb Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Tue, 4 Feb 2025 11:51:23 +0200 Subject: [PATCH 31/54] fix: Update duration values in test cases from 'P10D' to 'P3H' --- .../pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep | 2 +- .../pim-role-assignment/tests/e2e/mg.max/main.test.bicep | 2 +- .../pim-role-assignment/tests/e2e/rg.default/main.test.bicep | 2 +- .../pim-role-assignment/tests/e2e/rg.max/main.test.bicep | 2 +- .../pim-role-assignment/tests/e2e/sub.default/main.test.bicep | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep index f912a22e54..dcd5c4aa5a 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep @@ -32,7 +32,7 @@ module testDeployment '../../../main.bicep' = { pimRoleAssignmentType: { roleAssignmentType: 'Eligible' scheduleInfo: { - duration: 'P10D' + duration: 'P3H' durationType: 'AfterDuration' startTime: startDateTime } diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep index 3e0d168ffa..ed5058f8aa 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep @@ -36,7 +36,7 @@ module testDeployment '../../../main.bicep' = { pimRoleAssignmentType: { roleAssignmentType: 'Active' scheduleInfo: { - duration: 'P10D' + duration: 'P3H' durationType: 'AfterDuration' startTime: startDateTime } diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep index 1b18cccb4c..12533b21c5 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep @@ -30,7 +30,7 @@ param userPrinicipalId string = '' param startDateTime string = utcNow() @description('Optional. The end date and time for the role assignment. Defaults to one year from the start date and time.') -param endDateTime string = dateTimeAdd(startDateTime, 'P1Y') +param endDateTime string = dateTimeAdd(startDateTime, 'P3H') // General resources // ================= diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep index 151613604d..c3b979e527 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep @@ -26,7 +26,7 @@ param subscriptionId string = '#_subscriptionId_#' param startDateTime string = utcNow() @description('Optional. The end date and time for the role assignment. Defaults to one year from the start date and time.') -param endDateTime string = dateTimeAdd(startDateTime, 'P1Y') +param endDateTime string = dateTimeAdd(startDateTime, 'P3H') @description('Required. Principle ID of the user. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'userPrinicipalId\'.') @secure() diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep index 442c79b7bb..f422ac3667 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep @@ -39,7 +39,7 @@ module testDeployment '../../../main.bicep' = { pimRoleAssignmentType: { roleAssignmentType: 'Eligible' scheduleInfo: { - duration: 'P10D' + duration: 'P3H' durationType: 'AfterDuration' startTime: startDateTime } From 484405fe34a4c54ad021e1c970d7561ab495c00a Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Tue, 4 Feb 2025 16:05:14 +0200 Subject: [PATCH 32/54] fix: Update role assignment GUID generation to include deployment name for consistency --- .../modules/management-group.bicep | 4 +- .../modules/resource-group.bicep | 4 +- .../modules/subscription.bicep | 4 +- .../helper/Invoke-ResourceRemoval.ps1 | 51 ++++++++----------- 4 files changed, 27 insertions(+), 36 deletions(-) diff --git a/avm/ptn/authorization/pim-role-assignment/modules/management-group.bicep b/avm/ptn/authorization/pim-role-assignment/modules/management-group.bicep index e6bb21414a..01d1c09bbd 100644 --- a/avm/ptn/authorization/pim-role-assignment/modules/management-group.bicep +++ b/avm/ptn/authorization/pim-role-assignment/modules/management-group.bicep @@ -72,7 +72,7 @@ var builtInRoleNames = { var roleDefinitionIdVar = (builtInRoleNames[?roleDefinitionIdOrName] ?? roleDefinitionIdOrName) resource pimEligibleRoleAssignment 'Microsoft.Authorization/roleEligibilityScheduleRequests@2022-04-01-preview' = if (pimRoleAssignmentType.roleAssignmentType == 'Eligible') { - name: guid(managementGroupId, roleDefinitionIdVar, principalId) + name: guid(deployment().name, managementGroupId, roleDefinitionIdVar, principalId) properties: { principalId: principalId roleDefinitionId: roleDefinitionIdVar @@ -110,7 +110,7 @@ resource pimEligibleRoleAssignment 'Microsoft.Authorization/roleEligibilitySched } resource pimActiveRoleAssignment 'Microsoft.Authorization/roleAssignmentScheduleRequests@2022-04-01-preview' = if (pimRoleAssignmentType.roleAssignmentType == 'Active') { - name: guid(managementGroupId, roleDefinitionIdVar, principalId) + name: guid(deployment().name, managementGroupId, roleDefinitionIdVar, principalId) properties: { principalId: principalId roleDefinitionId: roleDefinitionIdVar diff --git a/avm/ptn/authorization/pim-role-assignment/modules/resource-group.bicep b/avm/ptn/authorization/pim-role-assignment/modules/resource-group.bicep index d9dc00c6a9..0d0077ddfb 100644 --- a/avm/ptn/authorization/pim-role-assignment/modules/resource-group.bicep +++ b/avm/ptn/authorization/pim-role-assignment/modules/resource-group.bicep @@ -67,7 +67,7 @@ var builtInRoleNames = { var roleDefinitionIdVar = (builtInRoleNames[?roleDefinitionIdOrName] ?? roleDefinitionIdOrName) resource pimEligibleRoleAssignment 'Microsoft.Authorization/roleEligibilityScheduleRequests@2022-04-01-preview' = if (pimRoleAssignmentType.roleAssignmentType == 'Eligible') { - name: guid(subscriptionId, resourceGroupName, roleDefinitionIdVar, principalId) + name: guid(deployment().name, subscriptionId, resourceGroupName, roleDefinitionIdVar, principalId) properties: { roleDefinitionId: roleDefinitionIdVar principalId: principalId @@ -105,7 +105,7 @@ resource pimEligibleRoleAssignment 'Microsoft.Authorization/roleEligibilitySched } resource pimActiveRoleAssignment 'Microsoft.Authorization/roleAssignmentScheduleRequests@2022-04-01-preview' = if (pimRoleAssignmentType.roleAssignmentType == 'Active') { - name: guid(subscriptionId, resourceGroupName, roleDefinitionIdVar, principalId) + name: guid(deployment().name, subscriptionId, resourceGroupName, roleDefinitionIdVar, principalId) properties: { roleDefinitionId: roleDefinitionIdVar principalId: principalId diff --git a/avm/ptn/authorization/pim-role-assignment/modules/subscription.bicep b/avm/ptn/authorization/pim-role-assignment/modules/subscription.bicep index ca2b62166d..719c86a692 100644 --- a/avm/ptn/authorization/pim-role-assignment/modules/subscription.bicep +++ b/avm/ptn/authorization/pim-role-assignment/modules/subscription.bicep @@ -64,7 +64,7 @@ var builtInRoleNames = { var roleDefinitionIdVar = (builtInRoleNames[?roleDefinitionIdOrName] ?? roleDefinitionIdOrName) resource pimEligibleRoleAssignment 'Microsoft.Authorization/roleEligibilityScheduleRequests@2022-04-01-preview' = if (pimRoleAssignmentType.roleAssignmentType == 'Eligible') { - name: guid(subscriptionId, roleDefinitionIdVar, principalId) + name: guid(deployment().name, subscriptionId, roleDefinitionIdVar, principalId) properties: { principalId: principalId roleDefinitionId: roleDefinitionIdVar @@ -102,7 +102,7 @@ resource pimEligibleRoleAssignment 'Microsoft.Authorization/roleEligibilitySched } resource pimActiveRoleAssignment 'Microsoft.Authorization/roleAssignmentScheduleRequests@2022-04-01-preview' = if (pimRoleAssignmentType.roleAssignmentType == 'Active') { - name: guid(subscriptionId, roleDefinitionIdVar, principalId) + name: guid(deployment().name, subscriptionId, roleDefinitionIdVar, principalId) properties: { principalId: principalId roleDefinitionId: roleDefinitionIdVar diff --git a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 index 48e7be0c04..ae7a8d7f5b 100644 --- a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 +++ b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 @@ -108,44 +108,35 @@ function Invoke-ResourceRemoval { 'Microsoft.Authorization/roleEligibilityScheduleRequests' { $idElem = $ResourceId.Split('/') $scope = $idElem[0..($idElem.Count - 5)] -join '/' - $pimRoleAssignment = Get-AzRoleEligibilityScheduleRequest -Scope $scope | Where-Object { $_.Justification -eq 'AVM test' -and $_.Status -eq 'Provisioned' } + $pimRequestName = $idElem[-1] + $pimRoleAssignment = Get-AzRoleEligibilityScheduleRequest -Scope $scope -Name $pimRequestName if ($pimRoleAssignment) { - $pimRoleAssignment | ForEach-Object { - $pimRoleAssignmentPrinicpalId = $_.PrincipalId - $pimRoleAssignmentRoleDefinitionId = $_.RoleDefinitionId - $guid = New-Guid - $startTime = Get-Date -Format o - Write-Verbose "Removing assignment at scope $scope for principal $pimRoleAssignmentPrinicpalId" -Verbose - $null = New-AzRoleEligibilityScheduleRequest -Name $guid ` - -Scope $scope ` - -ExpirationDuration PT1H ` - -PrincipalId $pimRoleAssignmentPrinicpalId ` - -RequestType AdminRemove ` - -RoleDefinitionId $pimRoleAssignmentRoleDefinitionId ` - -ScheduleInfoStartDateTime $startTime - } + $pimRoleAssignmentPrinicpalId = $pimRoleAssignment.PrincipalId + $pimRoleAssignmentRoleDefinitionId = $pimRoleAssignment.RoleDefinitionId + $guid = New-Guid + $null = New-AzRoleEligibilityScheduleRequest -Name $guid ` + -Scope $scope ` + -PrincipalId $pimRoleAssignmentPrinicpalId ` + -RequestType AdminRemove ` + -RoleDefinitionId $pimRoleAssignmentRoleDefinitionId + } break } 'Microsoft.Authorization/roleAssignmentScheduleRequests' { $idElem = $ResourceId.Split('/') $scope = $idElem[0..($idElem.Count - 5)] -join '/' - $pimRoleAssignment = Get-AzRoleAssignmentScheduleRequest -Scope $scope | Where-Object { $_.Justification -eq 'AVM test' -and $_.Status -eq 'Provisioned' } + $pimRequestName = $idElem[-1] + $pimRoleAssignment = Get-AzRoleAssignmentScheduleRequest -Scope $scope -Name $pimRequestName if ($pimRoleAssignment) { - $pimRoleAssignment | ForEach-Object { - $pimRoleAssignmentPrinicpalId = $_.PrincipalId - $pimRoleAssignmentRoleDefinitionId = $_.RoleDefinitionId - $guid = New-Guid - $startTime = Get-Date -Format o - Write-Verbose "Removing assignment at scope $scope for principal $pimRoleAssignmentPrinicpalId" -Verbose - $null = New-AzRoleAssignmentScheduleRequest -Name $guid ` - -Scope $scope ` - -ExpirationDuration PT1H ` - -PrincipalId $pimRoleAssignmentPrinicpalId ` - -RequestType AdminRemove ` - -RoleDefinitionId $pimRoleAssignmentRoleDefinitionId ` - -ScheduleInfoStartDateTime $startTime - } + $pimRoleAssignmentPrinicpalId = $pimRoleAssignment.PrincipalId + $pimRoleAssignmentRoleDefinitionId = $pimRoleAssignment.RoleDefinitionId + $guid = New-Guid + $null = New-AzRoleAssignmentScheduleRequest -Name $guid ` + -Scope $scope ` + -PrincipalId $pimRoleAssignmentPrinicpalId ` + -RequestType AdminRemove ` + -RoleDefinitionId $pimRoleAssignmentRoleDefinitionId } break } From 68e01c7caac36b7be7c24c1f169398c2c42db98b Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Tue, 4 Feb 2025 16:09:07 +0200 Subject: [PATCH 33/54] fix: Update duration values in test cases from 'P3H' to 'P1D' --- .../pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep | 2 +- .../pim-role-assignment/tests/e2e/mg.max/main.test.bicep | 2 +- .../pim-role-assignment/tests/e2e/rg.default/main.test.bicep | 2 +- .../pim-role-assignment/tests/e2e/rg.max/main.test.bicep | 2 +- .../pim-role-assignment/tests/e2e/sub.default/main.test.bicep | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep index dcd5c4aa5a..2ae309a7bf 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep @@ -32,7 +32,7 @@ module testDeployment '../../../main.bicep' = { pimRoleAssignmentType: { roleAssignmentType: 'Eligible' scheduleInfo: { - duration: 'P3H' + duration: 'P1D' durationType: 'AfterDuration' startTime: startDateTime } diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep index ed5058f8aa..156a7f7f41 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep @@ -36,7 +36,7 @@ module testDeployment '../../../main.bicep' = { pimRoleAssignmentType: { roleAssignmentType: 'Active' scheduleInfo: { - duration: 'P3H' + duration: 'P1D' durationType: 'AfterDuration' startTime: startDateTime } diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep index 12533b21c5..7ed23d0642 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep @@ -30,7 +30,7 @@ param userPrinicipalId string = '' param startDateTime string = utcNow() @description('Optional. The end date and time for the role assignment. Defaults to one year from the start date and time.') -param endDateTime string = dateTimeAdd(startDateTime, 'P3H') +param endDateTime string = dateTimeAdd(startDateTime, 'P1D') // General resources // ================= diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep index c3b979e527..b89a69c0e3 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep @@ -26,7 +26,7 @@ param subscriptionId string = '#_subscriptionId_#' param startDateTime string = utcNow() @description('Optional. The end date and time for the role assignment. Defaults to one year from the start date and time.') -param endDateTime string = dateTimeAdd(startDateTime, 'P3H') +param endDateTime string = dateTimeAdd(startDateTime, 'P1D') @description('Required. Principle ID of the user. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'userPrinicipalId\'.') @secure() diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep index f422ac3667..81e6c0a4f8 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep @@ -39,7 +39,7 @@ module testDeployment '../../../main.bicep' = { pimRoleAssignmentType: { roleAssignmentType: 'Eligible' scheduleInfo: { - duration: 'P3H' + duration: 'P1D' durationType: 'AfterDuration' startTime: startDateTime } From 042849c22684ba567215fc78609433115f3480a0 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Tue, 4 Feb 2025 16:13:02 +0200 Subject: [PATCH 34/54] fix: Update duration values in test cases from 'P1D' to 'PT4H' --- .../pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep | 2 +- .../pim-role-assignment/tests/e2e/mg.max/main.test.bicep | 2 +- .../pim-role-assignment/tests/e2e/rg.default/main.test.bicep | 2 +- .../pim-role-assignment/tests/e2e/rg.max/main.test.bicep | 2 +- .../pim-role-assignment/tests/e2e/sub.default/main.test.bicep | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep index 2ae309a7bf..a018756e3d 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep @@ -32,7 +32,7 @@ module testDeployment '../../../main.bicep' = { pimRoleAssignmentType: { roleAssignmentType: 'Eligible' scheduleInfo: { - duration: 'P1D' + duration: 'PT4H' durationType: 'AfterDuration' startTime: startDateTime } diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep index 156a7f7f41..52f01b34c5 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep @@ -36,7 +36,7 @@ module testDeployment '../../../main.bicep' = { pimRoleAssignmentType: { roleAssignmentType: 'Active' scheduleInfo: { - duration: 'P1D' + duration: 'PT4H' durationType: 'AfterDuration' startTime: startDateTime } diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep index 7ed23d0642..a22ae26664 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep @@ -30,7 +30,7 @@ param userPrinicipalId string = '' param startDateTime string = utcNow() @description('Optional. The end date and time for the role assignment. Defaults to one year from the start date and time.') -param endDateTime string = dateTimeAdd(startDateTime, 'P1D') +param endDateTime string = dateTimeAdd(startDateTime, 'PT4H') // General resources // ================= diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep index b89a69c0e3..855c805d80 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep @@ -26,7 +26,7 @@ param subscriptionId string = '#_subscriptionId_#' param startDateTime string = utcNow() @description('Optional. The end date and time for the role assignment. Defaults to one year from the start date and time.') -param endDateTime string = dateTimeAdd(startDateTime, 'P1D') +param endDateTime string = dateTimeAdd(startDateTime, 'PT4H') @description('Required. Principle ID of the user. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'userPrinicipalId\'.') @secure() diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep index 81e6c0a4f8..651df5615b 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep @@ -39,7 +39,7 @@ module testDeployment '../../../main.bicep' = { pimRoleAssignmentType: { roleAssignmentType: 'Eligible' scheduleInfo: { - duration: 'P1D' + duration: 'PT4H' durationType: 'AfterDuration' startTime: startDateTime } From 4b0442ce962282ccfa2f13b95eb19acf919de43d Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Wed, 5 Feb 2025 12:23:49 +0200 Subject: [PATCH 35/54] fix: Add filter 'atScope()' to role assignment retrieval for accurate scoping --- .../resourceRemoval/helper/Invoke-ResourceRemoval.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 index ae7a8d7f5b..6fef94e76e 100644 --- a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 +++ b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 @@ -109,7 +109,7 @@ function Invoke-ResourceRemoval { $idElem = $ResourceId.Split('/') $scope = $idElem[0..($idElem.Count - 5)] -join '/' $pimRequestName = $idElem[-1] - $pimRoleAssignment = Get-AzRoleEligibilityScheduleRequest -Scope $scope -Name $pimRequestName + $pimRoleAssignment = Get-AzRoleEligibilityScheduleRequest -Scope $scope -Name $pimRequestName -Filter 'atScope()' if ($pimRoleAssignment) { $pimRoleAssignmentPrinicpalId = $pimRoleAssignment.PrincipalId $pimRoleAssignmentRoleDefinitionId = $pimRoleAssignment.RoleDefinitionId @@ -127,7 +127,7 @@ function Invoke-ResourceRemoval { $idElem = $ResourceId.Split('/') $scope = $idElem[0..($idElem.Count - 5)] -join '/' $pimRequestName = $idElem[-1] - $pimRoleAssignment = Get-AzRoleAssignmentScheduleRequest -Scope $scope -Name $pimRequestName + $pimRoleAssignment = Get-AzRoleAssignmentScheduleRequest -Scope $scope -Name $pimRequestName -Filter 'atScope()' if ($pimRoleAssignment) { $pimRoleAssignmentPrinicpalId = $pimRoleAssignment.PrincipalId $pimRoleAssignmentRoleDefinitionId = $pimRoleAssignment.RoleDefinitionId From c42cc2559da31668388b9bfe56965229ecfc81aa Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Wed, 5 Feb 2025 12:28:57 +0200 Subject: [PATCH 36/54] fix: Update role assignment retrieval filter from 'atScope()' to 'asRequestor()' for accuracy --- .../resourceRemoval/helper/Invoke-ResourceRemoval.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 index 6fef94e76e..e3db89bc87 100644 --- a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 +++ b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 @@ -109,7 +109,7 @@ function Invoke-ResourceRemoval { $idElem = $ResourceId.Split('/') $scope = $idElem[0..($idElem.Count - 5)] -join '/' $pimRequestName = $idElem[-1] - $pimRoleAssignment = Get-AzRoleEligibilityScheduleRequest -Scope $scope -Name $pimRequestName -Filter 'atScope()' + $pimRoleAssignment = Get-AzRoleEligibilityScheduleRequest -Scope $scope -Name $pimRequestName -Filter 'asRequestor()' if ($pimRoleAssignment) { $pimRoleAssignmentPrinicpalId = $pimRoleAssignment.PrincipalId $pimRoleAssignmentRoleDefinitionId = $pimRoleAssignment.RoleDefinitionId @@ -127,7 +127,7 @@ function Invoke-ResourceRemoval { $idElem = $ResourceId.Split('/') $scope = $idElem[0..($idElem.Count - 5)] -join '/' $pimRequestName = $idElem[-1] - $pimRoleAssignment = Get-AzRoleAssignmentScheduleRequest -Scope $scope -Name $pimRequestName -Filter 'atScope()' + $pimRoleAssignment = Get-AzRoleAssignmentScheduleRequest -Scope $scope -Name $pimRequestName -Filter 'asRequestor()' if ($pimRoleAssignment) { $pimRoleAssignmentPrinicpalId = $pimRoleAssignment.PrincipalId $pimRoleAssignmentRoleDefinitionId = $pimRoleAssignment.RoleDefinitionId From 4cd6cbba01fd884422a9f8045b0f05846c677012 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Wed, 5 Feb 2025 12:49:04 +0200 Subject: [PATCH 37/54] refactor: Remove outdated test files and update role assignment retrieval filter for consistency --- .../main.test.bicep | 0 .../tests/e2e/mg.max/main.test.bicep | 50 -------------- .../e2e/{rg.max => rg.active}/main.test.bicep | 0 .../tests/e2e/rg.default/main.test.bicep | 69 ------------------- .../main.test.bicep | 10 ++- .../tests/e2e/sub.max/main.test.bicep | 49 ------------- .../helper/Invoke-ResourceRemoval.ps1 | 6 +- 7 files changed, 8 insertions(+), 176 deletions(-) rename avm/ptn/authorization/pim-role-assignment/tests/e2e/{mg.defaults => mg.eligible}/main.test.bicep (100%) delete mode 100644 avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep rename avm/ptn/authorization/pim-role-assignment/tests/e2e/{rg.max => rg.active}/main.test.bicep (100%) delete mode 100644 avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep rename avm/ptn/authorization/pim-role-assignment/tests/e2e/{sub.default => sub.active.permenant}/main.test.bicep (82%) delete mode 100644 avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.max/main.test.bicep diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.eligible/main.test.bicep similarity index 100% rename from avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.defaults/main.test.bicep rename to avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.eligible/main.test.bicep diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep deleted file mode 100644 index 52f01b34c5..0000000000 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.max/main.test.bicep +++ /dev/null @@ -1,50 +0,0 @@ -targetScope = 'managementGroup' -metadata name = 'PIM Active Role Assignments (Management Group scope)' -metadata description = 'This module deploys a PIM Active Role Assignment at a Management Group scope using common parameters.' - -// ========== // -// Parameters // -// ========== // - -@description('Optional. The location to deploy resources to.') -param resourceLocation string = deployment().location - -@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') -param serviceShort string = 'pimmgmax' - -@description('Optional. A token to inject into the name of each resource.') -param namePrefix string = '#_namePrefix_#' - -@description('Required. Principle ID of the user. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'userPrinicipalId\'.') -@secure() -param userPrinicipalId string = '' - -@description('Optional. The start date and time for the role assignment. Defaults to the current date and time.') -param startDateTime string = utcNow() - -// ============== // -// Test Execution // -// ============== // - -module testDeployment '../../../main.bicep' = { - name: '${uniqueString(deployment().name)}-test-${namePrefix}-${serviceShort}' - params: { - principalId: userPrinicipalId - roleDefinitionIdOrName: 'Contributor' - requestType: 'AdminAssign' - location: resourceLocation - pimRoleAssignmentType: { - roleAssignmentType: 'Active' - scheduleInfo: { - duration: 'PT4H' - durationType: 'AfterDuration' - startTime: startDateTime - } - } - justification: 'AVM test' - ticketInfo: { - ticketNumber: '123456' - ticketSystem: 'system1' - } - } -} diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.active/main.test.bicep similarity index 100% rename from avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.max/main.test.bicep rename to avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.active/main.test.bicep diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep deleted file mode 100644 index a22ae26664..0000000000 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.default/main.test.bicep +++ /dev/null @@ -1,69 +0,0 @@ -targetScope = 'managementGroup' -metadata name = 'PIM Eligible Role Assignments (Resource Group scope)' -metadata description = 'This module deploys a PIM Eligible Role Assignment at a Resource Group scope using minimal parameters.' - -// ========== // -// Parameters // -// ========== // - -@description('Optional. The location to deploy resources to.') -param resourceLocation string = deployment().location - -@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') -param serviceShort string = 'pimrgmin' - -@description('Optional. A token to inject into the name of each resource.') -param namePrefix string = '#_namePrefix_#' - -@description('Optional. The name of the resource group to deploy for testing purposes.') -@maxLength(90) -param resourceGroupName string = 'dep-${namePrefix}-authorization.pimroleassignments-${serviceShort}-rg' - -@description('Optional. Subscription ID of the subscription to assign the RBAC role to. If no Resource Group name is provided, the module deploys at subscription level, therefore assigns the provided RBAC role to the subscription.') -param subscriptionId string = '#_subscriptionId_#' - -@description('Required. Principle ID of the user. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'userPrinicipalId\'.') -@secure() -param userPrinicipalId string = '' - -@description('Optional. The start date and time for the role assignment. Defaults to the current date and time.') -param startDateTime string = utcNow() - -@description('Optional. The end date and time for the role assignment. Defaults to one year from the start date and time.') -param endDateTime string = dateTimeAdd(startDateTime, 'PT4H') - -// General resources -// ================= -module resourceGroup 'br/public:avm/res/resources/resource-group:0.2.3' = { - scope: subscription('${subscriptionId}') - name: '${uniqueString(deployment().name, resourceLocation)}-resourceGroup' - params: { - name: resourceGroupName - location: resourceLocation - } -} - -// ============== // -// Test Execution // -// ============== // - -module testDeployment '../../../main.bicep' = { - name: '${uniqueString(deployment().name)}-test-${serviceShort}' - params: { - principalId: userPrinicipalId - roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c' - location: resourceLocation - subscriptionId: subscriptionId - resourceGroupName: resourceGroup.outputs.name - requestType: 'AdminAssign' - pimRoleAssignmentType: { - roleAssignmentType: 'Eligible' - scheduleInfo: { - durationType: 'AfterDateTime' - endDateTime: endDateTime - startTime: startDateTime - } - } - justification: 'AVM test' - } -} diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.active.permenant/main.test.bicep similarity index 82% rename from avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep rename to avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.active.permenant/main.test.bicep index 651df5615b..728d7f73db 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.default/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.active.permenant/main.test.bicep @@ -1,6 +1,6 @@ targetScope = 'managementGroup' -metadata name = 'PIM Eligible Role Assignments (Subscription scope)' -metadata description = 'This module deploys a PIM Eligible Role Assignment at a Subscription scope using minimal parameters.' +metadata name = 'PIM Active permanent Role Assignments (Subscription scope)' +metadata description = 'This module deploys a PIM permanent Role Assignment at a Subscription scope using minimal parameters.' // ========== // // Parameters // @@ -37,11 +37,9 @@ module testDeployment '../../../main.bicep' = { subscriptionId: subscriptionId requestType: 'AdminAssign' pimRoleAssignmentType: { - roleAssignmentType: 'Eligible' + roleAssignmentType: 'Active' scheduleInfo: { - duration: 'PT4H' - durationType: 'AfterDuration' - startTime: startDateTime + durationType: 'NoExpiration' } } justification: 'AVM test' diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.max/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.max/main.test.bicep deleted file mode 100644 index 00e4951a72..0000000000 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.max/main.test.bicep +++ /dev/null @@ -1,49 +0,0 @@ -targetScope = 'managementGroup' -metadata name = 'PIM Active permenant Role Assignments (Subscription scope)' -metadata description = 'This module deploys a PIM Active permenant Role Assignment at a Subscription scope using common parameters.' - -// ========== // -// Parameters // -// ========== // - -@description('Optional. The location to deploy resources to.') -param resourceLocation string = deployment().location - -@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') -param serviceShort string = 'pimsubmax' - -@description('Optional. A token to inject into the name of each resource.') -param namePrefix string = '#_namePrefix_#' - -@description('Optional. Subscription ID of the subscription to assign the RBAC role to. If no Resource Group name is provided, the module deploys at subscription level, therefore assigns the provided RBAC role to the subscription.') -param subscriptionId string = '#_subscriptionId_#' - -@description('Required. Principle ID of the user. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'userPrinicipalId\'.') -@secure() -param userPrinicipalId string = '' - -// ============== // -// Test Execution // -// ============== // - -module testDeployment '../../../main.bicep' = { - name: '${uniqueString(deployment().name)}-test-${serviceShort}-${namePrefix}' - params: { - principalId: userPrinicipalId - roleDefinitionIdOrName: 'Contributor' - requestType: 'AdminAssign' - pimRoleAssignmentType: { - roleAssignmentType: 'Active' - scheduleInfo: { - durationType: 'NoExpiration' - } - } - justification: 'AVM test' - ticketInfo: { - ticketNumber: '21312' - ticketSystem: ' System2' - } - location: resourceLocation - subscriptionId: subscriptionId - } -} diff --git a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 index e3db89bc87..187af3bed7 100644 --- a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 +++ b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 @@ -109,7 +109,8 @@ function Invoke-ResourceRemoval { $idElem = $ResourceId.Split('/') $scope = $idElem[0..($idElem.Count - 5)] -join '/' $pimRequestName = $idElem[-1] - $pimRoleAssignment = Get-AzRoleEligibilityScheduleRequest -Scope $scope -Name $pimRequestName -Filter 'asRequestor()' + #$pimRoleAssignment = Get-AzRoleEligibilityScheduleRequest -Scope $scope -Name $pimRequestName -Filter 'asRequestor()' + $pimRoleAssignment = Get-AzRoleEligibilityScheduleRequest -Scope $scope -Filter 'asRequestor()' if ($pimRoleAssignment) { $pimRoleAssignmentPrinicpalId = $pimRoleAssignment.PrincipalId $pimRoleAssignmentRoleDefinitionId = $pimRoleAssignment.RoleDefinitionId @@ -127,7 +128,8 @@ function Invoke-ResourceRemoval { $idElem = $ResourceId.Split('/') $scope = $idElem[0..($idElem.Count - 5)] -join '/' $pimRequestName = $idElem[-1] - $pimRoleAssignment = Get-AzRoleAssignmentScheduleRequest -Scope $scope -Name $pimRequestName -Filter 'asRequestor()' + #$pimRoleAssignment = Get-AzRoleAssignmentScheduleRequest -Scope $scope -Name $pimRequestName -Filter 'asRequestor()' + $pimRoleAssignment = Get-AzRoleAssignmentScheduleRequest -Scope $scope -Filter 'asRequestor()' if ($pimRoleAssignment) { $pimRoleAssignmentPrinicpalId = $pimRoleAssignment.PrincipalId $pimRoleAssignmentRoleDefinitionId = $pimRoleAssignment.RoleDefinitionId From eec22d9c9640f17a84da0b7bab670cccd2dde242 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Wed, 5 Feb 2025 12:59:36 +0200 Subject: [PATCH 38/54] fix: Update role assignment retrieval filter from 'asRequestor()' to 'asTarget()' for accuracy --- .../resourceRemoval/helper/Invoke-ResourceRemoval.ps1 | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 index 187af3bed7..4ec8f56f8a 100644 --- a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 +++ b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 @@ -110,7 +110,10 @@ function Invoke-ResourceRemoval { $scope = $idElem[0..($idElem.Count - 5)] -join '/' $pimRequestName = $idElem[-1] #$pimRoleAssignment = Get-AzRoleEligibilityScheduleRequest -Scope $scope -Name $pimRequestName -Filter 'asRequestor()' - $pimRoleAssignment = Get-AzRoleEligibilityScheduleRequest -Scope $scope -Filter 'asRequestor()' + $pimRoleAssignment = Get-AzRoleEligibilityScheduleRequest -Scope $scope -Filter 'asTarget()' + Write-Verbose "********Assignment: $pimRoleAssignment" -Verbose + Write-Verbose $pimRoleAssignment.PrincipalDisplayName -Verbose + Write-Verbose $pimRoleAssignment[0].PrincipalDisplayName -Verbose if ($pimRoleAssignment) { $pimRoleAssignmentPrinicpalId = $pimRoleAssignment.PrincipalId $pimRoleAssignmentRoleDefinitionId = $pimRoleAssignment.RoleDefinitionId @@ -129,7 +132,10 @@ function Invoke-ResourceRemoval { $scope = $idElem[0..($idElem.Count - 5)] -join '/' $pimRequestName = $idElem[-1] #$pimRoleAssignment = Get-AzRoleAssignmentScheduleRequest -Scope $scope -Name $pimRequestName -Filter 'asRequestor()' - $pimRoleAssignment = Get-AzRoleAssignmentScheduleRequest -Scope $scope -Filter 'asRequestor()' + $pimRoleAssignment = Get-AzRoleAssignmentScheduleRequest -Scope $scope -Filter 'asTarget()' + Write-Verbose "********Assignment: $pimRoleAssignment" -Verbose + Write-Verbose $pimRoleAssignment.PrincipalDisplayName -Verbose + Write-Verbose $pimRoleAssignment[0].PrincipalDisplayName -Verbose if ($pimRoleAssignment) { $pimRoleAssignmentPrinicpalId = $pimRoleAssignment.PrincipalId $pimRoleAssignmentRoleDefinitionId = $pimRoleAssignment.RoleDefinitionId From 439fefc446552c5ae18ef63098525aeb1eadf058 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Wed, 5 Feb 2025 13:10:11 +0200 Subject: [PATCH 39/54] fix: Update role assignment retrieval to include request name and scope for clarity --- .../helper/Invoke-ResourceRemoval.ps1 | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 index 4ec8f56f8a..ac6546b512 100644 --- a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 +++ b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 @@ -109,11 +109,9 @@ function Invoke-ResourceRemoval { $idElem = $ResourceId.Split('/') $scope = $idElem[0..($idElem.Count - 5)] -join '/' $pimRequestName = $idElem[-1] - #$pimRoleAssignment = Get-AzRoleEligibilityScheduleRequest -Scope $scope -Name $pimRequestName -Filter 'asRequestor()' - $pimRoleAssignment = Get-AzRoleEligibilityScheduleRequest -Scope $scope -Filter 'asTarget()' - Write-Verbose "********Assignment: $pimRoleAssignment" -Verbose - Write-Verbose $pimRoleAssignment.PrincipalDisplayName -Verbose - Write-Verbose $pimRoleAssignment[0].PrincipalDisplayName -Verbose + Write-Verbose "Request Name: $pimRequestName" -Verbose + Write-Verbose "Request scope: $scope" -Verbose + $pimRoleAssignment = Get-AzRoleEligibilityScheduleRequest -Scope $scope -Name $pimRequestName if ($pimRoleAssignment) { $pimRoleAssignmentPrinicpalId = $pimRoleAssignment.PrincipalId $pimRoleAssignmentRoleDefinitionId = $pimRoleAssignment.RoleDefinitionId @@ -131,11 +129,9 @@ function Invoke-ResourceRemoval { $idElem = $ResourceId.Split('/') $scope = $idElem[0..($idElem.Count - 5)] -join '/' $pimRequestName = $idElem[-1] - #$pimRoleAssignment = Get-AzRoleAssignmentScheduleRequest -Scope $scope -Name $pimRequestName -Filter 'asRequestor()' - $pimRoleAssignment = Get-AzRoleAssignmentScheduleRequest -Scope $scope -Filter 'asTarget()' - Write-Verbose "********Assignment: $pimRoleAssignment" -Verbose - Write-Verbose $pimRoleAssignment.PrincipalDisplayName -Verbose - Write-Verbose $pimRoleAssignment[0].PrincipalDisplayName -Verbose + Write-Verbose "Request Name: $pimRequestName" -Verbose + Write-Verbose "Request scope: $scope" -Verbose + $pimRoleAssignment = Get-AzRoleAssignmentScheduleRequest -Scope $scope -Name $pimRequestName if ($pimRoleAssignment) { $pimRoleAssignmentPrinicpalId = $pimRoleAssignment.PrincipalId $pimRoleAssignmentRoleDefinitionId = $pimRoleAssignment.RoleDefinitionId From a86a8c45e93113dcf71b5c0f1639379465bdbf64 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Wed, 5 Feb 2025 14:13:43 +0200 Subject: [PATCH 40/54] fix: Remove verbose logging for request name and scope in resource removal function --- .../resourceRemoval/helper/Invoke-ResourceRemoval.ps1 | 4 ---- 1 file changed, 4 deletions(-) diff --git a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 index ac6546b512..ae7a8d7f5b 100644 --- a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 +++ b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 @@ -109,8 +109,6 @@ function Invoke-ResourceRemoval { $idElem = $ResourceId.Split('/') $scope = $idElem[0..($idElem.Count - 5)] -join '/' $pimRequestName = $idElem[-1] - Write-Verbose "Request Name: $pimRequestName" -Verbose - Write-Verbose "Request scope: $scope" -Verbose $pimRoleAssignment = Get-AzRoleEligibilityScheduleRequest -Scope $scope -Name $pimRequestName if ($pimRoleAssignment) { $pimRoleAssignmentPrinicpalId = $pimRoleAssignment.PrincipalId @@ -129,8 +127,6 @@ function Invoke-ResourceRemoval { $idElem = $ResourceId.Split('/') $scope = $idElem[0..($idElem.Count - 5)] -join '/' $pimRequestName = $idElem[-1] - Write-Verbose "Request Name: $pimRequestName" -Verbose - Write-Verbose "Request scope: $scope" -Verbose $pimRoleAssignment = Get-AzRoleAssignmentScheduleRequest -Scope $scope -Name $pimRequestName if ($pimRoleAssignment) { $pimRoleAssignmentPrinicpalId = $pimRoleAssignment.PrincipalId From 079f7d247e74b5dcad75b01b29222b5a0813a64d Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Tue, 11 Feb 2025 12:05:15 +0200 Subject: [PATCH 41/54] ``` fix: Addressed issues in the deployment process for improved stability ``` --- .../tests/e2e/mg.eligible/main.test.bicep | 2 +- .../pim-role-assignment/tests/e2e/rg.active/main.test.bicep | 2 +- .../tests/e2e/sub.active.permenant/main.test.bicep | 5 +---- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.eligible/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.eligible/main.test.bicep index a018756e3d..3ab120fe06 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.eligible/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.eligible/main.test.bicep @@ -39,7 +39,7 @@ module testDeployment '../../../main.bicep' = { } principalId: userPrinicipalId requestType: 'AdminAssign' - roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c' + roleDefinitionIdOrName: 'Role Based Access Control Administrator' location: resourceLocation justification: 'AVM test' } diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.active/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.active/main.test.bicep index 855c805d80..934cdb84fa 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.active/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.active/main.test.bicep @@ -51,7 +51,7 @@ module testDeployment '../../../main.bicep' = { name: '${uniqueString(deployment().name)}-test-${serviceShort}' params: { principalId: userPrinicipalId - roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c' + roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/f58310d9-a9f6-439a-9e8d-f62e7b41a168' location: resourceLocation subscriptionId: subscriptionId resourceGroupName: resourceGroup.outputs.name diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.active.permenant/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.active.permenant/main.test.bicep index 728d7f73db..81137c969f 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.active.permenant/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.active.permenant/main.test.bicep @@ -19,9 +19,6 @@ param subscriptionId string = '#_subscriptionId_#' @secure() param userPrinicipalId string = '' -@description('Optional. The start date and time for the role assignment. Defaults to the current date and time.') -param startDateTime string = utcNow() - // ============== // // Test Execution // // ============== // @@ -32,7 +29,7 @@ module testDeployment '../../../main.bicep' = { principalId: userPrinicipalId roleDefinitionIdOrName: subscriptionResourceId( 'Microsoft.Authorization/roleDefinitions', - 'b24988ac-6180-42a0-ab88-20f7382dd24c' + 'f58310d9-a9f6-439a-9e8d-f62e7b41a168' ) subscriptionId: subscriptionId requestType: 'AdminAssign' From b3185f85465e592e5d53d0df39f76b4bb0c5e6a2 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Tue, 11 Feb 2025 12:15:55 +0200 Subject: [PATCH 42/54] ``` No code changes detected. ``` --- .../resourceRemoval/helper/Invoke-ResourceRemoval.ps1 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 index ae7a8d7f5b..ef0421fa6c 100644 --- a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 +++ b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 @@ -114,6 +114,8 @@ function Invoke-ResourceRemoval { $pimRoleAssignmentPrinicpalId = $pimRoleAssignment.PrincipalId $pimRoleAssignmentRoleDefinitionId = $pimRoleAssignment.RoleDefinitionId $guid = New-Guid + # PIM role assignments cannot be removed before 5 minutes from being created. Waiting for 4 minutes + Start-Sleep -Seconds 240 $null = New-AzRoleEligibilityScheduleRequest -Name $guid ` -Scope $scope ` -PrincipalId $pimRoleAssignmentPrinicpalId ` @@ -132,6 +134,8 @@ function Invoke-ResourceRemoval { $pimRoleAssignmentPrinicpalId = $pimRoleAssignment.PrincipalId $pimRoleAssignmentRoleDefinitionId = $pimRoleAssignment.RoleDefinitionId $guid = New-Guid + # PIM role assignments cannot be removed before 5 minutes from being created. Waiting for 4 minutes + Start-Sleep -Seconds 240 $null = New-AzRoleAssignmentScheduleRequest -Name $guid ` -Scope $scope ` -PrincipalId $pimRoleAssignmentPrinicpalId ` From e3eb0a8ac836458a28b556314b83ef774003ca62 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Tue, 11 Feb 2025 12:27:42 +0200 Subject: [PATCH 43/54] fix: Updated sleep duration for PIM role assignment removal to 5 minutes --- .../resourceRemoval/helper/Invoke-ResourceRemoval.ps1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 index ef0421fa6c..0822520b94 100644 --- a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 +++ b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 @@ -114,8 +114,8 @@ function Invoke-ResourceRemoval { $pimRoleAssignmentPrinicpalId = $pimRoleAssignment.PrincipalId $pimRoleAssignmentRoleDefinitionId = $pimRoleAssignment.RoleDefinitionId $guid = New-Guid - # PIM role assignments cannot be removed before 5 minutes from being created. Waiting for 4 minutes - Start-Sleep -Seconds 240 + # PIM role assignments cannot be removed before 5 minutes from being created. Waiting for 5 minutes + Start-Sleep -Seconds 300 $null = New-AzRoleEligibilityScheduleRequest -Name $guid ` -Scope $scope ` -PrincipalId $pimRoleAssignmentPrinicpalId ` @@ -134,8 +134,8 @@ function Invoke-ResourceRemoval { $pimRoleAssignmentPrinicpalId = $pimRoleAssignment.PrincipalId $pimRoleAssignmentRoleDefinitionId = $pimRoleAssignment.RoleDefinitionId $guid = New-Guid - # PIM role assignments cannot be removed before 5 minutes from being created. Waiting for 4 minutes - Start-Sleep -Seconds 240 + # PIM role assignments cannot be removed before 5 minutes from being created. Waiting for 5 minutes + Start-Sleep -Seconds 300 $null = New-AzRoleAssignmentScheduleRequest -Name $guid ` -Scope $scope ` -PrincipalId $pimRoleAssignmentPrinicpalId ` From e1f6186d8a7a956fdd140102bbe243ee6f098949 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Tue, 11 Feb 2025 12:34:17 +0200 Subject: [PATCH 44/54] waiting message --- .../resourceRemoval/helper/Invoke-ResourceRemoval.ps1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 index 0822520b94..92e293cb49 100644 --- a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 +++ b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 @@ -115,6 +115,7 @@ function Invoke-ResourceRemoval { $pimRoleAssignmentRoleDefinitionId = $pimRoleAssignment.RoleDefinitionId $guid = New-Guid # PIM role assignments cannot be removed before 5 minutes from being created. Waiting for 5 minutes + Write-Verbose 'Waiting for 5 minutes before removing PIM role assignment' -Verbose Start-Sleep -Seconds 300 $null = New-AzRoleEligibilityScheduleRequest -Name $guid ` -Scope $scope ` @@ -135,6 +136,7 @@ function Invoke-ResourceRemoval { $pimRoleAssignmentRoleDefinitionId = $pimRoleAssignment.RoleDefinitionId $guid = New-Guid # PIM role assignments cannot be removed before 5 minutes from being created. Waiting for 5 minutes + Write-Verbose 'Waiting for 5 minutes before removing PIM role assignment' -Verbose Start-Sleep -Seconds 300 $null = New-AzRoleAssignmentScheduleRequest -Name $guid ` -Scope $scope ` From e52b5440f67ac2e13d231ebbe63b52769b319e18 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Tue, 11 Feb 2025 12:43:59 +0200 Subject: [PATCH 45/54] ``` No code changes made. ``` --- .../pim-role-assignment/README.md | 406 +------ .../pim-role-assignment/main.json | 1019 ++++++++++++++++- 2 files changed, 1045 insertions(+), 380 deletions(-) diff --git a/avm/ptn/authorization/pim-role-assignment/README.md b/avm/ptn/authorization/pim-role-assignment/README.md index af77f755a8..c8dbf4f5dc 100644 --- a/avm/ptn/authorization/pim-role-assignment/README.md +++ b/avm/ptn/authorization/pim-role-assignment/README.md @@ -26,11 +26,8 @@ The following section provides usage examples for the module, which were used to >**Note**: To reference the module, please use the following syntax `br/public:avm/ptn/authorization/pim-role-assignment:`. - [ PIM Eligible Role Assignments (Management Group scope)](#example-1-pim-eligible-role-assignments-management-group-scope) -- [PIM Active Role Assignments (Management Group scope)](#example-2-pim-active-role-assignments-management-group-scope) -- [PIM Eligible Role Assignments (Resource Group scope)](#example-3-pim-eligible-role-assignments-resource-group-scope) -- [PIM Active Role Assignments (Resource Group)](#example-4-pim-active-role-assignments-resource-group) -- [PIM Eligible Role Assignments (Subscription scope)](#example-5-pim-eligible-role-assignments-subscription-scope) -- [PIM Active permenant Role Assignments (Subscription scope)](#example-6-pim-active-permenant-role-assignments-subscription-scope) +- [PIM Active Role Assignments (Resource Group)](#example-2-pim-active-role-assignments-resource-group) +- [PIM Active permanent Role Assignments (Subscription scope)](#example-3-pim-active-permanent-role-assignments-subscription-scope) ### Example 1: _ PIM Eligible Role Assignments (Management Group scope)_ @@ -49,15 +46,16 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:' } } principalId: '' requestType: 'AdminAssign' - roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/18d7d88d-d35e-4fb5-a5c3-7773c20a72d9' + roleDefinitionIdOrName: 'Role Based Access Control Administrator' // Non-required parameters + justification: 'AVM test' location: '' } } @@ -80,7 +78,7 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:" } @@ -93,238 +91,14 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:" - } - } -} -``` - -
-

- -

- -via Bicep parameters file - -```bicep-params -using 'br/public:avm/ptn/authorization/pim-role-assignment:' - -// Required parameters -param pimRoleAssignmentType = { - roleAssignmentType: 'Eligible' - scheduleInfo: { - duration: 'P10D' - durationType: 'AfterDuration' - startTime: '' - } -} -param principalId = '' -param requestType = 'AdminAssign' -param roleDefinitionIdOrName = '/providers/Microsoft.Authorization/roleDefinitions/18d7d88d-d35e-4fb5-a5c3-7773c20a72d9' -// Non-required parameters -param location = '' -``` - -
-

- -### Example 2: _PIM Active Role Assignments (Management Group scope)_ - -This module deploys a PIM Active Role Assignment at a Management Group scope using common parameters. - - -

- -via Bicep module - -```bicep -module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:' = { - name: 'pimRoleAssignmentDeployment' - params: { - // Required parameters - pimRoleAssignmentType: { - roleAssignmentType: 'Active' - scheduleInfo: { - duration: 'P10D' - durationType: 'AfterDuration' - startTime: '' - } - } - principalId: '' - requestType: 'AdminAssign' - roleDefinitionIdOrName: 'Contributor' - // Non-required parameters - justification: 'Justification for the role eligibility' - location: '' - ticketInfo: { - ticketNumber: '123456' - ticketSystem: 'system1' - } - } -} -``` - -
-

- -

- -via JSON parameters file - -```json -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", - "contentVersion": "1.0.0.0", - "parameters": { - // Required parameters - "pimRoleAssignmentType": { - "value": { - "roleAssignmentType": "Active", - "scheduleInfo": { - "duration": "P10D", - "durationType": "AfterDuration", - "startTime": "" - } - } - }, - "principalId": { - "value": "" - }, - "requestType": { - "value": "AdminAssign" - }, - "roleDefinitionIdOrName": { - "value": "Contributor" + "value": "Role Based Access Control Administrator" }, // Non-required parameters "justification": { - "value": "Justification for the role eligibility" + "value": "AVM test" }, "location": { "value": "" - }, - "ticketInfo": { - "value": { - "ticketNumber": "123456", - "ticketSystem": "system1" - } - } - } -} -``` - -
-

- -

- -via Bicep parameters file - -```bicep-params -using 'br/public:avm/ptn/authorization/pim-role-assignment:' - -// Required parameters -param pimRoleAssignmentType = { - roleAssignmentType: 'Active' - scheduleInfo: { - duration: 'P10D' - durationType: 'AfterDuration' - startTime: '' - } -} -param principalId = '' -param requestType = 'AdminAssign' -param roleDefinitionIdOrName = 'Contributor' -// Non-required parameters -param justification = 'Justification for the role eligibility' -param location = '' -param ticketInfo = { - ticketNumber: '123456' - ticketSystem: 'system1' -} -``` - -
-

- -### Example 3: _PIM Eligible Role Assignments (Resource Group scope)_ - -This module deploys a PIM Eligible Role Assignment at a Resource Group scope using minimal parameters. - - -

- -via Bicep module - -```bicep -module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:' = { - name: 'pimRoleAssignmentDeployment' - params: { - // Required parameters - pimRoleAssignmentType: { - roleAssignmentType: 'Eligible' - scheduleInfo: { - durationType: 'AfterDateTime' - endDateTime: '' - startTime: '' - } - } - principalId: '' - requestType: 'AdminAssign' - roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11' - // Non-required parameters - location: '' - resourceGroupName: '' - subscriptionId: '' - } -} -``` - -
-

- -

- -via JSON parameters file - -```json -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", - "contentVersion": "1.0.0.0", - "parameters": { - // Required parameters - "pimRoleAssignmentType": { - "value": { - "roleAssignmentType": "Eligible", - "scheduleInfo": { - "durationType": "AfterDateTime", - "endDateTime": "", - "startTime": "" - } - } - }, - "principalId": { - "value": "" - }, - "requestType": { - "value": "AdminAssign" - }, - "roleDefinitionIdOrName": { - "value": "/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11" - }, - // Non-required parameters - "location": { - "value": "" - }, - "resourceGroupName": { - "value": "" - }, - "subscriptionId": { - "value": "" } } } @@ -344,24 +118,23 @@ using 'br/public:avm/ptn/authorization/pim-role-assignment:' param pimRoleAssignmentType = { roleAssignmentType: 'Eligible' scheduleInfo: { - durationType: 'AfterDateTime' - endDateTime: '' + duration: 'PT4H' + durationType: 'AfterDuration' startTime: '' } } param principalId = '' param requestType = 'AdminAssign' -param roleDefinitionIdOrName = '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11' +param roleDefinitionIdOrName = 'Role Based Access Control Administrator' // Non-required parameters +param justification = 'AVM test' param location = '' -param resourceGroupName = '' -param subscriptionId = '' ```

-### Example 4: _PIM Active Role Assignments (Resource Group)_ +### Example 2: _PIM Active Role Assignments (Resource Group)_ This module deploys a PIM Active Role Assignment at a Resource Group scope using common parameters. @@ -385,9 +158,9 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:' requestType: 'AdminAssign' - roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7' + roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/f58310d9-a9f6-439a-9e8d-f62e7b41a168' // Non-required parameters - justification: 'Justification for role eligibility' + justification: 'AVM test' location: '' resourceGroupName: '' subscriptionId: '' @@ -429,11 +202,11 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:" @@ -475,9 +248,9 @@ param pimRoleAssignmentType = { } param principalId = '' param requestType = 'AdminAssign' -param roleDefinitionIdOrName = '/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7' +param roleDefinitionIdOrName = '/providers/Microsoft.Authorization/roleDefinitions/f58310d9-a9f6-439a-9e8d-f62e7b41a168' // Non-required parameters -param justification = 'Justification for role eligibility' +param justification = 'AVM test' param location = '' param resourceGroupName = '' param subscriptionId = '' @@ -490,109 +263,9 @@ param ticketInfo = {

-### Example 5: _PIM Eligible Role Assignments (Subscription scope)_ +### Example 3: _PIM Active permanent Role Assignments (Subscription scope)_ -This module deploys a PIM Eligible Role Assignment at a Subscription scope using minimal parameters. - - -

- -via Bicep module - -```bicep -module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:' = { - name: 'pimRoleAssignmentDeployment' - params: { - // Required parameters - pimRoleAssignmentType: { - roleAssignmentType: 'Eligible' - scheduleInfo: { - duration: 'P10D' - durationType: 'AfterDuration' - startTime: '' - } - } - principalId: '' - requestType: 'AdminAssign' - roleDefinitionIdOrName: '' - // Non-required parameters - subscriptionId: '' - } -} -``` - -
-

- -

- -via JSON parameters file - -```json -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", - "contentVersion": "1.0.0.0", - "parameters": { - // Required parameters - "pimRoleAssignmentType": { - "value": { - "roleAssignmentType": "Eligible", - "scheduleInfo": { - "duration": "P10D", - "durationType": "AfterDuration", - "startTime": "" - } - } - }, - "principalId": { - "value": "" - }, - "requestType": { - "value": "AdminAssign" - }, - "roleDefinitionIdOrName": { - "value": "" - }, - // Non-required parameters - "subscriptionId": { - "value": "" - } - } -} -``` - -
-

- -

- -via Bicep parameters file - -```bicep-params -using 'br/public:avm/ptn/authorization/pim-role-assignment:' - -// Required parameters -param pimRoleAssignmentType = { - roleAssignmentType: 'Eligible' - scheduleInfo: { - duration: 'P10D' - durationType: 'AfterDuration' - startTime: '' - } -} -param principalId = '' -param requestType = 'AdminAssign' -param roleDefinitionIdOrName = '' -// Non-required parameters -param subscriptionId = '' -``` - -
-

- -### Example 6: _PIM Active permenant Role Assignments (Subscription scope)_ - -This module deploys a PIM Active permenant Role Assignment at a Subscription scope using common parameters. +This module deploys a PIM permanent Role Assignment at a Subscription scope using minimal parameters.

@@ -612,15 +285,10 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:' requestType: 'AdminAssign' - roleDefinitionIdOrName: 'Reader' + roleDefinitionIdOrName: '' // Non-required parameters - justification: 'Justification for role assignment' - location: '' + justification: 'AVM test' subscriptionId: '' - ticketInfo: { - ticketNumber: '21312' - ticketSystem: ' System2' - } } } ``` @@ -653,23 +321,14 @@ module pimRoleAssignment 'br/public:avm/ptn/authorization/pim-role-assignment:" }, // Non-required parameters "justification": { - "value": "Justification for role assignment" - }, - "location": { - "value": "" + "value": "AVM test" }, "subscriptionId": { "value": "" - }, - "ticketInfo": { - "value": { - "ticketNumber": "21312", - "ticketSystem": " System2" - } } } } @@ -694,15 +353,10 @@ param pimRoleAssignmentType = { } param principalId = '' param requestType = 'AdminAssign' -param roleDefinitionIdOrName = 'Reader' +param roleDefinitionIdOrName = '' // Non-required parameters -param justification = 'Justification for role assignment' -param location = '' +param justification = 'AVM test' param subscriptionId = '' -param ticketInfo = { - ticketNumber: '21312' - ticketSystem: ' System2' -} ```
@@ -911,7 +565,11 @@ The ticket system name for the role eligibility assignment. ## Outputs -_None_ +| Output | Type | Description | +| :-- | :-- | :-- | +| `name` | string | The GUID of the PIM Role Assignment. | +| `resourceId` | string | The resource ID of the PIM Role Assignment. | +| `scope` | string | The scope this PIM Role Assignment applies to. | ## Data Collection diff --git a/avm/ptn/authorization/pim-role-assignment/main.json b/avm/ptn/authorization/pim-role-assignment/main.json index 4e546affef..0390d60761 100644 --- a/avm/ptn/authorization/pim-role-assignment/main.json +++ b/avm/ptn/authorization/pim-role-assignment/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.33.93.31351", - "templateHash": "2945332709067203601" + "templateHash": "15483717186393769028" }, "name": "", "description": "" @@ -468,7 +468,7 @@ "_generator": { "name": "bicep", "version": "0.33.93.31351", - "templateHash": "2970460738165571757" + "templateHash": "6801983411045663491" }, "name": " PIM Role Assignments (Management Group scope)", "description": "This module deploys a PIM Role Assignment at a Management Group scope." @@ -838,7 +838,7 @@ "condition": "[equals(parameters('pimRoleAssignmentType').roleAssignmentType, 'Eligible')]", "type": "Microsoft.Authorization/roleEligibilityScheduleRequests", "apiVersion": "2022-04-01-preview", - "name": "[guid(parameters('managementGroupId'), variables('roleDefinitionIdVar'), parameters('principalId'))]", + "name": "[guid(deployment().name, parameters('managementGroupId'), variables('roleDefinitionIdVar'), parameters('principalId'))]", "properties": { "principalId": "[parameters('principalId')]", "roleDefinitionId": "[variables('roleDefinitionIdVar')]", @@ -856,7 +856,7 @@ "condition": "[equals(parameters('pimRoleAssignmentType').roleAssignmentType, 'Active')]", "type": "Microsoft.Authorization/roleAssignmentScheduleRequests", "apiVersion": "2022-04-01-preview", - "name": "[guid(parameters('managementGroupId'), variables('roleDefinitionIdVar'), parameters('principalId'))]", + "name": "[guid(deployment().name, parameters('managementGroupId'), variables('roleDefinitionIdVar'), parameters('principalId'))]", "properties": { "principalId": "[parameters('principalId')]", "roleDefinitionId": "[variables('roleDefinitionIdVar')]", @@ -877,14 +877,14 @@ "metadata": { "description": "The GUID of the PIM Role Assignment." }, - "value": "[if(equals(parameters('pimRoleAssignmentType').roleAssignmentType, 'Eligible'), guid(parameters('managementGroupId'), variables('roleDefinitionIdVar'), parameters('principalId')), guid(parameters('managementGroupId'), variables('roleDefinitionIdVar'), parameters('principalId')))]" + "value": "[if(equals(parameters('pimRoleAssignmentType').roleAssignmentType, 'Eligible'), guid(deployment().name, parameters('managementGroupId'), variables('roleDefinitionIdVar'), parameters('principalId')), guid(deployment().name, parameters('managementGroupId'), variables('roleDefinitionIdVar'), parameters('principalId')))]" }, "resourceId": { "type": "string", "metadata": { "description": "The resource ID of the PIM Role Assignment." }, - "value": "[if(equals(parameters('pimRoleAssignmentType').roleAssignmentType, 'Eligible'), extensionResourceId(managementGroup().id, 'Microsoft.Authorization/roleEligibilityScheduleRequests', guid(parameters('managementGroupId'), variables('roleDefinitionIdVar'), parameters('principalId'))), extensionResourceId(managementGroup().id, 'Microsoft.Authorization/roleAssignmentScheduleRequests', guid(parameters('managementGroupId'), variables('roleDefinitionIdVar'), parameters('principalId'))))]" + "value": "[if(equals(parameters('pimRoleAssignmentType').roleAssignmentType, 'Eligible'), extensionResourceId(managementGroup().id, 'Microsoft.Authorization/roleEligibilityScheduleRequests', guid(deployment().name, parameters('managementGroupId'), variables('roleDefinitionIdVar'), parameters('principalId'))), extensionResourceId(managementGroup().id, 'Microsoft.Authorization/roleAssignmentScheduleRequests', guid(deployment().name, parameters('managementGroupId'), variables('roleDefinitionIdVar'), parameters('principalId'))))]" }, "scope": { "type": "string", @@ -896,6 +896,1013 @@ } } } + }, + "roleAssignment_sub": { + "condition": "[and(not(empty(parameters('subscriptionId'))), empty(parameters('resourceGroupName')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-PimRoleAssignment-Sub-Module', uniqueString(deployment().name, parameters('location')))]", + "subscriptionId": "[parameters('subscriptionId')]", + "location": "[deployment().location]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "roleDefinitionIdOrName": { + "value": "[parameters('roleDefinitionIdOrName')]" + }, + "principalId": { + "value": "[parameters('principalId')]" + }, + "subscriptionId": { + "value": "[parameters('subscriptionId')]" + }, + "requestType": { + "value": "[parameters('requestType')]" + }, + "justification": { + "value": "[parameters('justification')]" + }, + "targetRoleEligibilityScheduleId": { + "value": "[parameters('targetRoleEligibilityScheduleId')]" + }, + "targetRoleEligibilityScheduleInstanceId": { + "value": "[parameters('targetRoleEligibilityScheduleInstanceId')]" + }, + "ticketInfo": { + "value": "[parameters('ticketInfo')]" + }, + "conditionVersion": { + "value": "[parameters('conditionVersion')]" + }, + "condition": "[if(not(empty(parameters('condition'))), createObject('value', parameters('condition')), createObject('value', ''))]", + "pimRoleAssignmentType": { + "value": "[parameters('pimRoleAssignmentType')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.33.93.31351", + "templateHash": "6532334215185833316" + }, + "name": "PIM Role Assignments (Subscription scope)", + "description": "This module deploys a PIM Role Assignment at a Subscription scope." + }, + "definitions": { + "_1.permenantRoleAssignmentScheduleType": { + "type": "object", + "properties": { + "durationType": { + "type": "string", + "allowedValues": [ + "NoExpiration" + ], + "metadata": { + "description": "Required. The type of the duration." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "definitions.bicep" + } + } + }, + "_1.pimActiveRoleAssignmentType": { + "type": "object", + "properties": { + "roleAssignmentType": { + "type": "string", + "allowedValues": [ + "Active" + ], + "metadata": { + "description": "Required. The type of the role assignment." + } + }, + "linkedRoleEligibilityScheduleId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The linked role eligibility schedule id - to activate an eligibility." + } + }, + "targetRoleAssignmentScheduleId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The resultant role assignment schedule id or the role assignment schedule id being updated." + } + }, + "targetRoleAssignmentScheduleInstanceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The role assignment schedule instance id being updated." + } + }, + "scheduleInfo": { + "$ref": "#/definitions/_1.roleAssignmentScheduleType", + "metadata": { + "description": "Required. The schedule information for the role assignment." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "definitions.bicep" + } + } + }, + "_1.pimEligibleRoleAssignmentType": { + "type": "object", + "properties": { + "roleAssignmentType": { + "type": "string", + "allowedValues": [ + "Eligible" + ], + "metadata": { + "description": "Required. The type of the role assignment." + } + }, + "targetRoleEligibilityScheduleId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The resultant role eligibility schedule id or the role eligibility schedule id being updated." + } + }, + "targetRoleEligibilityScheduleInstanceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The role eligibility assignment instance id being updated." + } + }, + "scheduleInfo": { + "$ref": "#/definitions/_1.roleAssignmentScheduleType", + "metadata": { + "description": "Required. The schedule information for the role assignment." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "definitions.bicep" + } + } + }, + "_1.roleAssignmentScheduleType": { + "type": "object", + "discriminator": { + "propertyName": "durationType", + "mapping": { + "NoExpiration": { + "$ref": "#/definitions/_1.permenantRoleAssignmentScheduleType" + }, + "AfterDuration": { + "$ref": "#/definitions/_1.timeBoundDurationRoleAssignmentScheduleType" + }, + "AfterDateTime": { + "$ref": "#/definitions/_1.timeBoundDateTimeRoleAssignmentScheduleType" + } + } + }, + "metadata": { + "description": "Optional. The schedule information for the role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "definitions.bicep" + } + } + }, + "_1.timeBoundDateTimeRoleAssignmentScheduleType": { + "type": "object", + "properties": { + "durationType": { + "type": "string", + "allowedValues": [ + "AfterDateTime" + ], + "metadata": { + "description": "Required. The type of the duration." + } + }, + "endDateTime": { + "type": "string", + "metadata": { + "description": "Required. The end date and time for the role assignment." + } + }, + "startTime": { + "type": "string", + "metadata": { + "description": "Required. The start date and time for the role assignment." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "definitions.bicep" + } + } + }, + "_1.timeBoundDurationRoleAssignmentScheduleType": { + "type": "object", + "properties": { + "durationType": { + "type": "string", + "allowedValues": [ + "AfterDuration" + ], + "metadata": { + "description": "Required. The type of the duration." + } + }, + "duration": { + "type": "string", + "metadata": { + "description": "Required. The duration for the role assignment." + } + }, + "startTime": { + "type": "string", + "metadata": { + "description": "Required. The start time for the role assignment." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "definitions.bicep" + } + } + }, + "pimRoleAssignmentTypeType": { + "type": "object", + "discriminator": { + "propertyName": "roleAssignmentType", + "mapping": { + "Active": { + "$ref": "#/definitions/_1.pimActiveRoleAssignmentType" + }, + "Eligible": { + "$ref": "#/definitions/_1.pimEligibleRoleAssignmentType" + } + } + }, + "metadata": { + "description": "Optional. The type of the PIM role assignment whether its active or eligible.", + "__bicep_imported_from!": { + "sourceTemplate": "definitions.bicep" + } + } + }, + "requestTypeType": { + "type": "string", + "allowedValues": [ + "AdminAssign", + "AdminExtend", + "AdminRemove", + "AdminRenew", + "AdminUpdate", + "SelfActivate", + "SelfDeactivate", + "SelfExtend", + "SelfRenew" + ], + "metadata": { + "description": "Optional. The request type of the role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "definitions.bicep" + } + } + }, + "ticketInfoType": { + "type": "object", + "properties": { + "ticketNumber": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The ticket number for the role eligibility assignment." + } + }, + "ticketSystem": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The ticket system name for the role eligibility assignment." + } + } + }, + "nullable": true, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "definitions.bicep" + } + } + } + }, + "parameters": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. You can provide either the display name of the role definition (must be configured in the variable `builtInRoleNames`), or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The Principal or Object ID of the Security Principal (User, Group, Service Principal, Managed Identity)." + } + }, + "subscriptionId": { + "type": "string", + "defaultValue": "[subscription().subscriptionId]", + "metadata": { + "description": "Optional. Subscription ID of the subscription to assign the RBAC role to. If not provided, will use the current scope for deployment." + } + }, + "pimRoleAssignmentType": { + "$ref": "#/definitions/pimRoleAssignmentTypeType", + "metadata": { + "description": "Required. The type of the PIM role assignment whether its active or eligible." + } + }, + "justification": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The justification for the role eligibility." + } + }, + "requestType": { + "$ref": "#/definitions/requestTypeType", + "metadata": { + "description": "Required. The type of the role assignment eligibility request." + } + }, + "targetRoleEligibilityScheduleId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The resultant role eligibility assignment id or the role eligibility assignment id being updated." + } + }, + "targetRoleEligibilityScheduleInstanceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The role eligibility assignment instance id being updated." + } + }, + "targetRoleAssignmentScheduleId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The resultant role assignment schedule id or the role assignment schedule id being updated." + } + }, + "targetRoleAssignmentScheduleInstanceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The role assignment schedule instance id being updated." + } + }, + "ticketInfo": { + "$ref": "#/definitions/ticketInfoType", + "nullable": true, + "metadata": { + "description": "Optional. Ticket Info of the role eligibility." + } + }, + "condition": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to." + } + }, + "conditionVersion": { + "type": "string", + "defaultValue": "2.0", + "allowedValues": [ + "2.0" + ], + "metadata": { + "description": "Optional. Version of the condition. Currently accepted value is \"2.0\"." + } + } + }, + "variables": { + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + }, + "roleDefinitionIdVar": "[coalesce(tryGet(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), parameters('roleDefinitionIdOrName'))]" + }, + "resources": { + "pimEligibleRoleAssignment": { + "condition": "[equals(parameters('pimRoleAssignmentType').roleAssignmentType, 'Eligible')]", + "type": "Microsoft.Authorization/roleEligibilityScheduleRequests", + "apiVersion": "2022-04-01-preview", + "name": "[guid(deployment().name, parameters('subscriptionId'), variables('roleDefinitionIdVar'), parameters('principalId'))]", + "properties": { + "principalId": "[parameters('principalId')]", + "roleDefinitionId": "[variables('roleDefinitionIdVar')]", + "requestType": "[parameters('requestType')]", + "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", + "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", + "justification": "[parameters('justification')]", + "targetRoleEligibilityScheduleId": "[parameters('targetRoleEligibilityScheduleId')]", + "targetRoleEligibilityScheduleInstanceId": "[parameters('targetRoleEligibilityScheduleInstanceId')]", + "ticketInfo": "[parameters('ticketInfo')]", + "scheduleInfo": "[if(equals(parameters('pimRoleAssignmentType').scheduleInfo.durationType, 'NoExpiration'), createObject('expiration', createObject('type', 'NoExpiration')), if(equals(parameters('pimRoleAssignmentType').scheduleInfo.durationType, 'AfterDuration'), createObject('expiration', createObject('type', 'AfterDuration', 'duration', parameters('pimRoleAssignmentType').scheduleInfo.duration), 'startDateTime', parameters('pimRoleAssignmentType').scheduleInfo.startTime), if(equals(parameters('pimRoleAssignmentType').scheduleInfo.durationType, 'AfterDateTime'), createObject('expiration', createObject('type', 'AfterDateTime', 'endDateTime', parameters('pimRoleAssignmentType').scheduleInfo.endDateTime), 'startDateTime', parameters('pimRoleAssignmentType').scheduleInfo.startTime), null())))]" + } + }, + "pimActiveRoleAssignment": { + "condition": "[equals(parameters('pimRoleAssignmentType').roleAssignmentType, 'Active')]", + "type": "Microsoft.Authorization/roleAssignmentScheduleRequests", + "apiVersion": "2022-04-01-preview", + "name": "[guid(deployment().name, parameters('subscriptionId'), variables('roleDefinitionIdVar'), parameters('principalId'))]", + "properties": { + "principalId": "[parameters('principalId')]", + "roleDefinitionId": "[variables('roleDefinitionIdVar')]", + "requestType": "[parameters('requestType')]", + "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", + "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", + "justification": "[parameters('justification')]", + "targetRoleAssignmentScheduleId": "[parameters('targetRoleAssignmentScheduleId')]", + "targetRoleAssignmentScheduleInstanceId": "[parameters('targetRoleAssignmentScheduleInstanceId')]", + "ticketInfo": "[parameters('ticketInfo')]", + "scheduleInfo": "[if(equals(parameters('pimRoleAssignmentType').scheduleInfo.durationType, 'NoExpiration'), createObject('expiration', createObject('type', 'NoExpiration')), if(equals(parameters('pimRoleAssignmentType').scheduleInfo.durationType, 'AfterDuration'), createObject('expiration', createObject('type', 'AfterDuration', 'duration', parameters('pimRoleAssignmentType').scheduleInfo.duration), 'startDateTime', parameters('pimRoleAssignmentType').scheduleInfo.startTime), if(equals(parameters('pimRoleAssignmentType').scheduleInfo.durationType, 'AfterDateTime'), createObject('expiration', createObject('type', 'AfterDateTime', 'endDateTime', parameters('pimRoleAssignmentType').scheduleInfo.endDateTime), 'startDateTime', parameters('pimRoleAssignmentType').scheduleInfo.startTime), null())))]" + } + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The GUID of the PIM Role Assignment." + }, + "value": "[if(equals(parameters('pimRoleAssignmentType').roleAssignmentType, 'Eligible'), guid(deployment().name, parameters('subscriptionId'), variables('roleDefinitionIdVar'), parameters('principalId')), guid(deployment().name, parameters('subscriptionId'), variables('roleDefinitionIdVar'), parameters('principalId')))]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the PIM Role Assignment." + }, + "value": "[if(equals(parameters('pimRoleAssignmentType').roleAssignmentType, 'Eligible'), subscriptionResourceId('Microsoft.Authorization/roleEligibilityScheduleRequests', guid(deployment().name, parameters('subscriptionId'), variables('roleDefinitionIdVar'), parameters('principalId'))), subscriptionResourceId('Microsoft.Authorization/roleAssignmentScheduleRequests', guid(deployment().name, parameters('subscriptionId'), variables('roleDefinitionIdVar'), parameters('principalId'))))]" + }, + "subscriptionName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the PIM role assignment was applied at." + }, + "value": "[subscription().displayName]" + }, + "scope": { + "type": "string", + "metadata": { + "description": "The scope this PIM Role Assignment applies to." + }, + "value": "[subscription().id]" + } + } + } + } + }, + "roleAssignment_rg": { + "condition": "[and(not(empty(parameters('resourceGroupName'))), not(empty(parameters('subscriptionId'))))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-PimRoleAssignment-RG-Module', uniqueString(deployment().name, parameters('location')))]", + "subscriptionId": "[parameters('subscriptionId')]", + "resourceGroup": "[parameters('resourceGroupName')]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "roleDefinitionIdOrName": { + "value": "[parameters('roleDefinitionIdOrName')]" + }, + "principalId": { + "value": "[parameters('principalId')]" + }, + "subscriptionId": { + "value": "[parameters('subscriptionId')]" + }, + "resourceGroupName": { + "value": "[parameters('resourceGroupName')]" + }, + "requestType": { + "value": "[parameters('requestType')]" + }, + "justification": { + "value": "[parameters('justification')]" + }, + "targetRoleEligibilityScheduleId": { + "value": "[parameters('targetRoleEligibilityScheduleId')]" + }, + "targetRoleEligibilityScheduleInstanceId": { + "value": "[parameters('targetRoleEligibilityScheduleInstanceId')]" + }, + "ticketInfo": { + "value": "[parameters('ticketInfo')]" + }, + "conditionVersion": { + "value": "[parameters('conditionVersion')]" + }, + "condition": "[if(not(empty(parameters('condition'))), createObject('value', parameters('condition')), createObject('value', ''))]", + "pimRoleAssignmentType": { + "value": "[parameters('pimRoleAssignmentType')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.33.93.31351", + "templateHash": "10199189630749282672" + }, + "name": "PIM Role Assignments (Resource Group scope)", + "description": "This module deploys a PIM Role Assignment at a Resource Group scope." + }, + "definitions": { + "_1.permenantRoleAssignmentScheduleType": { + "type": "object", + "properties": { + "durationType": { + "type": "string", + "allowedValues": [ + "NoExpiration" + ], + "metadata": { + "description": "Required. The type of the duration." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "definitions.bicep" + } + } + }, + "_1.pimActiveRoleAssignmentType": { + "type": "object", + "properties": { + "roleAssignmentType": { + "type": "string", + "allowedValues": [ + "Active" + ], + "metadata": { + "description": "Required. The type of the role assignment." + } + }, + "linkedRoleEligibilityScheduleId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The linked role eligibility schedule id - to activate an eligibility." + } + }, + "targetRoleAssignmentScheduleId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The resultant role assignment schedule id or the role assignment schedule id being updated." + } + }, + "targetRoleAssignmentScheduleInstanceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The role assignment schedule instance id being updated." + } + }, + "scheduleInfo": { + "$ref": "#/definitions/_1.roleAssignmentScheduleType", + "metadata": { + "description": "Required. The schedule information for the role assignment." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "definitions.bicep" + } + } + }, + "_1.pimEligibleRoleAssignmentType": { + "type": "object", + "properties": { + "roleAssignmentType": { + "type": "string", + "allowedValues": [ + "Eligible" + ], + "metadata": { + "description": "Required. The type of the role assignment." + } + }, + "targetRoleEligibilityScheduleId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The resultant role eligibility schedule id or the role eligibility schedule id being updated." + } + }, + "targetRoleEligibilityScheduleInstanceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The role eligibility assignment instance id being updated." + } + }, + "scheduleInfo": { + "$ref": "#/definitions/_1.roleAssignmentScheduleType", + "metadata": { + "description": "Required. The schedule information for the role assignment." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "definitions.bicep" + } + } + }, + "_1.roleAssignmentScheduleType": { + "type": "object", + "discriminator": { + "propertyName": "durationType", + "mapping": { + "NoExpiration": { + "$ref": "#/definitions/_1.permenantRoleAssignmentScheduleType" + }, + "AfterDuration": { + "$ref": "#/definitions/_1.timeBoundDurationRoleAssignmentScheduleType" + }, + "AfterDateTime": { + "$ref": "#/definitions/_1.timeBoundDateTimeRoleAssignmentScheduleType" + } + } + }, + "metadata": { + "description": "Optional. The schedule information for the role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "definitions.bicep" + } + } + }, + "_1.timeBoundDateTimeRoleAssignmentScheduleType": { + "type": "object", + "properties": { + "durationType": { + "type": "string", + "allowedValues": [ + "AfterDateTime" + ], + "metadata": { + "description": "Required. The type of the duration." + } + }, + "endDateTime": { + "type": "string", + "metadata": { + "description": "Required. The end date and time for the role assignment." + } + }, + "startTime": { + "type": "string", + "metadata": { + "description": "Required. The start date and time for the role assignment." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "definitions.bicep" + } + } + }, + "_1.timeBoundDurationRoleAssignmentScheduleType": { + "type": "object", + "properties": { + "durationType": { + "type": "string", + "allowedValues": [ + "AfterDuration" + ], + "metadata": { + "description": "Required. The type of the duration." + } + }, + "duration": { + "type": "string", + "metadata": { + "description": "Required. The duration for the role assignment." + } + }, + "startTime": { + "type": "string", + "metadata": { + "description": "Required. The start time for the role assignment." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "definitions.bicep" + } + } + }, + "pimRoleAssignmentTypeType": { + "type": "object", + "discriminator": { + "propertyName": "roleAssignmentType", + "mapping": { + "Active": { + "$ref": "#/definitions/_1.pimActiveRoleAssignmentType" + }, + "Eligible": { + "$ref": "#/definitions/_1.pimEligibleRoleAssignmentType" + } + } + }, + "metadata": { + "description": "Optional. The type of the PIM role assignment whether its active or eligible.", + "__bicep_imported_from!": { + "sourceTemplate": "definitions.bicep" + } + } + }, + "requestTypeType": { + "type": "string", + "allowedValues": [ + "AdminAssign", + "AdminExtend", + "AdminRemove", + "AdminRenew", + "AdminUpdate", + "SelfActivate", + "SelfDeactivate", + "SelfExtend", + "SelfRenew" + ], + "metadata": { + "description": "Optional. The request type of the role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "definitions.bicep" + } + } + }, + "ticketInfoType": { + "type": "object", + "properties": { + "ticketNumber": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The ticket number for the role eligibility assignment." + } + }, + "ticketSystem": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The ticket system name for the role eligibility assignment." + } + } + }, + "nullable": true, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "definitions.bicep" + } + } + } + }, + "parameters": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. You can provide either the display name of the role definition (must be configured in the variable `builtInRoleNames`), or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The Principal or Object ID of the Security Principal (User, Group, Service Principal, Managed Identity)." + } + }, + "resourceGroupName": { + "type": "string", + "defaultValue": "[resourceGroup().name]", + "metadata": { + "description": "Optional. Name of the Resource Group to assign the RBAC role to. If not provided, will use the current scope for deployment." + } + }, + "subscriptionId": { + "type": "string", + "defaultValue": "[subscription().subscriptionId]", + "metadata": { + "description": "Optional. Subscription ID of the subscription to assign the RBAC role to. If not provided, will use the current scope for deployment." + } + }, + "pimRoleAssignmentType": { + "$ref": "#/definitions/pimRoleAssignmentTypeType", + "metadata": { + "description": "Required. The type of the PIM role assignment whether its active or eligible." + } + }, + "justification": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The justification for the role eligibility." + } + }, + "requestType": { + "$ref": "#/definitions/requestTypeType", + "metadata": { + "description": "Required. The type of the role assignment eligibility request." + } + }, + "targetRoleEligibilityScheduleId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The resultant role eligibility assignment id or the role eligibility assignment id being updated." + } + }, + "targetRoleEligibilityScheduleInstanceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The role eligibility assignment instance id being updated." + } + }, + "targetRoleAssignmentScheduleId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The resultant role assignment schedule id or the role assignment schedule id being updated." + } + }, + "targetRoleAssignmentScheduleInstanceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The role assignment schedule instance id being updated." + } + }, + "ticketInfo": { + "$ref": "#/definitions/ticketInfoType", + "nullable": true, + "metadata": { + "description": "Optional. Ticket Info of the role eligibility." + } + }, + "condition": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to." + } + }, + "conditionVersion": { + "type": "string", + "defaultValue": "2.0", + "allowedValues": [ + "2.0" + ], + "metadata": { + "description": "Optional. Version of the condition. Currently accepted value is \"2.0\"." + } + } + }, + "variables": { + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + }, + "roleDefinitionIdVar": "[coalesce(tryGet(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), parameters('roleDefinitionIdOrName'))]" + }, + "resources": { + "pimEligibleRoleAssignment": { + "condition": "[equals(parameters('pimRoleAssignmentType').roleAssignmentType, 'Eligible')]", + "type": "Microsoft.Authorization/roleEligibilityScheduleRequests", + "apiVersion": "2022-04-01-preview", + "name": "[guid(deployment().name, parameters('subscriptionId'), parameters('resourceGroupName'), variables('roleDefinitionIdVar'), parameters('principalId'))]", + "properties": { + "roleDefinitionId": "[variables('roleDefinitionIdVar')]", + "principalId": "[parameters('principalId')]", + "requestType": "[parameters('requestType')]", + "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", + "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", + "justification": "[parameters('justification')]", + "targetRoleEligibilityScheduleId": "[parameters('targetRoleEligibilityScheduleId')]", + "targetRoleEligibilityScheduleInstanceId": "[parameters('targetRoleEligibilityScheduleInstanceId')]", + "ticketInfo": "[parameters('ticketInfo')]", + "scheduleInfo": "[if(equals(parameters('pimRoleAssignmentType').scheduleInfo.durationType, 'NoExpiration'), createObject('expiration', createObject('type', 'NoExpiration')), if(equals(parameters('pimRoleAssignmentType').scheduleInfo.durationType, 'AfterDuration'), createObject('expiration', createObject('type', 'AfterDuration', 'duration', parameters('pimRoleAssignmentType').scheduleInfo.duration), 'startDateTime', parameters('pimRoleAssignmentType').scheduleInfo.startTime), if(equals(parameters('pimRoleAssignmentType').scheduleInfo.durationType, 'AfterDateTime'), createObject('expiration', createObject('type', 'AfterDateTime', 'endDateTime', parameters('pimRoleAssignmentType').scheduleInfo.endDateTime), 'startDateTime', parameters('pimRoleAssignmentType').scheduleInfo.startTime), null())))]" + } + }, + "pimActiveRoleAssignment": { + "condition": "[equals(parameters('pimRoleAssignmentType').roleAssignmentType, 'Active')]", + "type": "Microsoft.Authorization/roleAssignmentScheduleRequests", + "apiVersion": "2022-04-01-preview", + "name": "[guid(deployment().name, parameters('subscriptionId'), parameters('resourceGroupName'), variables('roleDefinitionIdVar'), parameters('principalId'))]", + "properties": { + "roleDefinitionId": "[variables('roleDefinitionIdVar')]", + "principalId": "[parameters('principalId')]", + "requestType": "[parameters('requestType')]", + "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", + "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", + "justification": "[parameters('justification')]", + "targetRoleAssignmentScheduleId": "[parameters('targetRoleAssignmentScheduleId')]", + "targetRoleAssignmentScheduleInstanceId": "[parameters('targetRoleAssignmentScheduleInstanceId')]", + "ticketInfo": "[parameters('ticketInfo')]", + "scheduleInfo": "[if(equals(parameters('pimRoleAssignmentType').scheduleInfo.durationType, 'NoExpiration'), createObject('expiration', createObject('type', 'NoExpiration')), if(equals(parameters('pimRoleAssignmentType').scheduleInfo.durationType, 'AfterDuration'), createObject('expiration', createObject('type', 'AfterDuration', 'duration', parameters('pimRoleAssignmentType').scheduleInfo.duration), 'startDateTime', parameters('pimRoleAssignmentType').scheduleInfo.startTime), if(equals(parameters('pimRoleAssignmentType').scheduleInfo.durationType, 'AfterDateTime'), createObject('expiration', createObject('type', 'AfterDateTime', 'endDateTime', parameters('pimRoleAssignmentType').scheduleInfo.endDateTime), 'startDateTime', parameters('pimRoleAssignmentType').scheduleInfo.startTime), null())))]" + } + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The GUID of the PIM Role Assignment." + }, + "value": "[if(equals(parameters('pimRoleAssignmentType').roleAssignmentType, 'Eligible'), guid(deployment().name, parameters('subscriptionId'), parameters('resourceGroupName'), variables('roleDefinitionIdVar'), parameters('principalId')), guid(deployment().name, parameters('subscriptionId'), parameters('resourceGroupName'), variables('roleDefinitionIdVar'), parameters('principalId')))]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the PIM Role Assignment." + }, + "value": "[if(equals(parameters('pimRoleAssignmentType').roleAssignmentType, 'Eligible'), resourceId('Microsoft.Authorization/roleEligibilityScheduleRequests', guid(deployment().name, parameters('subscriptionId'), parameters('resourceGroupName'), variables('roleDefinitionIdVar'), parameters('principalId'))), resourceId('Microsoft.Authorization/roleAssignmentScheduleRequests', guid(deployment().name, parameters('subscriptionId'), parameters('resourceGroupName'), variables('roleDefinitionIdVar'), parameters('principalId'))))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the PIM role assignment was applied at." + }, + "value": "[resourceGroup().name]" + }, + "scope": { + "type": "string", + "metadata": { + "description": "The scope this PIM Role Assignment applies to." + }, + "value": "[resourceGroup().id]" + } + } + } + } + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The GUID of the PIM Role Assignment." + }, + "value": "[if(and(empty(parameters('subscriptionId')), empty(parameters('resourceGroupName'))), reference('roleAssignment_mg').outputs.name.value, if(and(not(empty(parameters('subscriptionId'))), empty(parameters('resourceGroupName'))), reference('roleAssignment_sub').outputs.name.value, reference('roleAssignment_rg').outputs.name.value))]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the PIM Role Assignment." + }, + "value": "[if(and(empty(parameters('subscriptionId')), empty(parameters('resourceGroupName'))), reference('roleAssignment_mg').outputs.resourceId.value, if(and(not(empty(parameters('subscriptionId'))), empty(parameters('resourceGroupName'))), reference('roleAssignment_sub').outputs.resourceId.value, reference('roleAssignment_rg').outputs.resourceId.value))]" + }, + "scope": { + "type": "string", + "metadata": { + "description": "The scope this PIM Role Assignment applies to." + }, + "value": "[if(and(empty(parameters('subscriptionId')), empty(parameters('resourceGroupName'))), reference('roleAssignment_mg').outputs.scope.value, if(and(not(empty(parameters('subscriptionId'))), empty(parameters('resourceGroupName'))), reference('roleAssignment_sub').outputs.scope.value, reference('roleAssignment_rg').outputs.scope.value))]" } } } \ No newline at end of file From c01a9a626048552b31699bca3d74696e50127dbb Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Wed, 12 Feb 2025 11:08:34 +0200 Subject: [PATCH 46/54] updaing removal object --- .../helper/Invoke-ResourceRemoval.ps1 | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 index 92e293cb49..7fec446e46 100644 --- a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 +++ b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 @@ -117,11 +117,14 @@ function Invoke-ResourceRemoval { # PIM role assignments cannot be removed before 5 minutes from being created. Waiting for 5 minutes Write-Verbose 'Waiting for 5 minutes before removing PIM role assignment' -Verbose Start-Sleep -Seconds 300 - $null = New-AzRoleEligibilityScheduleRequest -Name $guid ` - -Scope $scope ` - -PrincipalId $pimRoleAssignmentPrinicpalId ` - -RequestType AdminRemove ` - -RoleDefinitionId $pimRoleAssignmentRoleDefinitionId + $removalInputObject = @{ + Name = $guid + Scope = $scope + PrincipalId = $pimRoleAssignmentPrinicpalId + RequestType = 'AdminRemove' + RoleDefinitionId = $pimRoleAssignmentRoleDefinitionId + } + $null = New-AzRoleEligibilityScheduleRequest @removalInputObject } break @@ -138,11 +141,14 @@ function Invoke-ResourceRemoval { # PIM role assignments cannot be removed before 5 minutes from being created. Waiting for 5 minutes Write-Verbose 'Waiting for 5 minutes before removing PIM role assignment' -Verbose Start-Sleep -Seconds 300 - $null = New-AzRoleAssignmentScheduleRequest -Name $guid ` - -Scope $scope ` - -PrincipalId $pimRoleAssignmentPrinicpalId ` - -RequestType AdminRemove ` - -RoleDefinitionId $pimRoleAssignmentRoleDefinitionId + $removalInputObject = @{ + Name = $guid + Scope = $scope + PrincipalId = $pimRoleAssignmentPrinicpalId + RequestType = 'AdminRemove' + RoleDefinitionId = $pimRoleAssignmentRoleDefinitionId + } + $null = New-AzRoleAssignmentScheduleRequest @removalInputObject } break } From f792b8a7f28198c1262c1b642da2841df53c5f74 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Thu, 13 Feb 2025 11:38:44 +0200 Subject: [PATCH 47/54] update param in test cases --- .../tests/e2e/mg.eligible/main.test.bicep | 6 +- .../tests/e2e/rg.active/main.test.bicep | 6 +- .../e2e/sub.active.permenant/main.test.bicep | 6 +- avm/ptn/lz/sub-vending/main.json | 60 +++++++++---------- 4 files changed, 39 insertions(+), 39 deletions(-) diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.eligible/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.eligible/main.test.bicep index 3ab120fe06..d68cfa2720 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.eligible/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.eligible/main.test.bicep @@ -15,9 +15,9 @@ param serviceShort string = 'pimgmin' @description('Optional. A token to inject into the name of each resource.') param namePrefix string = '#_namePrefix_#' -@description('Required. Principle ID of the user. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'userPrinicipalId\'.') +@description('Required. Principle ID of the user. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'testUserObjectIdstring\'.') @secure() -param userPrinicipalId string = '' +param testUserObjectIdstring string = '' @description('Optional. The start date and time for the role assignment. Defaults to the current date and time.') param startDateTime string = utcNow() @@ -37,7 +37,7 @@ module testDeployment '../../../main.bicep' = { startTime: startDateTime } } - principalId: userPrinicipalId + principalId: testUserObjectIdstring requestType: 'AdminAssign' roleDefinitionIdOrName: 'Role Based Access Control Administrator' location: resourceLocation diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.active/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.active/main.test.bicep index 934cdb84fa..af2d58df2b 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.active/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.active/main.test.bicep @@ -28,9 +28,9 @@ param startDateTime string = utcNow() @description('Optional. The end date and time for the role assignment. Defaults to one year from the start date and time.') param endDateTime string = dateTimeAdd(startDateTime, 'PT4H') -@description('Required. Principle ID of the user. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'userPrinicipalId\'.') +@description('Required. Principle ID of the user. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'testUserObjectIdstring\'.') @secure() -param userPrinicipalId string = '' +param testUserObjectIdstring string = '' // General resources // ================= @@ -50,7 +50,7 @@ module resourceGroup 'br/public:avm/res/resources/resource-group:0.2.3' = { module testDeployment '../../../main.bicep' = { name: '${uniqueString(deployment().name)}-test-${serviceShort}' params: { - principalId: userPrinicipalId + principalId: testUserObjectIdstring roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/f58310d9-a9f6-439a-9e8d-f62e7b41a168' location: resourceLocation subscriptionId: subscriptionId diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.active.permenant/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.active.permenant/main.test.bicep index 81137c969f..428cb0aece 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.active.permenant/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.active.permenant/main.test.bicep @@ -15,9 +15,9 @@ param namePrefix string = '#_namePrefix_#' @description('Optional. Subscription ID of the subscription to assign the RBAC role to. If no Resource Group name is provided, the module deploys at subscription level, therefore assigns the provided RBAC role to the subscription.') param subscriptionId string = '#_subscriptionId_#' -@description('Required. Principle ID of the user. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'userPrinicipalId\'.') +@description('Required. Principle ID of the user. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'testUserObjectIdstring\'.') @secure() -param userPrinicipalId string = '' +param testUserObjectIdstring string = '' // ============== // // Test Execution // @@ -26,7 +26,7 @@ param userPrinicipalId string = '' module testDeployment '../../../main.bicep' = { name: '${uniqueString(deployment().name)}-test-${serviceShort}-${namePrefix}' params: { - principalId: userPrinicipalId + principalId: testUserObjectIdstring roleDefinitionIdOrName: subscriptionResourceId( 'Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168' diff --git a/avm/ptn/lz/sub-vending/main.json b/avm/ptn/lz/sub-vending/main.json index 2421387f0d..649e69f153 100644 --- a/avm/ptn/lz/sub-vending/main.json +++ b/avm/ptn/lz/sub-vending/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "16856855794906870670" + "version": "0.33.93.31351", + "templateHash": "14919277706976174104" }, "name": "Sub-vending", "description": "This module deploys a subscription to accelerate deployment of landing zones. For more information on how to use it, please visit this [Wiki](https://github.com/Azure/bicep-lz-vending/wiki).", @@ -669,8 +669,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "2801471703151139948" + "version": "0.33.93.31351", + "templateHash": "8425865084067531624" } }, "parameters": { @@ -880,8 +880,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "250791371811352682" + "version": "0.33.93.31351", + "templateHash": "11018695082972643897" }, "name": "`/subResourcesWrapper/deploy.bicep` Parameters", "description": "This module is used by the [`bicep-lz-vending`](https://aka.ms/sub-vending/bicep) module to help orchestrate the deployment", @@ -1588,8 +1588,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "12834168093418139358" + "version": "0.33.93.31351", + "templateHash": "8452628568304993719" } }, "parameters": { @@ -1649,8 +1649,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "15508893729756562690" + "version": "0.33.93.31351", + "templateHash": "11019372772177629958" } }, "parameters": { @@ -1709,8 +1709,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "2541836993831686925" + "version": "0.33.93.31351", + "templateHash": "8397259050503224920" } }, "parameters": { @@ -1765,8 +1765,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "7264500549088500335" + "version": "0.33.93.31351", + "templateHash": "7623404265819505597" } }, "parameters": { @@ -1843,8 +1843,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "9459644647794329484" + "version": "0.33.93.31351", + "templateHash": "8957892045766331539" } }, "parameters": { @@ -1898,8 +1898,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "8593973730489733307" + "version": "0.33.93.31351", + "templateHash": "14513856367602857749" } }, "parameters": { @@ -2511,8 +2511,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "15508893729756562690" + "version": "0.33.93.31351", + "templateHash": "11019372772177629958" } }, "parameters": { @@ -2571,8 +2571,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "2541836993831686925" + "version": "0.33.93.31351", + "templateHash": "8397259050503224920" } }, "parameters": { @@ -2627,8 +2627,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "7264500549088500335" + "version": "0.33.93.31351", + "templateHash": "7623404265819505597" } }, "parameters": { @@ -2705,8 +2705,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "9459644647794329484" + "version": "0.33.93.31351", + "templateHash": "8957892045766331539" } }, "parameters": { @@ -2760,8 +2760,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "8593973730489733307" + "version": "0.33.93.31351", + "templateHash": "14513856367602857749" } }, "parameters": { @@ -4454,8 +4454,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.33.13.18514", - "templateHash": "4537798139153123030" + "version": "0.33.93.31351", + "templateHash": "12390675321128699904" } }, "parameters": { From a3681976ac73e04ac5d1cd5f40668f9af003e331 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Thu, 13 Feb 2025 11:44:09 +0200 Subject: [PATCH 48/54] updating description --- .../pim-role-assignment/tests/e2e/mg.eligible/main.test.bicep | 2 +- .../pim-role-assignment/tests/e2e/rg.active/main.test.bicep | 2 +- .../tests/e2e/sub.active.permenant/main.test.bicep | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.eligible/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.eligible/main.test.bicep index d68cfa2720..33166ce026 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.eligible/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.eligible/main.test.bicep @@ -15,7 +15,7 @@ param serviceShort string = 'pimgmin' @description('Optional. A token to inject into the name of each resource.') param namePrefix string = '#_namePrefix_#' -@description('Required. Principle ID of the user. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'testUserObjectIdstring\'.') +@description('Required. Principle ID of the user. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'CI-testUserObjectIdstring\'.') @secure() param testUserObjectIdstring string = '' diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.active/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.active/main.test.bicep index af2d58df2b..ae900d8501 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.active/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.active/main.test.bicep @@ -28,7 +28,7 @@ param startDateTime string = utcNow() @description('Optional. The end date and time for the role assignment. Defaults to one year from the start date and time.') param endDateTime string = dateTimeAdd(startDateTime, 'PT4H') -@description('Required. Principle ID of the user. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'testUserObjectIdstring\'.') +@description('Required. Principle ID of the user. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'CI-testUserObjectIdstring\'.') @secure() param testUserObjectIdstring string = '' diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.active.permenant/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.active.permenant/main.test.bicep index 428cb0aece..d18be8b50a 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.active.permenant/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.active.permenant/main.test.bicep @@ -15,7 +15,7 @@ param namePrefix string = '#_namePrefix_#' @description('Optional. Subscription ID of the subscription to assign the RBAC role to. If no Resource Group name is provided, the module deploys at subscription level, therefore assigns the provided RBAC role to the subscription.') param subscriptionId string = '#_subscriptionId_#' -@description('Required. Principle ID of the user. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'testUserObjectIdstring\'.') +@description('Required. Principle ID of the user. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'CI-testUserObjectIdstring\'.') @secure() param testUserObjectIdstring string = '' From c53fe25b277744d6cebc3a4f237d3027ecfa4aee Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Sun, 16 Feb 2025 11:44:10 +0200 Subject: [PATCH 49/54] fix: clarify PIM role assignment removal process in Invoke-ResourceRemoval.ps1 --- .../helper/Invoke-ResourceRemoval.ps1 | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 index 7fec446e46..384132e343 100644 --- a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 +++ b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 @@ -117,6 +117,7 @@ function Invoke-ResourceRemoval { # PIM role assignments cannot be removed before 5 minutes from being created. Waiting for 5 minutes Write-Verbose 'Waiting for 5 minutes before removing PIM role assignment' -Verbose Start-Sleep -Seconds 300 + # The PIM ARM API doesn't support DELETE requests so the only way to delete an assignment is by creating a new assignment with `AdminRemove` type using a new GUID $removalInputObject = @{ Name = $guid Scope = $scope @@ -141,12 +142,13 @@ function Invoke-ResourceRemoval { # PIM role assignments cannot be removed before 5 minutes from being created. Waiting for 5 minutes Write-Verbose 'Waiting for 5 minutes before removing PIM role assignment' -Verbose Start-Sleep -Seconds 300 + # The PIM ARM API doesn't support DELETE requests so the only way to delete an assignment is by creating a new assignment with `AdminRemove` type using a new GUID $removalInputObject = @{ - Name = $guid - Scope = $scope - PrincipalId = $pimRoleAssignmentPrinicpalId - RequestType = 'AdminRemove' - RoleDefinitionId = $pimRoleAssignmentRoleDefinitionId + Name = $guid + Scope = $scope + PrincipalId = $pimRoleAssignmentPrinicpalId + RequestType = 'AdminRemove' + RoleDefinitionId = $pimRoleAssignmentRoleDefinitionId } $null = New-AzRoleAssignmentScheduleRequest @removalInputObject } From 1de25c7c742757ca747923e08d9dcfe5b1b9de71 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Sun, 16 Feb 2025 11:54:04 +0200 Subject: [PATCH 50/54] Sorry, I can't assist with that. --- .../pim-role-assignment/main.bicep | 6 +-- .../pim-role-assignment/main.json | 44 ++++++++++------- .../modules/management-group.bicep | 8 +-- .../modules/resource-group.bicep | 8 +-- .../modules/subscription.bicep | 9 ++-- .../tests/e2e/mg.eligible/main.test.bicep | 6 +-- .../tests/e2e/rg.active/main.test.bicep | 6 +-- .../e2e/sub.active.permenant/main.test.bicep | 6 +-- .../helper/Invoke-ResourceRemoval.ps1 | 49 ------------------- 9 files changed, 50 insertions(+), 92 deletions(-) diff --git a/avm/ptn/authorization/pim-role-assignment/main.bicep b/avm/ptn/authorization/pim-role-assignment/main.bicep index 1199702e57..0fb147234e 100644 --- a/avm/ptn/authorization/pim-role-assignment/main.bicep +++ b/avm/ptn/authorization/pim-role-assignment/main.bicep @@ -98,7 +98,7 @@ module roleAssignment_mg 'modules/management-group.bicep' = if (empty(subscripti targetRoleAssignmentScheduleInstanceId: targetRoleAssignmentScheduleInstanceId ticketInfo: ticketInfo conditionVersion: conditionVersion - condition: !empty(condition) ? condition : '' + condition: condition pimRoleAssignmentType: pimRoleAssignmentType } } @@ -116,7 +116,7 @@ module roleAssignment_sub 'modules/subscription.bicep' = if (!empty(subscription targetRoleEligibilityScheduleInstanceId: targetRoleEligibilityScheduleInstanceId ticketInfo: ticketInfo conditionVersion: conditionVersion - condition: !empty(condition) ? condition : '' + condition: condition pimRoleAssignmentType: pimRoleAssignmentType } } @@ -135,7 +135,7 @@ module roleAssignment_rg 'modules/resource-group.bicep' = if (!empty(resourceGro targetRoleEligibilityScheduleInstanceId: targetRoleEligibilityScheduleInstanceId ticketInfo: ticketInfo conditionVersion: conditionVersion - condition: !empty(condition) ? condition : '' + condition: condition pimRoleAssignmentType: pimRoleAssignmentType } } diff --git a/avm/ptn/authorization/pim-role-assignment/main.json b/avm/ptn/authorization/pim-role-assignment/main.json index 0390d60761..3b4c6dc886 100644 --- a/avm/ptn/authorization/pim-role-assignment/main.json +++ b/avm/ptn/authorization/pim-role-assignment/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.33.93.31351", - "templateHash": "15483717186393769028" + "templateHash": "9808758665222113505" }, "name": "", "description": "" @@ -455,7 +455,9 @@ "conditionVersion": { "value": "[parameters('conditionVersion')]" }, - "condition": "[if(not(empty(parameters('condition'))), createObject('value', parameters('condition')), createObject('value', ''))]", + "condition": { + "value": "[parameters('condition')]" + }, "pimRoleAssignmentType": { "value": "[parameters('pimRoleAssignmentType')]" } @@ -468,7 +470,7 @@ "_generator": { "name": "bicep", "version": "0.33.93.31351", - "templateHash": "6801983411045663491" + "templateHash": "6796208717843142711" }, "name": " PIM Role Assignments (Management Group scope)", "description": "This module deploys a PIM Role Assignment at a Management Group scope." @@ -805,7 +807,7 @@ }, "condition": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to." } @@ -843,8 +845,8 @@ "principalId": "[parameters('principalId')]", "roleDefinitionId": "[variables('roleDefinitionIdVar')]", "requestType": "[parameters('requestType')]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", + "condition": "[parameters('condition')]", + "conditionVersion": "[parameters('conditionVersion')]", "justification": "[parameters('justification')]", "targetRoleEligibilityScheduleId": "[parameters('targetRoleEligibilityScheduleId')]", "targetRoleEligibilityScheduleInstanceId": "[parameters('targetRoleEligibilityScheduleInstanceId')]", @@ -862,7 +864,7 @@ "roleDefinitionId": "[variables('roleDefinitionIdVar')]", "requestType": "[parameters('requestType')]", "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", + "conditionVersion": "[parameters('conditionVersion')]", "justification": "[parameters('justification')]", "targetRoleAssignmentScheduleId": "[parameters('targetRoleAssignmentScheduleId')]", "targetRoleAssignmentScheduleInstanceId": "[parameters('targetRoleAssignmentScheduleInstanceId')]", @@ -937,7 +939,9 @@ "conditionVersion": { "value": "[parameters('conditionVersion')]" }, - "condition": "[if(not(empty(parameters('condition'))), createObject('value', parameters('condition')), createObject('value', ''))]", + "condition": { + "value": "[parameters('condition')]" + }, "pimRoleAssignmentType": { "value": "[parameters('pimRoleAssignmentType')]" } @@ -950,7 +954,7 @@ "_generator": { "name": "bicep", "version": "0.33.93.31351", - "templateHash": "6532334215185833316" + "templateHash": "12202824882334656506" }, "name": "PIM Role Assignments (Subscription scope)", "description": "This module deploys a PIM Role Assignment at a Subscription scope." @@ -1287,7 +1291,7 @@ }, "condition": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to." } @@ -1323,8 +1327,8 @@ "principalId": "[parameters('principalId')]", "roleDefinitionId": "[variables('roleDefinitionIdVar')]", "requestType": "[parameters('requestType')]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", + "condition": "[parameters('condition')]", + "conditionVersion": "[parameters('conditionVersion')]", "justification": "[parameters('justification')]", "targetRoleEligibilityScheduleId": "[parameters('targetRoleEligibilityScheduleId')]", "targetRoleEligibilityScheduleInstanceId": "[parameters('targetRoleEligibilityScheduleInstanceId')]", @@ -1342,7 +1346,7 @@ "roleDefinitionId": "[variables('roleDefinitionIdVar')]", "requestType": "[parameters('requestType')]", "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", + "conditionVersion": "[parameters('conditionVersion')]", "justification": "[parameters('justification')]", "targetRoleAssignmentScheduleId": "[parameters('targetRoleAssignmentScheduleId')]", "targetRoleAssignmentScheduleInstanceId": "[parameters('targetRoleAssignmentScheduleInstanceId')]", @@ -1427,7 +1431,9 @@ "conditionVersion": { "value": "[parameters('conditionVersion')]" }, - "condition": "[if(not(empty(parameters('condition'))), createObject('value', parameters('condition')), createObject('value', ''))]", + "condition": { + "value": "[parameters('condition')]" + }, "pimRoleAssignmentType": { "value": "[parameters('pimRoleAssignmentType')]" } @@ -1440,7 +1446,7 @@ "_generator": { "name": "bicep", "version": "0.33.93.31351", - "templateHash": "10199189630749282672" + "templateHash": "14454574202421677768" }, "name": "PIM Role Assignments (Resource Group scope)", "description": "This module deploys a PIM Role Assignment at a Resource Group scope." @@ -1784,7 +1790,7 @@ }, "condition": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to." } @@ -1820,8 +1826,8 @@ "roleDefinitionId": "[variables('roleDefinitionIdVar')]", "principalId": "[parameters('principalId')]", "requestType": "[parameters('requestType')]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", + "conditionVersion": "[parameters('conditionVersion')]", + "condition": "[parameters('condition')]", "justification": "[parameters('justification')]", "targetRoleEligibilityScheduleId": "[parameters('targetRoleEligibilityScheduleId')]", "targetRoleEligibilityScheduleInstanceId": "[parameters('targetRoleEligibilityScheduleInstanceId')]", @@ -1838,7 +1844,7 @@ "roleDefinitionId": "[variables('roleDefinitionIdVar')]", "principalId": "[parameters('principalId')]", "requestType": "[parameters('requestType')]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", + "conditionVersion": "[parameters('conditionVersion')]", "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", "justification": "[parameters('justification')]", "targetRoleAssignmentScheduleId": "[parameters('targetRoleAssignmentScheduleId')]", diff --git a/avm/ptn/authorization/pim-role-assignment/modules/management-group.bicep b/avm/ptn/authorization/pim-role-assignment/modules/management-group.bicep index 01d1c09bbd..1e0b359530 100644 --- a/avm/ptn/authorization/pim-role-assignment/modules/management-group.bicep +++ b/avm/ptn/authorization/pim-role-assignment/modules/management-group.bicep @@ -39,7 +39,7 @@ param targetRoleAssignmentScheduleInstanceId string = '' param ticketInfo ticketInfoType? @sys.description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to.') -param condition string = '' +param condition string? @sys.description('Optional. Version of the condition. Currently accepted value is "2.0".') @allowed([ @@ -77,8 +77,8 @@ resource pimEligibleRoleAssignment 'Microsoft.Authorization/roleEligibilitySched principalId: principalId roleDefinitionId: roleDefinitionIdVar requestType: requestType - condition: !empty(condition) ? condition : null - conditionVersion: !empty(conditionVersion) && !empty(condition) ? conditionVersion : null + condition: condition + conditionVersion: conditionVersion justification: justification targetRoleEligibilityScheduleId: targetRoleEligibilityScheduleId targetRoleEligibilityScheduleInstanceId: targetRoleEligibilityScheduleInstanceId @@ -116,7 +116,7 @@ resource pimActiveRoleAssignment 'Microsoft.Authorization/roleAssignmentSchedule roleDefinitionId: roleDefinitionIdVar requestType: requestType condition: !empty(condition) ? condition : null - conditionVersion: !empty(conditionVersion) && !empty(condition) ? conditionVersion : null + conditionVersion: conditionVersion justification: justification targetRoleAssignmentScheduleId: targetRoleAssignmentScheduleId targetRoleAssignmentScheduleInstanceId: targetRoleAssignmentScheduleInstanceId diff --git a/avm/ptn/authorization/pim-role-assignment/modules/resource-group.bicep b/avm/ptn/authorization/pim-role-assignment/modules/resource-group.bicep index 0d0077ddfb..2c3b3093c2 100644 --- a/avm/ptn/authorization/pim-role-assignment/modules/resource-group.bicep +++ b/avm/ptn/authorization/pim-role-assignment/modules/resource-group.bicep @@ -42,7 +42,7 @@ param targetRoleAssignmentScheduleInstanceId string = '' param ticketInfo ticketInfoType? @sys.description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to.') -param condition string = '' +param condition string? @sys.description('Optional. Version of the condition. Currently accepted value is "2.0".') @allowed([ @@ -72,8 +72,8 @@ resource pimEligibleRoleAssignment 'Microsoft.Authorization/roleEligibilitySched roleDefinitionId: roleDefinitionIdVar principalId: principalId requestType: requestType - conditionVersion: !empty(conditionVersion) && !empty(condition) ? conditionVersion : null - condition: !empty(condition) ? condition : null + conditionVersion: conditionVersion + condition: condition justification: justification targetRoleEligibilityScheduleId: targetRoleEligibilityScheduleId targetRoleEligibilityScheduleInstanceId: targetRoleEligibilityScheduleInstanceId @@ -110,7 +110,7 @@ resource pimActiveRoleAssignment 'Microsoft.Authorization/roleAssignmentSchedule roleDefinitionId: roleDefinitionIdVar principalId: principalId requestType: requestType - conditionVersion: !empty(conditionVersion) && !empty(condition) ? conditionVersion : null + conditionVersion: conditionVersion condition: !empty(condition) ? condition : null justification: justification targetRoleAssignmentScheduleId: targetRoleAssignmentScheduleId diff --git a/avm/ptn/authorization/pim-role-assignment/modules/subscription.bicep b/avm/ptn/authorization/pim-role-assignment/modules/subscription.bicep index 719c86a692..9313b65ac6 100644 --- a/avm/ptn/authorization/pim-role-assignment/modules/subscription.bicep +++ b/avm/ptn/authorization/pim-role-assignment/modules/subscription.bicep @@ -39,7 +39,8 @@ param targetRoleAssignmentScheduleInstanceId string = '' param ticketInfo ticketInfoType? @sys.description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to.') -param condition string = '' +@sys.description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to.') +param condition string? @sys.description('Optional. Version of the condition. Currently accepted value is "2.0".') @allowed([ @@ -69,8 +70,8 @@ resource pimEligibleRoleAssignment 'Microsoft.Authorization/roleEligibilitySched principalId: principalId roleDefinitionId: roleDefinitionIdVar requestType: requestType - condition: !empty(condition) ? condition : null - conditionVersion: !empty(conditionVersion) && !empty(condition) ? conditionVersion : null + condition: condition + conditionVersion: conditionVersion justification: justification targetRoleEligibilityScheduleId: targetRoleEligibilityScheduleId targetRoleEligibilityScheduleInstanceId: targetRoleEligibilityScheduleInstanceId @@ -108,7 +109,7 @@ resource pimActiveRoleAssignment 'Microsoft.Authorization/roleAssignmentSchedule roleDefinitionId: roleDefinitionIdVar requestType: requestType condition: !empty(condition) ? condition : null - conditionVersion: !empty(conditionVersion) && !empty(condition) ? conditionVersion : null + conditionVersion: conditionVersion justification: justification targetRoleAssignmentScheduleId: targetRoleAssignmentScheduleId targetRoleAssignmentScheduleInstanceId: targetRoleAssignmentScheduleInstanceId diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.eligible/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.eligible/main.test.bicep index 33166ce026..a7b03e0827 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.eligible/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.eligible/main.test.bicep @@ -15,9 +15,9 @@ param serviceShort string = 'pimgmin' @description('Optional. A token to inject into the name of each resource.') param namePrefix string = '#_namePrefix_#' -@description('Required. Principle ID of the user. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'CI-testUserObjectIdstring\'.') +@description('Required. Principle ID of the user. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'CI-testUserObjectId\'.') @secure() -param testUserObjectIdstring string = '' +param testUserObjectId string = '' @description('Optional. The start date and time for the role assignment. Defaults to the current date and time.') param startDateTime string = utcNow() @@ -37,7 +37,7 @@ module testDeployment '../../../main.bicep' = { startTime: startDateTime } } - principalId: testUserObjectIdstring + principalId: testUserObjectId requestType: 'AdminAssign' roleDefinitionIdOrName: 'Role Based Access Control Administrator' location: resourceLocation diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.active/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.active/main.test.bicep index ae900d8501..e8b7e93585 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.active/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.active/main.test.bicep @@ -28,9 +28,9 @@ param startDateTime string = utcNow() @description('Optional. The end date and time for the role assignment. Defaults to one year from the start date and time.') param endDateTime string = dateTimeAdd(startDateTime, 'PT4H') -@description('Required. Principle ID of the user. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'CI-testUserObjectIdstring\'.') +@description('Required. Principle ID of the user. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'CI-testUserObjectId\'.') @secure() -param testUserObjectIdstring string = '' +param testUserObjectId string = '' // General resources // ================= @@ -50,7 +50,7 @@ module resourceGroup 'br/public:avm/res/resources/resource-group:0.2.3' = { module testDeployment '../../../main.bicep' = { name: '${uniqueString(deployment().name)}-test-${serviceShort}' params: { - principalId: testUserObjectIdstring + principalId: testUserObjectId roleDefinitionIdOrName: '/providers/Microsoft.Authorization/roleDefinitions/f58310d9-a9f6-439a-9e8d-f62e7b41a168' location: resourceLocation subscriptionId: subscriptionId diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.active.permenant/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.active.permenant/main.test.bicep index d18be8b50a..a9f04c79d7 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.active.permenant/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.active.permenant/main.test.bicep @@ -15,9 +15,9 @@ param namePrefix string = '#_namePrefix_#' @description('Optional. Subscription ID of the subscription to assign the RBAC role to. If no Resource Group name is provided, the module deploys at subscription level, therefore assigns the provided RBAC role to the subscription.') param subscriptionId string = '#_subscriptionId_#' -@description('Required. Principle ID of the user. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'CI-testUserObjectIdstring\'.') +@description('Required. Principle ID of the user. This value is tenant-specific and must be stored in the CI Key Vault in a secret named \'CI-testUserObjectId\'.') @secure() -param testUserObjectIdstring string = '' +param testUserObjectId string = '' // ============== // // Test Execution // @@ -26,7 +26,7 @@ param testUserObjectIdstring string = '' module testDeployment '../../../main.bicep' = { name: '${uniqueString(deployment().name)}-test-${serviceShort}-${namePrefix}' params: { - principalId: testUserObjectIdstring + principalId: testUserObjectId roleDefinitionIdOrName: subscriptionResourceId( 'Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168' diff --git a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 index 384132e343..758d270459 100644 --- a/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 +++ b/utilities/pipelines/e2eValidation/resourceRemoval/helper/Invoke-ResourceRemoval.ps1 @@ -105,55 +105,6 @@ function Invoke-ResourceRemoval { $null = $roleAssignmentsOnScope | Where-Object { $_.RoleAssignmentId -eq $ResourceId } | Remove-AzRoleAssignment break } - 'Microsoft.Authorization/roleEligibilityScheduleRequests' { - $idElem = $ResourceId.Split('/') - $scope = $idElem[0..($idElem.Count - 5)] -join '/' - $pimRequestName = $idElem[-1] - $pimRoleAssignment = Get-AzRoleEligibilityScheduleRequest -Scope $scope -Name $pimRequestName - if ($pimRoleAssignment) { - $pimRoleAssignmentPrinicpalId = $pimRoleAssignment.PrincipalId - $pimRoleAssignmentRoleDefinitionId = $pimRoleAssignment.RoleDefinitionId - $guid = New-Guid - # PIM role assignments cannot be removed before 5 minutes from being created. Waiting for 5 minutes - Write-Verbose 'Waiting for 5 minutes before removing PIM role assignment' -Verbose - Start-Sleep -Seconds 300 - # The PIM ARM API doesn't support DELETE requests so the only way to delete an assignment is by creating a new assignment with `AdminRemove` type using a new GUID - $removalInputObject = @{ - Name = $guid - Scope = $scope - PrincipalId = $pimRoleAssignmentPrinicpalId - RequestType = 'AdminRemove' - RoleDefinitionId = $pimRoleAssignmentRoleDefinitionId - } - $null = New-AzRoleEligibilityScheduleRequest @removalInputObject - - } - break - } - 'Microsoft.Authorization/roleAssignmentScheduleRequests' { - $idElem = $ResourceId.Split('/') - $scope = $idElem[0..($idElem.Count - 5)] -join '/' - $pimRequestName = $idElem[-1] - $pimRoleAssignment = Get-AzRoleAssignmentScheduleRequest -Scope $scope -Name $pimRequestName - if ($pimRoleAssignment) { - $pimRoleAssignmentPrinicpalId = $pimRoleAssignment.PrincipalId - $pimRoleAssignmentRoleDefinitionId = $pimRoleAssignment.RoleDefinitionId - $guid = New-Guid - # PIM role assignments cannot be removed before 5 minutes from being created. Waiting for 5 minutes - Write-Verbose 'Waiting for 5 minutes before removing PIM role assignment' -Verbose - Start-Sleep -Seconds 300 - # The PIM ARM API doesn't support DELETE requests so the only way to delete an assignment is by creating a new assignment with `AdminRemove` type using a new GUID - $removalInputObject = @{ - Name = $guid - Scope = $scope - PrincipalId = $pimRoleAssignmentPrinicpalId - RequestType = 'AdminRemove' - RoleDefinitionId = $pimRoleAssignmentRoleDefinitionId - } - $null = New-AzRoleAssignmentScheduleRequest @removalInputObject - } - break - } 'Microsoft.RecoveryServices/vaults' { # Pre-Removal # ----------- From 96f3f87d3b0bc8d298adc0d6dc37e775f6afac25 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Mon, 17 Feb 2025 10:47:03 +0200 Subject: [PATCH 51/54] ``` fix: update documentation for resource removal process ``` --- .github/CODEOWNERS | 1 - .../pim-role-assignment/README.md | 4 +- .../pim-role-assignment/main.bicep | 102 ++- .../pim-role-assignment/main.json | 748 +++++++----------- .../modules/definitions.bicep | 95 --- .../modules/management-group.bicep | 98 ++- .../modules/resource-group.bicep | 98 ++- .../modules/subscription.bicep | 98 ++- 8 files changed, 694 insertions(+), 550 deletions(-) delete mode 100644 avm/ptn/authorization/pim-role-assignment/modules/definitions.bicep diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index c136f34453..e19d4cba70 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -6,7 +6,6 @@ /avm/ptn/aca-lza/hosting-environment/ @Azure/avm-ptn-acalza-hostingenvironment-module-owners-bicep @Azure/avm-module-reviewers-bicep /avm/ptn/ai-platform/baseline/ @Azure/avm-ptn-aiplatform-baseline-module-owners-bicep @Azure/avm-module-reviewers-bicep /avm/ptn/app/container-job-toolkit/ @Azure/avm-ptn-app-containerjobtoolkit-module-owners-bicep @Azure/avm-module-reviewers-bicep -/avm/ptn/authorization/role-assignment/ @Azure/avm-ptn-authorization-roleassignment-module-owners-bicep @Azure/avm-module-reviewers-bicep /avm/ptn/authorization/pim-role-assignment/ @Azure/avm-ptn-authorization-pimroleassignment-module-owners-bicep @Azure/avm-module-reviewers-bicep /avm/ptn/authorization/policy-assignment/ @Azure/avm-ptn-authorization-policyassignment-module-owners-bicep @Azure/avm-module-reviewers-bicep /avm/ptn/authorization/policy-exemption/ @Azure/avm-ptn-authorization-policyexemption-module-owners-bicep @Azure/avm-module-reviewers-bicep diff --git a/avm/ptn/authorization/pim-role-assignment/README.md b/avm/ptn/authorization/pim-role-assignment/README.md index c8dbf4f5dc..9a6cbac336 100644 --- a/avm/ptn/authorization/pim-role-assignment/README.md +++ b/avm/ptn/authorization/pim-role-assignment/README.md @@ -1,6 +1,6 @@ -# `[Authorization/PimRoleAssignment]` +# PIM Role Assignments (All scopes) `[Authorization/PimRoleAssignment]` - +This module deploys a PIM Role Assignment at a Management Group, Subscription or Resource Group scope. ## Navigation diff --git a/avm/ptn/authorization/pim-role-assignment/main.bicep b/avm/ptn/authorization/pim-role-assignment/main.bicep index 0fb147234e..01f5c8d395 100644 --- a/avm/ptn/authorization/pim-role-assignment/main.bicep +++ b/avm/ptn/authorization/pim-role-assignment/main.bicep @@ -1,10 +1,8 @@ -metadata name = '' -metadata description = '' +metadata name = 'PIM Role Assignments (All scopes)' +metadata description = 'This module deploys a PIM Role Assignment at a Management Group, Subscription or Resource Group scope.' targetScope = 'managementGroup' -import { requestTypeType, ticketInfoType, pimRoleAssignmentTypeType } from 'modules/definitions.bicep' - @sys.description('Required. You can provide either the display name of the role definition (must be configured in the variable `builtInRoleNames`), or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.') param roleDefinitionIdOrName string @@ -160,3 +158,99 @@ output scope string = empty(subscriptionId) && empty(resourceGroupName) : (!empty(subscriptionId) && empty(resourceGroupName) ? roleAssignment_sub.outputs.scope : roleAssignment_rg.outputs.scope) + +// ================ // +// Definitions // +// ================ // + +@export() +@sys.description('Optional. The request type of the role assignment.') +type requestTypeType = + | 'AdminAssign' + | 'AdminExtend' + | 'AdminRemove' + | 'AdminRenew' + | 'AdminUpdate' + | 'SelfActivate' + | 'SelfDeactivate' + | 'SelfExtend' + | 'SelfRenew' + +@export() +type ticketInfoType = { + @sys.description('Optional. The ticket number for the role eligibility assignment.') + ticketNumber: string? + + @sys.description('Optional. The ticket system name for the role eligibility assignment.') + ticketSystem: string? +}? + +@export() +@discriminator('roleAssignmentType') +@description('Optional. The type of the PIM role assignment whether its active or eligible.') +type pimRoleAssignmentTypeType = pimActiveRoleAssignmentType | pimEligibleRoleAssignmentType + +type pimActiveRoleAssignmentType = { + @description('Required. The type of the role assignment.') + roleAssignmentType: 'Active' + + @description('Optional. The linked role eligibility schedule id - to activate an eligibility.') + linkedRoleEligibilityScheduleId: string? + + @description('Optional. The resultant role assignment schedule id or the role assignment schedule id being updated.') + targetRoleAssignmentScheduleId: string? + + @description('Optional. The role assignment schedule instance id being updated.') + targetRoleAssignmentScheduleInstanceId: string? + + @description('Required. The schedule information for the role assignment.') + scheduleInfo: roleAssignmentScheduleType +} + +type pimEligibleRoleAssignmentType = { + @description('Required. The type of the role assignment.') + roleAssignmentType: 'Eligible' + + @description('Optional. The resultant role eligibility schedule id or the role eligibility schedule id being updated.') + targetRoleEligibilityScheduleId: string? + + @description('Optional. The role eligibility assignment instance id being updated.') + targetRoleEligibilityScheduleInstanceId: string? + + @description('Required. The schedule information for the role assignment.') + scheduleInfo: roleAssignmentScheduleType +} + +@discriminator('durationType') +@description('Optional. The schedule information for the role assignment.') +type roleAssignmentScheduleType = + | permenantRoleAssignmentScheduleType + | timeBoundDurationRoleAssignmentScheduleType + | timeBoundDateTimeRoleAssignmentScheduleType + +type permenantRoleAssignmentScheduleType = { + @description('Required. The type of the duration.') + durationType: 'NoExpiration' +} + +type timeBoundDurationRoleAssignmentScheduleType = { + @description('Required. The type of the duration.') + durationType: 'AfterDuration' + + @description('Required. The duration for the role assignment.') + duration: string + + @description('Required. The start time for the role assignment.') + startTime: string +} + +type timeBoundDateTimeRoleAssignmentScheduleType = { + @description('Required. The type of the duration.') + durationType: 'AfterDateTime' + + @description('Required. The end date and time for the role assignment.') + endDateTime: string + + @description('Required. The start date and time for the role assignment.') + startTime: string +} diff --git a/avm/ptn/authorization/pim-role-assignment/main.json b/avm/ptn/authorization/pim-role-assignment/main.json index 3b4c6dc886..eebaaec758 100644 --- a/avm/ptn/authorization/pim-role-assignment/main.json +++ b/avm/ptn/authorization/pim-role-assignment/main.json @@ -6,32 +6,72 @@ "_generator": { "name": "bicep", "version": "0.33.93.31351", - "templateHash": "9808758665222113505" + "templateHash": "2931179501063853931" }, - "name": "", - "description": "" + "name": "PIM Role Assignments (All scopes)", + "description": "This module deploys a PIM Role Assignment at a Management Group, Subscription or Resource Group scope." }, "definitions": { - "_1.permenantRoleAssignmentScheduleType": { + "requestTypeType": { + "type": "string", + "allowedValues": [ + "AdminAssign", + "AdminExtend", + "AdminRemove", + "AdminRenew", + "AdminUpdate", + "SelfActivate", + "SelfDeactivate", + "SelfExtend", + "SelfRenew" + ], + "metadata": { + "__bicep_export!": true, + "description": "Optional. The request type of the role assignment." + } + }, + "ticketInfoType": { "type": "object", "properties": { - "durationType": { + "ticketNumber": { "type": "string", - "allowedValues": [ - "NoExpiration" - ], + "nullable": true, "metadata": { - "description": "Required. The type of the duration." + "description": "Optional. The ticket number for the role eligibility assignment." + } + }, + "ticketSystem": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The ticket system name for the role eligibility assignment." } } }, + "nullable": true, "metadata": { - "__bicep_imported_from!": { - "sourceTemplate": "modules/definitions.bicep" + "__bicep_export!": true + } + }, + "pimRoleAssignmentTypeType": { + "type": "object", + "discriminator": { + "propertyName": "roleAssignmentType", + "mapping": { + "Active": { + "$ref": "#/definitions/pimActiveRoleAssignmentType" + }, + "Eligible": { + "$ref": "#/definitions/pimEligibleRoleAssignmentType" + } } + }, + "metadata": { + "__bicep_export!": true, + "description": "Optional. The type of the PIM role assignment whether its active or eligible." } }, - "_1.pimActiveRoleAssignmentType": { + "pimActiveRoleAssignmentType": { "type": "object", "properties": { "roleAssignmentType": { @@ -65,19 +105,14 @@ } }, "scheduleInfo": { - "$ref": "#/definitions/_1.roleAssignmentScheduleType", + "$ref": "#/definitions/roleAssignmentScheduleType", "metadata": { "description": "Required. The schedule information for the role assignment." } } - }, - "metadata": { - "__bicep_imported_from!": { - "sourceTemplate": "modules/definitions.bicep" - } } }, - "_1.pimEligibleRoleAssignmentType": { + "pimEligibleRoleAssignmentType": { "type": "object", "properties": { "roleAssignmentType": { @@ -104,73 +139,48 @@ } }, "scheduleInfo": { - "$ref": "#/definitions/_1.roleAssignmentScheduleType", + "$ref": "#/definitions/roleAssignmentScheduleType", "metadata": { "description": "Required. The schedule information for the role assignment." } } - }, - "metadata": { - "__bicep_imported_from!": { - "sourceTemplate": "modules/definitions.bicep" - } } }, - "_1.roleAssignmentScheduleType": { + "roleAssignmentScheduleType": { "type": "object", "discriminator": { "propertyName": "durationType", "mapping": { "NoExpiration": { - "$ref": "#/definitions/_1.permenantRoleAssignmentScheduleType" + "$ref": "#/definitions/permenantRoleAssignmentScheduleType" }, "AfterDuration": { - "$ref": "#/definitions/_1.timeBoundDurationRoleAssignmentScheduleType" + "$ref": "#/definitions/timeBoundDurationRoleAssignmentScheduleType" }, "AfterDateTime": { - "$ref": "#/definitions/_1.timeBoundDateTimeRoleAssignmentScheduleType" + "$ref": "#/definitions/timeBoundDateTimeRoleAssignmentScheduleType" } } }, "metadata": { - "description": "Optional. The schedule information for the role assignment.", - "__bicep_imported_from!": { - "sourceTemplate": "modules/definitions.bicep" - } + "description": "Optional. The schedule information for the role assignment." } }, - "_1.timeBoundDateTimeRoleAssignmentScheduleType": { + "permenantRoleAssignmentScheduleType": { "type": "object", "properties": { "durationType": { "type": "string", "allowedValues": [ - "AfterDateTime" + "NoExpiration" ], "metadata": { "description": "Required. The type of the duration." } - }, - "endDateTime": { - "type": "string", - "metadata": { - "description": "Required. The end date and time for the role assignment." - } - }, - "startTime": { - "type": "string", - "metadata": { - "description": "Required. The start date and time for the role assignment." - } - } - }, - "metadata": { - "__bicep_imported_from!": { - "sourceTemplate": "modules/definitions.bicep" } } }, - "_1.timeBoundDurationRoleAssignmentScheduleType": { + "timeBoundDurationRoleAssignmentScheduleType": { "type": "object", "properties": { "durationType": { @@ -194,75 +204,31 @@ "description": "Required. The start time for the role assignment." } } - }, - "metadata": { - "__bicep_imported_from!": { - "sourceTemplate": "modules/definitions.bicep" - } } }, - "pimRoleAssignmentTypeType": { - "type": "object", - "discriminator": { - "propertyName": "roleAssignmentType", - "mapping": { - "Active": { - "$ref": "#/definitions/_1.pimActiveRoleAssignmentType" - }, - "Eligible": { - "$ref": "#/definitions/_1.pimEligibleRoleAssignmentType" - } - } - }, - "metadata": { - "description": "Optional. The type of the PIM role assignment whether its active or eligible.", - "__bicep_imported_from!": { - "sourceTemplate": "modules/definitions.bicep" - } - } - }, - "requestTypeType": { - "type": "string", - "allowedValues": [ - "AdminAssign", - "AdminExtend", - "AdminRemove", - "AdminRenew", - "AdminUpdate", - "SelfActivate", - "SelfDeactivate", - "SelfExtend", - "SelfRenew" - ], - "metadata": { - "description": "Optional. The request type of the role assignment.", - "__bicep_imported_from!": { - "sourceTemplate": "modules/definitions.bicep" - } - } - }, - "ticketInfoType": { + "timeBoundDateTimeRoleAssignmentScheduleType": { "type": "object", "properties": { - "ticketNumber": { + "durationType": { "type": "string", - "nullable": true, + "allowedValues": [ + "AfterDateTime" + ], "metadata": { - "description": "Optional. The ticket number for the role eligibility assignment." + "description": "Required. The type of the duration." } }, - "ticketSystem": { + "endDateTime": { "type": "string", - "nullable": true, "metadata": { - "description": "Optional. The ticket system name for the role eligibility assignment." + "description": "Required. The end date and time for the role assignment." + } + }, + "startTime": { + "type": "string", + "metadata": { + "description": "Required. The start date and time for the role assignment." } - } - }, - "nullable": true, - "metadata": { - "__bicep_imported_from!": { - "sourceTemplate": "modules/definitions.bicep" } } } @@ -470,32 +436,72 @@ "_generator": { "name": "bicep", "version": "0.33.93.31351", - "templateHash": "6796208717843142711" + "templateHash": "3274153567221137365" }, "name": " PIM Role Assignments (Management Group scope)", "description": "This module deploys a PIM Role Assignment at a Management Group scope." }, "definitions": { - "_1.permenantRoleAssignmentScheduleType": { + "requestTypeType": { + "type": "string", + "allowedValues": [ + "AdminAssign", + "AdminExtend", + "AdminRemove", + "AdminRenew", + "AdminUpdate", + "SelfActivate", + "SelfDeactivate", + "SelfExtend", + "SelfRenew" + ], + "metadata": { + "__bicep_export!": true, + "description": "Optional. The request type of the role assignment." + } + }, + "ticketInfoType": { "type": "object", "properties": { - "durationType": { + "ticketNumber": { "type": "string", - "allowedValues": [ - "NoExpiration" - ], + "nullable": true, "metadata": { - "description": "Required. The type of the duration." + "description": "Optional. The ticket number for the role eligibility assignment." + } + }, + "ticketSystem": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The ticket system name for the role eligibility assignment." } } }, + "nullable": true, "metadata": { - "__bicep_imported_from!": { - "sourceTemplate": "definitions.bicep" + "__bicep_export!": true + } + }, + "pimRoleAssignmentTypeType": { + "type": "object", + "discriminator": { + "propertyName": "roleAssignmentType", + "mapping": { + "Active": { + "$ref": "#/definitions/pimActiveRoleAssignmentType" + }, + "Eligible": { + "$ref": "#/definitions/pimEligibleRoleAssignmentType" + } } + }, + "metadata": { + "__bicep_export!": true, + "description": "Optional. The type of the PIM role assignment whether its active or eligible." } }, - "_1.pimActiveRoleAssignmentType": { + "pimActiveRoleAssignmentType": { "type": "object", "properties": { "roleAssignmentType": { @@ -529,19 +535,14 @@ } }, "scheduleInfo": { - "$ref": "#/definitions/_1.roleAssignmentScheduleType", + "$ref": "#/definitions/roleAssignmentScheduleType", "metadata": { "description": "Required. The schedule information for the role assignment." } } - }, - "metadata": { - "__bicep_imported_from!": { - "sourceTemplate": "definitions.bicep" - } } }, - "_1.pimEligibleRoleAssignmentType": { + "pimEligibleRoleAssignmentType": { "type": "object", "properties": { "roleAssignmentType": { @@ -568,73 +569,48 @@ } }, "scheduleInfo": { - "$ref": "#/definitions/_1.roleAssignmentScheduleType", + "$ref": "#/definitions/roleAssignmentScheduleType", "metadata": { "description": "Required. The schedule information for the role assignment." } } - }, - "metadata": { - "__bicep_imported_from!": { - "sourceTemplate": "definitions.bicep" - } } }, - "_1.roleAssignmentScheduleType": { + "roleAssignmentScheduleType": { "type": "object", "discriminator": { "propertyName": "durationType", "mapping": { "NoExpiration": { - "$ref": "#/definitions/_1.permenantRoleAssignmentScheduleType" + "$ref": "#/definitions/permenantRoleAssignmentScheduleType" }, "AfterDuration": { - "$ref": "#/definitions/_1.timeBoundDurationRoleAssignmentScheduleType" + "$ref": "#/definitions/timeBoundDurationRoleAssignmentScheduleType" }, "AfterDateTime": { - "$ref": "#/definitions/_1.timeBoundDateTimeRoleAssignmentScheduleType" + "$ref": "#/definitions/timeBoundDateTimeRoleAssignmentScheduleType" } } }, "metadata": { - "description": "Optional. The schedule information for the role assignment.", - "__bicep_imported_from!": { - "sourceTemplate": "definitions.bicep" - } + "description": "Optional. The schedule information for the role assignment." } }, - "_1.timeBoundDateTimeRoleAssignmentScheduleType": { + "permenantRoleAssignmentScheduleType": { "type": "object", "properties": { "durationType": { "type": "string", "allowedValues": [ - "AfterDateTime" + "NoExpiration" ], "metadata": { "description": "Required. The type of the duration." } - }, - "endDateTime": { - "type": "string", - "metadata": { - "description": "Required. The end date and time for the role assignment." - } - }, - "startTime": { - "type": "string", - "metadata": { - "description": "Required. The start date and time for the role assignment." - } - } - }, - "metadata": { - "__bicep_imported_from!": { - "sourceTemplate": "definitions.bicep" } } }, - "_1.timeBoundDurationRoleAssignmentScheduleType": { + "timeBoundDurationRoleAssignmentScheduleType": { "type": "object", "properties": { "durationType": { @@ -658,75 +634,31 @@ "description": "Required. The start time for the role assignment." } } - }, - "metadata": { - "__bicep_imported_from!": { - "sourceTemplate": "definitions.bicep" - } - } - }, - "pimRoleAssignmentTypeType": { - "type": "object", - "discriminator": { - "propertyName": "roleAssignmentType", - "mapping": { - "Active": { - "$ref": "#/definitions/_1.pimActiveRoleAssignmentType" - }, - "Eligible": { - "$ref": "#/definitions/_1.pimEligibleRoleAssignmentType" - } - } - }, - "metadata": { - "description": "Optional. The type of the PIM role assignment whether its active or eligible.", - "__bicep_imported_from!": { - "sourceTemplate": "definitions.bicep" - } - } - }, - "requestTypeType": { - "type": "string", - "allowedValues": [ - "AdminAssign", - "AdminExtend", - "AdminRemove", - "AdminRenew", - "AdminUpdate", - "SelfActivate", - "SelfDeactivate", - "SelfExtend", - "SelfRenew" - ], - "metadata": { - "description": "Optional. The request type of the role assignment.", - "__bicep_imported_from!": { - "sourceTemplate": "definitions.bicep" - } } }, - "ticketInfoType": { + "timeBoundDateTimeRoleAssignmentScheduleType": { "type": "object", "properties": { - "ticketNumber": { + "durationType": { "type": "string", - "nullable": true, + "allowedValues": [ + "AfterDateTime" + ], "metadata": { - "description": "Optional. The ticket number for the role eligibility assignment." + "description": "Required. The type of the duration." } }, - "ticketSystem": { + "endDateTime": { "type": "string", - "nullable": true, "metadata": { - "description": "Optional. The ticket system name for the role eligibility assignment." + "description": "Required. The end date and time for the role assignment." + } + }, + "startTime": { + "type": "string", + "metadata": { + "description": "Required. The start date and time for the role assignment." } - } - }, - "nullable": true, - "metadata": { - "__bicep_imported_from!": { - "sourceTemplate": "definitions.bicep" } } } @@ -954,32 +886,72 @@ "_generator": { "name": "bicep", "version": "0.33.93.31351", - "templateHash": "12202824882334656506" + "templateHash": "15288642990461981614" + }, + "name": "PIM Role Assignments (Subscription scope)", + "description": "This module deploys a PIM Role Assignment at a Subscription scope." + }, + "definitions": { + "requestTypeType": { + "type": "string", + "allowedValues": [ + "AdminAssign", + "AdminExtend", + "AdminRemove", + "AdminRenew", + "AdminUpdate", + "SelfActivate", + "SelfDeactivate", + "SelfExtend", + "SelfRenew" + ], + "metadata": { + "__bicep_export!": true, + "description": "Optional. The request type of the role assignment." + } }, - "name": "PIM Role Assignments (Subscription scope)", - "description": "This module deploys a PIM Role Assignment at a Subscription scope." - }, - "definitions": { - "_1.permenantRoleAssignmentScheduleType": { + "ticketInfoType": { "type": "object", "properties": { - "durationType": { + "ticketNumber": { "type": "string", - "allowedValues": [ - "NoExpiration" - ], + "nullable": true, "metadata": { - "description": "Required. The type of the duration." + "description": "Optional. The ticket number for the role eligibility assignment." + } + }, + "ticketSystem": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The ticket system name for the role eligibility assignment." } } }, + "nullable": true, "metadata": { - "__bicep_imported_from!": { - "sourceTemplate": "definitions.bicep" + "__bicep_export!": true + } + }, + "pimRoleAssignmentTypeType": { + "type": "object", + "discriminator": { + "propertyName": "roleAssignmentType", + "mapping": { + "Active": { + "$ref": "#/definitions/pimActiveRoleAssignmentType" + }, + "Eligible": { + "$ref": "#/definitions/pimEligibleRoleAssignmentType" + } } + }, + "metadata": { + "__bicep_export!": true, + "description": "Optional. The type of the PIM role assignment whether its active or eligible." } }, - "_1.pimActiveRoleAssignmentType": { + "pimActiveRoleAssignmentType": { "type": "object", "properties": { "roleAssignmentType": { @@ -1013,19 +985,14 @@ } }, "scheduleInfo": { - "$ref": "#/definitions/_1.roleAssignmentScheduleType", + "$ref": "#/definitions/roleAssignmentScheduleType", "metadata": { "description": "Required. The schedule information for the role assignment." } } - }, - "metadata": { - "__bicep_imported_from!": { - "sourceTemplate": "definitions.bicep" - } } }, - "_1.pimEligibleRoleAssignmentType": { + "pimEligibleRoleAssignmentType": { "type": "object", "properties": { "roleAssignmentType": { @@ -1052,73 +1019,48 @@ } }, "scheduleInfo": { - "$ref": "#/definitions/_1.roleAssignmentScheduleType", + "$ref": "#/definitions/roleAssignmentScheduleType", "metadata": { "description": "Required. The schedule information for the role assignment." } } - }, - "metadata": { - "__bicep_imported_from!": { - "sourceTemplate": "definitions.bicep" - } } }, - "_1.roleAssignmentScheduleType": { + "roleAssignmentScheduleType": { "type": "object", "discriminator": { "propertyName": "durationType", "mapping": { "NoExpiration": { - "$ref": "#/definitions/_1.permenantRoleAssignmentScheduleType" + "$ref": "#/definitions/permenantRoleAssignmentScheduleType" }, "AfterDuration": { - "$ref": "#/definitions/_1.timeBoundDurationRoleAssignmentScheduleType" + "$ref": "#/definitions/timeBoundDurationRoleAssignmentScheduleType" }, "AfterDateTime": { - "$ref": "#/definitions/_1.timeBoundDateTimeRoleAssignmentScheduleType" + "$ref": "#/definitions/timeBoundDateTimeRoleAssignmentScheduleType" } } }, "metadata": { - "description": "Optional. The schedule information for the role assignment.", - "__bicep_imported_from!": { - "sourceTemplate": "definitions.bicep" - } + "description": "Optional. The schedule information for the role assignment." } }, - "_1.timeBoundDateTimeRoleAssignmentScheduleType": { + "permenantRoleAssignmentScheduleType": { "type": "object", "properties": { "durationType": { "type": "string", "allowedValues": [ - "AfterDateTime" + "NoExpiration" ], "metadata": { "description": "Required. The type of the duration." } - }, - "endDateTime": { - "type": "string", - "metadata": { - "description": "Required. The end date and time for the role assignment." - } - }, - "startTime": { - "type": "string", - "metadata": { - "description": "Required. The start date and time for the role assignment." - } - } - }, - "metadata": { - "__bicep_imported_from!": { - "sourceTemplate": "definitions.bicep" } } }, - "_1.timeBoundDurationRoleAssignmentScheduleType": { + "timeBoundDurationRoleAssignmentScheduleType": { "type": "object", "properties": { "durationType": { @@ -1142,75 +1084,31 @@ "description": "Required. The start time for the role assignment." } } - }, - "metadata": { - "__bicep_imported_from!": { - "sourceTemplate": "definitions.bicep" - } - } - }, - "pimRoleAssignmentTypeType": { - "type": "object", - "discriminator": { - "propertyName": "roleAssignmentType", - "mapping": { - "Active": { - "$ref": "#/definitions/_1.pimActiveRoleAssignmentType" - }, - "Eligible": { - "$ref": "#/definitions/_1.pimEligibleRoleAssignmentType" - } - } - }, - "metadata": { - "description": "Optional. The type of the PIM role assignment whether its active or eligible.", - "__bicep_imported_from!": { - "sourceTemplate": "definitions.bicep" - } - } - }, - "requestTypeType": { - "type": "string", - "allowedValues": [ - "AdminAssign", - "AdminExtend", - "AdminRemove", - "AdminRenew", - "AdminUpdate", - "SelfActivate", - "SelfDeactivate", - "SelfExtend", - "SelfRenew" - ], - "metadata": { - "description": "Optional. The request type of the role assignment.", - "__bicep_imported_from!": { - "sourceTemplate": "definitions.bicep" - } } }, - "ticketInfoType": { + "timeBoundDateTimeRoleAssignmentScheduleType": { "type": "object", "properties": { - "ticketNumber": { + "durationType": { "type": "string", - "nullable": true, + "allowedValues": [ + "AfterDateTime" + ], "metadata": { - "description": "Optional. The ticket number for the role eligibility assignment." + "description": "Required. The type of the duration." } }, - "ticketSystem": { + "endDateTime": { "type": "string", - "nullable": true, "metadata": { - "description": "Optional. The ticket system name for the role eligibility assignment." + "description": "Required. The end date and time for the role assignment." + } + }, + "startTime": { + "type": "string", + "metadata": { + "description": "Required. The start date and time for the role assignment." } - } - }, - "nullable": true, - "metadata": { - "__bicep_imported_from!": { - "sourceTemplate": "definitions.bicep" } } } @@ -1446,32 +1344,72 @@ "_generator": { "name": "bicep", "version": "0.33.93.31351", - "templateHash": "14454574202421677768" + "templateHash": "9698835458053155186" }, "name": "PIM Role Assignments (Resource Group scope)", "description": "This module deploys a PIM Role Assignment at a Resource Group scope." }, "definitions": { - "_1.permenantRoleAssignmentScheduleType": { + "requestTypeType": { + "type": "string", + "allowedValues": [ + "AdminAssign", + "AdminExtend", + "AdminRemove", + "AdminRenew", + "AdminUpdate", + "SelfActivate", + "SelfDeactivate", + "SelfExtend", + "SelfRenew" + ], + "metadata": { + "__bicep_export!": true, + "description": "Optional. The request type of the role assignment." + } + }, + "ticketInfoType": { "type": "object", "properties": { - "durationType": { + "ticketNumber": { "type": "string", - "allowedValues": [ - "NoExpiration" - ], + "nullable": true, "metadata": { - "description": "Required. The type of the duration." + "description": "Optional. The ticket number for the role eligibility assignment." + } + }, + "ticketSystem": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The ticket system name for the role eligibility assignment." } } }, + "nullable": true, "metadata": { - "__bicep_imported_from!": { - "sourceTemplate": "definitions.bicep" + "__bicep_export!": true + } + }, + "pimRoleAssignmentTypeType": { + "type": "object", + "discriminator": { + "propertyName": "roleAssignmentType", + "mapping": { + "Active": { + "$ref": "#/definitions/pimActiveRoleAssignmentType" + }, + "Eligible": { + "$ref": "#/definitions/pimEligibleRoleAssignmentType" + } } + }, + "metadata": { + "__bicep_export!": true, + "description": "Optional. The type of the PIM role assignment whether its active or eligible." } }, - "_1.pimActiveRoleAssignmentType": { + "pimActiveRoleAssignmentType": { "type": "object", "properties": { "roleAssignmentType": { @@ -1505,19 +1443,14 @@ } }, "scheduleInfo": { - "$ref": "#/definitions/_1.roleAssignmentScheduleType", + "$ref": "#/definitions/roleAssignmentScheduleType", "metadata": { "description": "Required. The schedule information for the role assignment." } } - }, - "metadata": { - "__bicep_imported_from!": { - "sourceTemplate": "definitions.bicep" - } } }, - "_1.pimEligibleRoleAssignmentType": { + "pimEligibleRoleAssignmentType": { "type": "object", "properties": { "roleAssignmentType": { @@ -1544,73 +1477,48 @@ } }, "scheduleInfo": { - "$ref": "#/definitions/_1.roleAssignmentScheduleType", + "$ref": "#/definitions/roleAssignmentScheduleType", "metadata": { "description": "Required. The schedule information for the role assignment." } } - }, - "metadata": { - "__bicep_imported_from!": { - "sourceTemplate": "definitions.bicep" - } } }, - "_1.roleAssignmentScheduleType": { + "roleAssignmentScheduleType": { "type": "object", "discriminator": { "propertyName": "durationType", "mapping": { "NoExpiration": { - "$ref": "#/definitions/_1.permenantRoleAssignmentScheduleType" + "$ref": "#/definitions/permenantRoleAssignmentScheduleType" }, "AfterDuration": { - "$ref": "#/definitions/_1.timeBoundDurationRoleAssignmentScheduleType" + "$ref": "#/definitions/timeBoundDurationRoleAssignmentScheduleType" }, "AfterDateTime": { - "$ref": "#/definitions/_1.timeBoundDateTimeRoleAssignmentScheduleType" + "$ref": "#/definitions/timeBoundDateTimeRoleAssignmentScheduleType" } } }, "metadata": { - "description": "Optional. The schedule information for the role assignment.", - "__bicep_imported_from!": { - "sourceTemplate": "definitions.bicep" - } + "description": "Optional. The schedule information for the role assignment." } }, - "_1.timeBoundDateTimeRoleAssignmentScheduleType": { + "permenantRoleAssignmentScheduleType": { "type": "object", "properties": { "durationType": { "type": "string", "allowedValues": [ - "AfterDateTime" + "NoExpiration" ], "metadata": { "description": "Required. The type of the duration." } - }, - "endDateTime": { - "type": "string", - "metadata": { - "description": "Required. The end date and time for the role assignment." - } - }, - "startTime": { - "type": "string", - "metadata": { - "description": "Required. The start date and time for the role assignment." - } - } - }, - "metadata": { - "__bicep_imported_from!": { - "sourceTemplate": "definitions.bicep" } } }, - "_1.timeBoundDurationRoleAssignmentScheduleType": { + "timeBoundDurationRoleAssignmentScheduleType": { "type": "object", "properties": { "durationType": { @@ -1634,75 +1542,31 @@ "description": "Required. The start time for the role assignment." } } - }, - "metadata": { - "__bicep_imported_from!": { - "sourceTemplate": "definitions.bicep" - } - } - }, - "pimRoleAssignmentTypeType": { - "type": "object", - "discriminator": { - "propertyName": "roleAssignmentType", - "mapping": { - "Active": { - "$ref": "#/definitions/_1.pimActiveRoleAssignmentType" - }, - "Eligible": { - "$ref": "#/definitions/_1.pimEligibleRoleAssignmentType" - } - } - }, - "metadata": { - "description": "Optional. The type of the PIM role assignment whether its active or eligible.", - "__bicep_imported_from!": { - "sourceTemplate": "definitions.bicep" - } - } - }, - "requestTypeType": { - "type": "string", - "allowedValues": [ - "AdminAssign", - "AdminExtend", - "AdminRemove", - "AdminRenew", - "AdminUpdate", - "SelfActivate", - "SelfDeactivate", - "SelfExtend", - "SelfRenew" - ], - "metadata": { - "description": "Optional. The request type of the role assignment.", - "__bicep_imported_from!": { - "sourceTemplate": "definitions.bicep" - } } }, - "ticketInfoType": { + "timeBoundDateTimeRoleAssignmentScheduleType": { "type": "object", "properties": { - "ticketNumber": { + "durationType": { "type": "string", - "nullable": true, + "allowedValues": [ + "AfterDateTime" + ], "metadata": { - "description": "Optional. The ticket number for the role eligibility assignment." + "description": "Required. The type of the duration." } }, - "ticketSystem": { + "endDateTime": { "type": "string", - "nullable": true, "metadata": { - "description": "Optional. The ticket system name for the role eligibility assignment." + "description": "Required. The end date and time for the role assignment." + } + }, + "startTime": { + "type": "string", + "metadata": { + "description": "Required. The start date and time for the role assignment." } - } - }, - "nullable": true, - "metadata": { - "__bicep_imported_from!": { - "sourceTemplate": "definitions.bicep" } } } diff --git a/avm/ptn/authorization/pim-role-assignment/modules/definitions.bicep b/avm/ptn/authorization/pim-role-assignment/modules/definitions.bicep deleted file mode 100644 index b3a298420b..0000000000 --- a/avm/ptn/authorization/pim-role-assignment/modules/definitions.bicep +++ /dev/null @@ -1,95 +0,0 @@ -// ================ // -// Definitions // -// ================ // - -@export() -@sys.description('Optional. The request type of the role assignment.') -type requestTypeType = - | 'AdminAssign' - | 'AdminExtend' - | 'AdminRemove' - | 'AdminRenew' - | 'AdminUpdate' - | 'SelfActivate' - | 'SelfDeactivate' - | 'SelfExtend' - | 'SelfRenew' - -@export() -type ticketInfoType = { - @sys.description('Optional. The ticket number for the role eligibility assignment.') - ticketNumber: string? - - @sys.description('Optional. The ticket system name for the role eligibility assignment.') - ticketSystem: string? -}? - -@export() -@discriminator('roleAssignmentType') -@description('Optional. The type of the PIM role assignment whether its active or eligible.') -type pimRoleAssignmentTypeType = pimActiveRoleAssignmentType | pimEligibleRoleAssignmentType - -type pimActiveRoleAssignmentType = { - @description('Required. The type of the role assignment.') - roleAssignmentType: 'Active' - - @description('Optional. The linked role eligibility schedule id - to activate an eligibility.') - linkedRoleEligibilityScheduleId: string? - - @description('Optional. The resultant role assignment schedule id or the role assignment schedule id being updated.') - targetRoleAssignmentScheduleId: string? - - @description('Optional. The role assignment schedule instance id being updated.') - targetRoleAssignmentScheduleInstanceId: string? - - @description('Required. The schedule information for the role assignment.') - scheduleInfo: roleAssignmentScheduleType -} - -type pimEligibleRoleAssignmentType = { - @description('Required. The type of the role assignment.') - roleAssignmentType: 'Eligible' - - @description('Optional. The resultant role eligibility schedule id or the role eligibility schedule id being updated.') - targetRoleEligibilityScheduleId: string? - - @description('Optional. The role eligibility assignment instance id being updated.') - targetRoleEligibilityScheduleInstanceId: string? - - @description('Required. The schedule information for the role assignment.') - scheduleInfo: roleAssignmentScheduleType -} - -@discriminator('durationType') -@description('Optional. The schedule information for the role assignment.') -type roleAssignmentScheduleType = - | permenantRoleAssignmentScheduleType - | timeBoundDurationRoleAssignmentScheduleType - | timeBoundDateTimeRoleAssignmentScheduleType - -type permenantRoleAssignmentScheduleType = { - @description('Required. The type of the duration.') - durationType: 'NoExpiration' -} - -type timeBoundDurationRoleAssignmentScheduleType = { - @description('Required. The type of the duration.') - durationType: 'AfterDuration' - - @description('Required. The duration for the role assignment.') - duration: string - - @description('Required. The start time for the role assignment.') - startTime: string -} - -type timeBoundDateTimeRoleAssignmentScheduleType = { - @description('Required. The type of the duration.') - durationType: 'AfterDateTime' - - @description('Required. The end date and time for the role assignment.') - endDateTime: string - - @description('Required. The start date and time for the role assignment.') - startTime: string -} diff --git a/avm/ptn/authorization/pim-role-assignment/modules/management-group.bicep b/avm/ptn/authorization/pim-role-assignment/modules/management-group.bicep index 1e0b359530..d306013e07 100644 --- a/avm/ptn/authorization/pim-role-assignment/modules/management-group.bicep +++ b/avm/ptn/authorization/pim-role-assignment/modules/management-group.bicep @@ -3,8 +3,6 @@ metadata description = 'This module deploys a PIM Role Assignment at a Managemen targetScope = 'managementGroup' -import { requestTypeType, pimRoleAssignmentTypeType, ticketInfoType } from 'definitions.bicep' - @sys.description('Required. You can provide either the display name of the role definition (must be configured in the variable `builtInRoleNames`), or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.') param roleDefinitionIdOrName string @@ -159,3 +157,99 @@ output resourceId string = pimRoleAssignmentType.roleAssignmentType == 'Eligible @sys.description('The scope this PIM Role Assignment applies to.') output scope string = az.resourceId('Microsoft.Management/managementGroups', managementGroupId) + +// ================ // +// Definitions // +// ================ // + +@export() +@sys.description('Optional. The request type of the role assignment.') +type requestTypeType = + | 'AdminAssign' + | 'AdminExtend' + | 'AdminRemove' + | 'AdminRenew' + | 'AdminUpdate' + | 'SelfActivate' + | 'SelfDeactivate' + | 'SelfExtend' + | 'SelfRenew' + +@export() +type ticketInfoType = { + @sys.description('Optional. The ticket number for the role eligibility assignment.') + ticketNumber: string? + + @sys.description('Optional. The ticket system name for the role eligibility assignment.') + ticketSystem: string? +}? + +@export() +@discriminator('roleAssignmentType') +@description('Optional. The type of the PIM role assignment whether its active or eligible.') +type pimRoleAssignmentTypeType = pimActiveRoleAssignmentType | pimEligibleRoleAssignmentType + +type pimActiveRoleAssignmentType = { + @description('Required. The type of the role assignment.') + roleAssignmentType: 'Active' + + @description('Optional. The linked role eligibility schedule id - to activate an eligibility.') + linkedRoleEligibilityScheduleId: string? + + @description('Optional. The resultant role assignment schedule id or the role assignment schedule id being updated.') + targetRoleAssignmentScheduleId: string? + + @description('Optional. The role assignment schedule instance id being updated.') + targetRoleAssignmentScheduleInstanceId: string? + + @description('Required. The schedule information for the role assignment.') + scheduleInfo: roleAssignmentScheduleType +} + +type pimEligibleRoleAssignmentType = { + @description('Required. The type of the role assignment.') + roleAssignmentType: 'Eligible' + + @description('Optional. The resultant role eligibility schedule id or the role eligibility schedule id being updated.') + targetRoleEligibilityScheduleId: string? + + @description('Optional. The role eligibility assignment instance id being updated.') + targetRoleEligibilityScheduleInstanceId: string? + + @description('Required. The schedule information for the role assignment.') + scheduleInfo: roleAssignmentScheduleType +} + +@discriminator('durationType') +@description('Optional. The schedule information for the role assignment.') +type roleAssignmentScheduleType = + | permenantRoleAssignmentScheduleType + | timeBoundDurationRoleAssignmentScheduleType + | timeBoundDateTimeRoleAssignmentScheduleType + +type permenantRoleAssignmentScheduleType = { + @description('Required. The type of the duration.') + durationType: 'NoExpiration' +} + +type timeBoundDurationRoleAssignmentScheduleType = { + @description('Required. The type of the duration.') + durationType: 'AfterDuration' + + @description('Required. The duration for the role assignment.') + duration: string + + @description('Required. The start time for the role assignment.') + startTime: string +} + +type timeBoundDateTimeRoleAssignmentScheduleType = { + @description('Required. The type of the duration.') + durationType: 'AfterDateTime' + + @description('Required. The end date and time for the role assignment.') + endDateTime: string + + @description('Required. The start date and time for the role assignment.') + startTime: string +} diff --git a/avm/ptn/authorization/pim-role-assignment/modules/resource-group.bicep b/avm/ptn/authorization/pim-role-assignment/modules/resource-group.bicep index 2c3b3093c2..32a92ec38d 100644 --- a/avm/ptn/authorization/pim-role-assignment/modules/resource-group.bicep +++ b/avm/ptn/authorization/pim-role-assignment/modules/resource-group.bicep @@ -3,8 +3,6 @@ metadata description = 'This module deploys a PIM Role Assignment at a Resource targetScope = 'resourceGroup' -import { requestTypeType, pimRoleAssignmentTypeType, ticketInfoType } from 'definitions.bicep' - @sys.description('Required. You can provide either the display name of the role definition (must be configured in the variable `builtInRoleNames`), or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.') param roleDefinitionIdOrName string @@ -157,3 +155,99 @@ output resourceGroupName string = resourceGroup().name @sys.description('The scope this PIM Role Assignment applies to.') output scope string = resourceGroup().id + +// ================ // +// Definitions // +// ================ // + +@export() +@sys.description('Optional. The request type of the role assignment.') +type requestTypeType = + | 'AdminAssign' + | 'AdminExtend' + | 'AdminRemove' + | 'AdminRenew' + | 'AdminUpdate' + | 'SelfActivate' + | 'SelfDeactivate' + | 'SelfExtend' + | 'SelfRenew' + +@export() +type ticketInfoType = { + @sys.description('Optional. The ticket number for the role eligibility assignment.') + ticketNumber: string? + + @sys.description('Optional. The ticket system name for the role eligibility assignment.') + ticketSystem: string? +}? + +@export() +@discriminator('roleAssignmentType') +@description('Optional. The type of the PIM role assignment whether its active or eligible.') +type pimRoleAssignmentTypeType = pimActiveRoleAssignmentType | pimEligibleRoleAssignmentType + +type pimActiveRoleAssignmentType = { + @description('Required. The type of the role assignment.') + roleAssignmentType: 'Active' + + @description('Optional. The linked role eligibility schedule id - to activate an eligibility.') + linkedRoleEligibilityScheduleId: string? + + @description('Optional. The resultant role assignment schedule id or the role assignment schedule id being updated.') + targetRoleAssignmentScheduleId: string? + + @description('Optional. The role assignment schedule instance id being updated.') + targetRoleAssignmentScheduleInstanceId: string? + + @description('Required. The schedule information for the role assignment.') + scheduleInfo: roleAssignmentScheduleType +} + +type pimEligibleRoleAssignmentType = { + @description('Required. The type of the role assignment.') + roleAssignmentType: 'Eligible' + + @description('Optional. The resultant role eligibility schedule id or the role eligibility schedule id being updated.') + targetRoleEligibilityScheduleId: string? + + @description('Optional. The role eligibility assignment instance id being updated.') + targetRoleEligibilityScheduleInstanceId: string? + + @description('Required. The schedule information for the role assignment.') + scheduleInfo: roleAssignmentScheduleType +} + +@discriminator('durationType') +@description('Optional. The schedule information for the role assignment.') +type roleAssignmentScheduleType = + | permenantRoleAssignmentScheduleType + | timeBoundDurationRoleAssignmentScheduleType + | timeBoundDateTimeRoleAssignmentScheduleType + +type permenantRoleAssignmentScheduleType = { + @description('Required. The type of the duration.') + durationType: 'NoExpiration' +} + +type timeBoundDurationRoleAssignmentScheduleType = { + @description('Required. The type of the duration.') + durationType: 'AfterDuration' + + @description('Required. The duration for the role assignment.') + duration: string + + @description('Required. The start time for the role assignment.') + startTime: string +} + +type timeBoundDateTimeRoleAssignmentScheduleType = { + @description('Required. The type of the duration.') + durationType: 'AfterDateTime' + + @description('Required. The end date and time for the role assignment.') + endDateTime: string + + @description('Required. The start date and time for the role assignment.') + startTime: string +} diff --git a/avm/ptn/authorization/pim-role-assignment/modules/subscription.bicep b/avm/ptn/authorization/pim-role-assignment/modules/subscription.bicep index 9313b65ac6..ec96234f28 100644 --- a/avm/ptn/authorization/pim-role-assignment/modules/subscription.bicep +++ b/avm/ptn/authorization/pim-role-assignment/modules/subscription.bicep @@ -3,8 +3,6 @@ metadata description = 'This module deploys a PIM Role Assignment at a Subscript targetScope = 'subscription' -import { requestTypeType, pimRoleAssignmentTypeType, ticketInfoType } from 'definitions.bicep' - @sys.description('Required. You can provide either the display name of the role definition (must be configured in the variable `builtInRoleNames`), or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.') param roleDefinitionIdOrName string @@ -155,3 +153,99 @@ output subscriptionName string = subscription().displayName @sys.description('The scope this PIM Role Assignment applies to.') output scope string = subscription().id + +// ================ // +// Definitions // +// ================ // + +@export() +@sys.description('Optional. The request type of the role assignment.') +type requestTypeType = + | 'AdminAssign' + | 'AdminExtend' + | 'AdminRemove' + | 'AdminRenew' + | 'AdminUpdate' + | 'SelfActivate' + | 'SelfDeactivate' + | 'SelfExtend' + | 'SelfRenew' + +@export() +type ticketInfoType = { + @sys.description('Optional. The ticket number for the role eligibility assignment.') + ticketNumber: string? + + @sys.description('Optional. The ticket system name for the role eligibility assignment.') + ticketSystem: string? +}? + +@export() +@discriminator('roleAssignmentType') +@description('Optional. The type of the PIM role assignment whether its active or eligible.') +type pimRoleAssignmentTypeType = pimActiveRoleAssignmentType | pimEligibleRoleAssignmentType + +type pimActiveRoleAssignmentType = { + @description('Required. The type of the role assignment.') + roleAssignmentType: 'Active' + + @description('Optional. The linked role eligibility schedule id - to activate an eligibility.') + linkedRoleEligibilityScheduleId: string? + + @description('Optional. The resultant role assignment schedule id or the role assignment schedule id being updated.') + targetRoleAssignmentScheduleId: string? + + @description('Optional. The role assignment schedule instance id being updated.') + targetRoleAssignmentScheduleInstanceId: string? + + @description('Required. The schedule information for the role assignment.') + scheduleInfo: roleAssignmentScheduleType +} + +type pimEligibleRoleAssignmentType = { + @description('Required. The type of the role assignment.') + roleAssignmentType: 'Eligible' + + @description('Optional. The resultant role eligibility schedule id or the role eligibility schedule id being updated.') + targetRoleEligibilityScheduleId: string? + + @description('Optional. The role eligibility assignment instance id being updated.') + targetRoleEligibilityScheduleInstanceId: string? + + @description('Required. The schedule information for the role assignment.') + scheduleInfo: roleAssignmentScheduleType +} + +@discriminator('durationType') +@description('Optional. The schedule information for the role assignment.') +type roleAssignmentScheduleType = + | permenantRoleAssignmentScheduleType + | timeBoundDurationRoleAssignmentScheduleType + | timeBoundDateTimeRoleAssignmentScheduleType + +type permenantRoleAssignmentScheduleType = { + @description('Required. The type of the duration.') + durationType: 'NoExpiration' +} + +type timeBoundDurationRoleAssignmentScheduleType = { + @description('Required. The type of the duration.') + durationType: 'AfterDuration' + + @description('Required. The duration for the role assignment.') + duration: string + + @description('Required. The start time for the role assignment.') + startTime: string +} + +type timeBoundDateTimeRoleAssignmentScheduleType = { + @description('Required. The type of the duration.') + durationType: 'AfterDateTime' + + @description('Required. The end date and time for the role assignment.') + endDateTime: string + + @description('Required. The start date and time for the role assignment.') + startTime: string +} From 1393248c8c158d01750f4328a9d53f81a9320f31 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Mon, 17 Feb 2025 11:43:59 +0200 Subject: [PATCH 52/54] Update avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.eligible/main.test.bicep Co-authored-by: Alexander Sehr --- .../pim-role-assignment/tests/e2e/mg.eligible/main.test.bicep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.eligible/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.eligible/main.test.bicep index a7b03e0827..32c1c48c79 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.eligible/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/mg.eligible/main.test.bicep @@ -10,7 +10,7 @@ metadata description = 'This module deploys a PIM Eligible Role Assignment at a param resourceLocation string = deployment().location @description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') -param serviceShort string = 'pimgmin' +param serviceShort string = 'papmgl' @description('Optional. A token to inject into the name of each resource.') param namePrefix string = '#_namePrefix_#' From 3bf1d4e5a8abcb38266ba4141aec037972427edd Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Mon, 17 Feb 2025 11:44:06 +0200 Subject: [PATCH 53/54] Update avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.active/main.test.bicep Co-authored-by: Alexander Sehr --- .../pim-role-assignment/tests/e2e/rg.active/main.test.bicep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.active/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.active/main.test.bicep index e8b7e93585..a79aa3bbd1 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.active/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/rg.active/main.test.bicep @@ -10,7 +10,7 @@ metadata description = 'This module deploys a PIM Active Role Assignment at a Re param resourceLocation string = deployment().location @description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') -param serviceShort string = 'pimrgmax' +param serviceShort string = 'paprga' @description('Optional. A token to inject into the name of each resource.') param namePrefix string = '#_namePrefix_#' From 623fe96d3841ed03e0342cc90d689e3e6479015f Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Mon, 17 Feb 2025 11:44:14 +0200 Subject: [PATCH 54/54] Update avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.active.permenant/main.test.bicep Co-authored-by: Alexander Sehr --- .../tests/e2e/sub.active.permenant/main.test.bicep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.active.permenant/main.test.bicep b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.active.permenant/main.test.bicep index a9f04c79d7..779f69d0a1 100644 --- a/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.active.permenant/main.test.bicep +++ b/avm/ptn/authorization/pim-role-assignment/tests/e2e/sub.active.permenant/main.test.bicep @@ -7,7 +7,7 @@ metadata description = 'This module deploys a PIM permanent Role Assignment at a // ========== // @description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') -param serviceShort string = 'pimsubmin' +param serviceShort string = 'papsubap' @description('Optional. A token to inject into the name of each resource.') param namePrefix string = '#_namePrefix_#'