Skip to content

Commit

Permalink
Simplified global-settings.json, improved documentation scripts and m…
Browse files Browse the repository at this point in the history
…ulti-tenant handling

- Simplified `global-setting.jsonc`: **breaking changes**
  - Simplified the layout by removing the documentation specifications (`representativeAssignments` and `initiativeSetsToCompare`) from `global-settings.jsonc` and moving to a folder (see below)
  - Changed `managedIdentityLocation` to `managedIdentityLocations` (plural)
- Improved and consolidated automated generation of documentation
  - Folder `Definitions/DocumentationSpecs` conatains the instructions on what to generate (moved with substantial format chnages from `global-settings.jsonc`
  - Single script to generate documentation: `Scripts\Operations\Build-PolicyAssignmentDocumentation.ps1`
  - Removed  scripts `Get-AzEffectsForEnvironments.ps1` and `Get-AzEffectsForInitiative.ps1`, replaced by `Build-PolicyAssignmentDocumentation.ps1`
- Improved multi-tenant and cloud selection support, prompts for re-authentication in interactive mode
  - Detects when wrong cloud selected (additional field in `pacEnvironments` (`global-settings.jsonc`)
  - Detects when logged into wrong tenant
  - Detects when default subscription wrong (switches to correct one)
- Bug fixes
  - Solution had latent scope bug retrieving Policy and Initiative definitions from management Groups, if the default subscription was not in the right hierarchy.
  - Improved error handling
  • Loading branch information
techlake authored Jun 28, 2022
2 parents 6fae684 + 340ab66 commit 4b8c5c6
Show file tree
Hide file tree
Showing 64 changed files with 5,754 additions and 1,374 deletions.
19 changes: 10 additions & 9 deletions Definitions/Assignments/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

- [Components](#components)
- [Assignment File Overview Diagram](#assignment-file-overview-diagram)
- [Assignment JSON file structure](#assignment-json-file-structure)
- [Assignment Json file structure](#assignment-json-file-structure)
- [Assignment Node Components](#assignment-node-components)
- [Details for `scope` and `notScope` Values](#details-for--scope--and--notscope--values)
- [Using the `PacAssignmentSelector`](#using-the--pacassignmentselector-)
Expand All @@ -21,21 +21,21 @@ The components required for **creating / updating / deleting Policy assignments

| Component | What is it used for? | Where can it be found? |
|--|--|--|
| **Assignment JSON files** | The assignments JSON file follows the management group hierarchy (optionally including subscriptions and resource groups) and defines all policy and initiative assignments on these scopes. | `Definitions/Assignments` folder |
| **Assignment Json files** | The assignments Json file follows the management group hierarchy (optionally including subscriptions and resource groups) and defines all policy and initiative assignments on these scopes. | `Definitions/Assignments` folder |
| **Global Settings File** | The `global-settings.jsonc` file specifies common values for Policy Assignments | `Definitions` folder |

<br/>[Back to top](#policy-assignments)<br/>
<br/>

## Assignment File Overview Diagram

Assignment files are hierarchical for efficient JSON definitions, avoiding duplication of JSON with copy/paste.
Assignment files are hierarchical for efficient Json definitions, avoiding duplication of Json with copy/paste.
<br/>

![Assignment File Overview Diagram](../../Docs/Images/PaC-Assignment-Structure.png)

<br/>[Back to top](#policy-assignments)<br/>
<br/>

## Assignment JSON file structure
## Assignment Json file structure

`scope` and `notScope` use a `PacAssignmentSelector` to specify which scope to use for different environments and tenants. The value for the `PacAssignmentSelector` is passed to the build script as a parameter. A star matches any `PacAssignmentSelector` specified.

Expand Down Expand Up @@ -175,7 +175,7 @@ Assignment files are hierarchical for efficient JSON definitions, avoiding dupli
| `definitionEntry` | Specifies the `policyName` or `initiativeName` for the assignment. The name should not be a fully qualified `id`. `friendlyNameToDocumentIfGuid` and is purely used as a comment to make the Json more readable if the name is a GUID. | Must exist exactly once in each branch of the tree. |
| `additionalRoleAssignments` | `roleDefinitionIds` are calculated from the included (direct or indirect via Initiative) Policy definition(s). Fo some Policies, such as DINE `diagnosticsSettings` the monitor destination might be in a different branch of the Management Group tree from the Assignment. This field specifies any roles requiring assignments in that MG branch. The value is an array, each element containing two items: `roleDefinitionId` and `scope` | Union of all the `additionalRoleAssignments` defined in this branch |

<br/>[Back to top](#policy-assignments)<br/>
<br/>

## Details for `scope` and `notScope` Values

Expand All @@ -195,7 +195,7 @@ The assignment selector determines the array being selected for this run of the
| Subscription | `/subscriptions/<subscriptionId>` |
| Resource Group | `/subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>` |

<br/>[Back to top](#policy-assignments)<br/>
<br/>

## Reading List

Expand All @@ -209,7 +209,8 @@ The assignment selector determines the array being selected for this run of the

1. **[Define Policy Assignments](../../Definitions/Assignments/README.md)**

1. **[Documenting Assignments and Initiatives](../../Definitions/DocumentationSpecs/README.md)**

1. **[Operational Scripts](../../Scripts/Operations/README.md)**

**[Return to the main page](../../README.md)**
<br/>[Back to top](#policy-assignments)<br/>
211 changes: 211 additions & 0 deletions Definitions/DocumentationSpecs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
# Documenting Assignments and Initiatives

## Table of Contents

- [Documentation Specification Files](#documentation-specification-files)
- [Example File](#example-documentation-specification-file)
- [Specifying Assignment Documentation](#specifying-assignment-documentation)
- [Specifying Initiative Documentation](#specifying-initiative-documentation)
- [Reading List](#reading-list)

## Overview

The names of the definition Json files don't matter. reads any file in the folder with a `.json` and `.jsonc` extension.

Script [`./Scripts/Operations/Build-PolicyAssignmentDocumentation.ps1`](../../Scripts/Operations/README.md#build-policyassignmentdocumentationps1) documents Initiatives and Assignments in your environment. It retrieves its instruction from Json files in this folder.

- Read and process Policy Assignments representative of an environment category, such as PROD, DEV, SANDBOX. It generates Markdown and as Excel csv files.
- Read and process Initiative definitions to compare them for Policy and effect overlap. It generates Markdown and as Excel csv files. Additionaly, it generates a Json file (`.jsonc`) defining all the parameters for the union of Policies in the Initiatives. This Json file is useful when writting assignment files to copy/paste/modify the parameter values.

<br/>

## Example Documentation Specification File

Each file must contain one or both documentation topics. This example file has both topics. Element `pacEnvironment` references the Policy as Code environment in `global-settings.jsonc` defining the tenant and root scope where the Policy and Initiative definitions are deployed.

- [`documentAssignments`](#specifying-assignment-documentation)
- [`documentInitiatives`](#specifying-initiative-documentation)

<br/>

```jsonc
{
"documentAssignments": {
"environmentCategories": [
{
"pacEnvironment": "tenant1",
"environmentCategory": "PROD",
"scopes": [ // Used in Markdown output only
"Management Groups: Contoso-Prod"
],
"representativeAssignments": [
{
"shortName": "ASB",
"id": "/providers/Microsoft.Management/managementGroups/Contoso-Prod/providers/Microsoft.Authorization/policyAssignments/prod-asb"
},
{
"shortName": "ORG",
"id": "/providers/Microsoft.Management/managementGroups/Contoso-Prod/providers/Microsoft.Authorization/policyAssignments/prod-org"
}
]
},
{
"pacEnvironment": "tenant1",
"environmentCategory": "NONPROD",
"scopes": [ // Used in Markdown output only
"Management Groups: Contoso-NonProd"
],
"representativeAssignments": [
{
"shortName": "ASB",
"id": "/providers/Microsoft.Management/managementGroups/Contoso-NonProd/providers/Microsoft.Authorization/policyAssignments/prod-asb"
},
{
"shortName": "ORG",
"id": "/providers/Microsoft.Management/managementGroups/Contoso-NonProd/providers/Microsoft.Authorization/policyAssignments/prod-org"
}
]
},
{
"pacEnvironment": "tenant1",
"environmentCategory": "DEV",
"scopes": [ // Used in Markdown output only
"Management Groups: Contoso-Dev"
],
"representativeAssignments": [
{
"shortName": "ASB",
"id": "/providers/Microsoft.Management/managementGroups/Contoso-Dev/providers/Microsoft.Authorization/policyAssignments/prod-asb"
},
{
"shortName": "ORG",
"id": "/providers/Microsoft.Management/managementGroups/Contoso-Dev/providers/Microsoft.Authorization/policyAssignments/prod-org"
}
]
},
],
"documentationSpecifications": [
{
"fileNameStem": "contoso-PROD-policy-effects",
"type": "effectsPerEnvironment",
"environmentCategory": "PROD",
"title": "Contoso PROD environments Policy effects"
},
{
"fileNameStem": "contoso-NONPROD-policy-effects",
"type": "effectsPerEnvironment",
"environmentCategory": "NONPROD",
"title": "Contoso NONPROD environment Policy effects"
},
{
"fileNameStem": "contoso-DEV-policy-effects",
"type": "effectsPerEnvironment",
"environmentCategory": "DEV",
"title": "Contoso DEV environment Policy effects"
},
{
"fileNameStem": "contoso-policy-effects-across-environments",
"type": "effectsAcrossEnvironments",
"environmentCategories": [
"PROD",
"NONPROD",
"DEV"
],
"title": "Contoso Policy effects summary"
}
]
},
"documentInitiatives": [
{
"pacEnvironment": "tenant1",
"fileNameStem": "contoso-compliance-initiatives",
"title": "Document interesting Initiatives",
"initiatives": [
{
"shortName": "ASB",
"id": "/providers/Microsoft.Authorization/policySetDefinitions/1f3afdf9-d0c9-4c3d-847f-89da613e70a8" // Azure Security Benchmark v3
},
{
"shortName": "NIST 800-171",
"id": "/providers/Microsoft.Authorization/policySetDefinitions/03055927-78bd-4236-86c0-f36125a10dc9" // NIST SP 800-171 Rev. 2
},
{
"shortName": "NIST 800-53",
"id": "/providers/Microsoft.Authorization/policySetDefinitions/179d1daa-458f-4e47-8086-2a68d0d6c38f" // NIST SP 800-53 Rev. 5
},
{
"shortName": "ORG",
"id": "/providers/Microsoft.Management/managementGroups/Contoso-Root/providers/Microsoft.Authorization/policySetDefinitions/org-security-benchmark" // Organization Security Benchmark for Custom Policies
}
]
}
]
}
```

<br/>

## Specifying Assignment Documentation

### Element `environmentCategories`

For any given environment category, such as PROD, NONPROD, DEV, this section list Policy Assignment which are representative deployed in thos environments. In many organization, the same Policies and effects are applied to multiple Management Groups and even Azure tenants.

Each `environmentCategories` entry specifies:

- `pacEnvironment`: references the Policy as Code environment in `global-settings.jsonc` defining the tenant and root scope where the Policy and Initiative definitions are deployed.
- `environmentCategory`: name used for column headings.
- `scopes`: used in Markdown output only for the Scopes section.
- `representativeAssignments`: list Policy Assignment `id`s representing this `environmentCategory`. The `shortName` is used for column headings.

<br/>

### Element `documentationSpecifications`

This element defines the outputs. Each entry defines the output of one (1) Markdown and one (1) csv file.

- `fileNameStem`: the file name without the extension (.md, .csv)
- `type`: two documentation types are supported.
- `effectsPerEnvironment`: requires a single `environmentCategory`
- Creates a Markdown file with Policies grouped by effect, sorted by Policy category and display name with effect columns for each Initiative in the representative Assignments. The effective effect is bolded and the other allowed values are listed in the same cell one per line in italics. **No allowed values listed indicate a hard-coded effect.**
- Creates a csv file with Policies sorted by Policy category and display name with effect columns for each Initiative in the representative Assignments. The effective effect is listed first and the other allowed values are listed in the same cell one per line.
- `effectsAcrossEnvironments`: compares the most stringent effect from the Assignments across all `environmentCategories` listed as effect columns.
- `title`: Heading 1 text for Markdown.

<br/>

## Specifying Initiative Documentation

Compares Policy and Initiative definitions to Initiative definitions for Policy and effect overlap as Excel csv files.

Creates a Markdown file with Policies sorted by Policy category and display name with effect columns for each Initiative. The Policy column starts with the bolded display Name followed by the description and lines grouped by bolded Initiative short name with the effect parameter name in italics and the group names in normal text. In the per Initiative effect columns the default effect is bolded and the other allowed values are listed in the same cell one per line in italics. **No allowed values listed indicate a hard-coded effect.**

Create a Json file (`.jsonc`) defining all the parameters as Json for the union of Policies in the defined Initiative Definitions sorted an collated by Policy category and Policy display name. This Json file is useful when writing assignment files. You can use them with copy/paste and modify the parameter values in your assignment file(s).

Each array entry defines three (3) files to be generated: Markdown, csv, and Json parameter file (.jsonc)

- `pacEnvironment`: references the Policy as Code environment in `global-settings.jsonc` defining the tenant and root scope where the Policy and Initiative definitions are deployed.
- `fileNameStem`: the file name without the extension (.md, .csv, .jsonc)
- `title`: Heading 1 text for Markdown.
- `initiatives`: list Initiatives (`id`) to be compared and included in the parameter Json file. The `shortName` is used for column headings.

<br/>

## Reading List

1. **[Pipeline](../../Pipeline/README.md)**

1. **[Update Global Settings](../../Definitions/README.md)**

1. **[Create Policy Definitions](../../Definitions/Policies/README.md)**

1. **[Create Initiative Definitions](../../Definitions/Initiatives/README.md)**

1. **[Define Policy Assignments](../../Definitions/Assignments/README.md)**

1. **[Documenting Assignments and Initiatives](../../Definitions/DocumentationSpecs/README.md)**

1. **[Operational Scripts](../../Scripts/Operations/README.md)**

**[Return to the main page](../../README.md)**
<br/>
10 changes: 6 additions & 4 deletions Definitions/Initiatives/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

## Initiative (Policy Set) Definition Files

The names of the definition JSON files don't matter, the Initiative definitions are registered based on the `name` attribute. It is recommended that you use a `GUID` as the `name`. The solution also allows the use of JSON with comments by using `.jsonc` instead of `.json` for the file extension.
The names of the definition Json files don't matter, the Initiative definitions are registered based on the `name` attribute. It is recommended that you use a `GUID` as the `name`. The solution also allows the use of Json with comments by using `.jsonc` instead of `.json` for the file extension.

> **NOTE**:
> When authoring policy/initiative definitions, check out the [Maximum count of Azure Policy objects](https://docs.microsoft.com/en-us/azure/governance/policy/overview#maximum-count-of-azure-policy-objects)
Expand All @@ -26,7 +26,7 @@ The Initiative definition files are structured based on the official [Azure Init
- Do not specify an `id`
- Make the `effects` parameterized

<br/>[Back to top](#initiative-definitions)<br/>
<br/>

## Example

Expand Down Expand Up @@ -83,7 +83,7 @@ The Initiative definition files are structured based on the official [Azure Init
}
```

<br/>[Back to top](#initiative-definitions)<br/>
<br/>

## Merging Built-In Initiatives

Expand All @@ -101,7 +101,9 @@ The Initiative definition files are structured based on the official [Azure Init

1. **[Define Policy Assignments](../../Definitions/Assignments/README.md)**

1. **[Documenting Assignments and Initiatives](../../Definitions/DocumentationSpecs/README.md)**

1. **[Operational Scripts](../../Scripts/Operations/README.md)**

**[Return to the main page](../../README.md)**
<br/>[Back to top](#initiative-definitions)<br/>
<br/>
11 changes: 6 additions & 5 deletions Definitions/Policies/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@

## Policy Definition Files

The names of the definition JSON files don't matter, the Policy and Initiative definitions are registered based on the `name` attribute. It is recommended that you use a `GUID` as the `name`. The solution also allows the use of JSON with comments by using `.jsonc` instead of `.json` for the file extension.
The names of the definition Json files don't matter, the Policy and Initiative definitions are registered based on the `name` attribute. It is recommended that you use a `GUID` as the `name`. The solution also allows the use of Json with comments by using `.jsonc` instead of `.json` for the file extension.

> **NOTE**:
> When authoring policy/initiative definitions, check out the [Maximum count of Azure Policy objects](https://docs.microsoft.com/en-us/azure/governance/policy/overview#maximum-count-of-azure-policy-objects)
The Policy definition files are structured based on the official [Azure Policy definition structure](https://docs.microsoft.com/en-us/azure/governance/policy/concepts/definition-structure) published by Microsoft. There are numerous definition samples available on Microsoft's [GitHub repository for azure-policy](https://github.com/Azure/azure-policy).

<br/>[Back to top](#policy-definitions)<br/>
<br/>

## Recommendations

Expand All @@ -27,7 +27,7 @@ The Policy definition files are structured based on the official [Azure Policy d
- Whenever feasible, provide a `defaultValue` for parameters, especially for an `effect` parameter.
- Policy aliases are used by Azure Policy to refer to resource type properties in the `if` condition and in `existenceCondition`: <https://docs.microsoft.com/en-us/azure/governance/policy/concepts/definition-structure#aliases>.

<br/>[Back to top](#policy-definitions)<br/>
<br/>

## Example

Expand Down Expand Up @@ -68,7 +68,7 @@ The Policy definition files are structured based on the official [Azure Policy d
}
```

<br/>[Back to top](#policy-definitions)<br/>
<br/>

## Reading List

Expand All @@ -82,7 +82,8 @@ The Policy definition files are structured based on the official [Azure Policy d

1. **[Define Policy Assignments](../../Definitions/Assignments/README.md)**

1. **[Documenting Assignments and Initiatives](../../Definitions/DocumentationSpecs/README.md)**

1. **[Operational Scripts](../../Scripts/Operations/README.md)**

**[Return to the main page](../../README.md)**
<br/>[Back to top](#policy-definitions)<br/>
Loading

0 comments on commit 4b8c5c6

Please sign in to comment.