Skip to content

Commit

Permalink
Add support for selectors and overrides in Azure Policy CRUD cmdlets (A…
Browse files Browse the repository at this point in the history
…zure#26031)

* Implement ResourceSelector and Override parameters for New/Update-AzPolicyAssignment
Implement ResourceSelector parameter for New/Update-AzPolicyExemption
Add new tests for selectors and overrides
Add new examples for selectors and overrides

* Rerecord tests

* Fix two examples to contain only powershell commands

* Rebuild docs

* Switch tag new tests as -LiveOnly
  • Loading branch information
mentat9 authored and Jaskirat Singh committed Oct 8, 2024
1 parent b6d6410 commit 989d8cf
Show file tree
Hide file tree
Showing 86 changed files with 9,014 additions and 8,391 deletions.
4 changes: 1 addition & 3 deletions src/Resources/Policy.Autorest/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -282,12 +282,10 @@ directive:
- DisplayName

# Hide parameters that aren't supported.
# For some reason these can't be hidden by hiding them in
# the custom folder so we have to do it here.
- where:
verb: New|Update
subject: PolicyAssignment|PolicyExemption
parameter-name: PolicyDefinitionId|ResourceSelector|Override
parameter-name: PolicyDefinitionId
hide: true
- where:
verb: New
Expand Down
14 changes: 14 additions & 0 deletions src/Resources/Policy.Autorest/custom/New-AzPolicyAssignment.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,20 @@ param(
# To construct, see NOTES section for NONCOMPLIANCEMESSAGE properties and create a hash table.
${NonComplianceMessage},

[Parameter()]
[AllowEmptyCollection()]
[Microsoft.Azure.PowerShell.Cmdlets.Policy.Category('Body')]
[Microsoft.Azure.PowerShell.Cmdlets.Policy.Models.IOverride[]]
# The policy property value override.
${Override},

[Parameter()]
[AllowEmptyCollection()]
[Microsoft.Azure.PowerShell.Cmdlets.Policy.Category('Body')]
[Microsoft.Azure.PowerShell.Cmdlets.Policy.Models.IResourceSelector[]]
# The resource selector list to filter policies by resource properties.
${ResourceSelector},

[Parameter()]
[Obsolete('This parameter is a temporary bridge to new types and formats and will be removed in a future release.')]
[System.Management.Automation.SwitchParameter]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,13 @@ param(
# Metadata is an open ended object and is typically a collection of key value pairs.
${Metadata},

[Parameter()]
[AllowEmptyCollection()]
[Microsoft.Azure.PowerShell.Cmdlets.Policy.Category('Body')]
[Microsoft.Azure.PowerShell.Cmdlets.Policy.Models.IResourceSelector[]]
# The resource selector list to filter policies by resource properties.
${ResourceSelector},

[Parameter()]
[Obsolete('This parameter is a temporary bridge to new types and formats and will be removed in a future release.')]
[System.Management.Automation.SwitchParameter]
Expand Down
18 changes: 16 additions & 2 deletions src/Resources/Policy.Autorest/custom/Update-AzPolicyAssignment.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,20 @@ param(
[Microsoft.Azure.PowerShell.Cmdlets.Policy.Models.IPolicyAssignment]
${InputObject},

[Parameter()]
[AllowEmptyCollection()]
[Microsoft.Azure.PowerShell.Cmdlets.Policy.Category('Body')]
[Microsoft.Azure.PowerShell.Cmdlets.Policy.Models.IOverride[]]
# The policy property value override.
${Override},

[Parameter()]
[AllowEmptyCollection()]
[Microsoft.Azure.PowerShell.Cmdlets.Policy.Category('Body')]
[Microsoft.Azure.PowerShell.Cmdlets.Policy.Models.IResourceSelector[]]
# The resource selector list to filter policies by resource properties.
${ResourceSelector},

[Parameter()]
[Obsolete('This parameter is a temporary bridge to new types and formats and will be removed in a future release.')]
[System.Management.Automation.SwitchParameter]
Expand Down Expand Up @@ -279,7 +293,7 @@ process {
if ($InputObject) {
foreach ($parameterName in $InputObject.Keys) {
$value = $InputObject.($parameterName)
if ($value -or ($value -is [array])) {
if ($value -or ($value -is [array]) -or ($value -is [switch])) {
$calledParameters.($parameterName) = $value
}
}
Expand All @@ -288,7 +302,7 @@ process {
# skip $null and empty values to avoid validation failures on pipeline input
foreach ($parameterName in $PSBoundParameters.Keys) {
$value = $PSBoundParameters.($parameterName)
if ($value -or ($value -is [array])) {
if ($value -or ($value -is [array]) -or ($value -is [switch])) {
$calledParameters.($parameterName) = $value
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ process {
if ($InputObject) {
foreach ($parameterName in $InputObject.Keys) {
$value = $InputObject.($parameterName)
if ($value -or ($value -is [array])) {
if ($value -or ($value -is [array]) -or ($value -is [switch])) {
$calledParameters.($parameterName) = $value
}
}
Expand All @@ -229,7 +229,7 @@ process {
# skip $null and empty values to avoid validation failures on pipeline input
foreach ($parameterName in $PSBoundParameters.Keys) {
$value = $PSBoundParameters.($parameterName)
if ($value -or ($value -is [array])) {
if ($value -or ($value -is [array]) -or ($value -is [switch])) {
$calledParameters.($parameterName) = $value
}
}
Expand Down
19 changes: 13 additions & 6 deletions src/Resources/Policy.Autorest/custom/Update-AzPolicyExemption.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,11 @@ param(
${InputObject},

[Parameter()]
[Obsolete('This parameter is a temporary bridge to new types and formats and will be removed in a future release.')]
[System.Management.Automation.SwitchParameter]
# Causes cmdlet to return artifacts using legacy format placing policy-specific properties in a property bag object.
${BackwardCompatible} = $false,
[AllowEmptyCollection()]
[Microsoft.Azure.PowerShell.Cmdlets.Policy.Category('Body')]
[Microsoft.Azure.PowerShell.Cmdlets.Policy.Models.IResourceSelector[]]
# The resource selector list to filter policies by resource properties.
${ResourceSelector},

[Parameter()]
[ValidateSet('Default', 'DoNotValidate')]
Expand All @@ -122,6 +123,12 @@ param(
# The option whether validate the exemption is at or under the assignment scope.
${AssignmentScopeValidation},

[Parameter()]
[Obsolete('This parameter is a temporary bridge to new types and formats and will be removed in a future release.')]
[System.Management.Automation.SwitchParameter]
# Causes cmdlet to return artifacts using legacy format placing policy-specific properties in a property bag object.
${BackwardCompatible} = $false,

[Parameter()]
[Alias('AzureRMContext', 'AzureCredential')]
[ValidateNotNull()]
Expand Down Expand Up @@ -221,7 +228,7 @@ process {
if ($InputObject) {
foreach ($parameterName in $InputObject.Keys) {
$value = $InputObject.($parameterName)
if ($value -or ($value -is [array])) {
if ($value -or ($value -is [array]) -or ($value -is [switch])) {
$calledParameters.($parameterName) = $value
}
}
Expand All @@ -230,7 +237,7 @@ process {
# skip $null and empty values to avoid validation failures on pipeline input
foreach ($parameterName in $PSBoundParameters.Keys) {
$value = $PSBoundParameters.($parameterName)
if ($value -or ($value -is [array])) {
if ($value -or ($value -is [array]) -or ($value -is [switch])) {
$calledParameters.($parameterName) = $value
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ process {
if ($InputObject) {
foreach ($parameterName in $InputObject.Keys) {
$value = $InputObject.($parameterName)
if ($value -or ($value -is [array])) {
if ($value -or ($value -is [array]) -or ($value -is [switch])) {
$calledParameters.($parameterName) = $value
}
}
Expand All @@ -230,7 +230,7 @@ process {
# skip $null and empty values to avoid validation failures on pipeline input
foreach ($parameterName in $PSBoundParameters.Keys) {
$value = $PSBoundParameters.($parameterName)
if ($value -or ($value -is [array])) {
if ($value -or ($value -is [array]) -or ($value -is [switch])) {
$calledParameters.($parameterName) = $value
}
}
Expand Down
92 changes: 76 additions & 16 deletions src/Resources/Policy.Autorest/docs/New-AzPolicyAssignment.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,37 @@ Creates or updates a policy assignment.
New-AzPolicyAssignment -Name <String> [-Scope <String>] [-BackwardCompatible] [-Description <String>]
[-DisplayName <String>] [-EnforcementMode <String>] [-IdentityId <String>] [-IdentityType <String>]
[-Location <String>] [-Metadata <String>] [-NonComplianceMessage <PSObject[]>] [-NotScope <String[]>]
[-DefaultProfile <PSObject>] [-Confirm] [-WhatIf] [<CommonParameters>]
[-Override <IOverride[]>] [-ResourceSelector <IResourceSelector[]>] [-DefaultProfile <PSObject>] [-Confirm]
[-WhatIf] [<CommonParameters>]
```

### ParameterObject
```
New-AzPolicyAssignment -Name <String> -PolicyParameterObject <Hashtable> [-Scope <String>]
[-BackwardCompatible] [-DefinitionVersion <String>] [-Description <String>] [-DisplayName <String>]
[-EnforcementMode <String>] [-IdentityId <String>] [-IdentityType <String>] [-Location <String>]
[-Metadata <String>] [-NonComplianceMessage <PSObject[]>] [-NotScope <String[]>]
[-PolicyDefinition <PSObject>] [-DefaultProfile <PSObject>] [-Confirm] [-WhatIf] [<CommonParameters>]
[-Metadata <String>] [-NonComplianceMessage <PSObject[]>] [-NotScope <String[]>] [-Override <IOverride[]>]
[-PolicyDefinition <PSObject>] [-ResourceSelector <IResourceSelector[]>] [-DefaultProfile <PSObject>]
[-Confirm] [-WhatIf] [<CommonParameters>]
```

### ParameterString
```
New-AzPolicyAssignment -Name <String> -PolicyParameter <String> [-Scope <String>] [-BackwardCompatible]
[-DefinitionVersion <String>] [-Description <String>] [-DisplayName <String>] [-EnforcementMode <String>]
[-IdentityId <String>] [-IdentityType <String>] [-Location <String>] [-Metadata <String>]
[-NonComplianceMessage <PSObject[]>] [-NotScope <String[]>] [-PolicyDefinition <PSObject>]
[-DefaultProfile <PSObject>] [-Confirm] [-WhatIf] [<CommonParameters>]
[-NonComplianceMessage <PSObject[]>] [-NotScope <String[]>] [-Override <IOverride[]>]
[-PolicyDefinition <PSObject>] [-ResourceSelector <IResourceSelector[]>] [-DefaultProfile <PSObject>]
[-Confirm] [-WhatIf] [<CommonParameters>]
```

### PolicyDefinitionOrPolicySetDefinition
```
New-AzPolicyAssignment -Name <String> -PolicyDefinition <PSObject> [-Scope <String>] [-BackwardCompatible]
[-DefinitionVersion <String>] [-Description <String>] [-DisplayName <String>] [-EnforcementMode <String>]
[-IdentityId <String>] [-IdentityType <String>] [-Location <String>] [-Metadata <String>]
[-NonComplianceMessage <PSObject[]>] [-NotScope <String[]>] [-DefaultProfile <PSObject>] [-Confirm] [-WhatIf]
[-NonComplianceMessage <PSObject[]>] [-NotScope <String[]>] [-Override <IOverride[]>]
[-ResourceSelector <IResourceSelector[]>] [-DefaultProfile <PSObject>] [-Confirm] [-WhatIf]
[<CommonParameters>]
```

Expand Down Expand Up @@ -96,23 +100,24 @@ The **ResourceId** property of $ResourceGroup identifies the resource group.

### Example 4: Policy assignment at resource group level with policy parameter file
```powershell
{
'{
"listOfAllowedLocations": {
"value": [
"westus",
"westeurope",
"japanwest"
]
}
}
}' > .\AllowedLocations.json
$ResourceGroup = Get-AzResourceGroup -Name 'ResourceGroup11'
$Policy = Get-AzPolicyDefinition -BuiltIn | Where-Object {$_.DisplayName -eq 'Allowed locations'}
New-AzPolicyAssignment -Name 'RestrictLocationPolicyAssignment' -PolicyDefinition $Policy -Scope $ResourceGroup.ResourceId -PolicyParameter .\AllowedLocations.json
```

The first command gets a resource group named ResourceGroup11 by using the Get-AzResourceGroup cmdlet and stores it in the $ResourceGroup variable.
The second command gets the built-in policy definition for allowed locations by using the Get-AzPolicyDefinition cmdlet and stores it in the $Policy variable.
The first command creates a parameter file called _AllowedLocations.json_ in the local working directory.
The second command gets a resource group named ResourceGroup11 by using the Get-AzResourceGroup cmdlet and stores it in the $ResourceGroup variable.
The third command gets the built-in policy definition for allowed locations by using the Get-AzPolicyDefinition cmdlet and stores it in the $Policy variable.
The final command assigns the policy in $Policy at the resource group identified by the **ResourceId** property of $ResourceGroup using the policy parameter file AllowedLocations.json from the local working directory.

### Example 5: Policy assignment with a system assigned managed identity
Expand Down Expand Up @@ -167,7 +172,31 @@ The second command creates an array of non-compliance messages.
One general purpose message for the entire assignment and one message specific to a SKU restriction policy within the assigned policy set definition.
The final command assigns the policy set definition in $PolicySet to the subscription with two non-compliance messages that will be shown if a resource is denied by policy.

### Example 9: [Backcompat] Policy assignment at resource group level with policy parameter object
### Example 9: Policy assignment with resource selector
```powershell
$Policy = Get-AzPolicyDefinition -Name 'VirtualMachinePolicy'
$ResourceSelector = @{Name = "MyLocationSelector"; Selector = @(@{Kind = "resourceLocation"; In = @("eastus", "eastus2")})}
New-AzPolicyAssignment -Name 'VirtualMachinePolicyAssignment' -PolicyDefinition $Policy -ResourceSelector $ResourceSelector
```

The first command gets the policy definition named VirtualMachinePolicy by using the Get-AzPolicyDefinition cmdlet and stores it in the $Policy variable.
The second command creates a resource selector object that will be used to specify the assignment should only apply to resources located in East US or East US 2 and stores it in the $ResourceSelector variable.
The final command assigns the policy definition in $Policy to the subscription with the resource selector specified by $ResourceSelector.

### Example 10: Policy assignment with override
```powershell
$Policy = Get-AzPolicyDefinition -Name 'VirtualMachinePolicy'
$Selector = @{Kind = "resourceLocation"; In = @("eastus", "eastus2")}
$Override = @(@{Kind = "policyEffect"; Value = 'Disabled'; Selector = @($Selector)})
New-AzPolicyAssignment -Name 'VirtualMachinePolicyAssignment' -PolicyDefinition $Policy -Override $Override
```

The first command gets the policy definition named VirtualMachinePolicy by using the Get-AzPolicyDefinition cmdlet and stores it in the $Policy variable.
The second command creates a location selector specifying East US or East US 2 locations and stores it in the $Selector variable.
The third command creates an override object that will be used to specify that the assigned definition should have a Disabled effect in the locations identified by the $Selector object and stores it in the $Override variable.
The final command assigns the policy definition in $Policy to the subscription with the override specified by $Override.

### Example 11: [Backcompat] Policy assignment at resource group level with policy parameter object
```powershell
$ResourceGroup = Get-AzResourceGroup -Name 'ResourceGroup11'
$Policy = Get-AzPolicyDefinition -BuiltIn | Where-Object {$_.Properties.DisplayName -eq 'Allowed locations'}
Expand All @@ -185,25 +214,26 @@ The commands store that object in the $AllowedLocations variable.
The final command assigns the policy in $Policy at the level of a resource group using the policy parameter object in $AllowedLocations.
The **ResourceId** property of $ResourceGroup identifies the resource group.

### Example 10: [Backcompat] Policy assignment at resource group level with policy parameter file
### Example 12: [Backcompat] Policy assignment at resource group level with policy parameter file
```powershell
{
'{
"listOfAllowedLocations": {
"value": [
"westus",
"westeurope",
"japanwest"
]
}
}
}' > .\AllowedLocations.json
$ResourceGroup = Get-AzResourceGroup -Name 'ResourceGroup11'
$Policy = Get-AzPolicyDefinition -BuiltIn | Where-Object {$_.Properties.DisplayName -eq 'Allowed locations'}
New-AzPolicyAssignment -Name 'RestrictLocationPolicyAssignment' -PolicyDefinition $Policy -Scope $ResourceGroup.ResourceId -PolicyParameter .\AllowedLocations.json
```

The first command gets a resource group named ResourceGroup11 by using the Get-AzResourceGroup cmdlet and stores it in the $ResourceGroup variable.
The second command gets the built-in policy definition for allowed locations by using the Get-AzPolicyDefinition cmdlet and stores it in the $Policy variable.
The first command creates a parameter file called _AllowedLocations.json_ in the local working directory.
The second command gets a resource group named ResourceGroup11 by using the Get-AzResourceGroup cmdlet and stores it in the $ResourceGroup variable.
The third command gets the built-in policy definition for allowed locations by using the Get-AzPolicyDefinition cmdlet and stores it in the $Policy variable.
The final command assigns the policy in $Policy at the resource group identified by the **ResourceId** property of $ResourceGroup using the policy parameter file AllowedLocations.json from the local working directory.

## PARAMETERS
Expand Down Expand Up @@ -410,6 +440,21 @@ Accept pipeline input: True (ByPropertyName)
Accept wildcard characters: False
```
### -Override
The policy property value override.
```yaml
Type: Microsoft.Azure.PowerShell.Cmdlets.Policy.Models.IOverride[]
Parameter Sets: (All)
Aliases:

Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -PolicyDefinition
Accept policy definition or policy set definition object
Expand Down Expand Up @@ -457,6 +502,21 @@ Accept pipeline input: False
Accept wildcard characters: False
```
### -ResourceSelector
The resource selector list to filter policies by resource properties.
```yaml
Type: Microsoft.Azure.PowerShell.Cmdlets.Policy.Models.IResourceSelector[]
Parameter Sets: (All)
Aliases:

Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -Scope
The scope of the policy assignment.
Valid scopes are: management group (format: '/providers/Microsoft.Management/managementGroups/{managementGroup}'), subscription (format: '/subscriptions/{subscriptionId}'), resource group (format: '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}', or resource (format: '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/[{parentResourcePath}/]{resourceType}/{resourceName}'
Expand Down
Loading

0 comments on commit 989d8cf

Please sign in to comment.