Skip to content

Commit

Permalink
Updates to docs, global settings function, export and policy refresh (#…
Browse files Browse the repository at this point in the history
…782)

Co-authored-by: Anthony Watherston <[email protected]>
  • Loading branch information
anwather and Anthony Watherston authored Oct 16, 2024
1 parent dc74359 commit 51e58f3
Show file tree
Hide file tree
Showing 13 changed files with 883 additions and 427 deletions.
21 changes: 13 additions & 8 deletions Docs/ci-cd-github-actions.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ The previous version is still available in the starter kit in folder `Legacy` an

### Create GitHub Deployment Environments

You will need one [GitHub deployment environment](https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment) for the `epac-dev` workflow and three environments each for your epac-prod or tenant workflows. This documentation assumes the include starter kit pipelines.
Create two labels in the project called `PolicyDeployment` and `RoleDeployment`. Instructions to create new labels are [here](https://docs.github.com/en/issues/using-labels-and-milestones-to-track-work/managing-labels#creating-a-label).

You will need one [GitHub deployment environment](https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment) for the `epac-dev` workflow and three environments each for your epac-prod or tenant workflows. This documentation assumes the use of the included starter kit pipelines.

| Environment | Purpose | [App Registration](ci-cd-app-registrations.md) (SPN) |
|---|---|---|
Expand All @@ -20,7 +22,12 @@ You will need one [GitHub deployment environment](https://docs.github.com/en/act
| TENANT-DEPLOY-POLICY | Deploy Policy resources for `tenant` | ci-cd-root-policy-contributor |
| TENANT-DEPLOY-ROLES | Deploy Roles for `tenant` | ci-cd-root-user-assignments |

For each environment, [add to the environment secrets](https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment#environment-secrets) for the tenant id, client id and client secret for the SPN. The secrets must be named `TENANT_ID`, `CLIENT_ID` and `CLIENT_SECRET` respectively.
[Add the environment secrets for](https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment#environment-secrets) the Service Principal listed below to the GitHub repository. These are used to authenticate to Azure, and should be added to each Environment listed above.

| Secret Name | Value |
|---------|---------|
| AZURE_CLIENT_ID | Application ID for SPN |
| AZURE_TENANT_ID | Azure AD Tenant |

### Hardening each Environment

Expand Down Expand Up @@ -52,14 +59,12 @@ This section is retained from the previous documentation to enable you to contin
There are some steps to be performed in GitHub to ensure the action runs correctly.

1. Create two labels in the project called `PolicyDeployment` and `RoleDeployment`. Instructions to create new labels are [here](https://docs.github.com/en/issues/using-labels-and-milestones-to-track-work/managing-labels#creating-a-label).
2. Create secrets representing an SPN in GitHub for the repository as below - these are used to authenticate to Azure
2. An Environment should be created for each [SPN created](Docs/ci-cd-app-registrations.md)

| Secret Name | Value |
|---|---|
| CLIENT_ID | Application ID for SPN |
| CLIENT_SECRET | Client secret |
| TENANT_ID | Azure AD Tenant |
| SUBSCRIPTION_ID | Any subscription ID. Used to login but not in the process |
|---------|---------|
| AZURE_CLIENT_ID | Application ID for SPN |
| AZURE_TENANT_ID | Azure AD Tenant |

3. In the `.github\workflows\build.yaml` and `.github\workflows\deploy.yaml` file updated the `env:` section as below.

Expand Down
2 changes: 1 addition & 1 deletion Docs/integrating-with-alz.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ To deploy the ALZ policies using EPAC follow the steps below.
New-HydrationDefinitionFolder -DefinitionsRootFolder .\Definitions
```
3. Update the `global-settings.json` file in the Definitions folder as described [here](definitions-and-global-settings.md#global-settings)
3. Update the `global-settings.json` file in the Definitions folder as described [here](definitions-and-global-settings.md)
4. Synchronize the policies from the upstream repository. You should ensure that you are running the latest version of the EPAC module before running this script each time.
Expand Down
10 changes: 8 additions & 2 deletions Docs/operational-scripts.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,17 @@ The scripts `New-AzureDevOpsBug` and `New-GitHubIssue` create a Bug or Issue whe

## Export from AzAdvertizer

The script `Export-AzAdvertizerPolicy.ps1` creates for you the policyAssignments, policyDefinitions, and policySetDefinitions based on the provided URL in an Output folder under 'ALZ-Export'.
The script `Export-PolicyToEPAC.ps1` creates for you the policyAssignments, policyDefinitions, and policySetDefinitions based on the provided URL in an Output folder under 'ALZ-Export'.

Parameters:

* **AzAdvertizerUrl**: Mandatory url of the policy or policy set from AzAdvertizer.
* **PolicyDefinitionId**: Mandatory url of the policy or policy set from AzAdvertizer.

* **PolicySetDefinitionId**: Mandatory url of the policy or policy set from AzAdvertizer.

* **ALZPolicyDefinitionId**: Mandatory url of the policy or policy set from AzAdvertizer.

* **ALZPolicySetDefinitionId**: Mandatory url of the policy or policy set from AzAdvertizer.

* **OutputFolder**: Output Folder. Defaults to the path 'Output'.

Expand Down
8 changes: 4 additions & 4 deletions Docs/settings-desired-state.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Desired State strategy enables you to adjust the default behavior to fit more co
- `excludedPolicySetDefinitions`: An array of Policy Set Definitions to exclude from management by EPAC. The default is an empty array. Wild cards are supported.
- `excludedPolicyAssignments`: An array of Policy Assignments to exclude from management by EPAC. The default is an empty array. Wild cards are supported.
- `doNotDisableDeprecatedPolicies`: Automatically set deprecated policies' policy effect to "Disabled". This setting can be used to override that behavior by setting it to `true`. Default is `false`.
- `excludeSubscriptions`: Exclude all subscription under the deployment root scope. Designed for environments containing many frequently updated subscriptions that are not requiring management and where using ```excludedScopes``` would be impractical to maintain. If resource groups are added ```excludedScopes``` they will be ignored as this setting will take precedence. It will not effect excluded management group scopes. Default is `false`

The following example shows the `desiredState` element with all properties set:

Expand All @@ -40,7 +41,6 @@ The following example shows the `desiredState` element with all properties set:

While transitioning to EPAC, existing Policy resources may need to be kept. Setting `desiredState` to `ownedOnly` allows EPAC to remove its own resources while preserving instances requiring (temporary) preservation.


```json
"desiredState": {
"strategy": "ownedOnly",
Expand All @@ -62,7 +62,7 @@ After short transitioning period (weeks), it is recommended to set `desiredState
> [!WARNING]
> **Breaking Change in v10.0.0:** Policy Assignments at resource groups are **managed** by EPAC. The element `includeResourceGroups` has been deprecated and removed.
To exclude resource groups from management by EPAC, add an `excludedScopes` array element with a wild card for the subscription and resourceGroups to `desiredState`.
To exclude resource groups from management by EPAC, add an `excludedScopes` array element with a wild card for the subscription and resourceGroups to `desiredState`.

```json
"desiredState": {
Expand Down Expand Up @@ -90,8 +90,8 @@ In some organizations the lifecycle of different parts may be managed separately

EPAC only manages items with a directory in the `Definitions` folder. Therefore, you can use the same `pacOwnerId` from two repos and remove the folders to separate them. In this example:

* Repo1: `Definitions` contains `policyDefinitions`, `policySetDefinitions` and `policyAssignments` folders.
* Repo2: `Definitions` contains `policyExemptions` folder.
- Repo1: `Definitions` contains `policyDefinitions`, `policySetDefinitions` and `policyAssignments` folders.
- Repo2: `Definitions` contains `policyExemptions` folder.

Policy resource that would be defined in the folder. It is important to remove the folders. GitHub repos remove empty folder automatically.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,18 +58,6 @@
"policyId": "/providers/Microsoft.Authorization/policyDefinitions/1a5b4dca-0b6f-4cf5-907c-56316bc1bf3d",
"displayName": "AKS HTTPS Access"
}
},
{
"nodeName": "Security",
"assignment": {
"name": "Deploy-AKS-Policy",
"displayName": "Deploy Azure Policy Add-on to Azure Kubernetes Service clusters",
"description": "Use Azure Policy Add-on to manage and report on the compliance state of your Azure Kubernetes Service (AKS) clusters. For more information, see https://aka.ms/akspolicydoc."
},
"definitionEntry": {
"policyId": "/providers/Microsoft.Authorization/policyDefinitions/a8eff44f-8c92-45c3-a3fb-9880802d67a7",
"displayName": "Deploy AKS Policy"
}
}
]
},
Expand Down Expand Up @@ -146,6 +134,25 @@
"message": "Web Application Firewall (WAF) must be enabled for Application Gateway."
}
]
},
{
"nodeName": "Subnets",
"assignment": {
"name": "Enforce-Snet-Private-LZ",
"displayName": "Subnets should be private",
"description": "Ensure your subnets are secure by default by preventing default outbound access. For more information go to https://aka.ms/defaultoutboundaccessretirement"
},
"definitionEntry": {
"policyId": "/providers/Microsoft.Authorization/policyDefinitions/7bca8353-aa3b-429b-904a-9229c4385837",
"displayName": "Subnets should be private",
"nonComplianceMessages": [
{
"policyDefinitionReferenceId": null,
"message": "Subnets should be private."
}
]
},
"enforcementMode": "DoNotEnforce"
}
]
},
Expand Down Expand Up @@ -528,4 +535,4 @@
]
}
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,30 @@
}
}
]
},
{
"nodeName": "Networking",
"children": [
{
"nodeName": "Subnets",
"assignment": {
"name": "Enforce-Snet-Private-PLT",
"displayName": "Subnets should be private",
"description": "Ensure your subnets are secure by default by preventing default outbound access. For more information go to https://aka.ms/defaultoutboundaccessretirement"
},
"definitionEntry": {
"policyId": "/providers/Microsoft.Authorization/policyDefinitions/7bca8353-aa3b-429b-904a-9229c4385837",
"displayName": "Subnets should be private",
"nonComplianceMessages": [
{
"policyDefinitionReferenceId": null,
"message": "Subnets should be private."
}
]
},
"enforcementMode": "DoNotEnforce"
}
]
}
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"logAnalytics_1": "", // Replace with your central Log Analytics workspace ID
"emailSecurityContact": "", // Security contact email address for Microsoft Defender for Cloud
"ascExportResourceGroupName": "asc-export", // Resource group to export Microsoft Defender for Cloud data to
"ascExportResourceGroupLocation": "" // Location of the resource group to export Microsoft Defender for Cloud data to
"ascExportResourceGroupLocation": "", // Location of the resource group to export Microsoft Defender for Cloud data to
"createResourceGroup": "true" // A new resource group will be created if set to true for ascExportResourceGroupName
},
"children": [
{
Expand Down Expand Up @@ -241,7 +242,7 @@
"nonComplianceMessages": [
{
"policyDefinitionReferenceId": null,
"message": "Trust Launch must be used on supported virtual machines for enhanced security."
"message": "Trusted Launch must be used on supported virtual machines for enhanced security."
}
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,23 @@
}
]
},
{
"nodeName": "BotServices",
"assignment": {
"name": "Enforce-GR-BotService",
"displayName": "Enforce recommended guardrails for Bot Service",
"description": "This initiative assignment enables additional ALZ guardrails for Bot Service."
},
"definitionEntry": {
"policySetName": "Enforce-Guardrails-BotService",
"displayName": "Enforce recommended guardrails for Bot Service"
},
"nonComplianceMessages": [
{
"message": "Recommended guardrails must be enforced for Bot Service."
}
]
},
{
"nodeName": "CogServ",
"assignment": {
Expand Down
7 changes: 6 additions & 1 deletion Scripts/Helpers/Build-ScopeTableForDeploymentRootScope.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,12 @@ function Build-ScopeTableForDeploymentRootScope {
foreach ($resourceGroup in $resourceGroups) {
$subscriptionId = $resourceGroup.subscriptionId
$id = $resourceGroup.id
$isExcluded = $false
if ($PacEnvironment.desiredState.excludeSubscriptions) {
$isExcluded = $true
}
else {
$isExcluded = $false
}
$isInGlobalNotScope = $false
foreach ($globalNotScope in $PacEnvironment.globalNotScopesResourceGroups) {
if ($id -like $globalNotScope) {
Expand Down
3 changes: 3 additions & 0 deletions Scripts/Helpers/Build-ScopeTableForSubscription.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ function Build-ScopeTableForSubscription {

#region build scope details
$thisNotScope = $null
if ($PacEnvironment.desiredState.excludeSubscriptions) {
$IsExcluded = $true
}
if ($null -ne $ParentScopeDetails) {
# the root node is never not in scope or excluded
if (!$IsInGlobalNotScope) {
Expand Down
6 changes: 5 additions & 1 deletion Scripts/Helpers/Get-GlobalSettings.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ function Get-GlobalSettings {
excludedPolicyDefinitions = @()
excludedPolicySetDefinitions = @()
excludedPolicyAssignments = @()
excludeSubscriptions = $false
doNotDisableDeprecatedPolicies = $false
}

Expand Down Expand Up @@ -260,7 +261,7 @@ function Get-GlobalSettings {
}
else {
$null = $excludedScopesList.Add($excludedScope)
if ($excludedScope.StartsWith("/subscriptions/")) {
if ($excludedScope.StartsWith("/subscriptions/") -and $desired.excludeSubscriptions -eq $false) {
if ($excludedScope.Contains("/resourceGroups/", [System.StringComparison]::OrdinalIgnoreCase)) {
$null = $globalExcludedScopesResourceGroupsList.Add($excludedScope)
}
Expand Down Expand Up @@ -299,6 +300,9 @@ function Get-GlobalSettings {
}
$desiredState.excludedPolicyAssignments = $excluded
}
if ($desired.excludeSubscriptions) {
$desiredState.excludeSubscriptions = $true
}
$deleteExpired = $desired.deleteExpiredExemptions
if ($null -ne $deleteExpired) {
Add-ErrorMessage -ErrorInfo $errorInfo -ErrorString "Global settings error: pacEnvironment $pacSelector field desiredState.deleteExpiredExemptions is deprecated. Remove it!"
Expand Down
Loading

0 comments on commit 51e58f3

Please sign in to comment.