Skip to content

Commit d3f4078

Browse files
authored
Policy as rule baseline and ignore options Azure#2482 (Azure#2666)
1 parent 2f8227b commit d3f4078

39 files changed

+1007
-265
lines changed

.vscode/policy-ignore.schema.json

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"$schema": "https://json-schema.org/draft-07/schema#",
3+
"title": "Policy as Code Ignore",
4+
"description": "Policy ignore identifies policies that will be ignored by PSRule for generating rules during export of policies.",
5+
"type": "array",
6+
"items": {
7+
"properties": {
8+
"policyDefinitionIds": {
9+
"type": "array",
10+
"title": "Policy definition IDs",
11+
"description": "The resource IDs of built-in policies to ignore.",
12+
"minItems": 1,
13+
"uniqueItems": true,
14+
"items": {
15+
"type": "string"
16+
}
17+
},
18+
"reason": {
19+
"type": "string",
20+
"title": "The reason why the policy definition is ignored.",
21+
"enum": [
22+
"Duplicate",
23+
"NotApplicable"
24+
],
25+
"default": "Duplicate"
26+
},
27+
"value": {
28+
"type": "string",
29+
"title": "Value",
30+
"description": "An additional relating to the reason the policy definition was ignored."
31+
}
32+
},
33+
"additionalProperties": false,
34+
"examples": [
35+
{
36+
"policyDefinitionIds": [],
37+
"reason": "Duplicate",
38+
"value": ""
39+
}
40+
]
41+
}
42+
}

.vscode/settings.json

+8
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,14 @@
133133
"yaml",
134134
"yml"
135135
],
136+
"json.schemas": [
137+
{
138+
"fileMatch": [
139+
"**/data/policy-ignore.json"
140+
],
141+
"url": "./.vscode/policy-ignore.schema.json"
142+
}
143+
],
136144
"omnisharp.organizeImportsOnFormat": true,
137145
"omnisharp.enableEditorConfigSupport": true,
138146
"omnisharp.enableRoslynAnalyzers": true,

data/policy-ignore.json

+128-34
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,130 @@
11
[
2-
// Azure.ACR.AdminUser
3-
"/providers/Microsoft.Authorization/policyDefinitions/dc921057-6b28-4fbe-9b83-f7bec05db6c2",
4-
"/providers/Microsoft.Authorization/policyDefinitions/79fdfe03-ffcb-4e55-b4d0-b925b8241759",
5-
// Azure.SQL.AAD
6-
"/providers/Microsoft.Authorization/policyDefinitions/1f314764-cb73-4fc9-b863-8eca98ac36e9",
7-
// Azure.ServiceFabric.AAD
8-
"/providers/Microsoft.Authorization/policyDefinitions/b54ed75b-3e1a-44ac-a333-05ba39b99ff0",
9-
// Azure.Redis.NonSslPort
10-
"/providers/Microsoft.Authorization/policyDefinitions/22bee202-a82f-4305-9a2a-6d7f44d4dedb",
11-
// Azure.Automation.EncryptVariables
12-
"/providers/Microsoft.Authorization/policyDefinitions/3657f5a0-770e-44a3-b44e-9431ba1e9735",
13-
// Azure.AKS.UseRBAC
14-
"/providers/Microsoft.Authorization/policyDefinitions/ac4a19c2-fa67-49b4-8ae5-0b2e78c49457",
15-
// Azure.AKS.AzurePolicyAddOn
16-
"/providers/Microsoft.Authorization/policyDefinitions/0a15ec92-a229-4763-bb14-0ea34a568f8d",
17-
// Azure.Storage.BlobPublicAccess
18-
"/providers/Microsoft.Authorization/policyDefinitions/4fa4b6c0-31ca-4c0d-b10d-24b96f62a751",
19-
// Azure.PostgreSQL.UseSSL
20-
"/providers/Microsoft.Authorization/policyDefinitions/d158790f-bfb0-486c-8631-2dc6b4e8e6af",
21-
// Azure.MySQL.UseSSL
22-
"/providers/Microsoft.Authorization/policyDefinitions/e802a67a-daf5-4436-9ea6-f6d821dd0c5d",
23-
// Azure.KeyVault.SoftDelete
24-
"/providers/Microsoft.Authorization/policyDefinitions/0b60c0b2-2dc2-4e1c-b5c9-abbed971de53",
25-
// Checking for Network Watcher in a resource group is not enforcable by code.
26-
"/providers/Microsoft.Authorization/policyDefinitions/b6e2945c-0b7b-40f5-9233-7a5323b5cdc6",
27-
// Azure.AKS.LocalAccounts
28-
"/providers/Microsoft.Authorization/policyDefinitions/993c2fcd-2b29-49d2-9eb0-df2c3a730c32",
29-
// Azure.Cognitive.DisableLocalAuth
30-
"/providers/Microsoft.Authorization/policyDefinitions/71ef260a-8f18-47b7-abcb-62d0673d94dc",
31-
"/providers/Microsoft.Authorization/policyDefinitions/14de9e63-1b31-492e-a5a3-c3f7fd57f555",
32-
// Azure.Cognitive.ManagedIdentity
33-
"/providers/Microsoft.Authorization/policyDefinitions/fe3fd216-4f83-4fc1-8984-2bbec80a3418",
34-
// Azure.VM.UseManagedDisks
35-
"/providers/Microsoft.Authorization/policyDefinitions/06a78e20-9358-41c9-923c-fb736d382a4d"
2+
{
3+
"policyDefinitionIds": [
4+
"/providers/Microsoft.Authorization/policyDefinitions/dc921057-6b28-4fbe-9b83-f7bec05db6c2",
5+
"/providers/Microsoft.Authorization/policyDefinitions/79fdfe03-ffcb-4e55-b4d0-b925b8241759"
6+
],
7+
"reason": "Duplicate",
8+
"value": "Azure.ACR.AdminUser"
9+
},
10+
{
11+
"policyDefinitionIds": [
12+
"/providers/Microsoft.Authorization/policyDefinitions/1f314764-cb73-4fc9-b863-8eca98ac36e9"
13+
],
14+
"reason": "Duplicate",
15+
"value": "Azure.SQL.AAD"
16+
},
17+
{
18+
"policyDefinitionIds": [
19+
"/providers/Microsoft.Authorization/policyDefinitions/b54ed75b-3e1a-44ac-a333-05ba39b99ff0"
20+
],
21+
"reason": "Duplicate",
22+
"value": "Azure.ServiceFabric.AAD"
23+
},
24+
{
25+
"policyDefinitionIds": [
26+
"/providers/Microsoft.Authorization/policyDefinitions/22bee202-a82f-4305-9a2a-6d7f44d4dedb"
27+
],
28+
"reason": "Duplicate",
29+
"value": "Azure.Redis.NonSslPort"
30+
},
31+
{
32+
"policyDefinitionIds": [
33+
"/providers/Microsoft.Authorization/policyDefinitions/3657f5a0-770e-44a3-b44e-9431ba1e9735"
34+
],
35+
"reason": "Duplicate",
36+
"value": "Azure.Automation.EncryptVariables"
37+
},
38+
{
39+
"policyDefinitionIds": [
40+
"/providers/Microsoft.Authorization/policyDefinitions/ac4a19c2-fa67-49b4-8ae5-0b2e78c49457"
41+
],
42+
"reason": "Duplicate",
43+
"value": "Azure.AKS.UseRBAC"
44+
},
45+
{
46+
"policyDefinitionIds": [
47+
"/providers/Microsoft.Authorization/policyDefinitions/0a15ec92-a229-4763-bb14-0ea34a568f8d"
48+
],
49+
"reason": "Duplicate",
50+
"value": "Azure.AKS.AzurePolicyAddOn"
51+
},
52+
{
53+
"policyDefinitionIds": [
54+
"/providers/Microsoft.Authorization/policyDefinitions/4fa4b6c0-31ca-4c0d-b10d-24b96f62a751"
55+
],
56+
"reason": "Duplicate",
57+
"value": "Azure.Storage.BlobPublicAccess"
58+
},
59+
{
60+
"policyDefinitionIds": [
61+
"/providers/Microsoft.Authorization/policyDefinitions/d158790f-bfb0-486c-8631-2dc6b4e8e6af"
62+
],
63+
"reason": "Duplicate",
64+
"value": "Azure.PostgreSQL.UseSSL"
65+
},
66+
{
67+
"policyDefinitionIds": [
68+
"/providers/Microsoft.Authorization/policyDefinitions/e802a67a-daf5-4436-9ea6-f6d821dd0c5d"
69+
],
70+
"reason": "Duplicate",
71+
"value": "Azure.MySQL.UseSSL"
72+
},
73+
{
74+
"policyDefinitionIds": [
75+
"/providers/Microsoft.Authorization/policyDefinitions/0b60c0b2-2dc2-4e1c-b5c9-abbed971de53"
76+
],
77+
"reason": "Duplicate",
78+
"value": "Azure.KeyVault.PurgeProtect"
79+
},
80+
{
81+
"policyDefinitionIds": [
82+
"/providers/Microsoft.Authorization/policyDefinitions/b6e2945c-0b7b-40f5-9233-7a5323b5cdc6"
83+
],
84+
"reason": "NotApplicable",
85+
"value": "Checking for Network Watcher in a resource group is not enforcable by code."
86+
},
87+
{
88+
"policyDefinitionIds": [
89+
"/providers/Microsoft.Authorization/policyDefinitions/993c2fcd-2b29-49d2-9eb0-df2c3a730c32"
90+
],
91+
"reason": "Duplicate",
92+
"value": "Azure.AKS.LocalAccounts"
93+
},
94+
{
95+
"policyDefinitionIds": [
96+
"/providers/Microsoft.Authorization/policyDefinitions/71ef260a-8f18-47b7-abcb-62d0673d94dc",
97+
"/providers/Microsoft.Authorization/policyDefinitions/14de9e63-1b31-492e-a5a3-c3f7fd57f555"
98+
],
99+
"reason": "Duplicate",
100+
"value": "Azure.Cognitive.DisableLocalAuth"
101+
},
102+
{
103+
"policyDefinitionIds": [
104+
"/providers/Microsoft.Authorization/policyDefinitions/fe3fd216-4f83-4fc1-8984-2bbec80a3418"
105+
],
106+
"reason": "Duplicate",
107+
"value": "Azure.Cognitive.ManagedIdentity"
108+
},
109+
{
110+
"policyDefinitionIds": [
111+
"/providers/Microsoft.Authorization/policyDefinitions/06a78e20-9358-41c9-923c-fb736d382a4d"
112+
],
113+
"reason": "Duplicate",
114+
"value": "Azure.VM.UseManagedDisks"
115+
},
116+
{
117+
"policyDefinitionIds": [
118+
"/providers/Microsoft.Authorization/policyDefinitions/1e66c121-a66a-4b1f-9b83-0fd99bf0fc2d"
119+
],
120+
"reason": "Duplicate",
121+
"value": "Azure.KeyVault.SoftDelete"
122+
},
123+
{
124+
"policyDefinitionIds": [
125+
"/providers/Microsoft.Authorization/policyDefinitions/12d4fa5e-1f9f-4c21-97a9-b99b3c6611b5"
126+
],
127+
"reason": "Duplicate",
128+
"value": "Azure.KeyVault.RBAC"
129+
}
36130
]

docs/CHANGELOG-v1.md

+18
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,24 @@ See [upgrade notes][1] for helpful information when upgrading from previous vers
3232

3333
## Unreleased
3434

35+
What's changed since pre-release v1.33.0-B0126:
36+
37+
- New features:
38+
- Exporting policy as rules also generates a baseline by @BernieWhite.
39+
[#2482](https://github.com/Azure/PSRule.Rules.Azure/issues/2482)
40+
- A baseline is automatically generated that includes for all rules exported.
41+
If a policy rule has been replaced by a built-in rule, the baseline will include the built-in rule instead.
42+
- The baseline is named `<Prefix>.PolicyBaseline.All`. i.e. `Azure.PolicyBaseline.All` by default.
43+
- For details see [Policy as rules](./concepts/policy-as-rules.md#generated-baseline).
44+
- General improvements:
45+
- Rules that are ignored during exporting policy as rules are now generate a verbose logs by @BernieWhite.
46+
[#2482](https://github.com/Azure/PSRule.Rules.Azure/issues/2482)
47+
- This is to improve transparency of why rules are not exported.
48+
- To see details on why a rule is ignored, enable verbose logging with `-Verbose`.
49+
- Policies that duplicate built-in rules can now be exported by using the `-KeepDuplicates` parameter by @BernieWhite.
50+
[#2482](https://github.com/Azure/PSRule.Rules.Azure/issues/2482)
51+
- For details see [Policy as rules](./concepts/policy-as-rules.md#duplicate-policies).
52+
3553
## v1.33.0-B0126 (pre-release)
3654

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

docs/commands/Export-AzPolicyAssignmentRuleData.md

+21-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Export JSON based rules from policy assignment data.
1616
```text
1717
Export-AzPolicyAssignmentRuleData [-Name <String>] -AssignmentFile <String>
1818
[-ResourceGroup <ResourceGroupReference>] [-Subscription <SubscriptionReference>] [-OutputPath <String>]
19-
[-RulePrefix <String>] [-PassThru] [<CommonParameters>]
19+
[-RulePrefix <String>] [-PassThru] [-KeepDuplicates] [<CommonParameters>]
2020
```
2121

2222
## DESCRIPTION
@@ -200,7 +200,26 @@ Aliases:
200200
201201
Required: False
202202
Position: Named
203-
Default value: None
203+
Default value: False
204+
Accept pipeline input: False
205+
Accept wildcard characters: False
206+
```
207+
208+
### -KeepDuplicates
209+
210+
Determines if Azure policy definitions that duplicate existing built-in rules are exported.
211+
By default, duplicates are not exported.
212+
213+
This only applies to built-in policy definitions.
214+
215+
```yaml
216+
Type: SwitchParameter
217+
Parameter Sets: (All)
218+
Aliases:
219+
220+
Required: False
221+
Position: Named
222+
Default value: False
204223
Accept pipeline input: False
205224
Accept wildcard characters: False
206225
```

docs/concepts/about_PSRule_Azure_Configuration.md

+1
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ Example:
320320

321321
```yaml
322322
# YAML: Add a custom policy definition to ignore
323+
configuration:
323324
AZURE_POLICY_IGNORE_LIST:
324325
- '/providers/Microsoft.Authorization/policyDefinitions/1f314764-cb73-4fc9-b863-8eca98ac36e9'
325326
- '/providers/Microsoft.Authorization/policyDefinitions/b54ed75b-3e1a-44ac-a333-05ba39b99ff0'

docs/concepts/policy-as-rules.md

+58-2
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@ This feature does not support:
3434
- **Policies that check for assessment status** &mdash; Some policies use additional detection tools to check for compliance.
3535
Policies that check for assessment status are ignored.
3636
- **Importing rules** &mdash; Rules generated from policy assignments cannot be imported back into Azure Policy.
37-
- **Duplicate rules** &mdash; Currently, built-in Azure Policies that are duplicates of existing rules are ignored.
38-
[#2482](https://github.com/Azure/PSRule.Rules.Azure/issues/2482)
3937

4038
## Using policy as rules
4139

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

6260
After the command completes a new file `*.Rule.jsonc` should be generated containing generated rules.
61+
62+
## Customizing the generated rules
63+
64+
PSRule for Azure allows you to:
65+
66+
- **Set a name prefix** &mdash; to help identify generated rules.
67+
By default, generated rules and baselines are prefixed with `Azure`.
68+
To change the prefix:
69+
- Use the `-RulePrefix` parameter when running `Export-AzPolicyAssignmentRuleData`. _OR_
70+
- Set the `AZURE_POLICY_RULE_PREFIX` configuration option in `ps-rule.yaml`.
71+
- **Exclude specific policies** &mdash; by setting the `AZURE_POLICY_IGNORE_LIST` configuration option in `ps-rule.yaml`.
72+
This option allows you to prevent specific policies from being exported as rules.
73+
74+
For example:
75+
76+
```yaml title="ps-rule.yaml"
77+
configuration:
78+
AZURE_POLICY_RULE_PREFIX: MyOrg
79+
AZURE_POLICY_IGNORE_LIST:
80+
- /providers/Microsoft.Authorization/policyDefinitions/1f314764-cb73-4fc9-b863-8eca98ac36e9
81+
- /providers/Microsoft.Authorization/policyDefinitions/b54ed75b-3e1a-44ac-a333-05ba39b99ff0
82+
```
83+
84+
## Generated baseline
85+
86+
<!-- module:version v1.33.0 -->
87+
88+
When exporting policies, PSRule for Azure will automatically generate a baseline including any generated rules.
89+
By default, this baseline is called `Azure.PolicyBaseline.All`.
90+
If you change the prefix of generated rules the baseline will be named `<Prefix>.PolicyBaseline.All`.
91+
92+
See [Using baselines](../working-with-baselines.md#using-baselines) for examples on how to use a baseline in a run.
93+
94+
## Duplicate policies
95+
96+
<!-- module:version v1.33.0 -->
97+
98+
When exporting policies, you may encounter definitions that are duplicates of existing rules shipped with PSRule for Azure.
99+
By default, built-in Azure policies that are duplicates of existing rules are ignored.
100+
Additionally, PSRule for Azure will automatically switch in existing rules into the generated baseline.
101+
102+
!!! Note
103+
This only applies to built-in Azure policies that are duplicates of existing rules.
104+
Custom policies are not effected.
105+
106+
The list of built-in policies that are duplicates can be viewed [here][3].
107+
If you believe a policy is missing from this list, please [open an issue][4].
108+
109+
[3]: https://github.com/Azure/PSRule.Rules.Azure/blob/main/data/policy-ignore.json
110+
[4]: https://github.com/Azure/PSRule.Rules.Azure/issues/new/choose
111+
112+
This allows you to:
113+
114+
- Focus on policies that are unique to your environment and not already covered by PSRule for Azure.
115+
- Benefit from the additional references and examples provided by PSRule for Azure.
116+
- Reduce noise reporting the same issue multiple times.
117+
118+
To override this behavior use the `-KeepDuplicates` parameter switch when running `Export-AzPolicyAssignmentRuleData`.

0 commit comments

Comments
 (0)