Skip to content

Commit

Permalink
Policy as rule baseline and ignore options #2482 (#2666)
Browse files Browse the repository at this point in the history
  • Loading branch information
BernieWhite authored Feb 1, 2024
1 parent 2f8227b commit d3f4078
Show file tree
Hide file tree
Showing 39 changed files with 1,007 additions and 265 deletions.
42 changes: 42 additions & 0 deletions .vscode/policy-ignore.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"$schema": "https://json-schema.org/draft-07/schema#",
"title": "Policy as Code Ignore",
"description": "Policy ignore identifies policies that will be ignored by PSRule for generating rules during export of policies.",
"type": "array",
"items": {
"properties": {
"policyDefinitionIds": {
"type": "array",
"title": "Policy definition IDs",
"description": "The resource IDs of built-in policies to ignore.",
"minItems": 1,
"uniqueItems": true,
"items": {
"type": "string"
}
},
"reason": {
"type": "string",
"title": "The reason why the policy definition is ignored.",
"enum": [
"Duplicate",
"NotApplicable"
],
"default": "Duplicate"
},
"value": {
"type": "string",
"title": "Value",
"description": "An additional relating to the reason the policy definition was ignored."
}
},
"additionalProperties": false,
"examples": [
{
"policyDefinitionIds": [],
"reason": "Duplicate",
"value": ""
}
]
}
}
8 changes: 8 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,14 @@
"yaml",
"yml"
],
"json.schemas": [
{
"fileMatch": [
"**/data/policy-ignore.json"
],
"url": "./.vscode/policy-ignore.schema.json"
}
],
"omnisharp.organizeImportsOnFormat": true,
"omnisharp.enableEditorConfigSupport": true,
"omnisharp.enableRoslynAnalyzers": true,
Expand Down
162 changes: 128 additions & 34 deletions data/policy-ignore.json
Original file line number Diff line number Diff line change
@@ -1,36 +1,130 @@
[
// Azure.ACR.AdminUser
"/providers/Microsoft.Authorization/policyDefinitions/dc921057-6b28-4fbe-9b83-f7bec05db6c2",
"/providers/Microsoft.Authorization/policyDefinitions/79fdfe03-ffcb-4e55-b4d0-b925b8241759",
// Azure.SQL.AAD
"/providers/Microsoft.Authorization/policyDefinitions/1f314764-cb73-4fc9-b863-8eca98ac36e9",
// Azure.ServiceFabric.AAD
"/providers/Microsoft.Authorization/policyDefinitions/b54ed75b-3e1a-44ac-a333-05ba39b99ff0",
// Azure.Redis.NonSslPort
"/providers/Microsoft.Authorization/policyDefinitions/22bee202-a82f-4305-9a2a-6d7f44d4dedb",
// Azure.Automation.EncryptVariables
"/providers/Microsoft.Authorization/policyDefinitions/3657f5a0-770e-44a3-b44e-9431ba1e9735",
// Azure.AKS.UseRBAC
"/providers/Microsoft.Authorization/policyDefinitions/ac4a19c2-fa67-49b4-8ae5-0b2e78c49457",
// Azure.AKS.AzurePolicyAddOn
"/providers/Microsoft.Authorization/policyDefinitions/0a15ec92-a229-4763-bb14-0ea34a568f8d",
// Azure.Storage.BlobPublicAccess
"/providers/Microsoft.Authorization/policyDefinitions/4fa4b6c0-31ca-4c0d-b10d-24b96f62a751",
// Azure.PostgreSQL.UseSSL
"/providers/Microsoft.Authorization/policyDefinitions/d158790f-bfb0-486c-8631-2dc6b4e8e6af",
// Azure.MySQL.UseSSL
"/providers/Microsoft.Authorization/policyDefinitions/e802a67a-daf5-4436-9ea6-f6d821dd0c5d",
// Azure.KeyVault.SoftDelete
"/providers/Microsoft.Authorization/policyDefinitions/0b60c0b2-2dc2-4e1c-b5c9-abbed971de53",
// Checking for Network Watcher in a resource group is not enforcable by code.
"/providers/Microsoft.Authorization/policyDefinitions/b6e2945c-0b7b-40f5-9233-7a5323b5cdc6",
// Azure.AKS.LocalAccounts
"/providers/Microsoft.Authorization/policyDefinitions/993c2fcd-2b29-49d2-9eb0-df2c3a730c32",
// Azure.Cognitive.DisableLocalAuth
"/providers/Microsoft.Authorization/policyDefinitions/71ef260a-8f18-47b7-abcb-62d0673d94dc",
"/providers/Microsoft.Authorization/policyDefinitions/14de9e63-1b31-492e-a5a3-c3f7fd57f555",
// Azure.Cognitive.ManagedIdentity
"/providers/Microsoft.Authorization/policyDefinitions/fe3fd216-4f83-4fc1-8984-2bbec80a3418",
// Azure.VM.UseManagedDisks
"/providers/Microsoft.Authorization/policyDefinitions/06a78e20-9358-41c9-923c-fb736d382a4d"
{
"policyDefinitionIds": [
"/providers/Microsoft.Authorization/policyDefinitions/dc921057-6b28-4fbe-9b83-f7bec05db6c2",
"/providers/Microsoft.Authorization/policyDefinitions/79fdfe03-ffcb-4e55-b4d0-b925b8241759"
],
"reason": "Duplicate",
"value": "Azure.ACR.AdminUser"
},
{
"policyDefinitionIds": [
"/providers/Microsoft.Authorization/policyDefinitions/1f314764-cb73-4fc9-b863-8eca98ac36e9"
],
"reason": "Duplicate",
"value": "Azure.SQL.AAD"
},
{
"policyDefinitionIds": [
"/providers/Microsoft.Authorization/policyDefinitions/b54ed75b-3e1a-44ac-a333-05ba39b99ff0"
],
"reason": "Duplicate",
"value": "Azure.ServiceFabric.AAD"
},
{
"policyDefinitionIds": [
"/providers/Microsoft.Authorization/policyDefinitions/22bee202-a82f-4305-9a2a-6d7f44d4dedb"
],
"reason": "Duplicate",
"value": "Azure.Redis.NonSslPort"
},
{
"policyDefinitionIds": [
"/providers/Microsoft.Authorization/policyDefinitions/3657f5a0-770e-44a3-b44e-9431ba1e9735"
],
"reason": "Duplicate",
"value": "Azure.Automation.EncryptVariables"
},
{
"policyDefinitionIds": [
"/providers/Microsoft.Authorization/policyDefinitions/ac4a19c2-fa67-49b4-8ae5-0b2e78c49457"
],
"reason": "Duplicate",
"value": "Azure.AKS.UseRBAC"
},
{
"policyDefinitionIds": [
"/providers/Microsoft.Authorization/policyDefinitions/0a15ec92-a229-4763-bb14-0ea34a568f8d"
],
"reason": "Duplicate",
"value": "Azure.AKS.AzurePolicyAddOn"
},
{
"policyDefinitionIds": [
"/providers/Microsoft.Authorization/policyDefinitions/4fa4b6c0-31ca-4c0d-b10d-24b96f62a751"
],
"reason": "Duplicate",
"value": "Azure.Storage.BlobPublicAccess"
},
{
"policyDefinitionIds": [
"/providers/Microsoft.Authorization/policyDefinitions/d158790f-bfb0-486c-8631-2dc6b4e8e6af"
],
"reason": "Duplicate",
"value": "Azure.PostgreSQL.UseSSL"
},
{
"policyDefinitionIds": [
"/providers/Microsoft.Authorization/policyDefinitions/e802a67a-daf5-4436-9ea6-f6d821dd0c5d"
],
"reason": "Duplicate",
"value": "Azure.MySQL.UseSSL"
},
{
"policyDefinitionIds": [
"/providers/Microsoft.Authorization/policyDefinitions/0b60c0b2-2dc2-4e1c-b5c9-abbed971de53"
],
"reason": "Duplicate",
"value": "Azure.KeyVault.PurgeProtect"
},
{
"policyDefinitionIds": [
"/providers/Microsoft.Authorization/policyDefinitions/b6e2945c-0b7b-40f5-9233-7a5323b5cdc6"
],
"reason": "NotApplicable",
"value": "Checking for Network Watcher in a resource group is not enforcable by code."
},
{
"policyDefinitionIds": [
"/providers/Microsoft.Authorization/policyDefinitions/993c2fcd-2b29-49d2-9eb0-df2c3a730c32"
],
"reason": "Duplicate",
"value": "Azure.AKS.LocalAccounts"
},
{
"policyDefinitionIds": [
"/providers/Microsoft.Authorization/policyDefinitions/71ef260a-8f18-47b7-abcb-62d0673d94dc",
"/providers/Microsoft.Authorization/policyDefinitions/14de9e63-1b31-492e-a5a3-c3f7fd57f555"
],
"reason": "Duplicate",
"value": "Azure.Cognitive.DisableLocalAuth"
},
{
"policyDefinitionIds": [
"/providers/Microsoft.Authorization/policyDefinitions/fe3fd216-4f83-4fc1-8984-2bbec80a3418"
],
"reason": "Duplicate",
"value": "Azure.Cognitive.ManagedIdentity"
},
{
"policyDefinitionIds": [
"/providers/Microsoft.Authorization/policyDefinitions/06a78e20-9358-41c9-923c-fb736d382a4d"
],
"reason": "Duplicate",
"value": "Azure.VM.UseManagedDisks"
},
{
"policyDefinitionIds": [
"/providers/Microsoft.Authorization/policyDefinitions/1e66c121-a66a-4b1f-9b83-0fd99bf0fc2d"
],
"reason": "Duplicate",
"value": "Azure.KeyVault.SoftDelete"
},
{
"policyDefinitionIds": [
"/providers/Microsoft.Authorization/policyDefinitions/12d4fa5e-1f9f-4c21-97a9-b99b3c6611b5"
],
"reason": "Duplicate",
"value": "Azure.KeyVault.RBAC"
}
]
18 changes: 18 additions & 0 deletions docs/CHANGELOG-v1.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,24 @@ See [upgrade notes][1] for helpful information when upgrading from previous vers

## Unreleased

What's changed since pre-release v1.33.0-B0126:

- New features:
- Exporting policy as rules also generates a baseline by @BernieWhite.
[#2482](https://github.com/Azure/PSRule.Rules.Azure/issues/2482)
- A baseline is automatically generated that includes for all rules exported.
If a policy rule has been replaced by a built-in rule, the baseline will include the built-in rule instead.
- The baseline is named `<Prefix>.PolicyBaseline.All`. i.e. `Azure.PolicyBaseline.All` by default.
- For details see [Policy as rules](./concepts/policy-as-rules.md#generated-baseline).
- General improvements:
- Rules that are ignored during exporting policy as rules are now generate a verbose logs by @BernieWhite.
[#2482](https://github.com/Azure/PSRule.Rules.Azure/issues/2482)
- This is to improve transparency of why rules are not exported.
- To see details on why a rule is ignored, enable verbose logging with `-Verbose`.
- Policies that duplicate built-in rules can now be exported by using the `-KeepDuplicates` parameter by @BernieWhite.
[#2482](https://github.com/Azure/PSRule.Rules.Azure/issues/2482)
- For details see [Policy as rules](./concepts/policy-as-rules.md#duplicate-policies).

## v1.33.0-B0126 (pre-release)

What's changed since pre-release v1.33.0-B0088:
Expand Down
23 changes: 21 additions & 2 deletions docs/commands/Export-AzPolicyAssignmentRuleData.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Export JSON based rules from policy assignment data.
```text
Export-AzPolicyAssignmentRuleData [-Name <String>] -AssignmentFile <String>
[-ResourceGroup <ResourceGroupReference>] [-Subscription <SubscriptionReference>] [-OutputPath <String>]
[-RulePrefix <String>] [-PassThru] [<CommonParameters>]
[-RulePrefix <String>] [-PassThru] [-KeepDuplicates] [<CommonParameters>]
```

## DESCRIPTION
Expand Down Expand Up @@ -200,7 +200,26 @@ Aliases:
Required: False
Position: Named
Default value: None
Default value: False
Accept pipeline input: False
Accept wildcard characters: False
```

### -KeepDuplicates

Determines if Azure policy definitions that duplicate existing built-in rules are exported.
By default, duplicates are not exported.

This only applies to built-in policy definitions.

```yaml
Type: SwitchParameter
Parameter Sets: (All)
Aliases:
Required: False
Position: Named
Default value: False
Accept pipeline input: False
Accept wildcard characters: False
```
Expand Down
1 change: 1 addition & 0 deletions docs/concepts/about_PSRule_Azure_Configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ Example:

```yaml
# YAML: Add a custom policy definition to ignore
configuration:
AZURE_POLICY_IGNORE_LIST:
- '/providers/Microsoft.Authorization/policyDefinitions/1f314764-cb73-4fc9-b863-8eca98ac36e9'
- '/providers/Microsoft.Authorization/policyDefinitions/b54ed75b-3e1a-44ac-a333-05ba39b99ff0'
Expand Down
60 changes: 58 additions & 2 deletions docs/concepts/policy-as-rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ This feature does not support:
- **Policies that check for assessment status** &mdash; Some policies use additional detection tools to check for compliance.
Policies that check for assessment status are ignored.
- **Importing rules** &mdash; Rules generated from policy assignments cannot be imported back into Azure Policy.
- **Duplicate rules** &mdash; Currently, built-in Azure Policies that are duplicates of existing rules are ignored.
[#2482](https://github.com/Azure/PSRule.Rules.Azure/issues/2482)

## Using policy as rules

Expand All @@ -60,3 +58,61 @@ Run `Export-AzPolicyAssignmentRuleData` to convert assignments to rules.
To run this command an `-AssignmentFile` parameter with the path to the assignment JSON file generated in the previous step.

After the command completes a new file `*.Rule.jsonc` should be generated containing generated rules.

## Customizing the generated rules

PSRule for Azure allows you to:

- **Set a name prefix** &mdash; to help identify generated rules.
By default, generated rules and baselines are prefixed with `Azure`.
To change the prefix:
- Use the `-RulePrefix` parameter when running `Export-AzPolicyAssignmentRuleData`. _OR_
- Set the `AZURE_POLICY_RULE_PREFIX` configuration option in `ps-rule.yaml`.
- **Exclude specific policies** &mdash; by setting the `AZURE_POLICY_IGNORE_LIST` configuration option in `ps-rule.yaml`.
This option allows you to prevent specific policies from being exported as rules.

For example:

```yaml title="ps-rule.yaml"
configuration:
AZURE_POLICY_RULE_PREFIX: MyOrg
AZURE_POLICY_IGNORE_LIST:
- /providers/Microsoft.Authorization/policyDefinitions/1f314764-cb73-4fc9-b863-8eca98ac36e9
- /providers/Microsoft.Authorization/policyDefinitions/b54ed75b-3e1a-44ac-a333-05ba39b99ff0
```
## Generated baseline
<!-- module:version v1.33.0 -->
When exporting policies, PSRule for Azure will automatically generate a baseline including any generated rules.
By default, this baseline is called `Azure.PolicyBaseline.All`.
If you change the prefix of generated rules the baseline will be named `<Prefix>.PolicyBaseline.All`.

See [Using baselines](../working-with-baselines.md#using-baselines) for examples on how to use a baseline in a run.

## Duplicate policies

<!-- module:version v1.33.0 -->

When exporting policies, you may encounter definitions that are duplicates of existing rules shipped with PSRule for Azure.
By default, built-in Azure policies that are duplicates of existing rules are ignored.
Additionally, PSRule for Azure will automatically switch in existing rules into the generated baseline.

!!! Note
This only applies to built-in Azure policies that are duplicates of existing rules.
Custom policies are not effected.

The list of built-in policies that are duplicates can be viewed [here][3].
If you believe a policy is missing from this list, please [open an issue][4].

[3]: https://github.com/Azure/PSRule.Rules.Azure/blob/main/data/policy-ignore.json
[4]: https://github.com/Azure/PSRule.Rules.Azure/issues/new/choose

This allows you to:

- Focus on policies that are unique to your environment and not already covered by PSRule for Azure.
- Benefit from the additional references and examples provided by PSRule for Azure.
- Reduce noise reporting the same issue multiple times.

To override this behavior use the `-KeepDuplicates` parameter switch when running `Export-AzPolicyAssignmentRuleData`.
Loading

0 comments on commit d3f4078

Please sign in to comment.