diff --git a/.gitignore b/.gitignore index 28863ad5..d9b59b08 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ docs/static/examples/tf/accelerator/config/~$checklist.xlsx + +.DS_Store diff --git a/docs/.gitignore b/docs/.gitignore index 756a352c..70e0c2f9 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -14,3 +14,5 @@ hugo.linux # Exclude Terraform files used for testing examples .terraform .terraform.lock.hcl + +.DS_Store diff --git a/docs/content/policy/_index.md b/docs/content/policy/_index.md index bdb73f10..ef672ff1 100644 --- a/docs/content/policy/_index.md +++ b/docs/content/policy/_index.md @@ -4,12 +4,44 @@ geekdocCollapseSection: true weight: 30 --- -This section documents all the Azure Landing Zones specific Azure Policy details. - {{< hint type=note >}} This section is a work in progress as we slowly move content from the [wiki](https://aka.ms/alz/policy). {{< /hint >}} -## Table of Contents +Azure Policy and deployIfNotExist enables autonomy in the platform, and reduces operational burden as you scale your deployments and subscriptions in the Azure landing zone architecture. The primary purpose is to ensure that subscriptions and resources are compliant, while empowering application teams to use their own preferred tools/clients to deploy. + +> Please refer to [Policy Driven Governance](https://learn.microsoft.com/en-gb/azure/cloud-adoption-framework/ready/landing-zone/design-principles#policy-driven-governance) for further information. + +{{< hint type=important >}} +**IMPORTANT NOTE:** ALZ priority is to provide a secure by default, Zero Trust aligned, configuration, and occasionally we will rely on `-preview` policies in our default assignments to meet our core objective. These preview policies are maintained by the Azure product owners and versioning is not in our control, however, we feel they are sufficiently important to be included in our releases. If the inclusion of preview policies is of concern, please review all ALZ default initiative assignments and remove any `-preview` policies that you are not comfortable with. +{{< /hint >}} + +## FAQ and Tips + +We have added a dedicated [ALZ Policy FAQ and Tips]({{< relref "policyFAQ" >}}) based on common issues raised or questions asked by customers and partners. + +## Why are there custom policy definitions as part of Azure landing zones? + +We work with - and learn from our customers and partners to ensure that we evolve and enhance the reference implementations to meet customer requirements. The primary approach of the policies as part of Azure landing zones is to be proactive (deployIfNotExist, and modify), and preventive (deny). We are continuously moving these policies to built-ins. + +## What Azure Policies does Azure landing zone provide additionally to those already built-in? + +There are many custom Azure Policy Definitions and custom Azure Policy Initiatives included as part of the Azure Landing Zones implementation that add on to those already built-in within each Azure customers tenant. + +For Azure landing zones, the custom Azure Policy Definitions and Initiatives are consistent across the three implementation options, unless otherwise noted; [Terraform Module](https://aka.ms/alz/tf), [Bicep Modules](https://aka.ms/alz/bicep), [Azure landing zone portal accelerator](https://aka.ms/alz#azure-landing-zone-accelerator). + +> Our goal is always to try and use built-in policies where available and also work with product teams to adopt our custom policies and make them built-in, which takes time. This means there will always be a requirement for custom policies. + +## Why are managed identities deployed as part of the ALZ policies? + +Managed Identities provide an alternative way to access Azure resources without having to manage credentials. They are created as a part of the ALZ policies mainly for policies that have the deployIfNotExists (DINE) effect in this initiative. The managed identities are used in order to remediate resources that are not compliant with the policy. For further information on how remediation works with access control, please refer to the following documentation: [Remediate non-compliant resources - Azure Policy | Microsoft](https://learn.microsoft.com/en-us/azure/governance/policy/how-to/remediate-resources?tabs=azure-portal#how-remediation-access-control-works) + +## AzAdvertizer Integration + +We have worked with the creator of [AzAdvertizer](https://www.azadvertizer.net) to integrate all of the custom Azure Policy Definitions and Initiatives as part of Azure landing zones into it to help customers use the tool to look at the policies further in an easy to use tool that is popular in the community. + +On either the [Policy](https://www.azadvertizer.net/azpolicyadvertizer_all.html#%7B%22col_10%22%3A%7B%22flt%22%3A%22ESLZ%22%7D%7D) or [Initiative](https://www.azadvertizer.net/azpolicyinitiativesadvertizer_all.html) section of the site, set the 'Type' column drop down (last one on the right hand side) to 'ALZ' and you will see all the policies as mentioned above in the tool for you to investigate further. + +AzAdvertizer also updates once per day! -- [Policy Versioning]({{< relref "policyVersioning" >}}) +![AzAdvertizer ALZ Integration Slide](./img/alzPolicyAzAdvertizer.png) diff --git a/docs/content/policy/img/AzGovViz-ALZ-Policy.png b/docs/content/policy/img/AzGovViz-ALZ-Policy.png new file mode 100644 index 00000000..22763970 Binary files /dev/null and b/docs/content/policy/img/AzGovViz-ALZ-Policy.png differ diff --git a/docs/content/policy/img/MgmtGroups_Policies_v0.1.svg b/docs/content/policy/img/MgmtGroups_Policies_v0.1.svg new file mode 100644 index 00000000..2ead48cb --- /dev/null +++ b/docs/content/policy/img/MgmtGroups_Policies_v0.1.svg @@ -0,0 +1,3940 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Page-1 + + + Sheet.1624 + + + + Sheet.1026 + + + + Management Groups + + Sheet.18 + + + + + + + Sheet.19 + + + + + + + Sheet.20 + + + + + + + + + + Sheet.21 + + Sheet.22 + + + + + + + Sheet.23 + + + + + + + + + + Sheet.24 + + Sheet.25 + + + + + + + Sheet.26 + + + + + + + + + Sheet.27 + + + + + + + Sheet.28 + + + + + + + Sheet.29 + + + + + + + Sheet.30 + + + + + + + + Policy.1002 + + Sheet.1003 + + + + + + + Sheet.1004 + + + + + + + Sheet.1005 + + + + + + + Sheet.1006 + + + + + + + Sheet.1007 + + + + + + + Sheet.1008 + + + + + + + Sheet.1009 + + + + + + + Sheet.1010 + + + + + + + + Sheet.1024 + Policy Definition (i.e. Policies) + + + + Policy Definition (i.e. Policies) + + Sheet.1025 + Policy Set Definition (i.e. Initiatives) + + + + Policy Set Definition (i.e. Initiatives) + + Sheet.1027 + + + + Management Groups.1064 + + Sheet.1065 + + + + + + + Sheet.1066 + + + + + + + Sheet.1067 + + + + + + + + + + Sheet.1068 + + Sheet.1069 + + + + + + + Sheet.1070 + + + + + + + + + + Sheet.1071 + + Sheet.1072 + + + + + + + Sheet.1073 + + + + + + + + + Sheet.1074 + + + + + + + Sheet.1075 + + + + + + + Sheet.1076 + + + + + + + Sheet.1077 + + + + + + + + Sheet.1102 + + + + Sheet.1103 + + + + Sheet.1104 + Tenant Root + + + + Tenant Root + + Sheet.1105 + Intermediate Root + + + + Intermediate Root + + Management Groups.1106 + + Sheet.1107 + + + + + + + Sheet.1108 + + + + + + + Sheet.1109 + + + + + + + + + + Sheet.1110 + + Sheet.1111 + + + + + + + Sheet.1112 + + + + + + + + + + Sheet.1113 + + Sheet.1114 + + + + + + + Sheet.1115 + + + + + + + + + Sheet.1116 + + + + + + + Sheet.1117 + + + + + + + Sheet.1118 + + + + + + + Sheet.1119 + + + + + + + + Sheet.1120 + + + + Sheet.1121 + + + + Sheet.1122 + + + + Sheet.1124 + + + + Sheet.1125 + + + + Icon-377PolicySet.1142 + + Sheet.1143 + + Sheet.1144 + + + + Sheet.1145 + + + + Sheet.1146 + + + + Sheet.1147 + + + + Sheet.1148 + + + + Sheet.1149 + + + + Sheet.1150 + + + + Sheet.1151 + + + + Sheet.1152 + + + + Sheet.1153 + + + + Sheet.1154 + + + + Sheet.1155 + + + + Sheet.1156 + + + + Sheet.1157 + + + + + + Sheet.1183 + + + + Policy.1184 + + Sheet.1185 + + + + + + + Sheet.1186 + + + + + + + Sheet.1187 + + + + + + + Sheet.1188 + + + + + + + Sheet.1189 + + + + + + + Sheet.1190 + + + + + + + Sheet.1191 + + + + + + + Sheet.1192 + + + + + + + + Icon-377PolicySet.1193 + + Sheet.1194 + + Sheet.1195 + + + + Sheet.1196 + + + + Sheet.1197 + + + + Sheet.1198 + + + + Sheet.1199 + + + + Sheet.1200 + + + + Sheet.1201 + + + + Sheet.1202 + + + + Sheet.1203 + + + + Sheet.1204 + + + + Sheet.1205 + + + + Sheet.1206 + + + + Sheet.1207 + + + + Sheet.1208 + + + + + + Management Groups.1209 + + Sheet.1210 + + + + + + + Sheet.1211 + + + + + + + Sheet.1212 + + + + + + + + + + Sheet.1213 + + Sheet.1214 + + + + + + + Sheet.1215 + + + + + + + + + + Sheet.1216 + + Sheet.1217 + + + + + + + Sheet.1218 + + + + + + + + + Sheet.1219 + + + + + + + Sheet.1220 + + + + + + + Sheet.1221 + + + + + + + Sheet.1222 + + + + + + + + Sheet.1223 + + + + Sheet.1224 + + + + Policy.1225 + + Sheet.1226 + + + + + + + Sheet.1227 + + + + + + + Sheet.1228 + + + + + + + Sheet.1229 + + + + + + + Sheet.1230 + + + + + + + Sheet.1231 + + + + + + + Sheet.1232 + + + + + + + Sheet.1233 + + + + + + + + Icon-377PolicySet.1234 + + Sheet.1235 + + Sheet.1236 + + + + Sheet.1237 + + + + Sheet.1238 + + + + Sheet.1239 + + + + Sheet.1240 + + + + Sheet.1241 + + + + Sheet.1242 + + + + Sheet.1243 + + + + Sheet.1244 + + + + Sheet.1245 + + + + Sheet.1246 + + + + Sheet.1247 + + + + Sheet.1248 + + + + Sheet.1249 + + + + + + Sheet.1250 + + + + Sheet.1251 + + + + Policy.1252 + + Sheet.1253 + + + + + + + Sheet.1254 + + + + + + + Sheet.1255 + + + + + + + Sheet.1256 + + + + + + + Sheet.1257 + + + + + + + Sheet.1258 + + + + + + + Sheet.1259 + + + + + + + Sheet.1260 + + + + + + + + Management Groups.1277 + + Sheet.1278 + + + + + + + Sheet.1279 + + + + + + + Sheet.1280 + + + + + + + + + + Sheet.1281 + + Sheet.1282 + + + + + + + Sheet.1283 + + + + + + + + + + Sheet.1284 + + Sheet.1285 + + + + + + + Sheet.1286 + + + + + + + + + Sheet.1287 + + + + + + + Sheet.1288 + + + + + + + Sheet.1289 + + + + + + + Sheet.1290 + + + + + + + + Sheet.1291 + + + + Sheet.1292 + + + + Policy.1293 + + Sheet.1294 + + + + + + + Sheet.1295 + + + + + + + Sheet.1296 + + + + + + + Sheet.1297 + + + + + + + Sheet.1298 + + + + + + + Sheet.1299 + + + + + + + Sheet.1300 + + + + + + + Sheet.1301 + + + + + + + + Management Groups.1302 + + Sheet.1303 + + + + + + + Sheet.1304 + + + + + + + Sheet.1305 + + + + + + + + + + Sheet.1306 + + Sheet.1307 + + + + + + + Sheet.1308 + + + + + + + + + + Sheet.1309 + + Sheet.1310 + + + + + + + Sheet.1311 + + + + + + + + + Sheet.1312 + + + + + + + Sheet.1313 + + + + + + + Sheet.1314 + + + + + + + Sheet.1315 + + + + + + + + Sheet.1316 + + + + Sheet.1317 + + + + Policy.1318 + + Sheet.1319 + + + + + + + Sheet.1320 + + + + + + + Sheet.1321 + + + + + + + Sheet.1322 + + + + + + + Sheet.1323 + + + + + + + Sheet.1324 + + + + + + + Sheet.1325 + + + + + + + Sheet.1326 + + + + + + + + Sheet.1327 + Platform + + + + Platform + + Sheet.1328 + Connectivity + + + + Connectivity + + Sheet.1329 + Management + + + + Management + + Sheet.1331 + Identity + + + + Identity + + Subscriptions.1332 + + Sheet.1333 + + + + + + + Sheet.1334 + + + + + + + Sheet.1335 + + + + + + + Sheet.1336 + + + + + + + + Subscriptions.1337 + + Sheet.1338 + + + + + + + Sheet.1339 + + + + + + + Sheet.1340 + + + + + + + Sheet.1341 + + + + + + + + Subscriptions.1342 + + Sheet.1343 + + + + + + + Sheet.1344 + + + + + + + Sheet.1345 + + + + + + + Sheet.1346 + + + + + + + + Sheet.1347 + + + + Sheet.1348 + + + + Sheet.1349 + + + + Management Groups.1350 + + Sheet.1351 + + + + + + + Sheet.1352 + + + + + + + Sheet.1353 + + + + + + + + + + Sheet.1354 + + Sheet.1355 + + + + + + + Sheet.1356 + + + + + + + + + + Sheet.1357 + + Sheet.1358 + + + + + + + Sheet.1359 + + + + + + + + + Sheet.1360 + + + + + + + Sheet.1361 + + + + + + + Sheet.1362 + + + + + + + Sheet.1363 + + + + + + + + Management Groups.1364 + + Sheet.1365 + + + + + + + Sheet.1366 + + + + + + + Sheet.1367 + + + + + + + + + + Sheet.1368 + + Sheet.1369 + + + + + + + Sheet.1370 + + + + + + + + + + Sheet.1371 + + Sheet.1372 + + + + + + + Sheet.1373 + + + + + + + + + Sheet.1374 + + + + + + + Sheet.1375 + + + + + + + Sheet.1376 + + + + + + + Sheet.1377 + + + + + + + + Management Groups.1378 + + Sheet.1379 + + + + + + + Sheet.1380 + + + + + + + Sheet.1381 + + + + + + + + + + Sheet.1382 + + Sheet.1383 + + + + + + + Sheet.1384 + + + + + + + + + + Sheet.1385 + + Sheet.1386 + + + + + + + Sheet.1387 + + + + + + + + + Sheet.1388 + + + + + + + Sheet.1389 + + + + + + + Sheet.1390 + + + + + + + Sheet.1391 + + + + + + + + Management Groups.1392 + + Sheet.1393 + + + + + + + Sheet.1394 + + + + + + + Sheet.1395 + + + + + + + + + + Sheet.1396 + + Sheet.1397 + + + + + + + Sheet.1398 + + + + + + + + + + Sheet.1399 + + Sheet.1400 + + + + + + + Sheet.1401 + + + + + + + + + Sheet.1402 + + + + + + + Sheet.1403 + + + + + + + Sheet.1404 + + + + + + + Sheet.1405 + + + + + + + + Management Groups.1406 + + Sheet.1407 + + + + + + + Sheet.1408 + + + + + + + Sheet.1409 + + + + + + + + + + Sheet.1410 + + Sheet.1411 + + + + + + + Sheet.1412 + + + + + + + + + + Sheet.1413 + + Sheet.1414 + + + + + + + Sheet.1415 + + + + + + + + + Sheet.1416 + + + + + + + Sheet.1417 + + + + + + + Sheet.1418 + + + + + + + Sheet.1419 + + + + + + + + Sheet.1420 + + + + Sheet.1421 + Landing Zones + + + + Landing Zones + + Sheet.1422 + + + + Sheet.1423 + + + + Sheet.1425 + + + + Sheet.1426 + + + + Policy.1427 + + Sheet.1428 + + + + + + + Sheet.1429 + + + + + + + Sheet.1430 + + + + + + + Sheet.1431 + + + + + + + Sheet.1432 + + + + + + + Sheet.1433 + + + + + + + Sheet.1434 + + + + + + + Sheet.1435 + + + + + + + + Icon-377PolicySet.1436 + + Sheet.1437 + + Sheet.1438 + + + + Sheet.1439 + + + + Sheet.1440 + + + + Sheet.1441 + + + + Sheet.1442 + + + + Sheet.1443 + + + + Sheet.1444 + + + + Sheet.1445 + + + + Sheet.1446 + + + + Sheet.1447 + + + + Sheet.1448 + + + + Sheet.1449 + + + + Sheet.1450 + + + + Sheet.1451 + + + + + + Sheet.1452 + Corp + + + + Corp + + Sheet.1453 + Online + + + + Online + + Subscriptions.1454 + + Sheet.1455 + + + + + + + Sheet.1456 + + + + + + + Sheet.1457 + + + + + + + Sheet.1458 + + + + + + + + Subscriptions.1459 + + Sheet.1460 + + + + + + + Sheet.1461 + + + + + + + Sheet.1462 + + + + + + + Sheet.1463 + + + + + + + + Subscriptions.1464 + + Sheet.1465 + + + + + + + Sheet.1466 + + + + + + + Sheet.1467 + + + + + + + Sheet.1468 + + + + + + + + Subscriptions.1469 + + Sheet.1470 + + + + + + + Sheet.1471 + + + + + + + Sheet.1472 + + + + + + + Sheet.1473 + + + + + + + + Subscriptions.1474 + + Sheet.1475 + + + + + + + Sheet.1476 + + + + + + + Sheet.1477 + + + + + + + Sheet.1478 + + + + + + + + Subscriptions.1479 + + Sheet.1480 + + + + + + + Sheet.1481 + + + + + + + Sheet.1482 + + + + + + + Sheet.1483 + + + + + + + + Subscriptions.1484 + + Sheet.1485 + + + + + + + Sheet.1486 + + + + + + + Sheet.1487 + + + + + + + Sheet.1488 + + + + + + + + Subscriptions.1489 + + Sheet.1490 + + + + + + + Sheet.1491 + + + + + + + Sheet.1492 + + + + + + + Sheet.1493 + + + + + + + + Subscriptions.1494 + + Sheet.1495 + + + + + + + Sheet.1496 + + + + + + + Sheet.1497 + + + + + + + Sheet.1498 + + + + + + + + Subscriptions.1499 + + Sheet.1500 + + + + + + + Sheet.1501 + + + + + + + Sheet.1502 + + + + + + + Sheet.1503 + + + + + + + + Subscriptions.1504 + + Sheet.1505 + + + + + + + Sheet.1506 + + + + + + + Sheet.1507 + + + + + + + Sheet.1508 + + + + + + + + Subscriptions.1509 + + Sheet.1510 + + + + + + + Sheet.1511 + + + + + + + Sheet.1512 + + + + + + + Sheet.1513 + + + + + + + + Subscriptions.1514 + + Sheet.1515 + + + + + + + Sheet.1516 + + + + + + + Sheet.1517 + + + + + + + Sheet.1518 + + + + + + + + Subscriptions.1519 + + Sheet.1520 + + + + + + + Sheet.1521 + + + + + + + Sheet.1522 + + + + + + + Sheet.1523 + + + + + + + + Subscriptions.1524 + + Sheet.1525 + + + + + + + Sheet.1526 + + + + + + + Sheet.1527 + + + + + + + Sheet.1528 + + + + + + + + Subscriptions.1529 + + Sheet.1530 + + + + + + + Sheet.1531 + + + + + + + Sheet.1532 + + + + + + + Sheet.1533 + + + + + + + + Subscriptions.1534 + + Sheet.1535 + + + + + + + Sheet.1536 + + + + + + + Sheet.1537 + + + + + + + Sheet.1538 + + + + + + + + Subscriptions.1539 + + Sheet.1540 + + + + + + + Sheet.1541 + + + + + + + Sheet.1542 + + + + + + + Sheet.1543 + + + + + + + + Sheet.1544 + Decommissioned + + + + Decommissioned + + Sheet.1545 + Sandbox + + + + Sandbox + + Subscriptions.1546 + + Sheet.1547 + + + + + + + Sheet.1548 + + + + + + + Sheet.1549 + + + + + + + Sheet.1550 + + + + + + + + Subscriptions.1551 + + Sheet.1552 + + + + + + + Sheet.1553 + + + + + + + Sheet.1554 + + + + + + + Sheet.1555 + + + + + + + + Subscriptions.1556 + + Sheet.1557 + + + + + + + Sheet.1558 + + + + + + + Sheet.1559 + + + + + + + Sheet.1560 + + + + + + + + Subscriptions.1561 + + Sheet.1562 + + + + + + + Sheet.1563 + + + + + + + Sheet.1564 + + + + + + + Sheet.1565 + + + + + + + + Subscriptions.1566 + + Sheet.1567 + + + + + + + Sheet.1568 + + + + + + + Sheet.1569 + + + + + + + Sheet.1570 + + + + + + + + Subscriptions.1571 + + Sheet.1572 + + + + + + + Sheet.1573 + + + + + + + Sheet.1574 + + + + + + + Sheet.1575 + + + + + + + + Sheet.1576 + + + + Sheet.1577 + + + + Icon-377PolicySet.1587 + + Sheet.1588 + + Sheet.1589 + + + + Sheet.1590 + + + + Sheet.1591 + + + + Sheet.1592 + + + + Sheet.1593 + + + + Sheet.1594 + + + + Sheet.1595 + + + + Sheet.1596 + + + + Sheet.1597 + + + + Sheet.1598 + + + + Sheet.1599 + + + + Sheet.1600 + + + + Sheet.1601 + + + + Sheet.1602 + + + + + + Sheet.1603 + + + + Sheet.1604 + + + + Icon-377PolicySet.1605 + + Sheet.1606 + + Sheet.1607 + + + + Sheet.1608 + + + + Sheet.1609 + + + + Sheet.1610 + + + + Sheet.1611 + + + + Sheet.1612 + + + + Sheet.1613 + + + + Sheet.1614 + + + + Sheet.1615 + + + + Sheet.1616 + + + + Sheet.1617 + + + + Sheet.1618 + + + + Sheet.1619 + + + + Sheet.1620 + + + + + + Sheet.1621 + + + + Sheet.1622 + + + + Sheet.1623 + + + + Sheet.1625 + + + + Sheet.1626 + + + + Icon-377PolicySet.1627 + + Sheet.1628 + + Sheet.1629 + + + + Sheet.1630 + + + + Sheet.1631 + + + + Sheet.1632 + + + + Sheet.1633 + + + + Sheet.1634 + + + + Sheet.1635 + + + + Sheet.1636 + + + + Sheet.1637 + + + + Sheet.1638 + + + + Sheet.1639 + + + + Sheet.1640 + + + + Sheet.1641 + + + + Sheet.1642 + + + + + + diff --git a/docs/content/policy/img/alzPolicyAzAdvertizer.png b/docs/content/policy/img/alzPolicyAzAdvertizer.png new file mode 100644 index 00000000..e8682a33 Binary files /dev/null and b/docs/content/policy/img/alzPolicyAzAdvertizer.png differ diff --git a/docs/content/policy/policyAssignments/data/ALZPolicyAssignments.csv b/docs/content/policy/policyAssignments/data/ALZPolicyAssignments.csv new file mode 100644 index 00000000..ed19a3f1 --- /dev/null +++ b/docs/content/policy/policyAssignments/data/ALZPolicyAssignments.csv @@ -0,0 +1,74 @@ +Assignment Scope (MG),Assignment Name,Definition Name,Type,Custom/Builtin,Description,Effect +Intermediate Root,Deploy Microsoft Defender for Cloud configuration,Deploy Microsoft Defender for Cloud configuration,Initiative,Custom,"Configures all the MDFC settings, such as Microsoft Defender for Cloud per individual service, security contacts, and export from MDFC to Log Analytics workspace",DeployIfNotExists +Intermediate Root,Deploy-MDEndpoints,[Preview]: Deploy Microsoft Defender for Endpoint agent,Initiative,Built-in,Deploy Microsoft Defender for Endpoint agent on applicable images.,DeployIfNotExists +Intermediate Root,Deploy-MDEndpointsAMA,Configure multiple Microsoft Defender for Endpoint integration settings with Microsoft Defender for Cloud,Initiative,Built-in,"Configure the multiple Microsoft Defender for Endpoint integration settings with Microsoft Defender for Cloud (WDATP, WDATP_EXCLUDE_LINUX_PUBLIC_PREVIEW, WDATP_UNIFIED_SOLUTION etc.). See: https://learn.microsoft.com/azure/defender-for-cloud/integration-defender-for-endpoint for more information.",DeployIfNotExists +Intermediate Root,Deploy-Diag-Logs,Enable allLogs category group resource logging for supported resources to Log Analytics,Initiative,Built-in,Resource logs should be enabled to track activities and events that take place on your resources and give you visibility and insights into any changes that occur. This initiative deploys diagnostic setting using the allLogs category group to route logs to Log Analytics Workspace for all supported resources,DeployIfNotExists +Intermediate Root,Microsoft Cloud Security Benchmark,Azure Security Benchmark,Initiative,Built-in,"The Azure Security Benchmark initiative represents the policies and controls implementing security recommendations defined in Azure Security Benchmark v2, see https://aka.ms/azsecbm. This also serves as the Azure Security Center default policy initiative. You can directly assign this initiative, or manage its policies and compliance results within Azure Security Center.","Audit, AuditIfNotExists, Disabled" +Intermediate Root,Configure Advanced Threat Protection to be enabled on open-source relational databases,Configure Advanced Threat Protection to be enabled on open-source relational databases,Initiative,Built-in,Enable Advanced Threat Protection on your non-Basic tier open-source relational databases to detect anomalous activities indicating unusual and potentially harmful attempts to access or exploit databases. See https://aka.ms/AzDforOpenSourceDBsDocu.,DeployIfNotExists +Intermediate Root,Configure Azure Defender to be enabled on SQL Servers and SQL Managed Instances,Configure Azure Defender to be enabled on SQL Servers and SQL Managed Instances,Initiative,Built-in,Enable Azure Defender on your SQL Servers and SQL Managed Instances to detect anomalous activities indicating unusual and potentially harmful attempts to access or exploit databases.,DeployIfNotExists +Intermediate Root,Deploy Diagnostic Settings for Activity Log to Log Analytics workspace,Configure Azure Activity logs to stream to specified Log Analytics workspace,Policy,Built-in,Deploys the diagnostic settings for Azure Activity to stream subscriptions audit logs to a Log Analytics workspace to monitor subscription-level events,DeployIfNotExists +Intermediate Root,Deny the deployment of classic resources,Deny the deployment of classic resources,Policy,Custom,Denies deployment of classic resource types under the assigned scope.,Deny +Intermediate Root,Enforce Azure Compute Security Baseline compliance auditing,Enforce Azure Compute Security Baseline compliance auditing,Initiative,Custom,This initiative assignment enables Azure Compute Security Baseline compliance auditing for Windows and Linux virtual machines.,AuditIfNotExists +Intermediate Root,Deny virtual machines and virtual machine scale sets that do not use managed disk,Deny virtual machines and virtual machine scale sets not using OS Managed Disk,Policy,Custom,Deny virtual machines not using managed disk. It checks the managedDisk property on virtual machine OS Disk fields.,Deny +Intermediate Root,Unused resources driving cost should be avoided,Unused resources driving cost should be avoided,Initiative,Custom,This Policy initiative is a group of Policy definitions that help optimize cost by detecting unused but chargeable resources. Leverage this Policy initiative as a cost control to reveal orphaned resources that are driving cost.,Audit +Intermediate Root,Deploy Azure Monitor Baseline Alerts for Service Health,Deploy Azure Monitor Baseline Alerts for Service Health,Initiative,Custom,Initiative to deploy AMBA Service Health alerts to Azure services,DeployIfNotExists +Intermediate Root,Resources should be Zone Resilient,Resources should be Zone Resilient,Initiative,Built-in,"Some resource types can be deployed Zone Redundant (e.g. SQL Databases); some can be deploy Zone Aligned (e.g. Virtual Machines); and some can be deployed either Zone Aligned or Zone Redundant (e.g. Virtual Machine Scale Sets). Being zone aligned does not guarantee resilience, but it is the foundation on which a resilient solution can be built (e.g. three Virtual Machine Scale Sets zone aligned to three different zones in the same region with a load balancer). See https://aka.ms/AZResilience for more info.",Audit +Intermediate Root,Audit-TrustedLaunch,Audit-TrustedLaunch,Initiative,Custom,"Trusted Launch improves security of a Virtual Machine which requires VM SKU, OS Disk & OS Image to support it (Gen 2). To learn more about Trusted Launch, visit https://aka.ms/trustedlaunch.",Audit +Intermediate Root,Configure subscriptions to enable service health alert monitoring rule,[Preview]: Configure subscriptions to enable service health alert monitoring rule,Policy,Built-in,"Assignable at the subscription or management group level, this policy ensures that each subscription has a service health alert rule configured with alert conditions and mapping to action groups as specified in the policy parameters. By default creates a resource group, alert rule and action group configured to send emails to subscription owners for all service health events.",DeployIfNotExists +Platform,Enforce recommendded guardrails for Azure Key Vault,Enforce recommendded guardrails for Azure Key Vault,Initiative,Custom,This initiative assignment enables recommended ALZ guardrails for Azure Key Vault.,"Deny, Audit" +Platform,Enforce enhanced recovery and backup policies,Enforce enhanced recovery and backup policies,Initiative,Custom,This initiative assignment enables recommended audit policies for Azure Backup and Site Recovery.,Audit +Platform,Subnets should be private,Subnets should be private,Policy,Built-in,Ensure your subnets are secure by default by preventing default outbound access. For more information go to https://aka.ms/defaultoutboundaccessretirement,"Audit, Deny" +Platform/Connectivity,Virtual networks should be protected by Azure DDoS Protection Standard,Virtual networks should be protected by Azure DDoS Protection Standard,Policy,Built-in,"Protect your virtual networks against volumetric and protocol attacks with Azure DDoS Protection Standard. For more information, visit https://aka.ms/ddosprotectiondocs.",Modify +Platform/Connectivity,Deploy Azure Monitor Baseline Alerts for Connectivity,Deploy Azure Monitor Baseline Alerts for Connectivity,Initiative,Custom,Initiative to deploy AMBA alerts relevant to the ALZ Connectivity management group,DeployIfNotExists +Platform/Management,Deploy Azure Monitor Baseline Alerts for Management,Deploy Azure Monitor Baseline Alerts for Management,Initiative,Custom,Initiative to deploy AMBA alerts relevant to the ALZ Management management group,DeployIfNotExists +Platform/Identity,Deny the creation of public IP,Deny the creation of public IP,Policy,Custom,This policy denies creation of Public IPs under the assigned scope.,Deny +Platform/Identity,Management port access from the Internet should be blocked,Management port access from the Internet should be blocked,Policy,Custom,This policy denies any network security rule that allows management port access from the Internet,Deny +Platform/Identity,Subnets should have a Network Security Group,Subnets should have a Network Security Group,Policy,Custom,This policy denies the creation of a subnet without a Network Security Group. NSG help to protect traffic across subnet-level.,Deny +Platform/Identity,Configure backup on virtual machines without a given tag to a new recovery services vault with a default policy,Configure backup on virtual machines without a given tag to a new recovery services vault with a default policy,Policy,Built-in,Enforce backup for all virtual machines by deploying a recovery services vault in the same location and resource group as the virtual machine.,DeployIfNotExists +Platform/Identity,Deploy Azure Monitor Baseline Alerts for Identity,Deploy Azure Monitor Baseline Alerts for Identity,Initiative,Custom,Initiative to deploy AMBA alerts relevant to the ALZ Identity management group,DeployIfNotExists +Landing Zones,Deny or Deploy and append TLS requirements and SSL enforcement on resources without Encryption in transit,Deny or Deploy and append TLS requirements and SSL enforcement on resources without Encryption in transit,Initiative,Custom,TBC,"Audit, AuditIfNotExists, DeployIfNotExists, Deny" +Landing Zones,Management port access from the Internet should be blocked,Management port access from the Internet should be blocked,Policy,Custom,This policy denies any network security rule that allows management port access from the Internet,Deny +Landing Zones,Subnets should have a Network Security Group,Subnets should have a Network Security Group,Policy,Custom,This policy denies the creation of a subnet without a Network Security Group. NSG help to protect traffic across subnet-level.,Deny +Landing Zones,Network interfaces should disable IP forwarding,Network interfaces should disable IP forwarding,Policy,Built-in,This policy denies the network interfaces which enabled IP forwarding. The setting of IP forwarding disables Azure's check of the source and destination for a network interface.,Deny +Landing Zones,Secure transfer to storage accounts should be enabled,Secure transfer to storage accounts should be enabled,Policy,Built-in,"Audit requirement of Secure transfer in your storage account. Secure transfer is an option that forces your storage account to accept requests only from secure connections (HTTPS). Use of HTTPS ensures authentication between the server and the service and protects data in transit from network layer attacks such as man-in-the-middle, eavesdropping, and session-hijacking",Deny +Landing Zones,Deploy Azure Policy Add-on to Azure Kubernetes Service clusters,Deploy Azure Policy Add-on to Azure Kubernetes Service clusters,Policy,Built-in,Use Azure Policy Add-on to manage and report on the compliance state of your Azure Kubernetes Service (AKS) clusters.,DeployIfNotExists +Landing Zones,Configure SQL servers to have auditing enabled to Log Analytics workspace,Configure SQL servers to have auditing enabled to Log Analytics workspace,Policy,Built-in,"To ensure the operations performed against your SQL assets are captured, SQL servers should have auditing enabled. If auditing is not enabled, this policy will configure auditing events to flow to the specified Log Analytics workspace.",DeployIfNotExists +Landing Zones,Deploy Threat Detection on SQL servers,Configure Azure Defender to be enabled on SQL servers,Policy,Built-in,Enable Azure Defender on your Azure SQL Servers to detect anomalous activities indicating unusual and potentially harmful attempts to access or exploit databases.,DeployIfNotExists +Landing Zones,Deploy TDE on SQL servers,Deploy TDE on SQL servers,Policy,Built-in,This policy ensures that Transparent Data Encryption is enabled on SQL Servers.,DeployIfNotExists +Landing Zones,Virtual networks should be protected by Azure DDoS Protection Standard,Virtual networks should be protected by Azure DDoS Protection Standard,Policy,Built-in,Protect your virtual networks against volumetric and protocol attacks with Azure DDoS Protection Standard.,Modify +Landing Zones,Kubernetes cluster should not allow privileged containers,Kubernetes cluster should not allow privileged containers,Policy,Built-in,"Do not allow privileged containers creation in a Kubernetes cluster. This recommendation is part of CIS 5.2.1 which is intended to improve the security of your Kubernetes environments. This policy is generally available for Kubernetes Service (AKS), and preview for AKS Engine and Azure Arc enabled Kubernetes.",Deny +Landing Zones,Kubernetes clusters should not allow container privilege escalation,Kubernetes clusters should not allow container privilege escalation,Policy,Built-in,"Do not allow containers to run with privilege escalation to root in a Kubernetes cluster. This recommendation is part of CIS 5.2.5 which is intended to improve the security of your Kubernetes environments. This policy is generally available for Kubernetes Service (AKS), and preview for AKS Engine and Azure Arc enabled Kubernetes.",Deny +Landing Zones,Kubernetes clusters should be accessible only over HTTPS,Kubernetes clusters should be accessible only over HTTPS,Policy,Built-in,"Use of HTTPS ensures authentication and protects data in transit from network layer eavesdropping attacks. This capability is currently generally available for Kubernetes Service (AKS), and in preview for AKS Engine and Azure Arc enabled Kubernetes.",Deny +Landing Zones,Enforce recommendded guardrails for Azure Key Vault,Enforce recommendded guardrails for Azure Key Vault,Initiative,Custom,This initiative assignment enables recommended ALZ guardrails for Azure Key Vault.,"Deny, Audit" +Landing Zones,Enforce enhanced recovery and backup policies,Enforce enhanced recovery and backup policies,Initiative,Custom,This initiative assignment enables recommended audit policies for Azure Backup and Site Recovery.,Audit +Landing Zones,Web Application Firewall (WAF) should be enabled for Application Gateway,Web Application Firewall (WAF) should be enabled for Application Gateway,Policy,Built-in,Assign the WAF should be enabled for Application Gateway audit policy.,Audit +Landing Zones,Deploy Azure Monitor Baseline Alerts for Landing Zone,Deploy Azure Monitor Baseline Alerts for Landing Zone,Initiative,Custom,Initiative to deploy AMBA alerts relevant to the ALZ LandingZone management group,DeployIfNotExists +Landing Zones,Configure backup on virtual machines without a given tag to a new recovery services vault with a default policy,Configure backup on virtual machines without a given tag to a new recovery services vault with a default policy,Policy,Built-in,Enforce backup for all virtual machines by deploying a recovery services vault in the same location and resource group as the virtual machine. Doing this is useful when different application teams in your organization are allocated separate resource groups and need to manage their own backups and restores. You can optionally exclude virtual machines containing a specified tag to control the scope of assignment. See https://aka.ms/AzureVMAppCentricBackupExcludeTag.,DeployIfNotExists +Landing Zones,Subnets should be private,Subnets should be private,Policy,Built-in,Ensure your subnets are secure by default by preventing default outbound access. For more information go to https://aka.ms/defaultoutboundaccessretirement,"Audit, Deny" +Landing Zones/Corp,Public network access should be disabled for PaaS services,Public network access should be disabled for PaaS services,Initiative,Custom,This policy initiative is a group of policies that prevents creation of Azure PaaS services with exposed public endpoints,Deny +Landing Zones/Corp,Configure Azure PaaS services to use private DNS zones,Configure Azure PaaS services to use private DNS zones,Initiative,Custom,This policy initiative is a group of policies that ensures private endpoints to Azure PaaS services are integrated with Azure Private DNS zones,DeployIfNotExists +Landing Zones/Corp,Deny network interfaces having a public IP associated,Network interfaces should not have public Ips,Policy,Built-in,This policy denies network interfaces from having a public IP associated to it under the assigned scope.,Deny +Landing Zones/Corp,Audit the creation of Private Link Private DNS Zones,Audit the creation of Private Link Private DNS Zones,Policy,Built-in,Audits the deployment of Private Link Private DNS Zone resources in the Corp landing zone.,Audit +Landing Zones/Corp,Deny the deployment of vWAN/ER/VPN gateway resources,Deny the deployment of vWAN/ER/VPN gateway resources,Policy,Built-in,Denies deployment of vWAN/ER/VPN gateway resources in the Corp landing zone.,Deny +Landing Zones/Online,N/A,N/A,N/A,N/A,N/A,N/A +Decommissioned,Enforce ALZ Decommissioned Guardrails,Enforce ALZ Decommissioned Guardrails,Initiative,Custom,This initiative will help enforce and govern subscriptions that are placed within the decommissioned Management Group as part of your Subscription decommissioning process. See https://aka.ms/alz/policies for more information.,"Deny, DeployIfNotExists" +Sandbox,Enforce ALZ Sandbox Guardrails,Enforce ALZ Sandbox Guardrails,Initiative,Custom,This initiative will help enforce and govern subscriptions that are placed within the Sandobx Management Group. See https://aka.ms/alz/policies for more information.,Deny +Platform,Enable Azure Monitor for VMs,Enable Azure Monitor for VMs with Azure Monitoring Agent(AMA),Initiative,Built-in,"This policy initiative installs the Azure Monitoring Agent (AMA) on the virtual machines (VMs) and enables Azure Monitor for them. Azure Monitor collects and analyzes data from the VMs, such as performance metrics, logs, and dependencies.",DeployIfNotExists +Platform,Enable Azure Monitor for Virtual Machine Scale Sets,Enable Azure Monitor for VMSS with Azure Monitoring Agent(AMA),Initiative,Built-in,"This policy initiative installs the Azure Monitoring Agent (AMA) on the virtual machines scale sets (VMSS) and enables Azure Monitor for them. Azure Monitor collects and analyzes data from the VMs, such as performance metrics, logs, and dependencies.",DeployIfNotExists +Platform,Enable Azure Monitor for Hybrid Virtual Machines,Enable Azure Monitor for Hybrid VMs with AMA,Initiative,Built-in,"This policy initiative installs the Azure Monitoring Agent (AMA) on Arc-enabled servers (Hybrid) and enables Azure Monitor for them. Azure Monitor collects and analyzes data from the VMs, such as performance metrics, logs, and dependencies.",DeployIfNotExists +Platform,Enable ChangeTracking and Inventory for virtual machines,[Preview]: Enable ChangeTracking and Inventory for virtual machines,Initiative,Built-in,"This policy initiative enables ChangeTracking and Inventory for virtual machines. It uses a Data Collection Rule to define what data to collect and where to send it, and a user-assigned identity to authenticate the Azure Monitor Agent.",DeployIfNotExists +Platform,Enable ChangeTracking and Inventory for virtual machine scale sets,[Preview]: Enable ChangeTracking and Inventory for virtual machine scale sets,Initiative,Built-in,"This policy initiative enables ChangeTracking and Inventory for virtual machines scale sets. It uses a Data Collection Rule to define what data to collect and where to send it, and a user-assigned identity to authenticate the Azure Monitor Agent.",DeployIfNotExists +Platform,Enable ChangeTracking and Inventory for Arc-enabled virtual machines,[Preview]: Enable ChangeTracking and Inventory for Arc-enabled virtual machines,Initiative,Built-in,"This policy initiative enables ChangeTracking and Inventory for Arc-enabled servers. It uses a Data Collection Rule to define what data to collect and where to send it, and a user-assigned identity to authenticate the Azure Monitor Agent.",DeployIfNotExists +Platform,Enable Defender for SQL on SQL VMs and Arc-enabled SQL Servers,Configure SQL VMs and Arc-enabled SQL Servers to install Microsoft Defender for SQL and AMA with a user-defined LA workspace,Initiative,Built-in,This policy initiative enables Microsoft Defender for SQL and AMA on SQL VMs and Arc-enabled SQL Servers.,DeployIfNotExists +Platform,Do not allow deletion of resource types,Do not allow deletion of resource types,Policy,Built-in,This policy enables you to specify the resource types that your organization can protect from accidentals deletion by blocking delete calls using deny action effect. Assigned to deny the deletion of the User Assignment Managed Identity that is used for AMA.,DenyAction +Platform,Configure periodic checking for missing system updates on azure virtual machines and Arc-enabled virtual machines,Configure periodic checking for missing system updates on azure virtual machines and Arc-enabled virtual machines,Initiative,Custom,"With this policy initiative, you can enable automatic OS updates assessment every 24 hours. This is a custom initiative of built-in policies.",Modify +Landing Zones,Enable Azure Monitor for VMs,Enable Azure Monitor for VMs with Azure Monitoring Agent(AMA),Initiative,Built-in,"This policy initiative installs the Azure Monitoring Agent (AMA) on the virtual machines (VMs) and enables Azure Monitor for them. Azure Monitor collects and analyzes data from the VMs, such as performance metrics, logs, and dependencies.",DeployIfNotExists +Landing Zones,Enable Azure Monitor for Virtual Machine Scale Sets,Enable Azure Monitor for VMSS with Azure Monitoring Agent(AMA),Initiative,Built-in,"This policy initiative installs the Azure Monitoring Agent (AMA) on the virtual machines scale sets (VMSS) and enables Azure Monitor for them. Azure Monitor collects and analyzes data from the VMs, such as performance metrics, logs, and dependencies.",DeployIfNotExists +Landing Zones,Enable Azure Monitor for Hybrid Virtual Machines,Enable Azure Monitor for Hybrid VMs with AMA,Initiative,Built-in,"This policy initiative installs the Azure Monitoring Agent (AMA) on Arc-enabled servers (Hybrid) and enables Azure Monitor for them. Azure Monitor collects and analyzes data from the VMs, such as performance metrics, logs, and dependencies.",DeployIfNotExists +Landing Zones,Enable ChangeTracking and Inventory for virtual machines,[Preview]: Enable ChangeTracking and Inventory for virtual machines,Initiative,Built-in,"This policy initiative enables ChangeTracking and Inventory for virtual machines. It uses a Data Collection Rule to define what data to collect and where to send it, and a user-assigned identity to authenticate the Azure Monitor Agent.",DeployIfNotExists +Landing Zones,Enable ChangeTracking and Inventory for virtual machine scale sets,[Preview]: Enable ChangeTracking and Inventory for virtual machine scale sets,Initiative,Built-in,"This policy initiative enables ChangeTracking and Inventory for virtual machines scale sets. It uses a Data Collection Rule to define what data to collect and where to send it, and a user-assigned identity to authenticate the Azure Monitor Agent.",DeployIfNotExists +Landing Zones,Enable ChangeTracking and Inventory for Arc-enabled virtual machines,[Preview]: Enable ChangeTracking and Inventory for Arc-enabled virtual machines,Initiative,Built-in,"This policy initiative enables ChangeTracking and Inventory for Arc-enabled servers. It uses a Data Collection Rule to define what data to collect and where to send it, and a user-assigned identity to authenticate the Azure Monitor Agent.",DeployIfNotExists +Landing Zones,Enable Defender for SQL on SQL VMs and Arc-enabled SQL Servers,Configure SQL VMs and Arc-enabled SQL Servers to install Microsoft Defender for SQL and AMA with a user-defined LA workspace,Initiative,Built-in,This policy initiative enables Microsoft Defender for SQL and AMA on SQL VMs and Arc-enabled SQL Servers.,DeployIfNotExists +Landing Zones,Configure periodic checking for missing system updates on azure virtual machines and Arc-enabled virtual machines,Configure periodic checking for missing system updates on azure virtual machines and Arc-enabled virtual machines,Initiative,Custom,"With this policy initiative, you can enable automatic OS updates assessment every 24 hours. This is a custom initiative of built-in policies.",Modify +Landing Zones,Configure prerequisites to enable Guest Attestation on Trusted Launch enabled VMs,[Preview]: Configure prerequisites to enable Guest Attestation on Trusted Launch enabled VMs,Initiative,Built-in,"With this policy initiative, you can enable Guest Attestation on Trusted Launch enabled VMs.","DeployIfNotExists, Modify" +Platform,Configure prerequisites to enable Guest Attestation on Trusted Launch enabled VMs,[Preview]: Configure prerequisites to enable Guest Attestation on Trusted Launch enabled VMs,Initiative,Built-in,"With this policy initiative, you can enable Guest Attestation on Trusted Launch enabled VMs.","DeployIfNotExists, Modify" diff --git a/docs/content/policy/policyAssignments/data/ALZPolicyAssignments.xlsx b/docs/content/policy/policyAssignments/data/ALZPolicyAssignments.xlsx new file mode 100644 index 00000000..b277f400 Binary files /dev/null and b/docs/content/policy/policyAssignments/data/ALZPolicyAssignments.xlsx differ diff --git a/docs/content/policy/policyAssignments/img/ef73.jpg b/docs/content/policy/policyAssignments/img/ef73.jpg new file mode 100644 index 00000000..e70f7b96 Binary files /dev/null and b/docs/content/policy/policyAssignments/img/ef73.jpg differ diff --git a/docs/content/policy/policyAssignments/index.md b/docs/content/policy/policyAssignments/index.md new file mode 100644 index 00000000..45e4c1f3 --- /dev/null +++ b/docs/content/policy/policyAssignments/index.md @@ -0,0 +1,25 @@ +--- +title: Policy Assignments +weight: 5 +--- + +As part of a default deployment configuration, policy and policy set definitions are deployed at multiple levels within the Azure landing zone Management Group hierarchy as depicted within the below diagram. + +{{< figure src="../img/MgmtGroups_Policies_v0.1.svg">}} + +{{< hint type=important >}} +As part of the ALZ portal deployment/configuration, policy and policy set definitions are created only at the intermediate management group, e.g. `contoso` that is a child of the tenant root management group, created during the ALZ deployment. Our automation does not assign any policies to the tenant root management group scope, only the ALZ hierarchy it deploys and its children, e.g. `contoso` and below. This approach aligns with the Cloud Adoption Framework's best practices for Azure Policy assignment, ensuring clear delineation of policy application and avoiding unintended policy inheritance across the entire tenant. By placing policies only at the intermediary root and its child management groups, we maintain compliance, flexibility, and alignment with organizational governance requirements. And also allow multiple management groups hierarchies to exist in a single tenant such as the [canary approach](https://aka.ms/alz/canary#example-scenarios-and-outcomes) +{{< /hint >}} + +{{< hint type=note >}} +
+{{< figure src="../img/ef73.jpg">}}For convenience, an Excel version of the below information is available here or click the Excel icon.
+{{< /hint >}} + +## Default Policy Assignments + +{{< csv-table file="data/ALZPolicyAssignments.csv" >}} + +{{< hint type=note >}} +Be sure to also review the [Extra Policies and Information]({{< relref "policyExtras" >}}) document that describes additional ALZ custom policy definitions and initiatives that are not assigned by default in ALZ, but are provided as they may assist some consumers of ALZ in specific scenarios where they can assign these additional policies to help them meet their objectives. +{{< /hint >}} diff --git a/docs/content/policy/policyCustom.md b/docs/content/policy/policyCustom.md new file mode 100644 index 00000000..ee453411 --- /dev/null +++ b/docs/content/policy/policyCustom.md @@ -0,0 +1,107 @@ +--- +title: Custom Policy and ALZ +weight: 9 +geekdocCollapseSection: true +--- + + +
+ +This information documents considerations for creating and managing custom Azure Policy definitions within the Azure Landing Zones (ALZ) framework. + +When implementing custom policies in ALZ, it is essential to ensure that they align with the overall governance strategy and do not conflict with existing built-in policies. Custom policies should be designed to address specific organizational requirements while adhering to best practices for policy management. + +### Custom Policy Versioning + +{{< hint type=important >}} +This section refers to versioning of custom policies within ALZ, which is separate from the Azure Policy versioning schema described in the [Policy Versioning]({{< relref "policyVersioning" >}}) document. +{{< /hint >}} + +Each policy definition and initiative contains a version in its metadata section: +```json +"metadata": { + "version": "1.0.0", + "category": "{categoryName}", + "source": "https://github.com/Azure/Enterprise-Scale/", + "alzCloudEnvironments": [ + "AzureCloud", + "AzureChinaCloud", + "AzureUSGovernment" + ] +} +``` +To track and review policy and initiative versions, please refer to [AzAdvertizer](https://www.azadvertizer.net/index.html). + +This version is incremented according to the following rules (subject to change): + - **Major Version** (**1**.0.0) + - Policy Definitions + - Rule logic changes + - ifNotExists existence condition changes + - Major changes to the effect of the policy (i.e. adding a new resource to a deployment) + - Policy Set Definitions + - Addition or removal of a policy definition from the policy set + - **Minor Version** (1.**0**.0) + - Policy Definitions + - Changes to effect details that don't meet the major version criteria + - Adding new parameter allowed values + - Adding new parameters (with default values) + - Other minor changes to existing parameters + - Policy Set Definitions + - Adding new parameter allowed values + - Adding new parameters (with default values) + - Other minor changes to existing parameters + - **Patch Version** (1.0.**0**) + - Policy Definitions + - String changes (displayName, description, etc…) + - Other metadata changes + - Policy Set Definitions + - String changes (displayName, description, etc…) + - Other metadata changes + - **Suffix** + - Append "-preview" to the version if the policy is in a preview state + - Example: 1.3.2-preview + - Append "-deprecated" to the version if the policy is in a deprecated state + - Example: 1.3.2-deprecated + +## Preview and deprecated policies + +This section aims to explain what it means when a built-in policy has a state of ‘preview’ or ‘deprecated’. + +Policies can be in preview because a property (alias) referenced in the policy definition is in preview, or the policy is newly introduced and would like additional customer feedback. A policy may get deprecated when the property (alias) becomes deprecated & not supported in the resource type's latest API version, or when there is manual migration needed by customers due to a breaking change in a resource type's latest API version. + +When a policy gets deprecated or gets out of preview, there is no impact on existing assignments. Existing assignments continue to work as-is. The policy is still evaluated & enforced like normal and continues to produce compliance results. + +Here are the changes that occur when a policy gets deprecated: + +- Display name is appended with ‘[Deprecated]: ’ prefix, so that customers have awareness to migrate or delete the policy. +- Description gets updated to provide additional information regarding the deprecation with a link to the superseding policy. +- Add `supersededBy` metadata property to the policy definition with the name of the superseding policy. +- Add `deprecated` metadata property to the policy definition with value set to `true`. +- The version number is updated with ‘-deprecated’ suffix. (see [Policy Versioning](#custom-policy-versioning) above). + +Example (policy snippet of deprecated policy): + +```json + "policyType": "Custom", + "mode": "Indexed", + "displayName": "[Deprecated]: Deploy SQL Database vulnerability Assessments", + "description": "Deploy SQL Database vulnerability Assessments when it not exist in the deployment. Superseded by https://www.azadvertizer.net/azpolicyadvertizer/Deploy-Sql-vulnerabilityAssessments_20230706.html", + "metadata": { + "version": "1.0.1-deprecated", + "category": "SQL", + "source": "https://github.com/Azure/Enterprise-Scale/", + "deprecated": true, + "supersededBy": "Deploy-Sql-vulnerabilityAssessments_20230706", + "alzCloudEnvironments": [ + "AzureCloud", + "AzureChinaCloud", + "AzureUSGovernment" + ] + } +``` + +{{< hint type=note >}} +The `name` value must not change in the file through deprecation or preview. +{{< /hint >}} + +
diff --git a/docs/content/policy/policyExtras/data/ALZWorkloadAssignments.csv b/docs/content/policy/policyExtras/data/ALZWorkloadAssignments.csv new file mode 100644 index 00000000..90173ad5 --- /dev/null +++ b/docs/content/policy/policyExtras/data/ALZWorkloadAssignments.csv @@ -0,0 +1,27 @@ +WSC Option,Assignment Scope (MG),ID,Assignment Name,Definition Name,Type,Custom/Builtin,Description,Effect +Customer Managed Keys,Variable *,Enforce-Encryption-CMK_20250218,Enforce recommended guardrails for Customer Managed Keys,Deny or Audit resources without Encryption with a customer-managed key (CMK),Initiative,Custom,Deny or Audit resources without Encryption with a customer-managed key (CMK),Audit +AI Bot Service,Variable *,Enforce-Guardrails-BotService,Enforce recommended guardrails for Bot Service,Enforce recommended guardrails for Bot Service,Initiative,Custom,This policy initiative is a group of policies that ensures Bot Service is compliant per regulated Landing Zones.,Audit +AI Search,Variable *,Enforce-Guardrails-CognitiveServices,Enforce recommended guardrails for Cognitive Services,Enforce recommended guardrails for Cognitive Services,Initiative,Custom,This policy initiative is a group of policies that ensures Cognitive Services is compliant per regulated Landing Zones.,Audit +Machine Learning,Variable *,Enforce-Guardrails-MachineLearning,Enforce recommended guardrails for Machine Learning,Enforce recommended guardrails for Machine Learning,Initiative,Custom,This policy initiative is a group of policies that ensures Machine Learning is compliant per regulated Landing Zones.,Audit +Azure OpenAI,Variable *,Enforce-Guardrails-OpenAI,Enforce recommended guardrails for OpenAI,Enforce recommended guardrails for Open AI (Cognitive Service),Initiative,Custom,This policy initiative is a group of policies that ensures Open AI (Cognitive Service) is compliant per regulated Landing Zones.,Audit +Data Explorer,Variable *,Enforce-Guardrails-DataExplorer,Enforce recommended guardrails for Data Explorer,Enforce recommended guardrails for Data Explorer,Initiative,Custom,This policy initiative is a group of policies that ensures Data Explorer is compliant per regulated Landing Zones.,Audit +Data Factory,Variable *,Enforce-Guardrails-DataFactory,Enforce recommended guardrails for Data Factory,Enforce recommended guardrails for Data Factory,Initiative,Custom,This policy initiative is a group of policies that ensures Data Factory is compliant per regulated Landing Zones.,Audit +Synapse,Variable *,Enforce-Guardrails-Synapse,Enforce recommended guardrails for Synapse,Enforce recommended guardrails for Synapse workspaces,Initiative,Custom,This policy initiative is a group of policies that ensures Synapse workspaces is compliant per regulated Landing Zones.,Audit +Compute,Variable *,Enforce-Guardrails-Compute,Enforce recommended guardrails for Compute,Enforce recommended guardrails for Compute,Initiative,Custom,This policy initiative is a group of policies that ensures Compute is compliant per regulated Landing Zones.,Audit +Virtual Desktop,Variable *,Enforce-Guardrails-VirtualDesktop,Enforce recommended guardrails for Virtual Desktop,Enforce recommended guardrails for Virtual Desktop,Initiative,Custom,This policy initiative is a group of policies that ensures Virtual Desktop is compliant per regulated Landing Zones.,Audit +Container Apps,Variable *,Enforce-Guardrails-ContainerApps,Enforce recommended guardrails for Container Apps,Enforce recommended guardrails for Container Apps,Initiative,Custom,This policy initiative is a group of policies that ensures Container Apps is compliant per regulated Landing Zones.,Audit +Container Instance,Variable *,Enforce-Guardrails-ContainerInstance,Enforce recommended guardrails for Container Instance,Enforce recommended guardrails for Container Instance,Initiative,Custom,This policy initiative is a group of policies that ensures Container Apps is compliant per regulated Landing Zones.,Audit +Container Registry,Variable *,Enforce-Guardrails-ContainerRegistry,Enforce recommended guardrails for Container Registry,Enforce recommended guardrails for Container Registry,Initiative,Custom,This policy initiative is a group of policies that ensures Container Apps is compliant per regulated Landing Zones.,Audit +Kubernetes,Variable *,Enforce-Guardrails-Kubernetes,Enforce recommended guardrails for Kubernetes,Enforce recommended guardrails for Kubernetes,Initiative,Custom,This policy initiative is a group of policies that ensures Kubernetes is compliant per regulated Landing Zones.,Audit +Cosmos DB,Variable *,Enforce-Guardrails-CosmosDb,Enforce recommended guardrails for Cosmos DB,Enforce recommended guardrails for Cosmos DB,Initiative,Custom,This policy initiative is a group of policies that ensures Cosmos DB is compliant per regulated Landing Zones.,Audit +MySQL,Variable *,Enforce-Guardrails-MySQL,Enforce recommended guardrails for MySQL,Enforce recommended guardrails for MySQL,Initiative,Custom,This policy initiative is a group of policies that ensures MySQL is compliant per regulated Landing Zones.,Audit +PostgreSQL,Variable *,Enforce-Guardrails-PostgreSQL,Enforce recommended guardrails for PostgreSQL,Enforce recommended guardrails for PostgreSQL,Initiative,Custom,This policy initiative is a group of policies that ensures PostgreSQL is compliant per regulated Landing Zones.,Audit +SQL,Variable *,Enforce-Guardrails-SQL,Enforce recommended guardrails for SQL,Enforce recommended guardrails for SQL and SQL Managed Instance,Initiative,Custom,This policy initiative is a group of policies that ensures SQL and SQL Managed Instance is compliant per regulated Landing Zones.,Audit +Event Grid,Variable *,Enforce-Guardrails-EventGrid,Enforce recommended guardrails for Event Grid,Enforce recommended guardrails for Event Grid,Initiative,Custom,This policy initiative is a group of policies that ensures Event Grid is compliant per regulated Landing Zones.,Audit +Event Hub,Variable *,Enforce-Guardrails-EventHub,Enforce recommended guardrails for Event Hub,Enforce recommended guardrails for Event Hub,Initiative,Custom,This policy initiative is a group of policies that ensures Event Hub is compliant per regulated Landing Zones.,Audit +Service Bus,Variable *,Enforce-Guardrails-ServiceBus,Enforce recommended guardrails for Service Bus,Enforce recommended guardrails for Service Bus,Initiative,Custom,This policy initiative is a group of policies that ensures Service Bus is compliant per regulated Landing Zones.,Audit +Automation Accounts,Variable *,Enforce-Guardrails-Automation,Enforce recommended guardrails for Automation Accounts,Enforce recommended guardrails for Automation Account,Initiative,Custom,This policy initiative is a group of policies that ensures Automation Account is compliant per regulated Landing Zones.,Audit +Key Vault - Supplementary,Variable *,Enforce-Guardrails-KeyVault-Sup,Enforce recommended guardrails for Key Vault Supplementary,Enforce additional recommended guardrails for Key Vault,Initiative,Custom,This policy initiative is a group of policies that ensures Key Vault is compliant per regulated Landing Zones.,Audit +Storage,Variable *,Enforce-Guardrails-Storage,Enforce recommended guardrails for Storage,Enforce recommended guardrails for Storage Account,Initiative,Custom,This policy initiative is a group of policies that ensures Storage is compliant per regulated Landing Zones.,Audit +API Management,Variable *,Enforce-Guardrails-APIM,Enforce recommended guardrails for API Management,Enforce recommended guardrails for API Management,Initiative,Custom,This policy initiative is a group of policies that ensures API Management is compliant per regulated Landing Zones.,Audit +App Services,Variable *,Enforce-Guardrails-AppServices,Enforce recommended guardrails for App Services,Enforce recommended guardrails for App Service,Initiative,Custom,This policy initiative is a group of policies that ensures App Service is compliant per regulated Landing Zones.,Audit diff --git a/docs/content/policy/policyExtras/index.md b/docs/content/policy/policyExtras/index.md new file mode 100644 index 00000000..5bc8717d --- /dev/null +++ b/docs/content/policy/policyExtras/index.md @@ -0,0 +1,38 @@ +--- +title: Extra Policies and Information +weight: 7 +--- + +This document describes additional ALZ custom policy definitions and initiatives that are not assigned by default in ALZ, but are provided as they may assist some consumers of ALZ in specific scenarios where they can assign these additional policies to help them meet their objectives. We also provide guidance on how to handle certain situations as some of the policies require additional considerations prior to assigning. + +> For the complete list of Azure Landing Zones custom policies, please use [AzAdvertizer](https://www.azadvertizer.net/azpolicyadvertizer_all.html), and change `type` to `ALZ`. + +## Additional ALZ Custom Policies for consideration + +ALZ provides several additional policies that are not assigned by default but that can be used for specific scenarios should they be required. + +| Policy | Description | Notes | +|------------|-------------|-------------| +| Audit-Tags-Mandatory | Audit for mandatory tags on resources | Audits resources to ensure they have required tags based on tag array. Does not apply to resource groups. | +| Audit-Tags-Mandatory-RG | Audit for mandatory tags on resource groups | Audits resource groups to ensure they have required tags based on tag array. | +| Deny-Appgw-Without-Waf | Application Gateway should be deployed with WAF enabled | Use to ensure Application Gateways are deployed with Web Application Firewall enabled | +| Deny-Private-Dns-Zones | Deny the creation of private DNS | For organizations that centralize core networking functions, use this policy to prevent the creation of additional Private DNS Zones under specific scopes | +| Deny-Subnet-Without-Penp | Subnets without Private Endpoint Network Policies enabled should be denied | This policy denies the creation of a subnet without Private Endpoint Network Policies enabled. This policy is intended for 'workload' subnets, not 'central infrastructure' (aka, 'hub') subnets. | +| Deny-Subnet-Without-Udr | Subnets should have a User Defined Route | Should you require all network traffic be directed to an appliance for inspection, you can use this policy to ensure UDR is associated with a subnet | +| Deny-Udr-With-Specific-Nexthop | User Defined Routes with 'Next Hop Type' set to 'Internet' or 'VirtualNetworkGateway' should be denied | Refining `Deny-Subnet-Without-Udr` you can ensure non-compliant UDRs are denied (e.g., bypassing a firewall) | +| Deny-Vnet-Peering | Deny vNet peering | Use to prevent vNet peering under specific scopes (e.g., Sandbox management group) | +| Deny-Vnet-Peering-To-Non-Approved-Vnets | Deny vNet peering to non-approved vNets | Use to control vNet peering under specific scopes, like in the Corp management group, only allow peering to the hub vNet. | +| Deploy-Budget | Deploy a default budget on all subscriptions under the assigned scope | Set a default budget for a specific scope, like setting a $500 budget on all subscriptions in the Sandbox management group | +|Deploy-Sql-Security_20240529| Deploy-SQL Database built-in SQL security configuration| Deploy auditing, Alert, TDE and SQL vulnerability to SQL Databases when it not exist in the deployment| +| Deploy-Vnet-Hubspoke | Deploy Virtual Network with peering to the hub | Automatically peer a new virtual network with the hub, for example, in the Corp management group | +| Deploy-Windows-DomainJoin | Deploy Windows Domain Join Extension with Key Vault configuration | Windows Domain Join a virtual machine using domain name and password stored in Key Vault as secrets | + +## 2. ALZ, Workload Specific Compliance and Regulated Industries + +The Azure Landing Zone is designed to be a flexible and scalable solution that can be used by organizations in a variety of industries. However, organizations in regulated industries (FSI, Healthcare, etc.) may need to take additional steps to ensure compliance with industry-specific regulations. These regulations often commonly have a consistent set of controls to cover, like CMK, locking down public endpoints, TLS version enforcement, logging etc. + +To support the additional control requirements of these industries, we're providing the following additional initiatives that enhance the security and compliance posture of the Azure Landing Zone: + +> **Please Note:** These are meant to help customers across all regulated industries (FSI, Healthcare, etc.) and not be aligned to specific regulatory controls, as there are already policy initiatives available for these via [Azure Policy](https://learn.microsoft.com/azure/azure-resource-manager/management/security-controls-policy) & [Microsoft Defender for Cloud](https://learn.microsoft.com/azure/defender-for-cloud/regulatory-compliance-dashboard) + +{{< csv-table file="data/ALZWorkloadAssignments.csv" >}} diff --git a/docs/content/policy/policyFAQ.md b/docs/content/policy/policyFAQ.md new file mode 100644 index 00000000..746bea90 --- /dev/null +++ b/docs/content/policy/policyFAQ.md @@ -0,0 +1,106 @@ +--- +title: Policy FAQ and Tips +weight: 11 +geekdocCollapseSection: true +--- + +## Frequently asked questions about ALZ policies + +There is a lot of change happening for policies in Azure, and by extension ALZ, and we have a number of common issues being raised by our customers and partners. This page is intended to address those issues. + +### ALZ Policies and Initiatives and the escape character + +We've had a number of issues and pull requests submitted specifically around the extra bracket `[` that is present in all policies and initiatives in this repo. + +{{< hint type=note >}} +The policies and initiatives in this repo are NOT intended to be deployed directly in Azure. You cannot copy the definition and deploy the policy directly without editing first. If you want to deploy a specific policy you must first remove the additional leading `[` character from the policy or initiative definition. Alternatively, to deploy a specific policy directly in Azure Policy, please use AzAdvertizer to lookup the policy and use the `copy definition` button to copy a clean version of the policy ready for use (this will remove all the extra `[`). +{{< /hint >}} + +The reason for this is that the policies and initiatives in this repo are intended to be used as part of the ALZ deployment process, and are used to generate the ARM templates that are deployed to Azure. The leading `[` character is required to support the generation of the ARM templates. + +### Why does ALZ not promote the usage of User-Assigned Managed Identities for Policy Assignments? + +Whilst User-Assigned Managed Identities for Policy Assignments are now supported, there are a number of reasons why ALZ does not promote the usage of them. + +The primary risk is that the User-Assigned Managed Identity created and used for one or more policy assignments is an over-permissioned identity; both in terms of RBAC roles it has assigned to it and also the scope/s that it has been assigned to. With the focus on least privilege and zero trust security principles, we believe in ALZ that the use of a User-Assigned Managed Identity for policy assignments is not the best practice and instead you should continue to use the system-assigned managed identity for your Azure policy assignments. + +Not only does using a system-assigned managed identity for policy assignments reduce the risk of over-permissioning, but it also reduces the complexity of managing the identity and its RBAC permissions and assignments as the lifecycle of the system-assigned managed identity is managed by Azure policy automatically with the lifecycle of the policy assignment it is associated with. + +### Diagnostic Settings v2 (December 2023) + +There are several issues raised around Diagnostic Settings, and we acknowledge that this is a complex area that is causing a lot of pain. + +At this time, the owners of Azure features/services are reworking their policies to comply with the new diagnostic settings v2 schema (which includes logging categories which is a popular ask). New diagnostics settings policies are landing for Azure services, with dedicated policies depending on the logging target required (Log Analytics, Event Hub or storage accounts). We are working with the product groups to ensure that the policies are updated as soon as possible. + +Check back here for updates, and be sure to bookmark [What's New](https://aka.ms/alz/whatsnew) to see the latest updates to ALZ. + +To view the current list of GitHub issues related to diagnostic settings, please see [this link](https://github.com/Azure/Enterprise-Scale/labels/Area:%20Diagnostic%20Settings). + +> **UPDATE** New built-in Diagnostic Settings policies and initiatives will be landing in early CY2024. As a heads-up we will begin deprecating all our custom diagnostic settings policies, and changing our default assignment to leverage the associated built-in initiative for Log Analytics (as the target) - additional options will include targeting Event Hubs or Storage accounts. + +### Microsoft Monitoring Agent (MMA) Deprecation and Azure Monitor Agent (AMA) (January 2024) + +Similarly, as Microsoft Monitoring Agent (MMA) is on a deprecation path (August 2024), Azure Monitor Agent (AMA) is the recommended replacement and there are a number of requests to support AMA specific policies (**NOTE**: Some features are going agentless thus not requiring an agent, see [Table: AMA parity status](./ALZ-AMA-Update#table-ama-parity-status) following link for more detail). + +**Update January 2024** We have been working on the removal of MMA from ALZ and the first step in the overall removal process is to update the ALZ Portal reference implementation (greenfield deployments) which has now been updated. Our next step is to work on the deployment to Terraform and Bicep reference implementations which requires significant investment to minimise impact to existing customers and providing clear guidance for the transition. For more details please see [Azure Monitor Agent Update](./ALZ-AMA-Update.md). + +### Azure Database for MariaDB (Jan 2024) + +Azure Database for MariaDB is being deprecated, with the retirement process beginning on January 19, 2024. Due to retirement Azure is phasing out MariaDB policies, aligning with a strategic shift to Azure Database for MySQL - Flexible Server. This includes deprecating Azure Landing Zone (ALZ) custom policies 'Diagnostic Settings (Deploy)' and 'Public Endpoint (Deny)' for MariaDB. These policies are becoming redundant with MariaDB's phase-out: + +1. Diagnostic Settings (Deploy) for MariaDB +2. Public Endpoint (Deny) for MariaDB + +**Action for Users:** Users are encouraged to migrate to Azure Database for MySQL - Flexible Server. This migration will involve updating or replacing existing MariaDB-related policies with ones suitable for the MySQL Flexible Server environment. + +For more information on Azure Database for MariaDB, its retirement, and the migration process, visit [What's happening to Azure Database for MariaDB?](https://learn.microsoft.com/en-us/azure/mariadb/whats-happening-to-mariadb). + +### Sovereign Clouds (US Gov and China) + +Numerous GitHub issues related to sovereign clouds are currently within our scope, and our team is actively endeavoring to resolve these concerns. + +Regrettably, due to stringent security requirements inherent in sovereign cloud environments, our team lacks the necessary access privileges to validate policies or authenticate the successful deployment of ALZ. Presently, our access permissions are confined exclusively to the public cloud. + +Given our constraints in conducting direct tests, we are dependent on the invaluable support of the broader community to assist us in identifying potential issues and offering constructive feedback. We intend to respond to issues pertaining to sovereign clouds on an "as soon as possible" basis, deploying our best efforts. However, due to the aforementioned limitations, we are unable to offer precise timelines for issue resolution. + +To view the current list of GitHub issues related to sovereign clouds, please see [this link](https://github.com/Azure/Enterprise-Scale/labels/Area%3A%20Sovereign). + +### Private DNS Zone Issues + +There are a number of issues raised related to private DNS zones not functioning correctly, and in some cases this is due to specific services requiring additional configuration to function correctly. + +Known services causing issues include: + +- VM Guest Configuration ([additional configuration required](https://learn.microsoft.com/en-us/azure/governance/machine-configuration/overview#communicate-over-private-link-in-azure)) - [GitHub Issue](https://github.com/Azure/Enterprise-Scale/issues/1466) +- Power BI ([more info](https://learn.microsoft.com/en-us/power-bi/enterprise/service-security-private-links)) - [GitHub Issue](https://github.com/Azure/Enterprise-Scale/issues/1441) + +If you encounter problems with DNS resolution for PaaS services that have Private DNS Zones deployed by ALZ, first verify their necessity. If the services do not require Private Link, or you do not intend to use Private Link for the service, we recommend either disconnecting/unlinking or deleting the private DNS zone from the hub or virtual network for those services. Alternatively, you can follow the specific guidance provided for correctly configuring the resource. + +## Tips & Recommendations + +### Enforcement mode instead of the audit effect + +It is strongly suggested that the enforcement mode be utilized over the audit effect for policies such as deny or deployIfNotExists (DINE). The function of the audit effect primarily serves as a brief, introductory measure to gauge the impending impacts of the policy prior to activating the enforcement mode. This mechanism is not designed to act as a perpetual solution for these categories of policies. + +By modifying the enforcement mode to a "do not enforce" state on a policy or initiative assignment, the enforcement of the effect (deny or DINE) is effectively suspended, while still maintaining the auditing of policy compliance. This strategy is particularly beneficial when seeking to deactivate deny or DINE on a policy or initiative assignment and comes highly recommended for such circumstances. + +For a detailed explanation of this topic, please review [Adopt policy-driven guardrails](https://learn.microsoft.com/en-gb/azure/cloud-adoption-framework/ready/enterprise-scale/dine-guidance). + +### Deny policies also audit + +Numerous deny policies, constituting a part of the ALZ deployment, inherently carry out an action (i.e., denying the action). Nonetheless, it is critical to recognize that these policies additionally incorporate an auditing capability, particularly for pre-existing resources that remain unremediated or are inherently unremediable in instances of deny policies. + +For instance, consider the policy assignment Deny the deployment of classic resources. While this policy predominantly prevents the deployment of classic resources, it also performs an audit of classic resources that have been previously deployed. This functionality is instrumental in comprehending the extent of the issue at hand and thereby facilitates effective remediation efforts. + +### Unassigned custom policies deployed by ALZ + +ALZ deploys a number of custom policies that are not assigned to any scope by default. There are some very useful policies included that would not necessarily benefit all customers, as there may be dependencies or other decisions needed that would drive the decision to implement them. + +As an example, we provide the [Deploy a default budget on all subscriptions under the assigned scope](https://www.azadvertizer.net/azpolicyadvertizer/Deploy-Budget.html) policy that may be useful for managing costs for your subscriptions, e.g., subscriptions under the Sandboxes management group. + +As a starting point reviewing ALZ provided custom policies, we recommend that you review the [ALZ custom policies](https://www.azadvertizer.net/azpolicyadvertizer_all.html#%7B%22col_11%22%3A%7B%22flt%22%3A%22ALZ%22%7D%2C%22col_3%22%3A%7B%22flt%22%3A%22!diag%22%7D%2C%22page_length%22%3A100%7D). This link will show you all the ALZ custom policies that are not diagnostic settings policies. Some of these are assigned to specific scopes or included in initiatives that are assigned, but many are not ([AzAdvertizer](https://www.azadvertizer.net/) is not aware of ALZ policy assignments). + +Alternatively, we highly recommend you run [AzGovViz](https://github.com/JulianHayward/Azure-MG-Sub-Governance-Reporting) against your Azure estate to understand the policies that are assigned to your subscriptions and management groups, and get a tailored report that includes unassigned policies. An example, based on a vanilla ALZ deployment, is shown below: + +{{< figure src="../img/AzGovViz-ALZ-Policy.png">}} +To get the full list of unassigned ALZ policies, check "# Orphaned Custom Policy definitions" in the report. diff --git a/docs/content/policy/policyMigrate/img/alz-assign-builtin-policy-01.png b/docs/content/policy/policyMigrate/img/alz-assign-builtin-policy-01.png new file mode 100644 index 00000000..49535763 Binary files /dev/null and b/docs/content/policy/policyMigrate/img/alz-assign-builtin-policy-01.png differ diff --git a/docs/content/policy/policyMigrate/img/alz-delete-policy-assign-01.png b/docs/content/policy/policyMigrate/img/alz-delete-policy-assign-01.png new file mode 100644 index 00000000..735960f3 Binary files /dev/null and b/docs/content/policy/policyMigrate/img/alz-delete-policy-assign-01.png differ diff --git a/docs/content/policy/policyMigrate/img/alz-delete-policy-def-01.png b/docs/content/policy/policyMigrate/img/alz-delete-policy-def-01.png new file mode 100644 index 00000000..0b886872 Binary files /dev/null and b/docs/content/policy/policyMigrate/img/alz-delete-policy-def-01.png differ diff --git a/docs/content/policy/policyMigrate/img/alz-determine-policy-assign-01.png b/docs/content/policy/policyMigrate/img/alz-determine-policy-assign-01.png new file mode 100644 index 00000000..cd2e232d Binary files /dev/null and b/docs/content/policy/policyMigrate/img/alz-determine-policy-assign-01.png differ diff --git a/docs/content/policy/policyMigrate/img/alz-determine-policy-assign-02.png b/docs/content/policy/policyMigrate/img/alz-determine-policy-assign-02.png new file mode 100644 index 00000000..60519d47 Binary files /dev/null and b/docs/content/policy/policyMigrate/img/alz-determine-policy-assign-02.png differ diff --git a/docs/content/policy/policyMigrate/img/alz-update-initiative-with-builtin-01.png b/docs/content/policy/policyMigrate/img/alz-update-initiative-with-builtin-01.png new file mode 100644 index 00000000..63ba11a7 Binary files /dev/null and b/docs/content/policy/policyMigrate/img/alz-update-initiative-with-builtin-01.png differ diff --git a/docs/content/policy/policyMigrate/img/alz-update-initiative-with-builtin-02.png b/docs/content/policy/policyMigrate/img/alz-update-initiative-with-builtin-02.png new file mode 100644 index 00000000..58a825c5 Binary files /dev/null and b/docs/content/policy/policyMigrate/img/alz-update-initiative-with-builtin-02.png differ diff --git a/docs/content/policy/policyMigrate/img/alz-update-initiative-with-builtin-03.png b/docs/content/policy/policyMigrate/img/alz-update-initiative-with-builtin-03.png new file mode 100644 index 00000000..0d98a797 Binary files /dev/null and b/docs/content/policy/policyMigrate/img/alz-update-initiative-with-builtin-03.png differ diff --git a/docs/content/policy/policyMigrate/img/alz-update-initiative-with-builtin-04.png b/docs/content/policy/policyMigrate/img/alz-update-initiative-with-builtin-04.png new file mode 100644 index 00000000..bb3a3196 Binary files /dev/null and b/docs/content/policy/policyMigrate/img/alz-update-initiative-with-builtin-04.png differ diff --git a/docs/content/policy/policyMigrate/img/alz-update-to-builtin-01.png b/docs/content/policy/policyMigrate/img/alz-update-to-builtin-01.png new file mode 100644 index 00000000..b87464e4 Binary files /dev/null and b/docs/content/policy/policyMigrate/img/alz-update-to-builtin-01.png differ diff --git a/docs/content/policy/policyMigrate/index.md b/docs/content/policy/policyMigrate/index.md new file mode 100644 index 00000000..381a6c99 --- /dev/null +++ b/docs/content/policy/policyMigrate/index.md @@ -0,0 +1,162 @@ +--- +title: Migrating Policy to Built-in +weight: 15 +--- + +This article describes how to migrate ALZ custom policies and policy initiatives to Azure built-in policies. The guidance provided in this document describes manual steps for performing the migration, based on a set of specific policies and initiatives. + +## Detect updates to policy + +1. To determine if there has been updates to ALZ your first reference should be [What's New](https://github.com/Azure/Enterprise-Scale/wiki/Whats-new). Any updates to policies or other ALZ related artifacts will be reflected here upon release. An example of what that will look like can be seen [here](https://github.com/Azure/Enterprise-Scale/wiki/Whats-new#policy). Also note that a cumulative list of deprecated services for ALZ, including policies, is maintained [here](https://github.com/Azure/Enterprise-Scale/wiki/ALZ-Deprecated-Services) + +2. Alternatively or supplementary to the information available in [What's New](https://github.com/Azure/Enterprise-Scale/wiki/Whats-new), the AzPolicyAdvertizer with the ALZ and deprecated flags enabled (see [here](https://www.azadvertizer.net/azpolicyadvertizer_all.html#%7B%22col_10%22%3A%7B%22flt%22%3A%22Deprecated%22%7D%2C%22col_9%22%3A%7B%7D%2C%22col_11%22%3A%7B%22flt%22%3A%22ALZ%22%7D%7D)) can be leveraged to determine deprecated ALZ policies + +3. A third alternative or supplementary tool is [Azure Governance Visualizer](https://github.com/JulianHayward/Azure-MG-Sub-Governance-Reporting) which can be run in your environment and reveal information about the current state of policies and policy assignments. Note that Azure Governance Visualizer requires permissions in your tenant as described [here](https://github.com/JulianHayward/Azure-MG-Sub-Governance-Reporting#permissions-overview) + +## Update scenarios + +There are the following scenarios for ALZ custom policies being superseded by Azure built-in policies, listed in increasing order of complexity: + +1. A single ALZ custom policy, which is not assigned anywhere in your Azure estate, is superseded by an Azure built-in policy. This is the simplest scenario, and is not covered in more detail. +2. A single ALZ custom policy, which is assigned at one or more scopes in your Azure estate, is superseded by an Azure built-in policy. The process for managing this is described in [Migrate single ALZ custom policy to built-in policy](#migrate-single-pol). +3. One or more ALZ custom policies, assigned via ALZ custom policy initiative, which are superseded by Azure built-in policies. The process for managing this is described in [Migrate ALZ custom policies in initiatives to built-in policies](#migrate-multiple-pol). + +### Migrate single ALZ custom policy to built-in policy + +For this scenario we will use the ALZ custom policy _Deny the creation of public IP_ which will be migrated to the built-in policy _Not allowed resource types_ + +To carry out the instructions in the scenario the operator will require Resource Policy Permissions at the root of the ALZ management group hierarchy + +- Go to https://portal.azure.com +- Open Policy +- Go to Definitions and in Search find the ALZ custom policy. + + {{< figure src="./img/alz-update-to-builtin-01.png">}} + +- Click on the hyperlink for the policy definition +- To determine if the policy is assigned at any scope in the ALZ management group structure start by getting the policy definition ID + + ![alz-custom-policy-def-name](img/alz-determine-policy-assign-01.png) + +- Since there is no easy way to get the various scopes a policy is assigned to, go to Azure Resource Graph Explorer +- Ensure that scope for the query is Directory and then execute the following kusto query: + + ```kusto + PolicyResources | + where kind =~ 'policyassignments' and tostring(properties.policyDefinitionId) =~ '/providers/Microsoft.Management/managementGroups/contoso/providers/Microsoft.Authorization/policyDefinitions/Deny-PublicIP' + | extend + assignmentScope = tostring(properties.scope), + assignmmentNotScopes = tostring(properties.notScopes), + assignmmentParameters = tostring(properties.parameters) + | project assignmentScope, + assignmmentNotScopes, + assignmmentParameters + ``` + +- The above command will give a result similar to what is shown below + + ![alz-custom-policy-assignments](img/alz-determine-policy-assign-02.png) + +- As can be seen this particular policy is assigned with only a simple Deny effect parameter at the following levels in the management group structure + - Contoso/contoso-landingzones/contoso-landingzones-corp + - Contoso/contoso-platform/contoso-platform-identity + +> Note +that the provided example has a simple parameter set. If more complex parameters are assigned to a policy which is to be migrated those should be noted down. In that respect the possibility to download the query results as CSV could be leveraged. + +- Switch from Azure Resource Graph Explorer back to the Policy view +- Change the scope to include the scopes determined in the previous step. and search for the relevant policy + + ![alz-delete-policy-assignments](img/alz-delete-policy-assign-01.png) + +- For each assignment, click the ellipsis and select Delete Assignment. +- Once all policy assignments are deleted, go to the Definitions pane, search for the definition. Once found click the ellipsis and choose Delete Policy Definition + + ![alz-custom-policy-def-search](img/alz-update-to-builtin-01.png) + +- To assign the _Not allowed Resource types_ policy search for that policy definition. Once found click the ellipsis and choose Assign + + ![alz-builtin-policy-def-search](img/alz-assign-builtin-policy-01.png) + +- Set relevant parameters, for this particular policy this would be the resource type to disallow, i.e. Microsoft.Network/publicIpAddresses, then assign the policy to the scopes previously determined. + +### How to update child definitions in ALZ custom initiatives + +For this scenario we will use the ALZ custom initiative _Deploy Diagnostic Settings to Azure Services_ which is leveraging quite a large number of ALZ custom policies to apply diagnostics settings for various resources. As the initiative is updated at [source](https://github.com/Azure/Enterprise-Scale/tree/main/src/resources/Microsoft.Authorization/policySetDefinitions), the easiest way to achieve the migration in a manual way is to pull the newest version of the initiative from there. + +To carry out the instructions in the scenario the operator will require Resource Policy Permissions at the root of the ALZ management group hierarchy + +- Go to https://portal.azure.com +- Open Policy +- Go to Definitions and in Search find the ALZ custom policy initiative. + + ![alz-custom-initiative-def-search](img/alz-update-initiative-with-builtin-01.png) + +- Click on the hyperlink for the initiative definition +- To determine where the initiative is assigned at any scope in the ALZ management group structure start by getting the initiative name + + ![alz-custom-initiative-def-name](img/alz-update-initiative-with-builtin-02.png) + +- Since there is no easy way to get the various scopes an initiative is assigned to, got Azure Resource Graph Explorer +- Ensure that scope for the query is Directory and then execute the following kusto query: + + ```kusto + PolicyResources | + where kind =~ 'policyassignments' and tostring(properties.policyDefinitionId) =~ '/providers/Microsoft.Management/managementGroups/contoso/providers/Microsoft.Authorization/policySetDefinitions/Deploy-Diagnostics-LogAnalytics' + | extend + assignmentScope = tostring(properties.scope), + assignmmentNotScopes = tostring(properties.notScopes), + assignmmentParameters = tostring(properties.parameters) + | project assignmentScope, + assignmmentNotScopes, + assignmmentParameters + ``` + +- The above command will give a result similar to what is shown below + + ![alz-custom-initiative-assignments](img/alz-update-initiative-with-builtin-03.png) + +- As can be seen this particular initiative is assigned with only a single parameter at the following levels in the management group structure + - Contoso/ + +> Note +that the provided example has a simple parameter set. If more complex parameters are assigned to a policy which is to be migrated those should be noted down. In that respect the possibility to download the query results as CSV could be leveraged. + +- Switch from Azure Resource Graph Explorer back to the Policy view +- Change the scope to include the scope described above, and search for the relevant initiative + + ![alz-delete-initiative-assignments](img/alz-update-initiative-with-builtin-04.png) + +- For each assignment, click the ellipsis and select Delete Assignment. +- Once all initiative assignments are deleted, go to the Definitions pane, search for the initiative definition. Once found click the ellipsis and choose Delete Policy Definition + + ![alz-delete-initiative-def](img/alz-delete-policy-def-01.png) + +- To create the new version of the initiative, while this is possible to do in the portal through the portal GUI, with the number of policies to be included it would be a huge task. Instead you are suggested to use the templates available in https://aka.ms/alz/repo/src/resources/Microsoft.Authorization/policySetDefinitions to create the new policy as described in the following. + +- Go to https://portal.azure.com +- Start an Azure Cloud Shell with PowerShell engine +- Execute the following PowerShell script: + + ```posh + $policySetDefinitionPath = "./Deploy-Diagnostics-LogAnalytics.json" + Invoke-WebRequest -Uri https://raw.githubusercontent.com/Azure/Enterprise-Scale/main/src/resources/Microsoft.Authorization/policySetDefinitions/Deploy-Diagnostics-LogAnalytics.json -OutFile $policySetDefinitionPath + $policySetDef = Get-Content $policySetDefinitionPath | ConvertFrom-Json -Depth 100 + $policyName = $policySetDef.name + $displayName = $policySetDef.properties.displayName + $description = $policySetDef.properties.description + $metadata = $policySetDef.properties.metadata | ConvertTo-Json -Depth 100 + $parameters = $policySetDef.properties.parameters | ConvertTo-Json -Depth 100 + $policyDefinitions = ConvertTo-Json -InputObject @($policySetDef.properties.policyDefinitions) -Depth 100 + $policyDefinitions = $policyDefinitions.Replace('[[', '[') + New-AzPolicySetDefinition -Name $policyName -DisplayName $displayname -Description $description -PolicyDefinition $policyDefinitions -Metadata $metadata -Parameter $parameters -ManagementGroupName Contoso + ``` + +> Note that if you decide on another approach from the script above, there are a number of double brackets ('[[') in the file. These need to be replaced with single brackets before the policy set definition is valid syntax. + +- After running the above script go to the Definitions pane, and search for the initiative definition. Note that the initiative may take a while to show in the portal + + ![alz-custom-initiative-def-search](img/alz-update-initiative-with-builtin-01.png) + +- When the initiative materializes, click the ellipsis and choose Assign. +- Set relevant parameters for the initiative, then assign the policy to the scopes previously determined. diff --git a/docs/content/policy/policyTesting.md b/docs/content/policy/policyTesting.md new file mode 100644 index 00000000..3f79dca2 --- /dev/null +++ b/docs/content/policy/policyTesting.md @@ -0,0 +1,222 @@ +--- +title: Policy Testing Framework +weight: 9 +--- + +## Overview + +The ALZ Policy Testing Framework is a set of tools and scripts that can be used to test Azure Policies do what is expected and prevent breaking regressions. The framework is designed to be used with pipelines as part of CI/CD processes to test policies as they are developed and integrated to ultimately improve the quality and stability of policies going into production environments. + +This framework is based on the work done by @fawohlsc in this repo [azure-policy-testing](https://github.com/fawohlsc/azure-policy-testing), and is built on the well established PowerShell testing framework [Pester](https://pester.dev/). + +For ALZ, the focus is on testing Azure Policy definitions that have a DENY effect, as these can be very disruptive to organizations if a regression is introduced, and helps us improve the quality of the policies we are developing and deploying to production environments. The framework can be extended to test other policy effects, but this is not the focus of this framework. + +For authoring tests we standardized on using Az PowerShell native commands as much as possible as it is simpler to implement and read, however, there are circumstances where you will need to use REST APIs as not all features are exposed through Az PowerShell. To keep things simple, we have leveraged the `Invoke-AzRestMethod` function that wraps the REST API calls and make it easier to use in the Pester tests. + +### Prerequisites + +- An empty (dedicated) Azure subscription + - If following the same process as outlined below, you will also need to ensure this subscription is added to the "Corp" management group in the Azure Landing Zone +- [Pester](https://pester.dev/docs/introduction/installation) +- [Az PowerShell Module](https://learn.microsoft.com/en-us/powershell/azure/install-azure-powershell?view=azps-11.0.0&viewFallbackFrom=azps-6.2.0) +- [Invoke-AzRestMethod](https://learn.microsoft.com/en-us/powershell/module/az.accounts/invoke-azrestmethod?view=azps-11.0.0) + +### How it works + +The ALZ policy testing framework is designed to be used with GitHub Actions, but can be used with any CI/CD pipeline that supports PowerShell, or can be run directly on an ad hoc basis. The ALZ policy testing framework is designed to be used with the following workflow: + +1. A pull request is created to update a policy definition +2. The pull request triggers a GitHub Action workflow +3. The workflow runs the defined Pester tests against the policy definition +4. The workflow reports the results of the tests back to the pull request checks +5. The pull request is reviewed and handled based on the results of the tests + +### How to use it + +#### 1. Create a new GitHub Action workflow + +Create a new GitHub Action workflow in the `.github/workflows` folder of your repository. The workflow should be triggered on pull request events and should run on the `main` branch. The workflow should also allow being triggered manually to allow for testing of policies outside of pull requests. + +[Sample GitHub Action Workflow to run Policy tests](../policyTestingWorkflow) + +#### 2. Create a new Pester test file + +Create a new Pester test file in the `tests/policy` folder of your repository. The test file should be named the same as the policy definition file it is testing, but with a `.tests.ps1` extension. For example, if the policy definition file is named `azurepolicy.json`, the test file should be named `azurepolicy.tests.ps1`. + +#### 3. Write the Pester tests + +Write the Pester tests in the test file. The tests should cover the following scenarios: + +- Conditions that should be true when the policy is evaluated, so it is compliant +- Conditions that should be false when the policy is evaluated, so it is non-compliant + +It is important to test all the conditions evaluated in the policy. For example, if the policy is evaluating the `location` of a resource, you should test the following scenarios: + +- Resource is deployed in a location that is compliant with the policy +- Resource is deployed in a location that is non-compliant with the policy + +See the [How to write Pester tests for policies](#how-to-write-pester-tests-for-policies) section for more details on how to write Pester tests for policies. + +### Where is the testing framework? + +The testing framework is located in the [ALZ repository](https://aka.ms/alz/repo) in the `tests` folder. The framework consists of the following folders: + +- `policy` - Contains the Pester tests for the policies +- `utils` - Contains the utility functions used by the Pester tests + +### How to write Pester tests for policies + +For the purposes of this guide, we'll focus on the Policy test for `Deny-MgmtPorts-Internet` policy as it demonstrates using both Az PowerShell and REST API calls in the Pester test. The policy definition file is located in the `policy` folder of the [ALZ repository](https://aka.ms/alz/repo) in the `policy` folder. + +The policy tests are designed to run in an empty subscription(s) to ensure that the policy is evaluated in isolation and not impacted by other policies or resources in the subscription. + +> **_NOTE:_** Because we are testing Azure policies in the context of Azure Landing Zone, we are using a dedicated subscription in the "Corp" landing zone that is added under the Corp management group, where we retrieve the deployed policy definition ID and create a new policy assignment to test the policy (because we do not assign all policies by default, and some get assigned to different scopes). +> You can extend this methodology to test policies outside of Azure Landing Zone by deploying the policy you want to test and assigning it to the scope you want to test (e.g. subscription, resource group, etc. + +The policy test has 4 main sections (aligned with how Pester works): + +#### BeforeAll: This section is used to setup the environment for the tests. + +```powershell + # Set the default context for Az commands. + Set-AzContext -SubscriptionId $env:SUBSCRIPTION_ID -TenantId $env:TENANT_ID -Force + + if (-not [String]::IsNullOrEmpty($DeploymentConfigPath)) { + Write-Information "==> Loading deployment configuration from : $DeploymentConfigPath" + $deploymentObject = Get-Content -Path $DeploymentConfigPath | ConvertFrom-Json -AsHashTable + + # Set the esCompanyPrefix from the deployment configuration if not specified + $esCompanyPrefix = $deploymentObject.TemplateParameterObject.enterpriseScaleCompanyPrefix + $mangementGroupScope = "/providers/Microsoft.Management/managementGroups/$esCompanyPrefix-corp" + } + + $definition = Get-AzPolicyDefinition | Where-Object { $_.Name -eq 'Deny-MgmtPorts-From-Internet' } + New-AzPolicyAssignment -Name "TDeny-MgmtPorts-Internet" -Scope $mangementGroupScope + -PolicyDefinition $definition -PolicyParameterObject @{"ports" = @("3389", "22") + } +``` + +As part of the setup before running the test, we need to ensure we have the correct Azure context set, and that the policy is assigned to the correct scope. Because these steps are running as part of Azure Landing Zone pull request testing, the policies we want to test get deployed prior to running these test. In this case, we retrieve the policy definition and assign it to the management group scope, passing in the policy parameters to ensure the policy is evaluated correctly. + +If you want to extend this methodology to test policies independent of deploying ALZ, you could extend this section to also deploy the policy you want to test, and then do the policy assignment. + +#### DENY - group of tests to validate scenarios that where the policy effect is applied and deployment should fail. + +As an example, using Az PowerShell: + +```Powershell + It "Should deny non-compliant port '3389'" -Tag "deny-noncompliant-nsg-port" { + AzTest -ResourceGroup { + param($ResourceGroup) + + $networkSecurityGroup = New-AzNetworkSecurityGroup ` + -Name "nsg-test" ` + -ResourceGroupName $ResourceGroup.ResourceGroupName ` + -Location $ResourceGroup.Location + + # Should be disallowed by policy, so exception should be thrown. + { + $networkSecurityGroup | Add-AzNetworkSecurityRuleConfig ` + -Name RDP-rule ` + -Description "Allow RDP" ` + -Access Allow ` + -Protocol Tcp ` + -Direction Inbound ` + -Priority 200 ` + -SourceAddressPrefix * ` + -SourcePortRange * ` + -DestinationAddressPrefix * ` + -DestinationPortRange 3389 # Incompliant. + | Set-AzNetworkSecurityGroup + } | Should -Throw "*disallowed by policy*" + } + } +``` + +In this example, we are creating a new Network Security Group (NSG) and adding a rule to allow RDP traffic on port 3389. The policy we're testing is configured to deny traffic on port 3389, so we expect this operation to fail. We use the `Should -Throw` command to validate that the operation failed with the expected error message. + +#### ALLOW - group of tests to validate scenarios that are compliant with the policy conditions and should succeed. + +As an example, using REST API with `Invoke-AzRestMethod`: + +```Powershell + It "Should allow compliant port ranges* - API" -Tag "allow-compliant-nsg-port" { + AzTest -ResourceGroup { + param($ResourceGroup) + + #Destination port ranges to test + $portRanges = @("23","3390-3392","8080") + + # Create Payload for NSG + $securityRules = @( + @{ + name = "Web-rule" + properties = @{ + description = "Allow Web2" + protocol = "Tcp" + sourcePortRange = "*" + destinationPortRange = "443" + sourceAddressPrefix = "*" + destinationAddressPrefix = "*" + access = "Allow" + priority = 300 + direction = "Inbound" + } + }, + @{ + name = "Multi-rule" + properties = @{ + description = "Allow Mgmt3" + protocol = "Tcp" + sourcePortRange = "*" + destinationPortRanges = $portRanges + sourceAddressPrefix = "*" + destinationAddressPrefix = "*" + access = "Allow" + priority = 310 + direction = "Inbound" + } + } + ) + + $object = @{ + properties = @{ + securityRules = $securityRules + } + location = "uksouth" + } + + $payload = ConvertTo-Json -InputObject $object -Depth 100 + + # Should be disallowed by policy, so exception should be thrown. + { + $httpResponse = Invoke-AzRestMethod ` + -ResourceGroupName $ResourceGroup.ResourceGroupName ` + -ResourceProviderName "Microsoft.Network" ` + -ResourceType "networkSecurityGroups" ` + -Name "testNSG99" ` + -ApiVersion "2022-11-01" ` + -Method "PUT" ` + -Payload $payload + + if ($httpResponse.StatusCode -eq 200 -or $httpResponse.StatusCode -eq 201) { + # NSG created + } + # Error response describing why the operation failed. + else { + throw "Operation failed with message: '$($httpResponse.Content)'" + } + } | Should -Not -Throw + } + } +``` + +In this example, we are creating a new Network Security Group (NSG) and adding a rule to allow traffic on port 443. The policy we're testing is configured to deny traffic on port 3389, so we expect this operation to succeed. We use the `Should -Not -Throw` command to validate that the operation succeeded. + +#### AfterAll: This section is used to clean up the environment after the tests are completed. + +```Powershell + Remove-AzPolicyAssignment -Name "TDeny-MgmtPorts-Internet" -Scope $mangementGroupScope -Confirm:$false +``` + +In this example, we are removing the policy assignment after the tests are completed (if you're testing outside of an ALZ deployment, you can also use this to remove the deployed policy). \ No newline at end of file diff --git a/docs/content/policy/policyTestingWorkflow.md b/docs/content/policy/policyTestingWorkflow.md new file mode 100644 index 00000000..b55e5866 --- /dev/null +++ b/docs/content/policy/policyTestingWorkflow.md @@ -0,0 +1,86 @@ +--- +title: Policy Testing Workflow Sample +weight: 9 +--- + +``` YAML +name: ALZ Tests for Policy + +on: + pull_request: + types: + - opened + - reopened + - synchronize + - ready_for_review + branches: + - main + - TestingFramework # For testing purposes only update as needed based on branch name + paths: + - ".github/workflows/**" + - "tests/policy/**" + - "tests/utils/**" + workflow_dispatch: + inputs: + remarks: + description: "Reason for triggering the workflow run" + required: false + default: "Testing Azure Policies..." + +jobs: + test-alz-policies: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + ref: ${{ github.event.pull_request.head.sha }} + persist-credentials: false + + - name: Install PowerShell modules + shell: pwsh + run: | + Install-Module -Name "Az" -RequiredVersion "10.1.0" -Force -Scope CurrentUser -ErrorAction Stop + Update-AzConfig -DisplayBreakingChangeWarning $false + + - name: Azure login (OIDC) + uses: azure/login@v1 + if: ${{ success() && env.AZURE_CLIENT_SECRET == '' }} + with: + client-id: ${{ secrets.AZURE_CLIENT_ID }} + tenant-id: ${{ secrets.AZURE_TENANT_ID }} + subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + enable-AzPSSession: true + env: + AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }} + + - name: Azure login (Client Secret) + uses: azure/login@v1 + if: ${{ success() && env.AZURE_CLIENT_SECRET != '' }} + with: + creds: '{"clientId":"${{ secrets.AZURE_CLIENT_ID }}","clientSecret":"${{ secrets.AZURE_CLIENT_SECRET }}","subscriptionId":"${{ secrets.AZURE_SUBSCRIPTION_ID }}","tenantId":"${{ secrets.AZURE_TENANT_ID }}"}' + enable-AzPSSession: true + env: + AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }} + + - name: Pester Test for Policies + shell: pwsh + run: | + Import-Module Pester -Force + $pesterConfiguration = @{ + Run = @{ + Path = "tests/*.tests.ps1" + PassThru = $true + } + Output = @{ + Verbosity = 'Detailed' + CIFormat = 'Auto' + } + } + $result = Invoke-Pester -Configuration $pesterConfiguration + exit $result.FailedCount + env: + SUBSCRIPTION_ID: ${{ secrets.AZURE_POLICY_SUBSCRIPTION1_ID }} + SUBSCRIPTION2_ID: ${{ secrets.AZURE_POLICY_SUBSCRIPTION2_ID }} #Used for policy tests that require a second subscription (e.g. cross subscription peering) + TENANT_ID: ${{ secrets.AZURE_TENANT_ID }} +``` \ No newline at end of file diff --git a/docs/content/policy/policyUpdate2Latest/img/1.1.update-alz-custom-policy-def-search.png b/docs/content/policy/policyUpdate2Latest/img/1.1.update-alz-custom-policy-def-search.png new file mode 100644 index 00000000..b91ebb92 Binary files /dev/null and b/docs/content/policy/policyUpdate2Latest/img/1.1.update-alz-custom-policy-def-search.png differ diff --git a/docs/content/policy/policyUpdate2Latest/img/1.2.update-alz-custom-policy-def-name.png b/docs/content/policy/policyUpdate2Latest/img/1.2.update-alz-custom-policy-def-name.png new file mode 100644 index 00000000..a227fc8e Binary files /dev/null and b/docs/content/policy/policyUpdate2Latest/img/1.2.update-alz-custom-policy-def-name.png differ diff --git a/docs/content/policy/policyUpdate2Latest/img/2.1.update-alz-custom-policy-assignments.png b/docs/content/policy/policyUpdate2Latest/img/2.1.update-alz-custom-policy-assignments.png new file mode 100644 index 00000000..b0a67580 Binary files /dev/null and b/docs/content/policy/policyUpdate2Latest/img/2.1.update-alz-custom-policy-assignments.png differ diff --git a/docs/content/policy/policyUpdate2Latest/img/2.2.update-alz-custom-policy-delete-assignments.png b/docs/content/policy/policyUpdate2Latest/img/2.2.update-alz-custom-policy-delete-assignments.png new file mode 100644 index 00000000..964cfee1 Binary files /dev/null and b/docs/content/policy/policyUpdate2Latest/img/2.2.update-alz-custom-policy-delete-assignments.png differ diff --git a/docs/content/policy/policyUpdate2Latest/img/2.3.update-alz-custom-policy-search.png b/docs/content/policy/policyUpdate2Latest/img/2.3.update-alz-custom-policy-search.png new file mode 100644 index 00000000..b080a836 Binary files /dev/null and b/docs/content/policy/policyUpdate2Latest/img/2.3.update-alz-custom-policy-search.png differ diff --git a/docs/content/policy/policyUpdate2Latest/img/2.4.update-alz-custom-policy-search.png b/docs/content/policy/policyUpdate2Latest/img/2.4.update-alz-custom-policy-search.png new file mode 100644 index 00000000..70117725 Binary files /dev/null and b/docs/content/policy/policyUpdate2Latest/img/2.4.update-alz-custom-policy-search.png differ diff --git a/docs/content/policy/policyUpdate2Latest/img/AzGovViz-ALZ-Policy-outDated.png b/docs/content/policy/policyUpdate2Latest/img/AzGovViz-ALZ-Policy-outDated.png new file mode 100644 index 00000000..404a4d64 Binary files /dev/null and b/docs/content/policy/policyUpdate2Latest/img/AzGovViz-ALZ-Policy-outDated.png differ diff --git a/docs/content/policy/policyUpdate2Latest/img/alz-update-initiative-with-builtin-01.png b/docs/content/policy/policyUpdate2Latest/img/alz-update-initiative-with-builtin-01.png new file mode 100644 index 00000000..63ba11a7 Binary files /dev/null and b/docs/content/policy/policyUpdate2Latest/img/alz-update-initiative-with-builtin-01.png differ diff --git a/docs/content/policy/policyUpdate2Latest/img/alz-update-initiative-with-builtin-02.png b/docs/content/policy/policyUpdate2Latest/img/alz-update-initiative-with-builtin-02.png new file mode 100644 index 00000000..58a825c5 Binary files /dev/null and b/docs/content/policy/policyUpdate2Latest/img/alz-update-initiative-with-builtin-02.png differ diff --git a/docs/content/policy/policyUpdate2Latest/img/alz-update-initiative-with-builtin-03.png b/docs/content/policy/policyUpdate2Latest/img/alz-update-initiative-with-builtin-03.png new file mode 100644 index 00000000..0d98a797 Binary files /dev/null and b/docs/content/policy/policyUpdate2Latest/img/alz-update-initiative-with-builtin-03.png differ diff --git a/docs/content/policy/policyUpdate2Latest/img/alz-update-initiative-with-builtin-04.png b/docs/content/policy/policyUpdate2Latest/img/alz-update-initiative-with-builtin-04.png new file mode 100644 index 00000000..bb3a3196 Binary files /dev/null and b/docs/content/policy/policyUpdate2Latest/img/alz-update-initiative-with-builtin-04.png differ diff --git a/docs/content/policy/policyUpdate2Latest/index.md b/docs/content/policy/policyUpdate2Latest/index.md new file mode 100644 index 00000000..7be44108 --- /dev/null +++ b/docs/content/policy/policyUpdate2Latest/index.md @@ -0,0 +1,307 @@ +--- +title: Update ALZ Custom Policies to Latest +weight: 14 +--- + +This article describes how to update ALZ custom policies and policy initiatives to latest versions of ALZ custom policies. The guidance provided in this document describes manual steps for performing the update, based on a set of specific policies and initiatives, with PowerShell. + +{{< hint type=note >}} +If you are already managing Azure Policies through Infrastructure as Code (IaC), you may not want to be updating your Azure Policies outside of your pipeline. This article assumes a manual approach to updating Azure landing zone (ALZ) policies. +{{< /hint >}} + +{{< hint type=important >}} +To carry out the instructions below, the operator will require Resource Policy Contributor permissions at the root of the ALZ management group hierarchy. +{{< /hint >}} + +## Detect updates to policy + +1. To determine if there has been updates to ALZ your first reference should be [What's New](https://github.com/Azure/Enterprise-Scale/wiki/Whats-new). Any updates to policies or other ALZ related artifacts will be reflected here upon release. An example of what that will look like can be seen [here](https://github.com/Azure/Enterprise-Scale/wiki/Whats-new#policy). + +2. Alternatively, [Azure Governance Visualizer](https://github.com/JulianHayward/Azure-MG-Sub-Governance-Reporting) can be run in your environment and reveal information about the current state of policies and policy assignments. Part of the output of Azure Governance Visualizer is Azure Landing Zones (ALZ) Policy Version Checker which will allows you to see all **outDated** ALZ policies in your environment (see figure 1). +![AzGovViz-ALZ-Policy-Checker](img/AzGovViz-ALZ-Policy-outDated.png) +*Figure 1: Azure Governance Visualizer filtering on outDated ALZ policies* + +{{< hint type=note >}} +Note that Azure Governance Visualizer requires permissions in your tenant as described [here](https://github.com/JulianHayward/Azure-MG-Sub-Governance-Reporting#permissions-overview) +{{< /hint >}} + +## Updating scenarios + +These are the following scenarios for ALZ custom policies being updated to latest versions of the custom ALZ policies, listed in increasing order of complexity: + +1. One or more ALZ custom policies, whether assigned or not at one or more scopes in your Azure estate, is superseded by a newer version of that same ALZ custom policy. The process for managing this is described in [Updating one or more ALZ custom policy to newer ALZ custom policies](#updating-one-or-more-alz-custom-policies-to-newer-alz-custom-policy). + +2. One or more ALZ custom policies, assigned at one or more scopes in your Azure estate, is superseded by a newer version of the same ALZ custom policy with **updated parameters**. The process for managing this is described in [Updating one or more ALZ custom policies to a newer ALZ custom policy with updated parameters](#updating-one-or-more-alz-custom-policies-to-newer-alz-custom-policy-with-updated-parameters) + +3. One or more ALZ custom policies, assigned via ALZ custom policy initiative, are superseded by a newer version of the same ALZ custom policy(s) with **updated parameters**. The process for managing this is described in [Updating ALZ custom policies in ALZ custom policy initiative to newer ALZ custom policies](#updating-alz-custom-policies-in-alz-custom-policy-initiative-to-newer-alz-custom-policies) + +### Updating one or more ALZ custom policies to newer ALZ custom policy + +For this scenario we will use the ALZ custom policy *Deploy Diagnostic Settings for AVD Host Pools to Log Analytics workspace*. + +Considering no parameters have changed, this is a simple exercise that consists of replacing the policy definition content with the latest policy definition. While it is possible to update the policy definition via the portal GUI, there are some properties than can't be updated, like version. To minimize errors and include all updated policy definition properties, we will be updating this policy via a PowerShell script. + +Before we begin, we need to identify the policy definition name and location to be used in our PowerShell script below. + +- Go to [Azure Portal](https://portal.azure.com) +- Open Policy +- Go to Definitions and in Search, find the ALZ custom policy. + + ![alz-custom-policy-def-search](img/1.1.update-alz-custom-policy-def-search.png) + +- Click on the hyperlink for the policy definition +- Capture the policy definition name and scope from `Definition ID` and `Definition location`. In this example, the `Definition ID` is `/providers/Microsoft.Management/managementGroups/MTB/providers/Microsoft.Authorization/policyDefinitions/Deploy-Diagnostics-WVDHostPools` with a policy definition name of **Deploy-Diagnostics-WVDHostPools** and a scope of **MTB**. The policy definition name is the set of characters following the last `/`. Both the policy definition name and scope will be used in the PowerShell script below. + + ![alz-custom-policy-def-name](img/1.2.update-alz-custom-policy-def-name.png) + +- To update to the latest version of the definition, we will use the policy definition templates available in https://github.com/Azure/Enterprise-Scale/tree/main/src/resources/Microsoft.Authorization/policyDefinitions as described in the following. + +- Go to https://portal.azure.com +- Start an Azure Cloud Shell with PowerShell engine +- Execute the following PowerShell script ([disclaimer](https://github.com/Azure/Enterprise-Scale/blob/main/SUPPORT.md)) for each ALZ custom policy definition: + - Before executing the following PowerShell script, update the first two variables: + - `$policyDefinitionName` + - `$policyDefinitionLocation` + + ```posh + $policyDefinitionName = "Deploy-Diagnostics-WVDHostPools" # <-- Replace with policy definition name found earlier + $policyDefinitionLocation = "MTB" # <-- Replace with Definition location found earlier + $policyDefinitionPath = "./$($policyDefinitionName).json" + Invoke-WebRequest -Uri "https://raw.githubusercontent.com/Azure/Enterprise-Scale/main/src/resources/Microsoft.Authorization/policyDefinitions/$($policyDefinitionName).json" -OutFile $policyDefinitionPath + $policyDef = Get-Content $policyDefinitionPath | ConvertFrom-Json -Depth 100 + $policyName = $policyDef.name + $displayName = $policyDef.properties.displayName + $description = $policyDef.properties.description + $mode = $policyDef.properties.mode + $metadata = $policyDef.properties.metadata | ConvertTo-Json -Depth 100 + $parameters = $policyDef.properties.parameters | ConvertTo-Json -Depth 100 + $policyRule = $policyDef.properties.policyRule | ConvertTo-Json -Depth 100 + $policyRule = $policyRule.Replace('[[', '[') + Set-AzPolicyDefinition -Name $policyName -DisplayName $displayname -Description $description -Policy $policyRule -Mode $mode -Metadata $metadata -Parameter $parameters -ManagementGroupName $policyDefinitionLocation + ``` + +{{< hint type=note >}} +Note that if you decide on another approach from the script above, there are a number of double brackets ('[[') in the file. These need to be replaced with single brackets before the policy set definition is valid syntax. +{{< /hint >}} + +### Updating one or more ALZ custom policies to newer ALZ custom policy with updated parameters + +For this scenario, we will use the ALZ custom policy *Deploy Diagnostic Settings for AVD Host Pools to Log Analytics workspace*. Even though this policy doesn't have any updated parameters, we will walk through the steps as though it does. + +- Go to [Azure Portal](https://portal.azure.com) +- Open Policy +- Go to Definitions and in Search, find the ALZ custom policy. + + ![alz-custom-policy-def-search](img/1.1.update-alz-custom-policy-def-search.png) + +- Click on the hyperlink for the policy definition + +- To determine if the policy is assigned at any scope in the ALZ management group structure start by getting the policy definition ID + - Capture the policy definition name and scope from `Definition ID` and `Definition location`. In this example, the `Definition ID` is `/providers/Microsoft.Management/managementGroups/MTB/providers/Microsoft.Authorization/policyDefinitions/Deploy-Diagnostics-WVDHostPools` with a policy definition name of **Deploy-Diagnostics-WVDHostPools** and a scope of **MTB**. The policy definition name is the set of characters following the last `/`. Both the policy definition name and scope will be used in the PowerShell script below. + + ![alz-custom-policy-def-name](img/1.2.update-alz-custom-policy-def-name.png) + +- Since there is no easy way to get the various scopes a policy is assigned to, go to Azure Resource Graph Explorer +- Ensure that scope for the query is Directory and then execute the following kusto query: + + ```kusto + PolicyResources | + where kind =~ 'policyassignments' and tostring(properties.policyDefinitionId) =~ '/providers/Microsoft.Management/managementGroups/MTB/providers/Microsoft.Authorization/policyDefinitions/Deploy-Diagnostics-WVDHostPools' + | extend + assignmentScope = tostring(properties.scope), + assignmmentNotScopes = tostring(properties.notScopes), + assignmmentParameters = tostring(properties.parameters) + | project assignmentScope, + assignmmentNotScopes, + assignmmentParameters + ``` + +- The above command will give a result similar to what is shown below + + ![alz-custom-policy-assignments](img/2.1.update-alz-custom-policy-assignments.png) + +- Record the assignment scopes so you can recreate the assignments later +- As can be seen this particular policy is assigned with only a single DINE effect parameter at the following levels in the management group structure: + - MTB/MTB-landingzones + - MTB/MTB-sandboxes + +{{< hint type=note >}} +Note that if more complex parameters are assigned to a policy which is to be updated, those should be noted down. In that respect the possibility to download the query results as CSV could be leveraged. +{{< /hint >}} + +- Switch from Azure Resource Graph Explorer back to the Policy Assignments view +- Change the scope to include the scopes determined in the previous step and search for the relevant policy + + ![alz-delete-policy-assignments](img/2.2.update-alz-custom-policy-delete-assignments.png) + +- For each assignment, click the ellipsis and select Delete Assignment. +- Once all policy assignments are deleted, go to the Definitions pane, search for the definition. Once found click the ellipsis and choose Delete Policy Definition + + ![alz-custom-policy-def-search](img/2.3.update-alz-custom-policy-search.png) + +{{< hint type=important >}} +Record the **Definition location** of the Policy Definition as it will be used in (`$policyDefinitionLocation`) the script below. +{{< /hint >}} + +- To update to the latest version of the definition, we will use the policy definition templates available in https://github.com/Azure/Enterprise-Scale/tree/main/src/resources/Microsoft.Authorization/policyDefinitions as described in the following. + +- Go to https://portal.azure.com +- Start an Azure Cloud Shell with PowerShell engine +- Execute the following PowerShell script ([disclaimer](https://github.com/Azure/Enterprise-Scale/blob/main/SUPPORT.md)) for each ALZ custom policy definition: + - Before executing the following PowerShell script, update the first two variables: + - `$policyDefinitionName` + - `$policyDefinitionLocation` + + ```posh + $policyDefinitionName = "Deploy-Diagnostics-WVDHostPools" # <-- Replace with policy definition name found earlier + $policyDefinitionLocation = "MTB" # <-- Replace with Definition location found earlier + $policyDefinitionPath = "./$($policyDefinitionName).json" + Invoke-WebRequest -Uri "https://raw.githubusercontent.com/Azure/Enterprise-Scale/main/src/resources/Microsoft.Authorization/policyDefinitions/$($policyDefinitionName).json" -OutFile $policyDefinitionPath + $policyDef = Get-Content $policyDefinitionPath | ConvertFrom-Json -Depth 100 + $policyName = $policyDef.name + $displayName = $policyDef.properties.displayName + $description = $policyDef.properties.description + $mode = $policyDef.properties.mode + $metadata = $policyDef.properties.metadata | ConvertTo-Json -Depth 100 + $parameters = $policyDef.properties.parameters | ConvertTo-Json -Depth 100 + $policyRule = $policyDef.properties.policyRule | ConvertTo-Json -Depth 100 + $policyRule = $policyRule.Replace('[[', '[') + New-AzPolicyDefinition -Name $policyName -DisplayName $displayname -Description $description -Policy $policyRule -Mode $mode -Metadata $metadata -Parameter $parameters -ManagementGroupName $policyDefinitionLocation + ``` + +{{< hint type=note >}} +Note that if you decide on another approach from the script above, there are a number of double brackets ('[[') in the file. These need to be replaced with single brackets before the policy set definition is valid syntax. +{{< /hint >}} + +- To assign *Deploy Diagnostic Settings for AVD Host Pools to Log Analytics workspace* policy, search for that policy definition. Once found click the ellipsis and choose Assign + + ![alz-custom-policy-def-search](img/2.4.update-alz-custom-policy-search.png) + +{{< hint type=note >}} +Note how the display name changed from WVD to AVD. +{{< /hint >}} + +- Set relevant parameters which were captured earlier. + +### Updating ALZ custom policies in ALZ custom policy initiative to newer ALZ custom policies + +For this scenario we will use the ALZ custom initiative _Deploy Diagnostic Settings to Azure Services_ which is leveraging quite a large number of ALZ custom policies to apply diagnostics settings for various resources. As the initiative is updated at [source](https://github.com/Azure/Enterprise-Scale/tree/main/src/resources/Microsoft.Authorization/policySetDefinitions), the easiest way to achieve the migration in a manual way is to pull the newest version of the initiative from there. + +- Go to https://portal.azure.com +- Open Policy +- Go to Definitions and in Search find the ALZ custom policy initiative. + + ![alz-custom-initiative-def-search](img/alz-update-initiative-with-builtin-01.png) + +- Click on the hyperlink for the initiative definition +- To determine where the initiative is assigned at any scope in the ALZ management group structure start by getting the initiative **Definition ID**. Record the initiative name (/providers/Microsoft.Management/managementGroups/**Contoso**/providers/Microsoft.Authorization/policySetDefinitions/***Deploy-Diagnostics-LogAnalytics***) and location as it will be used in the PowerShell script below. + + ![alz-custom-initiative-def-name](img/alz-update-initiative-with-builtin-02.png) + +- Since there is no easy way to get the various scopes an initiative is assigned to, go to Azure Resource Graph Explorer +- Ensure that scope for the query is Directory and then execute the following kusto query: + + ```kusto + PolicyResources | + where kind =~ 'policyassignments' and tostring(properties.policyDefinitionId) =~ '/providers/Microsoft.Management/managementGroups/contoso/providers/Microsoft.Authorization/policySetDefinitions/Deploy-Diagnostics-LogAnalytics' + | extend + assignmentScope = tostring(properties.scope), + assignmmentNotScopes = tostring(properties.notScopes), + assignmmentParameters = tostring(properties.parameters) + | project assignmentScope, + assignmmentNotScopes, + assignmmentParameters + ``` + +- The above command will give a result similar to what is shown below + + ![alz-custom-initiative-assignments](img/alz-update-initiative-with-builtin-03.png) + +- Record the assignment scopes so you can recreate the assignments later +- As can be seen this particular initiative is assigned with only a single parameter at the following levels in the management group structure + - Contoso/ + +{{< hint type=note >}} +Note that the provided example has a simple parameter set. Even though this initiative has over 60 parameters, the other parameters are utilizing the **Default value**. If more complex parameters are assigned to a policy which is to be migrated those should be noted down. In that respect the possibility to download the query results as CSV could be leveraged. +{{< /hint >}} + +- Switch from Azure Resource Graph Explorer back to the Policy view +- Change the scope to include the scope described above, and search for the relevant initiative + + ![alz-delete-initiative-assignments](img/alz-update-initiative-with-builtin-04.png) + +- For each assignment, click the ellipsis and select Delete Assignment +- Once all initiative assignments are deleted, go to the Definitions pane, search for the initiative definition + +{{< hint type=note >}} +It is highly recommended you update all the ALZ custom policies to the latest version before continuing. The script below has a variable, `$updateCustomALZPolicies`, to update all of the ALZ custom policy definitions if set to `$true`. +{{< /hint >}} + +- Once found click the ellipsis and choose Delete Policy Initiative Definition + + ![alz-custom-initiative-def-search](img/alz-update-initiative-with-builtin-01.png) + +{{< hint type=important >}} +Record the **Definition location** of the Policy Initiative Definition as it will be used in (`$policySetDefinitionLocation`) the script below. +{{< /hint >}} + +- To create the new version of the initiative, while this is possible to do in the portal through the portal GUI, with the number of policies to be included it would be a huge task. Instead, we suggest the use of the templates available in https://github.com/Azure/Enterprise-Scale/tree/main/src/resources/Microsoft.Authorization/policySetDefinitions to create the new policy initiative definition and update the custom ALZ policy definitions as described in the following. + +- Go to https://portal.azure.com +- Start an Azure Cloud Shell with PowerShell engine +- Before executing the following PowerShell script ([disclaimer](https://github.com/Azure/Enterprise-Scale/blob/main/SUPPORT.md)), update the first three variables: + - `$updateCustomALZPolicies` + - `$policySetDefinitionName` + - `$policySetDefinitionLocation` + + ```posh + $updateCustomALZPolicies = $true # <-- $false = don't update the policy definitions + $policySetDefinitionName = "Deploy-Diagnostics-LogAnalytics" # <-- Replace with policy definition name found earlier + $policySetDefinitionLocation = "Contoso" # <-- Replace with Definition location found earlier + $policySetDefinitionPath = "./$($policySetDefinitionName).json" + Invoke-WebRequest -Uri https://raw.githubusercontent.com/Azure/Enterprise-Scale/main/src/resources/Microsoft.Authorization/policySetDefinitions/$($policySetDefinitionName).json -OutFile $policySetDefinitionPath + $policySetDef = Get-Content $policySetDefinitionPath | ConvertFrom-Json -Depth 100 + + # Update all ALZ custom policy definitions first + if ($updateCustomALZPolicies) { + foreach ($policyDefId in $policySetDef.properties.policyDefinitions.policyDefinitionId) { + if ($policyDefId -match '(\/\w+\/\w+\.\w+\/\w+\/)(\w+)(\/.+)') { + $policyDefinitionName = $policyDefId.substring($policyDefId.lastindexof('/') + 1) + $policyDefinitionPath = "./$($policyDefinitionName).json" + Invoke-WebRequest -Uri "https://raw.githubusercontent.com/Azure/Enterprise-Scale/main/src/resources/Microsoft.Authorization/policyDefinitions/$($policyDefinitionName).json" -OutFile $policyDefinitionPath + $policyDef = Get-Content $policyDefinitionPath | ConvertFrom-Json -Depth 100 + $policyName = $policyDef.name + $displayName = $policyDef.properties.displayName + $description = $policyDef.properties.description + $mode = $policyDef.properties.mode + $metadata = $policyDef.properties.metadata | ConvertTo-Json -Depth 100 + $parameters = $policyDef.properties.parameters | ConvertTo-Json -Depth 100 + $policyRule = $policyDef.properties.policyRule | ConvertTo-Json -Depth 100 + $policyRule = $policyRule.Replace('[[', '[') + New-AzPolicyDefinition -Name $policyName -DisplayName $displayname -Description $description -Policy $policyRule -Mode $mode -Metadata $metadata -Parameter $parameters -ManagementGroupName $policySetDefinitionLocation + } + } + } + # End of updating all ALZ custom policy definitions + + $policyName = $policySetDef.name + $displayName = $policySetDef.properties.displayName + $description = $policySetDef.properties.description + $metadata = $policySetDef.properties.metadata | ConvertTo-Json -Depth 100 + $parameters = $policySetDef.properties.parameters | ConvertTo-Json -Depth 100 + $policyDefinitions = ConvertTo-Json -InputObject @($policySetDef.properties.policyDefinitions) -Depth 100 + $policyDefinitions = $policyDefinitions.Replace('[[', '[') + $policyDefinitions = $policyDefinitions -replace '(\/\w+\/\w+\.\w+\/\w+\/)(\w+)(\/.+)', "`${1}$policySetDefinitionLocation`${3}" + New-AzPolicySetDefinition -Name $policyName -DisplayName $displayname -Description $description -PolicyDefinition $policyDefinitions -Metadata $metadata -Parameter $parameters -ManagementGroupName $policySetDefinitionLocation + ``` + +{{< hint type=note >}} +Note that if you decide on another approach from the script above, there are a number of double square brackets ('[[') in the file. These need to be replaced with single square brackets before the policy set definition is valid syntax. +{{< /hint >}} + +- After running the above script go to the Definitions pane, and search for the initiative definition. Note that the initiative may take a while to show in the portal + + ![alz-custom-initiative-def-search](img/alz-update-initiative-with-builtin-01.png) + +- When the initiative materializes, click the ellipsis and choose Assign +- Set relevant parameters for the initiative, then assign the policy to the scopes previously determined diff --git a/docs/layouts/shortcodes/csv-table.html b/docs/layouts/shortcodes/csv-table.html new file mode 100644 index 00000000..21270a7c --- /dev/null +++ b/docs/layouts/shortcodes/csv-table.html @@ -0,0 +1,29 @@ +{{ $file := .Get "file" }} +{{ $data := slice }} +{{ with or ($.Page.Resources.Get $file) (resources.Get $file) }} + {{ $csv := .Content }} + {{ $data = $csv | transform.Unmarshal }} +{{ end }} + +{{ with $data }} + + + + {{ range index . 0 }} + + {{ end }} + + + + {{ range after 1 . }} + + {{ range . }} + + {{ end }} + + {{ end }} + +
{{ . }}
{{ . }}
+{{ else }} +

No data found for file: {{ $file }}

+{{ end }} diff --git a/docs/static/css/dark-code.css b/docs/static/css/dark-code.css new file mode 100644 index 00000000..8a5d8730 --- /dev/null +++ b/docs/static/css/dark-code.css @@ -0,0 +1,55 @@ +/* Dark theme for code blocks */ +.dark-code-page pre, +.dark-code-page code { + background-color: #1e1e1e !important; + color: #d4d4d4 !important; +} + +.dark-code-page .chroma { + background-color: #1e1e1e !important; +} + +.dark-code-page .chroma .err { color: #f48771; } /* Error */ +.dark-code-page .chroma .k { color: #569cd6; } /* Keyword */ +.dark-code-page .chroma .l { color: #ce9178; } /* Literal */ +.dark-code-page .chroma .n { color: #d4d4d4; } /* Name */ +.dark-code-page .chroma .o { color: #d4d4d4; } /* Operator */ +.dark-code-page .chroma .p { color: #d4d4d4; } /* Punctuation */ +.dark-code-page .chroma .ch { color: #6a9955; } /* Comment.Hashbang */ +.dark-code-page .chroma .cm { color: #6a9955; } /* Comment.Multiline */ +.dark-code-page .chroma .c1 { color: #6a9955; } /* Comment.Single */ +.dark-code-page .chroma .cs { color: #6a9955; } /* Comment.Special */ +.dark-code-page .chroma .kc { color: #569cd6; } /* Keyword.Constant */ +.dark-code-page .chroma .kd { color: #569cd6; } /* Keyword.Declaration */ +.dark-code-page .chroma .kn { color: #c586c0; } /* Keyword.Namespace */ +.dark-code-page .chroma .kp { color: #569cd6; } /* Keyword.Pseudo */ +.dark-code-page .chroma .kr { color: #569cd6; } /* Keyword.Reserved */ +.dark-code-page .chroma .kt { color: #4ec9b0; } /* Keyword.Type */ +.dark-code-page .chroma .ld { color: #ce9178; } /* Literal.Date */ +.dark-code-page .chroma .m { color: #b5cea8; } /* Literal.Number */ +.dark-code-page .chroma .s { color: #ce9178; } /* Literal.String */ +.dark-code-page .chroma .na { color: #9cdcfe; } /* Name.Attribute */ +.dark-code-page .chroma .nb { color: #dcdcaa; } /* Name.Builtin */ +.dark-code-page .chroma .nc { color: #4ec9b0; } /* Name.Class */ +.dark-code-page .chroma .no { color: #569cd6; } /* Name.Constant */ +.dark-code-page .chroma .nd { color: #dcdcaa; } /* Name.Decorator */ +.dark-code-page .chroma .ni { color: #d4d4d4; } /* Name.Entity */ +.dark-code-page .chroma .ne { color: #4ec9b0; } /* Name.Exception */ +.dark-code-page .chroma .nf { color: #dcdcaa; } /* Name.Function */ +.dark-code-page .chroma .nl { color: #d4d4d4; } /* Name.Label */ +.dark-code-page .chroma .nn { color: #4ec9b0; } /* Name.Namespace */ +.dark-code-page .chroma .nt { color: #569cd6; } /* Name.Tag */ +.dark-code-page .chroma .nv { color: #9cdcfe; } /* Name.Variable */ +.dark-code-page .chroma .s2 { color: #ce9178; } /* Literal.String.Double */ +.dark-code-page .chroma .sc { color: #ce9178; } /* Literal.String.Char */ +.dark-code-page .chroma .sd { color: #6a9955; } /* Literal.String.Doc */ +.dark-code-page .chroma .se { color: #d7ba7d; } /* Literal.String.Escape */ +.dark-code-page .chroma .si { color: #ce9178; } /* Literal.String.Interpol */ +.dark-code-page .chroma .sx { color: #ce9178; } /* Literal.String.Other */ +.dark-code-page .chroma .sr { color: #d16969; } /* Literal.String.Regex */ +.dark-code-page .chroma .s1 { color: #ce9178; } /* Literal.String.Single */ +.dark-code-page .chroma .mb { color: #b5cea8; } /* Literal.Number.Bin */ +.dark-code-page .chroma .mf { color: #b5cea8; } /* Literal.Number.Float */ +.dark-code-page .chroma .mh { color: #b5cea8; } /* Literal.Number.Hex */ +.dark-code-page .chroma .mi { color: #b5cea8; } /* Literal.Number.Integer */ +.dark-code-page .chroma .mo { color: #b5cea8; } /* Literal.Number.Oct */