Start the Enterprise Policy as Code (EPAC) Implementation
Caution
EPAC is a true desired state deployment technology. It takes possession of all Policy Resources at the deploymentRootScope
and its children. It will delete any Policy resources not defined in the EPAC repo. This behavior can be modified as documented in the desired state strategy page.
Getting Started
The following steps are required to implement Enterprise Policy as Code (EPAC) in your environment:
- Understand concepts and environments.
- Determine desired state strategy.
- How to handle Defender for Cloud Policy Assignments.
- Design your CI/CD process.
- Install Powershell and EPAC.
- Create your
Definitions
folder and subfolders. - Populate
global-settings.jsonc
with your environment settings and desired state strategy. - Populate your Definitions folder with Policy resources. (For a folder structure example, please see StarterKit/Definitions-Common)
- [Option A:] Extract existing Policy resources from your Azure environment.
- [Option B:] Integrate Azure Landing Zones (ALZ).
- [Option C:] Utilize the hydration kit and
StarterKit
content. - [Optional] Create custom Policy definitions.
- [Optional] Create custom Policy Set definitions.
- Create your Policy Assignments.
- [Optional] Manage Policy Exemptions.
- Implement your CI/CD pipelines.
- Operate your environment with the provided operational scripts.
EPAC Concepts and Environments
Important
Understanding the concepts and environments is crucial. Do not proceed until you completely understand this section.
EPAC Concepts
Like any other code development project (including Infrastructure as Code - IaC), developing Policy requires a development area to test and validate the Policy resources before deploying them to production. EPAC is no different.
- EPAC's nonprod environment is used to develop and test Policy resources. In most cases you will need one management group hierarchy to simulate EPAC production tenants and management groups for development and testing of Policy definitions and Policy Assignments.
- EPAC's prod environment will govern all other IaC environments (e.g., sandbox, development, integration, test/qa, pre-prod, prod, ...) and tenants. This can be confusing. We will use EPAC environments and IaC environments to disambiguate the environments.
Defining EPAC Environments
EPAC defines environments identified by a string (unique per repository) called pacSelector
. pacEnvironments
in global-settings.jsonc
environment map a pacSelector
to the following settings:
cloud
- to select commercial or sovereign cloud environments.tenantId
- enables multi-tenant scenarios.rootDefinitionScope
- scope for custom Policy and Policy Set definition deployment.- [Optional] Define the following items:
globalNotScopes
- used to exclude scopes from Policy Assignments.managedIdentityLocation
- used for the location for created Managed Identities.desiredState
- desired state strategy and details for Policy resources.managedTenant
- used for environments that are in a lighthouse managed tenant.
These associations are stored in global-settings.jsonc in an element called pacEnvironments
.
Multi-Tenant Support
EPAC supports single and multi-tenant deployments from a single source. In most cases you should have a fully or partially isolated area for Policy development and testing, such as a Management Group. An entire tenant can be used; however, it is not necessary since EPAC has sophisticated partitioning capabilities. EPAC also supports deployments to managed (Lighthouse) tenants and is able to deploy cross tenant role assignments to projected subscriptions in order to facilitate writing data back to the managing tenant (e.g. diagnostic settings).
Example Management Group Structure and EPAC Environments
Assuming that you have a single tenant with a management group hierarchy as follows (with additional levels of management groups not shown for brevity):
- Root tenant (always present)
- mg-Enterprise (pseudo root)
- mg-Identity
- mg-NonProd
- mg-Dev
- mg-Sandbox
- ...
- mg-Prod
- mg-LandingZones
- mg-PCI
- mg-EpacDev (EPAC development)
You should create a development testing structure for EPAC in mg-EpacDev
. We have found little need for a separate management group for EPAC testing, but you can create one mirroring the structure of mg-EpacDev
.
- Root tenant (always present)
- mg-Enterprise (pseudo root) :arrow_right: EPAC environment
"tenant"
- mg-Identity
- mg-NonProd
- mg-Sandbox
- mg-Prod
- mg-PCI
- mg-EpacDev (EPAC development) :arrow_right: EPAC environment
"epac-dev"
- mg-EpacDev-Identity
- mg-EpacDev-NonProd
- mg-EpacDev-Dev
- mg-EpacDev-Sandbox
- mg-EpacDev-Prod
- mg-EpacDev-LandingZones
- mg-EpacDev-PCI
The simplest global-settings.jsonc
for the above structure is:
{
"$schema": "https://raw.githubusercontent.com/Azure/enterprise-azure-policy-as-code/main/Schemas/global-settings-schema.json",
"pacOwnerId": "{{guid}}",
"pacEnvironments": [
{
"pacSelector": "epac-dev",
"cloud": "AzureCloud",
"tenantId": "{{tenant-id}}",
"deploymentRootScope": "/providers/Microsoft.Management/managementGroups/mg-Epac-Dev"
},
{
"pacSelector": "tenant",
"cloud": "AzureCloud",
"tenantId": "{{tenant-id}}",
"deploymentRootScope": "/providers/Microsoft.Management/managementGroups/mg-Enterprise"
}
]
}
For assignment files, this is a top level property on the assignment's root node:
"nodeName": "/root",
"epacCloudEnvironments": [
"AzureChinaCloud"
],
Install Powershell and EPAC
EPAC can be installed in two ways:
- Install the
EnterprisePolicyAsCode
module from the PowerShell marketplace. This is the recommended approach documented here. - Copy the source code from an EPAC GitHub repository fork. The process is described in Forking the GitHub Repo - an Alternate Installation Method page.
Installation Steps
- Install PowerShell 7.4 or later.
- Install the Az PowerShell modules and Enterprise Policy as Code module.
Install-Module Az -Scope CurrentUser
Install-Module EnterprisePolicyAsCode -Scope CurrentUser
Many scripts use parameters for input and output folders. They default to the current directory. We recommend that you do one of the following approaches instead of accepting the default to prevent your files being created in the wrong location:
- [Preferred] Set the environment variables PAC_DEFINITIONS_FOLDER
, PAC_OUTPUT_FOLDER
, and PAC_INPUT_FOLDER
.
- [Alternative] Use the script parameters -DefinitionsRootFolder
, -OutputFolder
, and -InputFolder
.
Definitions
Folder Structure
- Define the Azure environment(s) in file
global-settings.jsonc
- Create custom Policies (optional) in folder
policyDefinitions
- Create custom Policy Sets (optional) in folder
policySetDefinitions
- Define the Policy Assignments in folder
policyAssignments
- Define the Policy Exemptions (optional) in folder
policyExemptions
- Define Documentation in folder
policyDocumentations
Create the Definitions folder
Create a new EPAC Definitions
folder with a number of subfolder and a global-settings.jsonc
file.
Tip
For a folder structure example, please see StarterKit/Definitions-Common.
New-HydrationDefinitionsFolder -DefinitionsRootFolder Definitions
Cloud Environment with Unsupported/Missing Policy Definitions
In some multi-tenant implementations, not all policies, policy sets, and/or assignments will function in all tenants, usually due to either built-in policies that don't exist in some tenant types or unavailable resource providers. In order to facilitate multi-tenant deployments in these scenarios, utilize the epacCloudEnvironments
property to specify which cloud type a specific file should be considered in. For example in order to have a policy definition deployed only to epacEnvironments that are China cloud tenants, add a metadata property like this to that definition (or definitionSet) file:
"metadata": {
"epacCloudEnvironments": [
"AzureChinaCloud"
]
},
Debug EPAC issues
Should you encounter issues with the expected behavior of EPAC, try the following:
- Run the scripts interactively.
- Debug the scripts in VS Code.
- Ask for help by raising a GitHub Issue