From 011065c6938ed96fc1f228ab0b28dd5358f70a6f Mon Sep 17 00:00:00 2001 From: erjosito Date: Fri, 15 Dec 2023 08:52:37 +0000 Subject: [PATCH] [create-pull-request] automated change --- checklists/aro_checklist.en.json | 4 +- checklists/aro_checklist.es.json | 116 +- checklists/aro_checklist.ja.json | 140 +- checklists/aro_checklist.ko.json | 92 +- checklists/aro_checklist.pt.json | 38 +- checklists/aro_checklist.zh-Hant.json | 543 + checklists/checklist.en.master.json | 30910 ++++++++-------- spreadsheet/macrofree/aro_checklist.en.xlsx | Bin 25221 -> 24997 bytes spreadsheet/macrofree/aro_checklist.es.xlsx | Bin 25786 -> 25605 bytes spreadsheet/macrofree/aro_checklist.ja.xlsx | Bin 26982 -> 26793 bytes spreadsheet/macrofree/aro_checklist.ko.xlsx | Bin 26511 -> 26340 bytes spreadsheet/macrofree/aro_checklist.pt.xlsx | Bin 25842 -> 25631 bytes .../macrofree/aro_checklist.zh-Hant.xlsx | Bin 0 -> 26135 bytes .../macrofree/checklist.en.master.xlsx | Bin 297071 -> 297205 bytes .../alz_checklist.en_network_counters.json | 488 +- ...hecklist.en_network_counters_template.json | 2 +- .../alz_checklist.en_network_tabcounters.json | 1464 +- ...klist.en_network_tabcounters_template.json | 2 +- .../alz_checklist.en_network_workbook.json | 314 +- ...hecklist.en_network_workbook_template.json | 2 +- 20 files changed, 17317 insertions(+), 16798 deletions(-) create mode 100644 checklists/aro_checklist.zh-Hant.json create mode 100644 spreadsheet/macrofree/aro_checklist.zh-Hant.xlsx diff --git a/checklists/aro_checklist.en.json b/checklists/aro_checklist.en.json index b0bb2d739..bf398e6dd 100644 --- a/checklists/aro_checklist.en.json +++ b/checklists/aro_checklist.en.json @@ -538,6 +538,6 @@ "metadata": { "name": "Use the 'Import latest checklist' button to get the latest version of a review checklist", "state": " ", - "timestamp": "September 19, 2023" + "timestamp": "December 15, 2023" } -} +} \ No newline at end of file diff --git a/checklists/aro_checklist.es.json b/checklists/aro_checklist.es.json index 1c9b8b31c..010ab526c 100644 --- a/checklists/aro_checklist.es.json +++ b/checklists/aro_checklist.es.json @@ -10,7 +10,7 @@ "name": "Gestión de operaciones" }, { - "name": "Automatización de plataformas" + "name": "Automatización de la plataforma" }, { "name": "Seguridad" @@ -34,33 +34,42 @@ "link": "https://learn.microsoft.com/azure/openshift/configure-azure-ad-ui", "severity": "Alto", "subcategory": "Identidad", - "text": "Use AAD para autenticar usuarios en su clúster de ARO.", + "text": "Use AAD para autenticar a los usuarios del clúster de ARO.", "waf": "Seguridad" }, { "category": "Gestión de identidades y accesos", - "guid": "483835c9-86bb-4291-8155-a11475e39f54", + "guid": "adfec5f9-a82d-46e9-a8d1-5a0c7fed5d15", "id": "A01.03", + "link": "https://docs.openshift.com/container-platform/4.14/authentication/remove-kubeadmin.html", + "subcategory": "Identidad", + "text": "Al usar la autenticación de AAD, quite el usuario kubeadmin del clúster.", + "waf": "Seguridad" + }, + { + "category": "Gestión de identidades y accesos", + "guid": "483835c9-86bb-4291-8155-a11475e39f54", + "id": "A01.04", "link": "https://docs.openshift.com/container-platform/4.13/applications/projects/working-with-projects.html", "severity": "Alto", "subcategory": "Identidad", - "text": "Defina proyectos de OpenShift para restringir los privilegios RBAC y aislar las cargas de trabajo en el clúster.", + "text": "Defina proyectos de OpenShift para restringir los privilegios de RBAC y aislar las cargas de trabajo en el clúster.", "waf": "Seguridad" }, { "category": "Gestión de identidades y accesos", "guid": "0acccd97-9376-4bcd-a375-0ab2ab039da6", - "id": "A01.04", + "id": "A01.05", "link": "https://docs.openshift.com/container-platform/4.13/authentication/using-rbac.html", "severity": "Medio", "subcategory": "Identidad", - "text": "Definir los roles RBAC requeridos en OpenShift se limitan a un proyecto o a un clúster.", + "text": "Definir los roles RBAC necesarios en OpenShift se limitan a un proyecto o a un clúster.", "waf": "Seguridad" }, { "category": "Gestión de identidades y accesos", "guid": "d54d7c89-29db-4107-b532-5ae625ca44e4", - "id": "A01.05", + "id": "A01.06", "link": "https://learn.microsoft.com/azure/cost-management-billing/manage/direct-ea-administration#manage-notification-contacts", "severity": "Medio", "subcategory": "Identidad", @@ -70,11 +79,11 @@ { "category": "Gestión de identidades y accesos", "guid": "685e2223-ace8-4bb1-8307-ca5f16f154e3", - "id": "A01.06", + "id": "A01.07", "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-configure", "severity": "Medio", "subcategory": "Identidad", - "text": "Use la administración de identidades con privilegios en AAD para usuarios de ARO con roles privilegiados.", + "text": "Use Privileged Identity Management en AAD para usuarios de ARO con roles privilegiados.", "waf": "Seguridad" }, { @@ -94,7 +103,7 @@ "link": "https://docs.openshift.com/container-platform/4.13/networking/routes/secured-routes.html", "severity": "Alto", "subcategory": "Encriptación", - "text": "Todas las aplicaciones web que configure para usar una entrada deben usar cifrado TLS y no deben permitir el acceso a través de HTTP sin cifrar.", + "text": "Todas las aplicaciones web que configure para usar una entrada deben usar el cifrado TLS y no deben permitir el acceso a través de HTTP sin cifrar.", "waf": "Seguridad" }, { @@ -114,7 +123,7 @@ "link": "https://learn.microsoft.com/azure/openshift/howto-secure-openshift-with-front-door", "severity": "Medio", "subcategory": "Internet", - "text": "Si expone una aplicación en ARO con Azure Front Door, use un vínculo privado para conectar Front Door con el enrutador ARO.", + "text": "Si expone una aplicación en ARO con Azure Front Door, use Private Link para conectar Front Door con el enrutador de ARO.", "waf": "Seguridad" }, { @@ -124,7 +133,7 @@ "link": "https://learn.microsoft.com/azure/openshift/howto-restrict-egress", "severity": "Medio", "subcategory": "Internet", - "text": "Si su directiva de seguridad requiere que inspeccione todo el tráfico saliente de Internet generado en el clúster de ARO, proteja el tráfico de red de salida mediante Azure Firewall o un NVA.", + "text": "Si la directiva de seguridad requiere que inspeccione todo el tráfico saliente de Internet que se genera en el clúster de ARO, proteja el tráfico de red de salida mediante Azure Firewall o una aplicación virtual de red.", "waf": "Seguridad" }, { @@ -134,7 +143,7 @@ "link": "https://learn.microsoft.com/azure/openshift/howto-create-private-cluster-4x", "severity": "Alto", "subcategory": "Acceso privado", - "text": "Si su política de seguridad requiere que utilice una dirección IP privada para la API de OpenShift, implemente un clúster ARO privado.", + "text": "Si la política de seguridad requiere que utilice una dirección IP privada para la API de OpenShift, implemente un clúster de ARO privado.", "waf": "Seguridad" }, { @@ -144,7 +153,7 @@ "link": "https://learn.microsoft.com/azure/container-registry/container-registry-private-link", "severity": "Medio", "subcategory": "Acceso privado", - "text": "Use Azure Private Link para proteger las conexiones de red a los servicios administrados de Azure, incluido Azure Container Registry.", + "text": "Use Azure Private Link para proteger las conexiones de red a los servicios administrados de Azure, incluida Azure Container Registry.", "waf": "Seguridad" }, { @@ -154,8 +163,7 @@ "link": "https://learn.microsoft.com/azure/azure-monitor/containers/container-insights-enable-arc-enabled-clusters", "severity": "Alto", "subcategory": "Operaciones", - "text": "Establezca un proceso de supervisión utilizando la integración incorporada de Prometheus, OpenShift Logging o Container Insights.", - "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", + "text": "Establezca un proceso de supervisión mediante la integración incorporada de Prometheus, OpenShift Logging o Container Insights.", "waf": "Operaciones" }, { @@ -165,19 +173,17 @@ "link": "https://docs.openshift.com/container-platform/4.13/cicd/pipelines/understanding-openshift-pipelines.html", "severity": "Medio", "subcategory": "Operaciones", - "text": "Automatice el proceso de entrega de aplicaciones a través de prácticas de DevOps y soluciones de CI/CD, como Pipelines/GitOps proporcionados por OpenShift.", - "training": "https://learn.microsoft.com/learn/modules/plan-implement-administer-conditional-access/", + "text": "Automatice el proceso de entrega de aplicaciones a través de prácticas de DevOps y soluciones de CI/CD, como Pipelines/GitOps proporcionado por OpenShift.", "waf": "Operaciones" }, { "category": "Gestión de operaciones", "guid": "467a1f89-35bd-4a43-924f-14811533182a", "id": "C01.03", - "link": "https://learn.microsoft.com/azure/active-directory-domain-services/overview", + "link": "https://learn.microsoft.com/azure/architecture/guide/design-principles/managed-services", "severity": "Bajo", "subcategory": "Operaciones", - "text": "Siempre que sea posible, elimine el estado del servicio del interior de los contenedores. En su lugar, use una plataforma como servicio (PaaS) de Azure que admita la replicación multiregión.", - "training": "https://learn.microsoft.com/learn/modules/azure-active-directory/", + "text": "Siempre que sea posible, quite el estado de servicio del interior de los contenedores. En su lugar, use una plataforma como servicio (PaaS) de Azure que admita la replicación en varias regiones.", "waf": "Operaciones" }, { @@ -187,8 +193,7 @@ "link": "https://learn.microsoft.com/azure/openshift/howto-create-a-storageclass", "severity": "Bajo", "subcategory": "Operaciones", - "text": "Use el almacenamiento RWX con la clase de almacenamiento integrada de Azure Files.", - "training": "https://learn.microsoft.com/learn/modules/design-identity-security-strategy/", + "text": "Use el almacenamiento RWX con la clase de almacenamiento Azure Files incorporada.", "waf": "Operaciones" }, { @@ -198,8 +203,7 @@ "link": "https://docs.openshift.com/container-platform/4.13/nodes/clusters/nodes-cluster-limit-ranges.html", "severity": "Medio", "subcategory": "Rendimiento", - "text": "Use solicitudes y límites de pod para administrar los recursos informáticos dentro de un clúster.", - "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/", + "text": "Utilice las solicitudes y los límites de pod para administrar los recursos informáticos dentro de un clúster.", "waf": "Rendimiento" }, { @@ -220,7 +224,6 @@ "severity": "Alto", "subcategory": "Rendimiento", "text": "Defina ClusterAutoScaler y MachineAutoScaler para escalar máquinas cuando el clúster se quede sin recursos para admitir más implementaciones.", - "training": "https://learn.microsoft.com/learn/modules/secure-aad-users-with-mfa/", "waf": "Rendimiento" }, { @@ -231,7 +234,6 @@ "severity": "Alto", "subcategory": "Fiabilidad", "text": "Use tamaños de máquina virtual que sean lo suficientemente grandes como para contener varias instancias de contenedor para obtener los beneficios de una mayor densidad, pero no tan grandes como para que el clúster no pueda manejar la carga de trabajo de un nodo con errores.", - "training": "https://learn.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview", "waf": "Fiabilidad" }, { @@ -241,8 +243,7 @@ "link": "https://docs.openshift.com/container-platform/4.13/machine_management/deploying-machine-health-checks.html", "severity": "Alto", "subcategory": "Fiabilidad", - "text": "Implemente comprobaciones de estado de la máquina para reparar automáticamente las máquinas dañadas en un grupo de máquinas.", - "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-identities-governance/", + "text": "Implemente comprobaciones de estado de máquinas para reparar automáticamente las máquinas dañadas en un grupo de máquinas.", "waf": "Fiabilidad" }, { @@ -252,8 +253,7 @@ "link": "https://learn.microsoft.com/azure/azure-monitor/containers/container-insights-metric-alerts", "severity": "Alto", "subcategory": "Fiabilidad", - "text": "Use un sistema de alertas para proporcionar notificaciones cuando las cosas necesiten una acción directa: alertas de métricas de Container Insights o interfaz de usuario de alertas integrada.", - "training": "https://learn.microsoft.com/learn/modules/explore-basic-services-identity-types/", + "text": "Utilice un sistema de alertas para proporcionar notificaciones cuando las cosas requieran una acción directa: alertas de métricas de Container Insights o interfaz de usuario de alertas integrada.", "waf": "Fiabilidad" }, { @@ -264,7 +264,6 @@ "severity": "Alto", "subcategory": "Fiabilidad", "text": "Asegúrese de que el clúster se crea en una región que admita zonas de disponibilidad y cree un conjunto de máquinas para cada zona de disponibilidad.", - "training": "https://learn.microsoft.com/learn/paths/manage-identity-and-access/", "waf": "Fiabilidad" }, { @@ -274,8 +273,7 @@ "link": "https://docs.openshift.com/container-platform/4.13/machine_management/creating-infrastructure-machinesets.html", "severity": "Bajo", "subcategory": "Fiabilidad", - "text": "Cree conjuntos de máquinas de infraestructura para contener componentes de infraestructura. Aplique etiquetas específicas de Kubernetes a estas máquinas y, a continuación, actualice los componentes de infraestructura para que se ejecuten solo en esas máquinas.", - "training": "https://learn.microsoft.com/learn/paths/secure-your-cloud-data/", + "text": "Cree conjuntos de máquinas de infraestructura para contener componentes de infraestructura. Aplique etiquetas específicas de Kubernetes a estas máquinas y, a continuación, actualice los componentes de la infraestructura para que se ejecuten solo en esas máquinas.", "waf": "Fiabilidad" }, { @@ -286,7 +284,6 @@ "severity": "Medio", "subcategory": "Fiabilidad", "text": "Cree una copia de seguridad de la aplicación y planifique la restauración e incluya volúmenes persistentes en la copia de seguridad.", - "training": "https://learn.microsoft.com/azure/architecture/example-scenario/identity/adds-extend-domain", "waf": "Fiabilidad" }, { @@ -296,7 +293,7 @@ "link": "https://docs.openshift.com/container-platform/4.13/nodes/pods/nodes-pods-priority.html", "severity": "Bajo", "subcategory": "Fiabilidad", - "text": "Use prioridades de pods, de modo que en caso de recursos limitados se ejecuten los pods más críticos.", + "text": "Utilice las prioridades de los pods, de modo que, en caso de recursos limitados, se ejecuten los pods más críticos.", "waf": "Fiabilidad" }, { @@ -306,7 +303,7 @@ "link": "https://docs.openshift.com/container-platform/4.13/architecture/admission-plug-ins.html", "severity": "Bajo", "subcategory": "Seguridad", - "text": "Regule las funciones del clúster mediante complementos de admisión, que se utilizan habitualmente para aplicar directivas de seguridad, limitaciones de recursos o requisitos de configuración.", + "text": "Regule las funciones de clúster mediante complementos de admisión, que se utilizan normalmente para aplicar la política de seguridad, las limitaciones de recursos o los requisitos de configuración.", "waf": "Seguridad" }, { @@ -316,7 +313,7 @@ "link": "https://learn.microsoft.com/azure/container-registry/container-registry-geo-replication", "severity": "Bajo", "subcategory": "Seguridad", - "text": "Almacene las imágenes de contenedor en Azure Container Registry y replique geográficamente el Registro en cada región.", + "text": "Almacene las imágenes de contenedor en Azure Container Registry y realice una replicación geográfica del registro en cada región.", "waf": "Seguridad" }, { @@ -326,7 +323,7 @@ "link": "https://docs.openshift.com/container-platform/4.13/nodes/pods/nodes-pods-vertical-autoscaler.html", "severity": "Medio", "subcategory": "Carga de trabajo", - "text": "Optimice los valores de solicitud de CPU y memoria, y maximice la eficiencia de los recursos del clúster mediante el escalador automático de pods verticales.", + "text": "Optimice los valores de solicitud de CPU y memoria, y maximice la eficiencia de los recursos del clúster mediante el escalador automático vertical de pods.", "waf": "Rendimiento" }, { @@ -336,7 +333,7 @@ "link": "https://docs.openshift.com/container-platform/4.13/applications/application-health.html", "severity": "Medio", "subcategory": "Carga de trabajo", - "text": "Agregue sondeos de estado a los pods para supervisar el estado de la aplicación. Asegúrese de que los pods contengan livenessProbe y readinessProbe. Utilice sondeos de inicio para determinar el punto en el que se ha iniciado la aplicación.", + "text": "Agregue sondeos de estado a los pods para supervisar el estado de la aplicación. Asegúrese de que los pods contengan livenessProbe y readinessProbe. Utilice Sondeos de inicio para determinar el punto en el que se ha iniciado la aplicación.", "waf": "Fiabilidad" }, { @@ -346,8 +343,7 @@ "link": "https://docs.openshift.com/container-platform/4.13/nodes/pods/nodes-pods-autoscaling.html", "severity": "Medio", "subcategory": "Carga de trabajo", - "text": "Escale pods para satisfacer la demanda utilizando el escalador automático de pods horizontales.", - "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/", + "text": "Escale los pods para satisfacer la demanda mediante el escalador automático de pods horizontal.", "waf": "Fiabilidad" }, { @@ -357,8 +353,7 @@ "link": "https://docs.openshift.com/container-platform/4.13/nodes/pods/nodes-pods-configuring.html#nodes-pods-pod-distruption-about_nodes-pods-configuring", "severity": "Medio", "subcategory": "Carga de trabajo", - "text": "Utilice presupuestos de interrupción para asegurarse de que existe el número necesario de réplicas de pods para manejar la carga esperada de las aplicaciones.", - "training": "https://learn.microsoft.com/learn/paths/implement-windows-server-iaas-virtual-machine-identity/", + "text": "Utilice presupuestos de interrupción para asegurarse de que existe el número necesario de réplicas de pods para controlar la carga esperada de aplicaciones.", "waf": "Fiabilidad" }, { @@ -368,28 +363,27 @@ "link": "https://docs.openshift.com/container-platform/4.13/nodes/scheduling/nodes-scheduler-pod-topology-spread-constraints.html", "severity": "Medio", "subcategory": "Carga de trabajo", - "text": "Utilice restricciones de topología de pod para programar automáticamente pods en los nodos de todo el clúster.", - "training": "https://learn.microsoft.com/learn/paths/implement-applications-external-access-azure-ad/", + "text": "Utilice las restricciones de topología de pods para programar automáticamente pods en los nodos de todo el clúster.", "waf": "Fiabilidad" }, { - "category": "Automatización de plataformas", + "category": "Automatización de la plataforma", "guid": "42324ece-81c1-4231-a1a6-417415833fb4", "id": "D01.01", "link": "https://docs.openshift.com/container-platform/4.13/applications/deployments/route-based-deployment-strategies.html", "severity": "Bajo", "subcategory": "Carga de trabajo", - "text": "Considere estrategias azul/verde o canarias para implementar nuevas versiones de aplicaciones.", + "text": "Considere las estrategias azul/verde o canary para implementar nuevas versiones de la aplicación.", "waf": "Operaciones" }, { - "category": "Automatización de plataformas", + "category": "Automatización de la plataforma", "guid": "ae3c2df7-4316-46c3-acbe-05bbe209d4a0", "id": "D01.02", "link": "https://docs.openshift.com/container-platform/4.13/cicd/gitops/understanding-openshift-gitops.html", "severity": "Bajo", "subcategory": "Carga de trabajo", - "text": "Considere la posibilidad de utilizar Red Hat OpenShift GitOps. Red Hat OpenShift GitOps utiliza Argo CD para mantener los recursos del clúster y admitir CI/CD de aplicaciones.", + "text": "Considere la posibilidad de utilizar Red Hat OpenShift GitOps. Red Hat OpenShift GitOps utiliza Argo CD para mantener los recursos del clúster y dar soporte a CI/CD de aplicaciones.", "waf": "Operaciones" }, { @@ -399,7 +393,7 @@ "link": "https://learn.microsoft.com/azure/openshift/support-lifecycle", "severity": "Alto", "subcategory": "Plano de control", - "text": "Mantenga sus clústeres en la última versión de OpenShift para evitar posibles problemas de seguridad o actualización.", + "text": "Mantenga los clústeres en la versión más reciente de OpenShift para evitar posibles problemas de seguridad o actualización.", "waf": "Seguridad" }, { @@ -409,7 +403,7 @@ "link": "https://learn.microsoft.com/azure/azure-arc/kubernetes/quickstart-connect-cluster", "severity": "Alto", "subcategory": "Plano de control", - "text": "Conecte clústeres de Red Hat OpenShift de Azure a Kubernetes habilitado para Azure Arc.", + "text": "Conecte clústeres de Red Hat OpenShift en Azure a Kubernetes habilitado para Azure Arc.", "waf": "Seguridad" }, { @@ -419,7 +413,7 @@ "link": "https://docs.openshift.com/container-platform/4.10/security/encrypting-etcd.html", "severity": "Bajo", "subcategory": "Encriptación", - "text": "Para los clústeres de Azure Red Hat OpenShift 4, los datos etcd no se cifran de forma predeterminada, pero se recomienda habilitar el cifrado etcd para proporcionar otra capa de seguridad de datos.", + "text": "En el caso de los clústeres de Red Hat OpenShift 4 en Azure, los datos etcd no se cifran de forma predeterminada, pero se recomienda habilitar el cifrado etcd para proporcionar otra capa de seguridad de datos.", "waf": "Seguridad" }, { @@ -429,7 +423,7 @@ "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-introduction", "severity": "Medio", "subcategory": "Postura", - "text": "Use Microsoft Defender para contenedores compatibles con Kubernetes habilitado para Arc para proteger clústeres, contenedores y aplicaciones.", + "text": "Use Microsoft Defender para contenedores compatible con Kubernetes habilitado para Arc para proteger clústeres, contenedores y aplicaciones.", "waf": "Seguridad" }, { @@ -439,7 +433,7 @@ "link": "https://learn.microsoft.com/azure/azure-arc/kubernetes/tutorial-akv-secrets-provider", "severity": "Medio", "subcategory": "Secretos", - "text": "Para las aplicaciones que requieren acceso a información confidencial, utilice una entidad de servicio y AKV Secrets Provider con la extensión para clústeres de Kubernetes habilitados para Arc.", + "text": "En el caso de las aplicaciones que requieren acceso a información confidencial, use una entidad de servicio y el proveedor de secretos AKV con la extensión para clústeres de Kubernetes habilitados para Arc.", "waf": "Seguridad" }, { @@ -449,7 +443,7 @@ "link": "https://learn.microsoft.com/azure/aks/developer-best-practices-pod-security#secure-pod-access-to-resources", "severity": "Medio", "subcategory": "Carga de trabajo", - "text": "Acceso seguro de pods a los recursos. Proporcione el menor número de permisos y evite el uso de la raíz o la escalada privilegiada.", + "text": "Proteja el acceso de los pods a los recursos. Proporcione el menor número de permisos y evite el uso de la raíz o la escalación con privilegios.", "waf": "Seguridad" }, { @@ -459,7 +453,7 @@ "link": "https://learn.microsoft.com/azure/governance/policy/concepts/policy-for-kubernetes#install-azure-policy-extension-for-azure-arc-enabled-kubernetes", "severity": "Medio", "subcategory": "Carga de trabajo", - "text": "Supervise y aplique la configuración mediante la extensión de directiva de Azure.", + "text": "Supervise y aplique la configuración mediante la extensión de Azure Policy.", "waf": "Seguridad" }, { @@ -469,7 +463,7 @@ "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-introduction", "severity": "Alto", "subcategory": "Carga de trabajo", - "text": "Escanea tus imágenes en busca de vulnerabilidades con Microsoft Defender o cualquier otra solución de escaneo de imágenes.", + "text": "Examine las imágenes en busca de vulnerabilidades con Microsoft Defender o cualquier otra solución de análisis de imágenes.", "waf": "Seguridad" }, { @@ -486,7 +480,7 @@ "metadata": { "name": "Use the 'Import latest checklist' button to get the latest version of a review checklist", "state": " ", - "timestamp": "September 19, 2023" + "timestamp": "December 15, 2023" }, "severities": [ { @@ -509,12 +503,12 @@ "name": "Abrir" }, { - "description": "Esta comprobación se ha comprobado y no hay más elementos de acción asociados a ella", + "description": "Esta comprobación se ha verificado y no hay más elementos de acción asociados a ella", "name": "Cumplido" }, { "description": "Recomendación entendida, pero no necesaria por los requisitos actuales", - "name": "No es necesario" + "name": "Riesgo aceptado" }, { "description": "No aplicable para el diseño actual", diff --git a/checklists/aro_checklist.ja.json b/checklists/aro_checklist.ja.json index dfea0e391..e2bdb92f1 100644 --- a/checklists/aro_checklist.ja.json +++ b/checklists/aro_checklist.ja.json @@ -1,10 +1,10 @@ { "categories": [ { - "name": "ID およびアクセス管理" + "name": "IDおよびアクセス管理" }, { - "name": "ネットワーク トポロジと接続性" + "name": "ネットワークトポロジと接続性" }, { "name": "運用管理" @@ -18,7 +18,7 @@ ], "items": [ { - "category": "ID およびアクセス管理", + "category": "IDおよびアクセス管理", "guid": "d7e47431-76c8-4bdb-b55b-ce619e8a03f9", "id": "A01.01", "link": "https://learn.microsoft.com/azure/openshift/howto-create-service-principal?pivots=aro-azurecli", @@ -28,39 +28,48 @@ "waf": "安全" }, { - "category": "ID およびアクセス管理", + "category": "IDおよびアクセス管理", "guid": "7879424d-6267-486d-90b9-6c97be985190", "id": "A01.02", "link": "https://learn.microsoft.com/azure/openshift/configure-azure-ad-ui", "severity": "高い", "subcategory": "同一性", - "text": "AAD を使用して、ARO クラスター内のユーザーを認証します。", + "text": "AAD を使用して ARO クラスター内のユーザーを認証します。", "waf": "安全" }, { - "category": "ID およびアクセス管理", - "guid": "483835c9-86bb-4291-8155-a11475e39f54", + "category": "IDおよびアクセス管理", + "guid": "adfec5f9-a82d-46e9-a8d1-5a0c7fed5d15", "id": "A01.03", + "link": "https://docs.openshift.com/container-platform/4.14/authentication/remove-kubeadmin.html", + "subcategory": "同一性", + "text": "AAD 認証を使用する場合は、クラスターから kubeadmin ユーザーを削除します。", + "waf": "安全" + }, + { + "category": "IDおよびアクセス管理", + "guid": "483835c9-86bb-4291-8155-a11475e39f54", + "id": "A01.04", "link": "https://docs.openshift.com/container-platform/4.13/applications/projects/working-with-projects.html", "severity": "高い", "subcategory": "同一性", - "text": "OpenShift プロジェクトを定義して、RBAC 特権を制限し、クラスター内のワークロードを分離します。", + "text": "OpenShift プロジェクトを定義して、RBAC 権限を制限し、クラスター内のワークロードを分離します。", "waf": "安全" }, { - "category": "ID およびアクセス管理", + "category": "IDおよびアクセス管理", "guid": "0acccd97-9376-4bcd-a375-0ab2ab039da6", - "id": "A01.04", + "id": "A01.05", "link": "https://docs.openshift.com/container-platform/4.13/authentication/using-rbac.html", "severity": "中程度", "subcategory": "同一性", - "text": "OpenShift で必要な RBAC ロールをプロジェクトまたはクラスターのいずれかにスコープで定義します。", + "text": "OpenShift で必要な RBAC ロールの定義は、プロジェクトまたはクラスターのいずれかにスコープされます。", "waf": "安全" }, { - "category": "ID およびアクセス管理", + "category": "IDおよびアクセス管理", "guid": "d54d7c89-29db-4107-b532-5ae625ca44e4", - "id": "A01.05", + "id": "A01.06", "link": "https://learn.microsoft.com/azure/cost-management-billing/manage/direct-ea-administration#manage-notification-contacts", "severity": "中程度", "subcategory": "同一性", @@ -68,47 +77,47 @@ "waf": "安全" }, { - "category": "ID およびアクセス管理", + "category": "IDおよびアクセス管理", "guid": "685e2223-ace8-4bb1-8307-ca5f16f154e3", - "id": "A01.06", + "id": "A01.07", "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-configure", "severity": "中程度", "subcategory": "同一性", - "text": "特権ロールを持つ ARO ユーザーに対して、AAD で特権 ID 管理を使用します。", + "text": "特権ロールを持つ ARO ユーザーには、AAD の Privileged Identity Management を使用します。", "waf": "安全" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "aa369282-9e7e-4216-8836-87af467a1f89", "id": "B01.01", "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", "severity": "低い", - "subcategory": "DDoS", - "text": "一元化されたサブスクリプションで Azure Firewall または WAF を使用しない限り、Azure DDoS ネットワーク/IP 保護を使用して、ARO クラスターに使用する仮想ネットワークを保護します", + "subcategory": "DDoS攻撃", + "text": "Azure DDoS Network/IP Protection を使用して、一元化されたサブスクリプションで Azure Firewall または WAF を使用しない限り、ARO クラスターに使用する仮想ネットワークを保護します", "waf": "安全" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "35bda433-24f1-4481-8533-182aa5174269", "id": "B02.01", "link": "https://docs.openshift.com/container-platform/4.13/networking/routes/secured-routes.html", "severity": "高い", "subcategory": "暗号化", - "text": "イングレスを使用するように構成するすべての Web アプリケーションは、TLS 暗号化を使用する必要があり、暗号化されていない HTTP 経由のアクセスを許可しないでください。", + "text": "イングレスを使用するように構成するすべての Web アプリケーションでは、TLS 暗号化を使用する必要があり、暗号化されていない HTTP 経由のアクセスを許可しないでください。", "waf": "安全" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "44008ae7-d7e4-4743-876c-8bdbf55bce61", "id": "B03.01", "link": "https://learn.microsoft.com/azure/frontdoor/front-door-overview", "severity": "中程度", "subcategory": "インターネット", - "text": "Azure Front Door と WAF を使用して、特に複数リージョン環境で ARO アプリケーションをインターネットに安全に発行します。", + "text": "Azure Front Door と WAF を使用して、特にマルチリージョン環境で ARO アプリケーションをインターネットに安全に発行します。", "waf": "安全" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "9e8a03f9-7879-4424-b626-786d60b96c97", "id": "B03.02", "link": "https://learn.microsoft.com/azure/openshift/howto-secure-openshift-with-front-door", @@ -118,33 +127,33 @@ "waf": "安全" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "be985190-4838-435c-a86b-b2912155a114", "id": "B03.03", "link": "https://learn.microsoft.com/azure/openshift/howto-restrict-egress", "severity": "中程度", "subcategory": "インターネット", - "text": "セキュリティ ポリシーで、ARO クラスターで生成されるすべての送信インターネット トラフィックを検査する必要がある場合は、Azure Firewall または NVA を使用してエグレス ネットワーク トラフィックをセキュリティで保護します。", + "text": "セキュリティ ポリシーで、ARO クラスターで生成されたすべての送信インターネット トラフィックを検査する必要がある場合は、Azure Firewall または NVA を使用してエグレス ネットワーク トラフィックをセキュリティで保護します。", "waf": "安全" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "75e39f54-0acc-4cd9-9937-6bcda3750ab2", "id": "B04.01", "link": "https://learn.microsoft.com/azure/openshift/howto-create-private-cluster-4x", "severity": "高い", "subcategory": "プライベートアクセス", - "text": "セキュリティポリシーで OpenShift API にプライベート IP アドレスを使用する必要がある場合は、プライベート ARO クラスターをデプロイします。", + "text": "セキュリティーポリシーで OpenShift API にプライベート IP アドレスを使用する必要がある場合は、プライベート ARO クラスターをデプロイします。", "waf": "安全" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "ab039da6-d54d-47c8-a29d-b107d5325ae6", "id": "B04.02", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-private-link", "severity": "中程度", "subcategory": "プライベートアクセス", - "text": "Azure プライベート リンクを使用して、マネージド Azure サービス (Azure コンテナー レジストリを含む) へのネットワーク接続をセキュリティで保護します。", + "text": "Azure Private Link を使用して、Azure Container Registry など、マネージド Azure サービスへのネットワーク接続をセキュリティで保護します。", "waf": "安全" }, { @@ -154,8 +163,7 @@ "link": "https://learn.microsoft.com/azure/azure-monitor/containers/container-insights-enable-arc-enabled-clusters", "severity": "高い", "subcategory": "オペレーションズ", - "text": "組み込みのPrometheus、OpenShiftロギング、またはコンテナインサイトの統合を使用して監視プロセスを確立します。", - "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", + "text": "組み込みの Prometheus、OpenShift Logging、または Container Insights 統合を使用して監視プロセスを確立します。", "waf": "オペレーションズ" }, { @@ -165,19 +173,17 @@ "link": "https://docs.openshift.com/container-platform/4.13/cicd/pipelines/understanding-openshift-pipelines.html", "severity": "中程度", "subcategory": "オペレーションズ", - "text": "DevOps プラクティスと CI/CD ソリューション (OpenShift によって提供されるパイプライン/GitOps など) を通じて、アプリケーション デリバリ プロセスを自動化します。", - "training": "https://learn.microsoft.com/learn/modules/plan-implement-administer-conditional-access/", + "text": "DevOps プラクティスと CI/CD ソリューション (OpenShift が提供する Pipelines/GitOps など) を通じて、アプリケーション配信プロセスを自動化します。", "waf": "オペレーションズ" }, { "category": "運用管理", "guid": "467a1f89-35bd-4a43-924f-14811533182a", "id": "C01.03", - "link": "https://learn.microsoft.com/azure/active-directory-domain-services/overview", + "link": "https://learn.microsoft.com/azure/architecture/guide/design-principles/managed-services", "severity": "低い", "subcategory": "オペレーションズ", - "text": "可能な限り、コンテナー内からサービスの状態を削除します。代わりに、マルチリージョン レプリケーションをサポートするサービスとしての Azure プラットフォーム (PaaS) を使用します。", - "training": "https://learn.microsoft.com/learn/modules/azure-active-directory/", + "text": "可能な限り、コンテナー内からサービス状態を削除します。代わりに、複数リージョンのレプリケーションをサポートする Azure のサービスとしてのプラットフォーム (PaaS) を使用します。", "waf": "オペレーションズ" }, { @@ -187,8 +193,7 @@ "link": "https://learn.microsoft.com/azure/openshift/howto-create-a-storageclass", "severity": "低い", "subcategory": "オペレーションズ", - "text": "組み込みの Azure ファイル ストレージ クラスで RWX ストレージを使用します。", - "training": "https://learn.microsoft.com/learn/modules/design-identity-security-strategy/", + "text": "組み込みの Azure Files ストレージ クラスで RWX ストレージを使用します。", "waf": "オペレーションズ" }, { @@ -199,7 +204,6 @@ "severity": "中程度", "subcategory": "パフォーマンス", "text": "ポッドの要求と制限を使用して、クラスター内のコンピューティング リソースを管理します。", - "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/", "waf": "パフォーマンス" }, { @@ -209,7 +213,7 @@ "link": "https://docs.openshift.com/container-platform/4.13/applications/quotas/quotas-setting-per-project.html", "severity": "中程度", "subcategory": "パフォーマンス", - "text": "プロジェクトにリソース クォータを適用します。", + "text": "プロジェクトにリソースクォータを適用します。", "waf": "パフォーマンス" }, { @@ -219,8 +223,7 @@ "link": "https://docs.openshift.com/container-platform/4.13/machine_management/applying-autoscaling.html", "severity": "高い", "subcategory": "パフォーマンス", - "text": "クラスター自動スケーラーとマシン自動スケーラーを定義して、クラスターのリソースが不足したときにマシンをスケーリングし、より多くのデプロイをサポートします。", - "training": "https://learn.microsoft.com/learn/modules/secure-aad-users-with-mfa/", + "text": "ClusterAutoScaler と MachineAutoScaler を定義して、クラスターのリソースが不足したときにマシンをスケーリングし、より多くのデプロイをサポートします。", "waf": "パフォーマンス" }, { @@ -230,8 +233,7 @@ "link": "https://learn.microsoft.com/azure/openshift/support-policies-v4#supported-virtual-machine-sizes", "severity": "高い", "subcategory": "確実", - "text": "複数のコンテナインスタンスを含むのに十分な大きさの仮想マシンサイズを使用して、密度を高めるというメリットを享受しますが、クラスターが障害が発生したノードのワークロードを処理できないほど大きくしないでください。", - "training": "https://learn.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview", + "text": "複数のコンテナー インスタンスを格納するのに十分な大きさの仮想マシン サイズを使用して、密度を高めるというメリットを享受できますが、クラスターが障害が発生したノードのワークロードを処理できないほど大きくはありません。", "waf": "確実" }, { @@ -242,7 +244,6 @@ "severity": "高い", "subcategory": "確実", "text": "マシンの正常性チェックを展開して、マシン プール内の損傷したマシンを自動的に修復します。", - "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-identities-governance/", "waf": "確実" }, { @@ -252,8 +253,7 @@ "link": "https://learn.microsoft.com/azure/azure-monitor/containers/container-insights-metric-alerts", "severity": "高い", "subcategory": "確実", - "text": "アラート システムを使用して、直接的なアクションが必要な場合に通知を提供します (コンテナー インサイト メトリック アラートまたは組み込みのアラート UI)。", - "training": "https://learn.microsoft.com/learn/modules/explore-basic-services-identity-types/", + "text": "アラート システムを使用して、直接的なアクションが必要なときに通知を提供します (Container Insights メトリック アラートまたは組み込みのアラート UI)。", "waf": "確実" }, { @@ -264,7 +264,6 @@ "severity": "高い", "subcategory": "確実", "text": "クラスターが AZ をサポートするリージョンに作成されていることを確認し、AZ ごとにマシンセットを作成します。", - "training": "https://learn.microsoft.com/learn/paths/manage-identity-and-access/", "waf": "確実" }, { @@ -274,8 +273,7 @@ "link": "https://docs.openshift.com/container-platform/4.13/machine_management/creating-infrastructure-machinesets.html", "severity": "低い", "subcategory": "確実", - "text": "インフラストラクチャコンポーネントを保持するインフラストラクチャマシンセットを作成します。これらのマシンに特定の Kubernetes ラベルを適用し、それらのマシンでのみ実行されるようにインフラストラクチャ コンポーネントを更新します。", - "training": "https://learn.microsoft.com/learn/paths/secure-your-cloud-data/", + "text": "インフラストラクチャ コンポーネントを保持するインフラストラクチャ マシン セットを作成します。これらのマシンに特定の Kubernetes ラベルを適用し、それらのマシンでのみ実行するようにインフラストラクチャ コンポーネントを更新します。", "waf": "確実" }, { @@ -286,7 +284,6 @@ "severity": "中程度", "subcategory": "確実", "text": "アプリケーションのバックアップを作成し、復元を計画し、バックアップに永続ボリュームを含めます。", - "training": "https://learn.microsoft.com/azure/architecture/example-scenario/identity/adds-extend-domain", "waf": "確実" }, { @@ -306,7 +303,7 @@ "link": "https://docs.openshift.com/container-platform/4.13/architecture/admission-plug-ins.html", "severity": "低い", "subcategory": "安全", - "text": "セキュリティー・ポリシー、リソース制限、または構成要件を適用するために一般的に使用されるアドミッション・プラグインを使用して、クラスター機能を規制します。", + "text": "セキュリティポリシー、リソース制限、または構成要件を適用するために一般的に使用されるアドミッションプラグインを使用して、クラスタ機能を規制します。", "waf": "安全" }, { @@ -316,7 +313,7 @@ "link": "https://learn.microsoft.com/azure/container-registry/container-registry-geo-replication", "severity": "低い", "subcategory": "安全", - "text": "コンテナー イメージを Azure コンテナー レジストリに格納し、レジストリを各リージョンに geo レプリケートします。", + "text": "コンテナー イメージを Azure Container Registry に格納し、レジストリを各リージョンに geo レプリケートします。", "waf": "安全" }, { @@ -336,7 +333,7 @@ "link": "https://docs.openshift.com/container-platform/4.13/applications/application-health.html", "severity": "中程度", "subcategory": "ワークロード", - "text": "正常性プローブをポッドに追加して、アプリケーションの正常性を監視します。ポッドに活性プローブと準備プローブが含まれていることを確認してください。スタートアップ プローブを使用して、アプリケーションが起動した時点を判別します。", + "text": "正常性プローブをポッドに追加して、アプリケーションの正常性を監視します。ポッドに livenessProbe と readinessProbe が含まれていることを確認します。スタートアッププローブを使用して、アプリケーションが起動したポイントを判別します。", "waf": "確実" }, { @@ -347,7 +344,6 @@ "severity": "中程度", "subcategory": "ワークロード", "text": "ポッドの水平オートスケーラーを使用して、需要に合わせてポッドをスケーリングします。", - "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/", "waf": "確実" }, { @@ -357,8 +353,7 @@ "link": "https://docs.openshift.com/container-platform/4.13/nodes/pods/nodes-pods-configuring.html#nodes-pods-pod-distruption-about_nodes-pods-configuring", "severity": "中程度", "subcategory": "ワークロード", - "text": "中断バジェットを使用して、予想されるアプリケーションの負荷を処理するために必要な数のポッド レプリカが存在することを確認します。", - "training": "https://learn.microsoft.com/learn/paths/implement-windows-server-iaas-virtual-machine-identity/", + "text": "中断バジェットを使用して、予想されるアプリケーション負荷を処理するために必要な数のポッドレプリカが存在することを確認します。", "waf": "確実" }, { @@ -369,7 +364,6 @@ "severity": "中程度", "subcategory": "ワークロード", "text": "ポッド トポロジの制約を使用して、クラスター全体のノードでポッドを自動的にスケジュールします。", - "training": "https://learn.microsoft.com/learn/paths/implement-applications-external-access-azure-ad/", "waf": "確実" }, { @@ -389,7 +383,7 @@ "link": "https://docs.openshift.com/container-platform/4.13/cicd/gitops/understanding-openshift-gitops.html", "severity": "低い", "subcategory": "ワークロード", - "text": "Red Hat OpenShift GitOps の使用を検討してください。Red Hat OpenShift GitOps は Argo CD を使用してクラスタリソースを維持し、アプリケーション CI/CD をサポートします。", + "text": "Red Hat OpenShift GitOps の使用を検討してください。Red Hat OpenShift GitOps は Argo CD を使用してクラスターリソースを維持し、アプリケーションの CI/CD をサポートします。", "waf": "オペレーションズ" }, { @@ -398,8 +392,8 @@ "id": "E01.01", "link": "https://learn.microsoft.com/azure/openshift/support-lifecycle", "severity": "高い", - "subcategory": "コントロール プレーン", - "text": "クラスターを最新の OpenShift バージョンに維持して、潜在的なセキュリティやアップグレードの問題を回避します。", + "subcategory": "コントロールプレーン", + "text": "クラスターを最新の OpenShift バージョンに保ち、潜在的なセキュリティやアップグレードの問題を回避します。", "waf": "安全" }, { @@ -408,8 +402,8 @@ "id": "E01.02", "link": "https://learn.microsoft.com/azure/azure-arc/kubernetes/quickstart-connect-cluster", "severity": "高い", - "subcategory": "コントロール プレーン", - "text": "Azure Red Hat OpenShift クラスターを Azure Arc-enabled Kubernetes に接続します。", + "subcategory": "コントロールプレーン", + "text": "Azure Red Hat OpenShift クラスターを Azure Arc 対応 Kubernetes に接続します。", "waf": "安全" }, { @@ -429,7 +423,7 @@ "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-introduction", "severity": "中程度", "subcategory": "姿勢", - "text": "Arc 対応 Kubernetes を介してサポートされるコンテナーに対して Microsoft Defender を使用して、クラスター、コンテナー、アプリケーションをセキュリティで保護します。", + "text": "Arc 対応 Kubernetes でサポートされている Microsoft Defender for Containers を使用して、クラスター、コンテナー、アプリケーションをセキュリティで保護します。", "waf": "安全" }, { @@ -439,7 +433,7 @@ "link": "https://learn.microsoft.com/azure/azure-arc/kubernetes/tutorial-akv-secrets-provider", "severity": "中程度", "subcategory": "秘密", - "text": "機密情報へのアクセスが必要なアプリケーションの場合は、サービス プリンシパルと、Arc 対応 Kubernetes クラスターの拡張機能と共に AKV シークレット プロバイダーを使用します。", + "text": "機密情報へのアクセスを必要とするアプリケーションの場合は、サービス プリンシパルと AKV シークレット プロバイダーを Arc 対応 Kubernetes クラスターの拡張機能と共に使用します。", "waf": "安全" }, { @@ -459,7 +453,7 @@ "link": "https://learn.microsoft.com/azure/governance/policy/concepts/policy-for-kubernetes#install-azure-policy-extension-for-azure-arc-enabled-kubernetes", "severity": "中程度", "subcategory": "ワークロード", - "text": "Azure ポリシー拡張機能を使用して構成を監視および適用します。", + "text": "Azure Policy 拡張機能を使用して構成を監視および適用します。", "waf": "安全" }, { @@ -479,14 +473,14 @@ "link": "https://learn.microsoft.com/azure/container-registry/container-registry-private-link", "severity": "低い", "subcategory": "ワークロード", - "text": "Azure コンテナー レジストリの専用インスタンスとプライベート インスタンスを各ランディング ゾーン サブスクリプションにデプロイします。", + "text": "Azure Container Registry の専用インスタンスとプライベート インスタンスを各ランディング ゾーン サブスクリプションにデプロイします。", "waf": "安全" } ], "metadata": { "name": "Use the 'Import latest checklist' button to get the latest version of a review checklist", "state": " ", - "timestamp": "September 19, 2023" + "timestamp": "December 15, 2023" }, "severities": [ { @@ -505,16 +499,16 @@ "name": "未確認" }, { - "description": "このチェックに関連付けられているアクションアイテムがあります", + "description": "このチェックにはアクションアイテムが関連付けられています", "name": "開ける" }, { - "description": "このチェックは検証済みであり、それ以上のアクションアイテムは関連付けられていません", + "description": "このチェックは検証済みで、これ以上のアクションアイテムは関連付けられていません", "name": "達成" }, { - "description": "推奨事項は理解されていますが、現在の要件では必要ありません", - "name": "必須ではありません" + "description": "推奨事項は理解されているが、現在の要件では不要", + "name": "リスクの受け入れ" }, { "description": "現在のデザインには適用されません", diff --git a/checklists/aro_checklist.ko.json b/checklists/aro_checklist.ko.json index bff44792b..c2bad5d52 100644 --- a/checklists/aro_checklist.ko.json +++ b/checklists/aro_checklist.ko.json @@ -39,8 +39,17 @@ }, { "category": "ID 및 액세스 관리", - "guid": "483835c9-86bb-4291-8155-a11475e39f54", + "guid": "adfec5f9-a82d-46e9-a8d1-5a0c7fed5d15", "id": "A01.03", + "link": "https://docs.openshift.com/container-platform/4.14/authentication/remove-kubeadmin.html", + "subcategory": "신원", + "text": "AAD 인증을 사용하는 경우 클러스터에서 kubeadmin 사용자를 제거합니다.", + "waf": "안전" + }, + { + "category": "ID 및 액세스 관리", + "guid": "483835c9-86bb-4291-8155-a11475e39f54", + "id": "A01.04", "link": "https://docs.openshift.com/container-platform/4.13/applications/projects/working-with-projects.html", "severity": "높다", "subcategory": "신원", @@ -50,17 +59,17 @@ { "category": "ID 및 액세스 관리", "guid": "0acccd97-9376-4bcd-a375-0ab2ab039da6", - "id": "A01.04", + "id": "A01.05", "link": "https://docs.openshift.com/container-platform/4.13/authentication/using-rbac.html", "severity": "보통", "subcategory": "신원", - "text": "OpenShift에서 필요한 RBAC 역할의 범위가 프로젝트 또는 클러스터로 지정되도록 정의합니다.", + "text": "OpenShift에서 필요한 RBAC 역할의 범위는 프로젝트 또는 클러스터로 정의됩니다.", "waf": "안전" }, { "category": "ID 및 액세스 관리", "guid": "d54d7c89-29db-4107-b532-5ae625ca44e4", - "id": "A01.05", + "id": "A01.06", "link": "https://learn.microsoft.com/azure/cost-management-billing/manage/direct-ea-administration#manage-notification-contacts", "severity": "보통", "subcategory": "신원", @@ -70,7 +79,7 @@ { "category": "ID 및 액세스 관리", "guid": "685e2223-ace8-4bb1-8307-ca5f16f154e3", - "id": "A01.06", + "id": "A01.07", "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-configure", "severity": "보통", "subcategory": "신원", @@ -83,7 +92,7 @@ "id": "B01.01", "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", "severity": "낮다", - "subcategory": "디도스(DD", + "subcategory": "디도스(DDoS)", "text": "중앙 집중식 구독에서 Azure Firewall 또는 WAF를 사용하지 않는 한 Azure DDoS 네트워크/IP 보호를 사용하여 ARO 클러스터에 사용하는 가상 네트워크를 보호합니다", "waf": "안전" }, @@ -133,8 +142,8 @@ "id": "B04.01", "link": "https://learn.microsoft.com/azure/openshift/howto-create-private-cluster-4x", "severity": "높다", - "subcategory": "전용 액세스", - "text": "보안 정책에 따라 OpenShift API에 전용 IP 주소를 사용해야 하는 경우 전용 ARO 클러스터를 배포합니다.", + "subcategory": "전용 이용 가능 공간", + "text": "보안 정책에 따라 OpenShift API에 개인 IP 주소를 사용해야 하는 경우 개인 ARO 클러스터를 배포합니다.", "waf": "안전" }, { @@ -143,8 +152,8 @@ "id": "B04.02", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-private-link", "severity": "보통", - "subcategory": "전용 액세스", - "text": "Azure Private Link를 사용하여 Azure Container Registry를 비롯한 관리되는 Azure 서비스에 대한 네트워크 연결을 보호합니다.", + "subcategory": "전용 이용 가능 공간", + "text": "Azure Private Link를 사용하여 Azure Container Registry를 포함하여 관리되는 Azure 서비스에 대한 네트워크 연결을 보호합니다.", "waf": "안전" }, { @@ -155,7 +164,6 @@ "severity": "높다", "subcategory": "작업", "text": "내장된 Prometheus, OpenShift Logging 또는 Container Insights 통합을 사용하여 모니터링 프로세스를 설정합니다.", - "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", "waf": "작업" }, { @@ -165,19 +173,17 @@ "link": "https://docs.openshift.com/container-platform/4.13/cicd/pipelines/understanding-openshift-pipelines.html", "severity": "보통", "subcategory": "작업", - "text": "DevOps 사례 및 CI/CD 솔루션(예: OpenShift에서 제공하는 Pipelines/GitOps)을 통해 애플리케이션 제공 프로세스를 자동화합니다.", - "training": "https://learn.microsoft.com/learn/modules/plan-implement-administer-conditional-access/", + "text": "OpenShift에서 제공하는 파이프라인/GitOps와 같은 DevOps 사례 및 CI/CD 솔루션을 통해 애플리케이션 제공 프로세스를 자동화합니다.", "waf": "작업" }, { "category": "운영 관리", "guid": "467a1f89-35bd-4a43-924f-14811533182a", "id": "C01.03", - "link": "https://learn.microsoft.com/azure/active-directory-domain-services/overview", + "link": "https://learn.microsoft.com/azure/architecture/guide/design-principles/managed-services", "severity": "낮다", "subcategory": "작업", "text": "가능하면 컨테이너 내부에서 서비스 상태를 제거합니다. 대신 다중 지역 복제를 지원하는 Azure PaaS(Platform as a Service)를 사용합니다.", - "training": "https://learn.microsoft.com/learn/modules/azure-active-directory/", "waf": "작업" }, { @@ -188,7 +194,6 @@ "severity": "낮다", "subcategory": "작업", "text": "기본 제공 Azure Files 스토리지 클래스와 함께 RWX 스토리지를 사용합니다.", - "training": "https://learn.microsoft.com/learn/modules/design-identity-security-strategy/", "waf": "작업" }, { @@ -198,8 +203,7 @@ "link": "https://docs.openshift.com/container-platform/4.13/nodes/clusters/nodes-cluster-limit-ranges.html", "severity": "보통", "subcategory": "공연", - "text": "Pod 요청 및 제한을 사용하여 클러스터 내에서 컴퓨팅 리소스를 관리합니다.", - "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/", + "text": "Pod 요청 및 제한을 사용하여 클러스터 내의 컴퓨팅 리소스를 관리합니다.", "waf": "공연" }, { @@ -209,7 +213,7 @@ "link": "https://docs.openshift.com/container-platform/4.13/applications/quotas/quotas-setting-per-project.html", "severity": "보통", "subcategory": "공연", - "text": "프로젝트에 리소스 할당량을 적용합니다.", + "text": "프로젝트에 자원 할당량을 적용합니다.", "waf": "공연" }, { @@ -219,8 +223,7 @@ "link": "https://docs.openshift.com/container-platform/4.13/machine_management/applying-autoscaling.html", "severity": "높다", "subcategory": "공연", - "text": "ClusterAutoScaler 및 MachineAutoScaler를 정의하여 클러스터의 리소스가 부족할 때 머신의 크기를 조정하여 더 많은 배포를 지원합니다.", - "training": "https://learn.microsoft.com/learn/modules/secure-aad-users-with-mfa/", + "text": "ClusterAutoScaler 및 MachineAutoScaler를 정의하여 클러스터의 리소스가 부족할 때 더 많은 배포를 지원하기 위해 머신의 크기를 조정합니다.", "waf": "공연" }, { @@ -230,8 +233,7 @@ "link": "https://learn.microsoft.com/azure/openshift/support-policies-v4#supported-virtual-machine-sizes", "severity": "높다", "subcategory": "신뢰도", - "text": "여러 컨테이너 인스턴스를 포함할 수 있을 만큼 충분히 큰 가상 머신 크기를 사용하여 밀도를 높이는 이점을 얻을 수 있지만 클러스터가 실패한 노드의 워크로드를 처리할 수 없을 정도로 크지는 않습니다.", - "training": "https://learn.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview", + "text": "여러 컨테이너 인스턴스를 포함할 수 있을 만큼 충분히 큰 가상 머신 크기를 사용하여 밀도 증가의 이점을 얻을 수 있지만 클러스터가 실패한 노드의 워크로드를 처리할 수 없을 정도로 크지 않습니다.", "waf": "신뢰도" }, { @@ -241,8 +243,7 @@ "link": "https://docs.openshift.com/container-platform/4.13/machine_management/deploying-machine-health-checks.html", "severity": "높다", "subcategory": "신뢰도", - "text": "컴퓨터 풀에서 손상된 컴퓨터를 자동으로 복구하기 위해 컴퓨터 상태 검사를 배포합니다.", - "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-identities-governance/", + "text": "컴퓨터 상태 검사를 배포하여 컴퓨터 풀에서 손상된 컴퓨터를 자동으로 복구합니다.", "waf": "신뢰도" }, { @@ -252,8 +253,7 @@ "link": "https://learn.microsoft.com/azure/azure-monitor/containers/container-insights-metric-alerts", "severity": "높다", "subcategory": "신뢰도", - "text": "Container Insights 메트릭 경고 또는 기본 제공 경고 UI와 같은 직접적인 조치가 필요한 경우 알림 시스템을 사용하여 알림을 제공합니다.", - "training": "https://learn.microsoft.com/learn/modules/explore-basic-services-identity-types/", + "text": "경고 시스템을 사용하여 Container Insights 메트릭 경고 또는 기본 제공 경고 UI와 같은 직접적인 조치가 필요할 때 알림을 제공합니다.", "waf": "신뢰도" }, { @@ -264,7 +264,6 @@ "severity": "높다", "subcategory": "신뢰도", "text": "클러스터가 AZ를 지원하는 리전에 생성되었는지 확인하고 각 AZ에 대한 머신 세트를 생성합니다.", - "training": "https://learn.microsoft.com/learn/paths/manage-identity-and-access/", "waf": "신뢰도" }, { @@ -274,8 +273,7 @@ "link": "https://docs.openshift.com/container-platform/4.13/machine_management/creating-infrastructure-machinesets.html", "severity": "낮다", "subcategory": "신뢰도", - "text": "인프라 구성 요소를 보관할 인프라 머신 세트를 생성합니다. 이러한 머신에 특정 Kubernetes 레이블을 적용한 다음, 해당 머신에서만 실행되도록 인프라 구성 요소를 업데이트합니다.", - "training": "https://learn.microsoft.com/learn/paths/secure-your-cloud-data/", + "text": "인프라 구성 요소를 저장할 인프라 머신 세트를 만듭니다. 이러한 머신에 특정 Kubernetes 레이블을 적용한 다음, 해당 머신에서만 실행되도록 인프라 구성 요소를 업데이트합니다.", "waf": "신뢰도" }, { @@ -285,8 +283,7 @@ "link": "https://learn.microsoft.com/azure/openshift/howto-create-a-backup#create-a-backup-with-velero-to-include-snapshots", "severity": "보통", "subcategory": "신뢰도", - "text": "애플리케이션 백업을 생성하고, 복원을 계획하고, 백업에 영구 볼륨을 포함합니다.", - "training": "https://learn.microsoft.com/azure/architecture/example-scenario/identity/adds-extend-domain", + "text": "응용 프로그램 백업을 만들고 복원을 계획하고 백업에 영구 볼륨을 포함합니다.", "waf": "신뢰도" }, { @@ -306,7 +303,7 @@ "link": "https://docs.openshift.com/container-platform/4.13/architecture/admission-plug-ins.html", "severity": "낮다", "subcategory": "안전", - "text": "보안 정책, 자원 제한 또는 구성 요구사항을 적용하는 데 일반적으로 사용되는 승인 플러그인을 사용하여 클러스터 기능을 조절합니다.", + "text": "보안 정책, 자원 제한 또는 구성 요구 사항을 적용하는 데 일반적으로 사용되는 승인 플러그인을 사용하여 클러스터 기능을 규제합니다.", "waf": "안전" }, { @@ -316,7 +313,7 @@ "link": "https://learn.microsoft.com/azure/container-registry/container-registry-geo-replication", "severity": "낮다", "subcategory": "안전", - "text": "컨테이너 이미지를 Azure Container Registry에 저장하고 레지스트리를 각 지역에 지역 복제합니다.", + "text": "Azure Container Registry에 컨테이너 이미지를 저장하고 레지스트리를 각 지역에 지역 복제합니다.", "waf": "안전" }, { @@ -326,7 +323,7 @@ "link": "https://docs.openshift.com/container-platform/4.13/nodes/pods/nodes-pods-vertical-autoscaler.html", "severity": "보통", "subcategory": "작업", - "text": "CPU 및 메모리 요청 값을 최적화하고 수직 Pod 자동 크기 조정기를 사용하여 클러스터 리소스의 효율성을 극대화합니다.", + "text": "CPU 및 메모리 요청 값을 최적화하고 수직 Pod 자동 스케일러를 사용하여 클러스터 리소스의 효율성을 최대화합니다.", "waf": "공연" }, { @@ -346,8 +343,7 @@ "link": "https://docs.openshift.com/container-platform/4.13/nodes/pods/nodes-pods-autoscaling.html", "severity": "보통", "subcategory": "작업", - "text": "수평 Pod 자동 크기 조정기를 사용하여 수요에 맞게 Pod를 확장합니다.", - "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/", + "text": "수평 Pod 자동 확장 처리를 사용하여 수요에 맞게 Pod를 확장합니다.", "waf": "신뢰도" }, { @@ -357,8 +353,7 @@ "link": "https://docs.openshift.com/container-platform/4.13/nodes/pods/nodes-pods-configuring.html#nodes-pods-pod-distruption-about_nodes-pods-configuring", "severity": "보통", "subcategory": "작업", - "text": "중단 예산을 사용하여 예상되는 애플리케이션 로드를 처리하는 데 필요한 수의 Pod 복제본이 있는지 확인합니다.", - "training": "https://learn.microsoft.com/learn/paths/implement-windows-server-iaas-virtual-machine-identity/", + "text": "중단 예산을 사용하여 예상되는 애플리케이션 부하를 처리하는 데 필요한 수의 Pod 복제본이 있는지 확인합니다.", "waf": "신뢰도" }, { @@ -369,7 +364,6 @@ "severity": "보통", "subcategory": "작업", "text": "Pod 토폴로지 제약 조건을 사용하여 클러스터 전체의 노드에서 Pod를 자동으로 예약합니다.", - "training": "https://learn.microsoft.com/learn/paths/implement-applications-external-access-azure-ad/", "waf": "신뢰도" }, { @@ -389,7 +383,7 @@ "link": "https://docs.openshift.com/container-platform/4.13/cicd/gitops/understanding-openshift-gitops.html", "severity": "낮다", "subcategory": "작업", - "text": "Red Hat OpenShift GitOps를 사용하는 것이 좋습니다. Red Hat OpenShift GitOps는 Argo CD를 사용하여 클러스터 리소스를 유지 관리하고 애플리케이션 CI/CD를 지원합니다.", + "text": "Red Hat OpenShift GitOps 사용을 고려합니다. Red Hat OpenShift GitOps는 Argo CD를 사용하여 클러스터 리소스를 유지 관리하고 애플리케이션 CI/CD를 지원합니다.", "waf": "작업" }, { @@ -419,7 +413,7 @@ "link": "https://docs.openshift.com/container-platform/4.10/security/encrypting-etcd.html", "severity": "낮다", "subcategory": "암호화", - "text": "Azure Red Hat OpenShift 4 클러스터의 경우 etcd 데이터는 기본적으로 암호화되지 않지만 etcd 암호화를 사용하도록 설정하여 다른 데이터 보안 계층을 제공하는 것이 좋습니다.", + "text": "Azure Red Hat OpenShift 4 클러스터의 경우 etcd 데이터는 기본적으로 암호화되지 않지만 etcd 암호화를 사용하도록 설정하여 또 다른 데이터 보안 계층을 제공하는 것이 좋습니다.", "waf": "안전" }, { @@ -429,7 +423,7 @@ "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-introduction", "severity": "보통", "subcategory": "자세", - "text": "Arc 지원 Kubernetes를 통해 지원되는 컨테이너용 Microsoft Defender를 사용하여 클러스터, 컨테이너 및 애플리케이션을 보호합니다.", + "text": "Arc 지원 Kubernetes를 통해 지원되는 컨테이너용 Microsoft Defender 사용하여 클러스터, 컨테이너 및 애플리케이션을 보호합니다.", "waf": "안전" }, { @@ -449,7 +443,7 @@ "link": "https://learn.microsoft.com/azure/aks/developer-best-practices-pod-security#secure-pod-access-to-resources", "severity": "보통", "subcategory": "작업", - "text": "리소스에 대한 Pod 액세스를 보호합니다. 최소한의 권한을 제공하고 루트 또는 권한 있는 에스컬레이션을 사용하지 마십시오.", + "text": "리소스에 대한 Pod 액세스를 보호합니다. 최소한의 권한을 제공하고 루트 또는 권한 에스컬레이션을 사용하지 마십시오.", "waf": "안전" }, { @@ -469,7 +463,7 @@ "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-introduction", "severity": "높다", "subcategory": "작업", - "text": "Microsoft Defender 또는 기타 이미지 검사 솔루션을 사용하여 이미지에서 취약성을 검사합니다.", + "text": "Microsoft Defender 또는 다른 이미지 검사 솔루션을 사용하여 이미지의 취약성을 검사합니다.", "waf": "안전" }, { @@ -486,7 +480,7 @@ "metadata": { "name": "Use the 'Import latest checklist' button to get the latest version of a review checklist", "state": " ", - "timestamp": "September 19, 2023" + "timestamp": "December 15, 2023" }, "severities": [ { @@ -513,12 +507,12 @@ "name": "성취" }, { - "description": "권장 사항을 이해했지만 현재 요구 사항에는 필요하지 않습니다.", - "name": "필요하지 않음" + "description": "권장 사항은 이해되었지만 현재 요구 사항에 필요하지 않음", + "name": "감수된 위험" }, { "description": "현재 설계에는 적용되지 않습니다.", - "name": "해당 사항 없음" + "name": "해당 없음" } ], "waf": [ diff --git a/checklists/aro_checklist.pt.json b/checklists/aro_checklist.pt.json index 14410d5f0..522537c18 100644 --- a/checklists/aro_checklist.pt.json +++ b/checklists/aro_checklist.pt.json @@ -39,8 +39,17 @@ }, { "category": "Gerenciamento de identidades e acesso", - "guid": "483835c9-86bb-4291-8155-a11475e39f54", + "guid": "adfec5f9-a82d-46e9-a8d1-5a0c7fed5d15", "id": "A01.03", + "link": "https://docs.openshift.com/container-platform/4.14/authentication/remove-kubeadmin.html", + "subcategory": "Identidade", + "text": "Ao usar a autenticação AAD, remova o usuário kubeadmin do cluster.", + "waf": "Segurança" + }, + { + "category": "Gerenciamento de identidades e acesso", + "guid": "483835c9-86bb-4291-8155-a11475e39f54", + "id": "A01.04", "link": "https://docs.openshift.com/container-platform/4.13/applications/projects/working-with-projects.html", "severity": "Alto", "subcategory": "Identidade", @@ -50,7 +59,7 @@ { "category": "Gerenciamento de identidades e acesso", "guid": "0acccd97-9376-4bcd-a375-0ab2ab039da6", - "id": "A01.04", + "id": "A01.05", "link": "https://docs.openshift.com/container-platform/4.13/authentication/using-rbac.html", "severity": "Média", "subcategory": "Identidade", @@ -60,7 +69,7 @@ { "category": "Gerenciamento de identidades e acesso", "guid": "d54d7c89-29db-4107-b532-5ae625ca44e4", - "id": "A01.05", + "id": "A01.06", "link": "https://learn.microsoft.com/azure/cost-management-billing/manage/direct-ea-administration#manage-notification-contacts", "severity": "Média", "subcategory": "Identidade", @@ -70,7 +79,7 @@ { "category": "Gerenciamento de identidades e acesso", "guid": "685e2223-ace8-4bb1-8307-ca5f16f154e3", - "id": "A01.06", + "id": "A01.07", "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-configure", "severity": "Média", "subcategory": "Identidade", @@ -155,7 +164,6 @@ "severity": "Alto", "subcategory": "Operações", "text": "Estabeleça um processo de monitoramento usando a integração integrada Prometheus, OpenShift Logging ou Container Insights.", - "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", "waf": "Operações" }, { @@ -166,18 +174,16 @@ "severity": "Média", "subcategory": "Operações", "text": "Automatize o processo de entrega de aplicativos por meio de práticas de DevOps e soluções de CI/CD, como Pipelines/GitOps fornecidos pelo OpenShift.", - "training": "https://learn.microsoft.com/learn/modules/plan-implement-administer-conditional-access/", "waf": "Operações" }, { "category": "Gestão de operações", "guid": "467a1f89-35bd-4a43-924f-14811533182a", "id": "C01.03", - "link": "https://learn.microsoft.com/azure/active-directory-domain-services/overview", + "link": "https://learn.microsoft.com/azure/architecture/guide/design-principles/managed-services", "severity": "Baixo", "subcategory": "Operações", "text": "Sempre que possível, remova o estado de serviço de dentro dos contêineres. Em vez disso, use uma plataforma como serviço (PaaS) do Azure que ofereça suporte à replicação de várias regiões.", - "training": "https://learn.microsoft.com/learn/modules/azure-active-directory/", "waf": "Operações" }, { @@ -188,7 +194,6 @@ "severity": "Baixo", "subcategory": "Operações", "text": "Use o armazenamento RWX com a classe de armazenamento de Arquivos do Azure incorporada.", - "training": "https://learn.microsoft.com/learn/modules/design-identity-security-strategy/", "waf": "Operações" }, { @@ -199,7 +204,6 @@ "severity": "Média", "subcategory": "Desempenho", "text": "Use solicitações de pod e limites para gerenciar os recursos de computação em um cluster.", - "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/", "waf": "Desempenho" }, { @@ -220,7 +224,6 @@ "severity": "Alto", "subcategory": "Desempenho", "text": "Defina ClusterAutoScaler e MachineAutoScaler para dimensionar máquinas quando o cluster ficar sem recursos para oferecer suporte a mais implantações.", - "training": "https://learn.microsoft.com/learn/modules/secure-aad-users-with-mfa/", "waf": "Desempenho" }, { @@ -231,7 +234,6 @@ "severity": "Alto", "subcategory": "Fiabilidade", "text": "Use tamanhos de máquina virtual grandes o suficiente para conter várias instâncias de contêiner para que você obtenha os benefícios do aumento da densidade, mas não tão grande que seu cluster não possa lidar com a carga de trabalho de um nó com falha.", - "training": "https://learn.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview", "waf": "Fiabilidade" }, { @@ -242,7 +244,6 @@ "severity": "Alto", "subcategory": "Fiabilidade", "text": "Implante verificações de integridade da máquina para reparar automaticamente máquinas danificadas em um pool de máquinas.", - "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-identities-governance/", "waf": "Fiabilidade" }, { @@ -253,7 +254,6 @@ "severity": "Alto", "subcategory": "Fiabilidade", "text": "Use um sistema de alertas para fornecer notificações quando as coisas precisarem de ação direta: alertas de métrica do Container Insights ou interface do usuário de alerta integrada.", - "training": "https://learn.microsoft.com/learn/modules/explore-basic-services-identity-types/", "waf": "Fiabilidade" }, { @@ -264,7 +264,6 @@ "severity": "Alto", "subcategory": "Fiabilidade", "text": "Certifique-se de que o cluster seja criado em uma região que ofereça suporte a AZs e crie um conjunto de máquinas para cada AZ.", - "training": "https://learn.microsoft.com/learn/paths/manage-identity-and-access/", "waf": "Fiabilidade" }, { @@ -275,7 +274,6 @@ "severity": "Baixo", "subcategory": "Fiabilidade", "text": "Crie conjuntos de máquinas de infraestrutura para armazenar componentes de infraestrutura. Aplique rótulos Kubernetes específicos a essas máquinas e, em seguida, atualize os componentes de infraestrutura para serem executados somente nessas máquinas.", - "training": "https://learn.microsoft.com/learn/paths/secure-your-cloud-data/", "waf": "Fiabilidade" }, { @@ -286,7 +284,6 @@ "severity": "Média", "subcategory": "Fiabilidade", "text": "Crie backup de aplicativos e planeje a restauração e inclua volumes persistentes no backup.", - "training": "https://learn.microsoft.com/azure/architecture/example-scenario/identity/adds-extend-domain", "waf": "Fiabilidade" }, { @@ -347,7 +344,6 @@ "severity": "Média", "subcategory": "Carga", "text": "Dimensione pods para atender à demanda usando o autoscaler de pod horizontal.", - "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/", "waf": "Fiabilidade" }, { @@ -358,7 +354,6 @@ "severity": "Média", "subcategory": "Carga", "text": "Use orçamentos de interrupção para garantir que o número necessário de réplicas de pod exista para lidar com a carga esperada do aplicativo.", - "training": "https://learn.microsoft.com/learn/paths/implement-windows-server-iaas-virtual-machine-identity/", "waf": "Fiabilidade" }, { @@ -369,7 +364,6 @@ "severity": "Média", "subcategory": "Carga", "text": "Use restrições de topologia de pod para agendar automaticamente pods em nós em todo o cluster.", - "training": "https://learn.microsoft.com/learn/paths/implement-applications-external-access-azure-ad/", "waf": "Fiabilidade" }, { @@ -486,7 +480,7 @@ "metadata": { "name": "Use the 'Import latest checklist' button to get the latest version of a review checklist", "state": " ", - "timestamp": "September 19, 2023" + "timestamp": "December 15, 2023" }, "severities": [ { @@ -514,7 +508,7 @@ }, { "description": "Recomendação compreendida, mas não necessária pelos requisitos atuais", - "name": "Não é necessário" + "name": "Risco aceito" }, { "description": "Não aplicável ao projeto atual", diff --git a/checklists/aro_checklist.zh-Hant.json b/checklists/aro_checklist.zh-Hant.json new file mode 100644 index 000000000..c9c32e737 --- /dev/null +++ b/checklists/aro_checklist.zh-Hant.json @@ -0,0 +1,543 @@ +{ + "categories": [ + { + "name": "身份和訪問管理" + }, + { + "name": "網路拓撲和連接" + }, + { + "name": "運營管理" + }, + { + "name": "平臺自動化" + }, + { + "name": "安全" + } + ], + "items": [ + { + "category": "身份和訪問管理", + "guid": "d7e47431-76c8-4bdb-b55b-ce619e8a03f9", + "id": "A01.01", + "link": "https://learn.microsoft.com/azure/openshift/howto-create-service-principal?pivots=aro-azurecli", + "severity": "高", + "subcategory": "身份", + "text": "在創建 ARO 群集之前,請創建服務主體及其角色分配。", + "waf": "安全" + }, + { + "category": "身份和訪問管理", + "guid": "7879424d-6267-486d-90b9-6c97be985190", + "id": "A01.02", + "link": "https://learn.microsoft.com/azure/openshift/configure-azure-ad-ui", + "severity": "高", + "subcategory": "身份", + "text": "使用 AAD 對 ARO 群集中的用戶進行身份驗證。", + "waf": "安全" + }, + { + "category": "身份和訪問管理", + "guid": "adfec5f9-a82d-46e9-a8d1-5a0c7fed5d15", + "id": "A01.03", + "link": "https://docs.openshift.com/container-platform/4.14/authentication/remove-kubeadmin.html", + "subcategory": "身份", + "text": "使用 AAD 身份驗證時,請從群集中刪除 kubeadmin 使用者。", + "waf": "安全" + }, + { + "category": "身份和訪問管理", + "guid": "483835c9-86bb-4291-8155-a11475e39f54", + "id": "A01.04", + "link": "https://docs.openshift.com/container-platform/4.13/applications/projects/working-with-projects.html", + "severity": "高", + "subcategory": "身份", + "text": "定義 OpenShift 專案以限制 RBAC 許可權並隔離集群中的工作負載。", + "waf": "安全" + }, + { + "category": "身份和訪問管理", + "guid": "0acccd97-9376-4bcd-a375-0ab2ab039da6", + "id": "A01.05", + "link": "https://docs.openshift.com/container-platform/4.13/authentication/using-rbac.html", + "severity": "中等", + "subcategory": "身份", + "text": "在OpenShift中定義所需的 RBAC 角色,這些角色的範圍限定為專案或集群。", + "waf": "安全" + }, + { + "category": "身份和訪問管理", + "guid": "d54d7c89-29db-4107-b532-5ae625ca44e4", + "id": "A01.06", + "link": "https://learn.microsoft.com/azure/cost-management-billing/manage/direct-ea-administration#manage-notification-contacts", + "severity": "中等", + "subcategory": "身份", + "text": "最大程度地減少具有管理員許可權和機密訪問許可權的用戶數量。", + "waf": "安全" + }, + { + "category": "身份和訪問管理", + "guid": "685e2223-ace8-4bb1-8307-ca5f16f154e3", + "id": "A01.07", + "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-configure", + "severity": "中等", + "subcategory": "身份", + "text": "在 AAD 中對具有特權角色的 ARO 使用者使用 Privileged Identity Management。", + "waf": "安全" + }, + { + "category": "網路拓撲和連接", + "guid": "aa369282-9e7e-4216-8836-87af467a1f89", + "id": "B01.01", + "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", + "severity": "低", + "subcategory": "DDoS 攻擊", + "text": "使用 Azure DDoS 網路/IP 防護來保護用於 ARO 群集的虛擬網路,除非在集中式訂閱中使用 Azure 防火牆或 WAF", + "waf": "安全" + }, + { + "category": "網路拓撲和連接", + "guid": "35bda433-24f1-4481-8533-182aa5174269", + "id": "B02.01", + "link": "https://docs.openshift.com/container-platform/4.13/networking/routes/secured-routes.html", + "severity": "高", + "subcategory": "加密", + "text": "配置為使用入口的所有 Web 應用程式都應使用 TLS 加密,並且不應允許通過未加密的 HTTP 進行訪問。", + "waf": "安全" + }, + { + "category": "網路拓撲和連接", + "guid": "44008ae7-d7e4-4743-876c-8bdbf55bce61", + "id": "B03.01", + "link": "https://learn.microsoft.com/azure/frontdoor/front-door-overview", + "severity": "中等", + "subcategory": "互聯網", + "text": "將 Azure Front Door 與 WAF 結合使用,將 ARO 應用程式安全地發布到 Internet,尤其是在多區域環境中。", + "waf": "安全" + }, + { + "category": "網路拓撲和連接", + "guid": "9e8a03f9-7879-4424-b626-786d60b96c97", + "id": "B03.02", + "link": "https://learn.microsoft.com/azure/openshift/howto-secure-openshift-with-front-door", + "severity": "中等", + "subcategory": "互聯網", + "text": "如果使用 Azure Front Door 在 ARO 上公開應用,請使用專用連結將 Front Door 與 ARO 路由器連接。", + "waf": "安全" + }, + { + "category": "網路拓撲和連接", + "guid": "be985190-4838-435c-a86b-b2912155a114", + "id": "B03.03", + "link": "https://learn.microsoft.com/azure/openshift/howto-restrict-egress", + "severity": "中等", + "subcategory": "互聯網", + "text": "如果安全策略要求檢查 ARO 群集中生成的所有出站 Internet 流量,請使用 Azure 防火牆或 NVA 保護出口網路流量。", + "waf": "安全" + }, + { + "category": "網路拓撲和連接", + "guid": "75e39f54-0acc-4cd9-9937-6bcda3750ab2", + "id": "B04.01", + "link": "https://learn.microsoft.com/azure/openshift/howto-create-private-cluster-4x", + "severity": "高", + "subcategory": "私人訪問", + "text": "如果您的安全策略要求您為 OpenShift API 使用私有 IP 位址,請部署私有 ARO 集群。", + "waf": "安全" + }, + { + "category": "網路拓撲和連接", + "guid": "ab039da6-d54d-47c8-a29d-b107d5325ae6", + "id": "B04.02", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-private-link", + "severity": "中等", + "subcategory": "私人訪問", + "text": "使用 Azure 專用連結來保護與託管 Azure 服務(包括 Azure 容器註冊表)的網路連接。", + "waf": "安全" + }, + { + "category": "運營管理", + "guid": "25ca44e4-685e-4222-9ace-8bb12307ca5f", + "id": "C01.01", + "link": "https://learn.microsoft.com/azure/azure-monitor/containers/container-insights-enable-arc-enabled-clusters", + "severity": "高", + "subcategory": "操作", + "text": "使用內置的 Prometheus、OpenShift Logging 或 Container Insights 集成建立監控流程。", + "waf": "操作" + }, + { + "category": "運營管理", + "guid": "16f154e3-aa36-4928-89e7-e216183687af", + "id": "C01.02", + "link": "https://docs.openshift.com/container-platform/4.13/cicd/pipelines/understanding-openshift-pipelines.html", + "severity": "中等", + "subcategory": "操作", + "text": "通過 DevOps 實踐和 CI/CD 解決方案(例如 OpenShift 提供的 Pipelines/GitOps)自動執行應用程式交付流程。", + "waf": "操作" + }, + { + "category": "運營管理", + "guid": "467a1f89-35bd-4a43-924f-14811533182a", + "id": "C01.03", + "link": "https://learn.microsoft.com/azure/architecture/guide/design-principles/managed-services", + "severity": "低", + "subcategory": "操作", + "text": "盡可能從容器內部刪除服務狀態。請改用支援多區域複製的 Azure 平臺即服務 (PaaS)。", + "waf": "操作" + }, + { + "category": "運營管理", + "guid": "1b7da8cf-aa66-4e15-b4d5-ada97dc3e232", + "id": "C01.04", + "link": "https://learn.microsoft.com/azure/openshift/howto-create-a-storageclass", + "severity": "低", + "subcategory": "操作", + "text": "將 RWX 儲存與內置的 Azure 檔儲存類配合使用。", + "waf": "操作" + }, + { + "category": "運營管理", + "guid": "6bb235c7-05e1-4696-bded-fa8a4c8cdec4", + "id": "C02.01", + "link": "https://docs.openshift.com/container-platform/4.13/nodes/clusters/nodes-cluster-limit-ranges.html", + "severity": "中等", + "subcategory": "性能", + "text": "使用 Pod 請求和限制來管理集群中的計算資源。", + "waf": "性能" + }, + { + "category": "運營管理", + "guid": "c620c30c-14ee-4b7f-9ae8-d9b3fec228e7", + "id": "C02.02", + "link": "https://docs.openshift.com/container-platform/4.13/applications/quotas/quotas-setting-per-project.html", + "severity": "中等", + "subcategory": "性能", + "text": "對項目強制實施資源配額。", + "waf": "性能" + }, + { + "category": "運營管理", + "guid": "87ab177a-db59-4f6b-a613-334fd09dc234", + "id": "C02.03", + "link": "https://docs.openshift.com/container-platform/4.13/machine_management/applying-autoscaling.html", + "severity": "高", + "subcategory": "性能", + "text": "定義 ClusterAutoScaler 和 MachineAutoScaler,以便在群集耗盡資源以支援更多部署時擴展電腦。", + "waf": "性能" + }, + { + "category": "運營管理", + "guid": "19db6128-1269-4040-a4ba-4d3e0804276d", + "id": "C03.01", + "link": "https://learn.microsoft.com/azure/openshift/support-policies-v4#supported-virtual-machine-sizes", + "severity": "高", + "subcategory": "可靠性", + "text": "使用足夠大以包含多個容器實例的虛擬機大小,以便獲得增加密度的好處,但又不能太大以至於群集無法處理故障節點的工作負載。", + "waf": "可靠性" + }, + { + "category": "運營管理", + "guid": "4b98b15c-8b31-4aa5-aceb-58889135e227", + "id": "C03.02", + "link": "https://docs.openshift.com/container-platform/4.13/machine_management/deploying-machine-health-checks.html", + "severity": "高", + "subcategory": "可靠性", + "text": "部署電腦運行狀況檢查以自動修復計算機池中損壞的電腦。", + "waf": "可靠性" + }, + { + "category": "運營管理", + "guid": "896d31b6-6c67-4ba5-a119-c08e8f5d587c", + "id": "C03.03", + "link": "https://learn.microsoft.com/azure/azure-monitor/containers/container-insights-metric-alerts", + "severity": "高", + "subcategory": "可靠性", + "text": "使用警報系統在需要直接操作時提供通知:容器見解指標警報或內置警報 UI。", + "waf": "可靠性" + }, + { + "category": "運營管理", + "guid": "7e9ced16-acd1-476e-b9b2-41a998a57ae7", + "id": "C03.04", + "link": "https://learn.microsoft.com/azure/reliability/availability-zones-overview#availability-zones", + "severity": "高", + "subcategory": "可靠性", + "text": "確保集群創建在支援可用區的地域,併為每個可用區創建一台機器。", + "waf": "可靠性" + }, + { + "category": "運營管理", + "guid": "7b997e71-1b7d-4a8c-baa6-6e15d4d5ada9", + "id": "C03.05", + "link": "https://docs.openshift.com/container-platform/4.13/machine_management/creating-infrastructure-machinesets.html", + "severity": "低", + "subcategory": "可靠性", + "text": "創建基礎架構機器集以容納基礎架構元件。將特定的 Kubernetes 標籤應用於這些電腦,然後更新基礎結構元件以僅在這些電腦上運行。", + "waf": "可靠性" + }, + { + "category": "運營管理", + "guid": "7dc3e232-6bb2-435c-905e-1696fdedfa8a", + "id": "C03.06", + "link": "https://learn.microsoft.com/azure/openshift/howto-create-a-backup#create-a-backup-with-velero-to-include-snapshots", + "severity": "中等", + "subcategory": "可靠性", + "text": "創建應用程式備份並規劃還原,並在備份中包括永久性卷。", + "waf": "可靠性" + }, + { + "category": "運營管理", + "guid": "81c12318-1a64-4174-8583-3fb4ae3c2df7", + "id": "C03.07", + "link": "https://docs.openshift.com/container-platform/4.13/nodes/pods/nodes-pods-priority.html", + "severity": "低", + "subcategory": "可靠性", + "text": "使用 Pod 優先順序,以便在資源有限的情況下運行最關鍵的 Pod。", + "waf": "可靠性" + }, + { + "category": "運營管理", + "guid": "43166c3b-cbe0-45bb-b209-d4a0da577784", + "id": "C04.01", + "link": "https://docs.openshift.com/container-platform/4.13/architecture/admission-plug-ins.html", + "severity": "低", + "subcategory": "安全", + "text": "使用准入外掛程式管理集群功能,這些外掛程式通常用於強制實施安全策略、資源限制或配置要求。", + "waf": "安全" + }, + { + "category": "運營管理", + "guid": "24d21678-5d2f-4a56-a56a-d48408fe8273", + "id": "C04.02", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-geo-replication", + "severity": "低", + "subcategory": "安全", + "text": "將容器映像存儲在 Azure 容器註冊表中,並將註冊表異地複製到每個區域。", + "waf": "安全" + }, + { + "category": "運營管理", + "guid": "4c486ba2-80dc-4059-8cf7-5ee8e1309ccc", + "id": "C05.01", + "link": "https://docs.openshift.com/container-platform/4.13/nodes/pods/nodes-pods-vertical-autoscaler.html", + "severity": "中等", + "subcategory": "工作量", + "text": "優化CPU和記憶體請求值,並使用垂直Pod自動縮放程式最大限度地提高集群資源的效率。", + "waf": "性能" + }, + { + "category": "運營管理", + "guid": "d579366b-cda2-4750-aa1a-bfe9d55d14c3", + "id": "C05.02", + "link": "https://docs.openshift.com/container-platform/4.13/applications/application-health.html", + "severity": "中等", + "subcategory": "工作量", + "text": "向Pod添加運行狀況探測以監視應用程式運行狀況。確保 Pod 包含 livenessProbe 和 readinessProbe。使用啟動探測器確定應用程式啟動的點。", + "waf": "可靠性" + }, + { + "category": "運營管理", + "guid": "c4929cb1-b3d1-4325-ae12-4ba34d0685ed", + "id": "C05.03", + "link": "https://docs.openshift.com/container-platform/4.13/nodes/pods/nodes-pods-autoscaling.html", + "severity": "中等", + "subcategory": "工作量", + "text": "使用水準 Pod 自動縮放程式縮放 Pod 以滿足需求。", + "waf": "可靠性" + }, + { + "category": "運營管理", + "guid": "dce9be3b-b0dd-4b3b-95fb-2ec14eeaa359", + "id": "C05.04", + "link": "https://docs.openshift.com/container-platform/4.13/nodes/pods/nodes-pods-configuring.html#nodes-pods-pod-distruption-about_nodes-pods-configuring", + "severity": "中等", + "subcategory": "工作量", + "text": "使用中斷預算來確保存在所需數量的 Pod 副本來處理預期的應用程式負載。", + "waf": "可靠性" + }, + { + "category": "運營管理", + "guid": "2829e2ed-b217-4367-9aff-6791b4935ada", + "id": "C05.05", + "link": "https://docs.openshift.com/container-platform/4.13/nodes/scheduling/nodes-scheduler-pod-topology-spread-constraints.html", + "severity": "中等", + "subcategory": "工作量", + "text": "使用 Pod 拓撲約束在整個集群的節點上自動調度 Pod。", + "waf": "可靠性" + }, + { + "category": "平臺自動化", + "guid": "42324ece-81c1-4231-a1a6-417415833fb4", + "id": "D01.01", + "link": "https://docs.openshift.com/container-platform/4.13/applications/deployments/route-based-deployment-strategies.html", + "severity": "低", + "subcategory": "工作量", + "text": "考慮使用藍/綠或金絲雀策略來部署新版本的應用程式。", + "waf": "操作" + }, + { + "category": "平臺自動化", + "guid": "ae3c2df7-4316-46c3-acbe-05bbe209d4a0", + "id": "D01.02", + "link": "https://docs.openshift.com/container-platform/4.13/cicd/gitops/understanding-openshift-gitops.html", + "severity": "低", + "subcategory": "工作量", + "text": "請考慮使用紅帽 OpenShift GitOps。Red Hat OpenShift GitOps 使用 Argo CD 來維護集群資源並支援應用 CI/CD。", + "waf": "操作" + }, + { + "category": "安全", + "guid": "da577784-24d2-4167-a5d2-fa56c56ad484", + "id": "E01.01", + "link": "https://learn.microsoft.com/azure/openshift/support-lifecycle", + "severity": "高", + "subcategory": "控制平面", + "text": "讓您的集群保持在最新的 OpenShift 版本上,以避免潛在的安全或升級問題。", + "waf": "安全" + }, + { + "category": "安全", + "guid": "08fe8273-4c48-46ba-880d-c0591cf75ee8", + "id": "E01.02", + "link": "https://learn.microsoft.com/azure/azure-arc/kubernetes/quickstart-connect-cluster", + "severity": "高", + "subcategory": "控制平面", + "text": "將 Azure Red Hat OpenShift 群集連接到已啟用 Azure Arc 的 Kubernetes。", + "waf": "安全" + }, + { + "category": "安全", + "guid": "e1309ccc-d579-4366-acda-2750aa1abfe9", + "id": "E02.01", + "link": "https://docs.openshift.com/container-platform/4.10/security/encrypting-etcd.html", + "severity": "低", + "subcategory": "加密", + "text": "對於 Azure Red Hat OpenShift 4 群集,預設情況下不會對 etcd 數據進行加密,但建議啟用 etcd 加密以提供另一層數據安全性。", + "waf": "安全" + }, + { + "category": "安全", + "guid": "d55d14c3-c492-49cb-8b3d-1325ae124ba3", + "id": "E03.01", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-introduction", + "severity": "中等", + "subcategory": "姿勢", + "text": "使用已啟用 Arc 的 Kubernetes 支援的 Microsoft Defender for Containers 來保護群集、容器和應用程式。", + "waf": "安全" + }, + { + "category": "安全", + "guid": "4d0685ed-dce9-4be3-ab0d-db3b55fb2ec1", + "id": "E04.01", + "link": "https://learn.microsoft.com/azure/azure-arc/kubernetes/tutorial-akv-secrets-provider", + "severity": "中等", + "subcategory": "秘密", + "text": "對於需要訪問敏感資訊的應用程式,請將服務主體和AKV機密提供程式與已啟用Arc的 Kubernetes 群集的擴展配合使用。", + "waf": "安全" + }, + { + "category": "安全", + "guid": "4eeaa359-2829-4e2e-bb21-73676aff6791", + "id": "E05.01", + "link": "https://learn.microsoft.com/azure/aks/developer-best-practices-pod-security#secure-pod-access-to-resources", + "severity": "中等", + "subcategory": "工作量", + "text": "保護 Pod 對資源的訪問。提供最少數量的許可權,並避免使用根或特權升級。", + "waf": "安全" + }, + { + "category": "安全", + "guid": "b4935ada-4232-44ec-b81c-123181a64174", + "id": "E05.02", + "link": "https://learn.microsoft.com/azure/governance/policy/concepts/policy-for-kubernetes#install-azure-policy-extension-for-azure-arc-enabled-kubernetes", + "severity": "中等", + "subcategory": "工作量", + "text": "使用 Azure Policy 擴展監視和強制實施配置。", + "waf": "安全" + }, + { + "category": "安全", + "guid": "15833fb4-ae3c-42df-9431-66c3bcbe05bb", + "id": "E05.03", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-introduction", + "severity": "高", + "subcategory": "工作量", + "text": "使用 Microsoft Defender 或任何其他圖像掃描解決方案掃描圖像以查找漏洞。", + "waf": "安全" + }, + { + "category": "安全", + "guid": "e209d4a0-da57-4778-924d-216785d2fa56", + "id": "E05.04", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-private-link", + "severity": "低", + "subcategory": "工作量", + "text": "將 Azure 容器註冊表的專用專用實例部署到每個登陸區域訂閱。", + "waf": "安全" + } + ], + "metadata": { + "name": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "state": " ", + "timestamp": "December 15, 2023" + }, + "severities": [ + { + "name": "高" + }, + { + "name": "中等" + }, + { + "name": "低" + } + ], + "status": [ + { + "description": "此檢查尚未查看", + "name": "未驗證" + }, + { + "description": "有一個與此檢查關聯的操作項", + "name": "打開" + }, + { + "description": "此檢查已經過驗證,沒有與之關聯的其他操作項", + "name": "實現" + }, + { + "description": "建議已理解,但當前要求不需要", + "name": "接受風險" + }, + { + "description": "不適用於當前設計", + "name": "不適用" + } + ], + "waf": [ + { + "name": "可靠性" + }, + { + "name": "安全" + }, + { + "name": "成本" + }, + { + "name": "操作" + }, + { + "name": "性能" + } + ], + "yesno": [ + { + "name": "是的" + }, + { + "name": "不" + } + ] +} \ No newline at end of file diff --git a/checklists/checklist.en.master.json b/checklists/checklist.en.master.json index 6df17d3aa..3d4f9d54b 100644 --- a/checklists/checklist.en.master.json +++ b/checklists/checklist.en.master.json @@ -1,22060 +1,22060 @@ { "items": [ { - "category": "Version Control", - "checklist": "Azure DevOps", - "description": "Implement branching policy in Azure DevOps", - "guid": "eda1dae2-cc85-4c47-a6b7-81cca0e6c465", + "category": "Security", + "checklist": "Azure Container Registry Security Review", + "description": "Disable image export to prevent data exfiltration. Note that this will prevent image import of images into another ACR instance.", + "guid": "ab91932c-9fc9-4d1b-a880-37f5e6bfcb9e", "id": "A01.01", - "link": "https://learn.microsoft.com/azure/devops/repos/git/branch-policies-overview?view=azure-devops", + "link": "https://learn.microsoft.com/azure/container-registry/data-loss-prevention", "services": [ - "AzurePolicy" + "ACR" ], "severity": "High", - "subcategory": "Branching Policy", - "text": " Branch Policies" + "subcategory": "Data Protection", + "text": "Disable Azure Container Registry image export", + "waf": "Security" }, { - "category": "Version Control", - "checklist": "Azure DevOps", - "description": "Understand branch strategy such as GitFlow or GitHub Flow", - "guid": "bc288bec-6a16-4ca7-8444-51e1add34529", + "category": "Security", + "checklist": "Azure Container Registry Security Review", + "description": "Enable audit compliance visibility by enabling Azure Policy for Azure Container Registry", + "guid": "d503547c-d447-4e82-9128-a7100f1cac6d", "id": "A01.02", - "link": "https://learn.microsoft.com/azure/devops/repos/git/git-branching-guidance?view=azure-devops", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-azure-policy", "services": [ + "ACR", "AzurePolicy" ], "severity": "High", - "subcategory": "Branching Policy", - "text": "Branching strategy" + "subcategory": "Data Protection", + "text": "Enable Azure Policies for Azure Container Registry", + "waf": "Security" }, { - "category": "Version Control", - "checklist": "Azure DevOps", - "description": "Understand how teams work with git", - "guid": "ec723823-7a15-41c5-ab4e-401914387e5c", + "category": "Security", + "checklist": "Azure Container Registry Security Review", + "description": "The Azure Key Vault (AKV) is used to store a signing key that can be utilized by?notation?with the notation AKV plugin (azure-kv) to sign and verify container images and other artifacts. The Azure Container Registry (ACR) allows you to attach these signatures using the?az?or?oras?CLI commands.", + "guid": "d345293c-7639-4637-a551-c5c04e401955", "id": "A01.03", - "link": "https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-tutorial-sign-build-push", "services": [ - "AzurePolicy" + "ACR", + "AKV" ], "severity": "High", - "subcategory": "Branching Policy", - "text": "Understand GitFlow Branch Strategy" + "subcategory": "Data Protection", + "text": "Sign and Verify containers with notation (Notary v2)", + "waf": "Security" }, { - "category": "Version Control", - "checklist": "Azure DevOps", - "description": "Merge into higher branches after two or more reviewers in a PR", - "guid": "a9c26c9c-32ab-45bd-8c69-98a246e33899", + "category": "Security", + "checklist": "Azure Container Registry Security Review", + "description": "Azure Container Registry automatically encrypts images and other artifacts that you store. By default, Azure automatically encrypts the registry content at rest by using service-managed keys. By using a customer-managed key, you can supplement default encryption with an additional encryption layer.", + "guid": "0bd05dc2-efd5-4d76-8d41-d2500cc47b49", "id": "A01.04", - "link": "https://learn.microsoft.com/azure/devops/repos/git/review-pull-requests?view=azure-devops&tabs=browser", + "link": "https://learn.microsoft.com/azure/container-registry/tutorial-customer-managed-keys", "services": [ - "AzurePolicy" + "ACR", + "AKV" + ], + "severity": "Medium", + "subcategory": "Data Protection", + "text": "Encrypt registry with a customer managed key", + "waf": "Security" + }, + { + "category": "Security", + "checklist": "Azure Container Registry Security Review", + "description": "Use managed identities to secure ACRPull/Push RBAC access from client applications", + "guid": "8f42d78e-79dc-47b3-9bd2-a1a27e7a8e90", + "id": "A02.01", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", + "services": [ + "ACR", + "RBAC", + "Entra" ], "severity": "High", - "subcategory": "Branching Policy", - "text": "Pull Request Review" + "subcategory": "Identity and Access Control", + "text": "Use Managed Identities to connect instead of Service Principals", + "waf": "Security" }, { - "category": "Version Control", - "checklist": "Azure DevOps", - "description": "Implement access control to the branches", - "guid": "7e41c77d-68cb-46a2-8ac1-9f916d697d8e", - "id": "A01.05", - "link": "https://learn.microsoft.com/azure/devops/repos/git/branch-permissions?view=azure-devops", + "category": "Security", + "checklist": "Azure Container Registry Security Review", + "description": "The local Administrator account is disabled by default and should not be enabled. Use either Token or RBAC-based access methods instead", + "guid": "be0e38ce-e297-411b-b363-caaab79b198d", + "id": "A02.02", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", "services": [ - "AzurePolicy" + "ACR", + "RBAC", + "Entra" ], - "severity": "Medium", - "subcategory": "Branching Policy", - "text": "Access Control to the Branch" + "severity": "High", + "subcategory": "Identity and Access Control", + "text": "Disable local authentication for management plane access", + "waf": "Security" }, { - "category": "Version Control", - "checklist": "Azure DevOps", - "description": "Perform SAST code scan", - "guid": "adfd27bd-e187-401a-a252-baa9b68a088c", - "id": "A02.01", - "link": "https://devblogs.microsoft.com/devops/integrate-security-into-your-developer-workflow-with-github-advanced-security-for-azure-devops/", - "services": [], + "category": "Security", + "checklist": "Azure Container Registry Security Review", + "description": "Disable Administrator account and assign RBAC roles to principals for ACR Pull/Push operations", + "guid": "387e5ced-126c-4d13-8af5-b20c6998a646", + "id": "A02.03", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-roles?tabs=azure-cli", + "services": [ + "ACR", + "RBAC", + "Entra" + ], "severity": "High", - "subcategory": "Security", - "text": "Code Scan" + "subcategory": "Identity and Access Control", + "text": "Assign AcrPull & AcrPush RBAC roles rather than granting Administrative access to identity principals", + "waf": "Security" }, { - "category": "Version Control", - "checklist": "Azure DevOps", - "description": "Understand TFVC as Code Repo", - "guid": "9a8f822b-8eb9-4d1b-a77f-26e5e6beba8e", - "id": "A03.01", - "link": "https://learn.microsoft.com/azure/devops/repos/tfvc/what-is-tfvc?view=azure-devops", - "services": [], - "severity": "Low", - "subcategory": "Practice", - "text": "TFVC as Code Repository" + "category": "Security", + "checklist": "Azure Container Registry Security Review", + "description": "Disable anonymous pull/push access", + "guid": "e338997e-41c7-47d7-acf6-a62a1194956d", + "id": "A02.04", + "link": "https://learn.microsoft.com/azure/container-registry/anonymous-pull-access#configure-anonymous-pull-access", + "services": [ + "ACR", + "Entra" + ], + "severity": "Medium", + "subcategory": "Identity and Access Control", + "text": "Disable Anonymous pull access", + "waf": "Security" }, { - "category": "Version Control", - "checklist": "Azure DevOps", - "description": "Compare Git vs TFVC for your project", - "guid": "d4f3437b-c336-4d71-9f27-a71eee0b9b5d", - "id": "A03.02", - "link": "https://learn.microsoft.com/azure/devops/repos/tfvc/comparison-git-tfvc?view=azure-devops", - "services": [], - "severity": "Low", - "subcategory": "Practice", - "text": "Choose Right version control" + "category": "Security", + "checklist": "Azure Container Registry Security Review", + "description": "Token authentication doesn't support assignment to an AAD principal. Any tokens provided are able to be used by anyone who can access the token", + "guid": "698dc3a2-fd27-4b2e-8870-1a1252beedf6", + "id": "A02.05", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication?tabs=azure-cli", + "services": [ + "ACR", + "Entra" + ], + "severity": "High", + "subcategory": "Identity and Access Control", + "text": "Disable repository-scoped access tokens", + "waf": "Security" }, { - "category": "Azure Boards", - "checklist": "Azure DevOps", - "description": "Set up your team management", - "guid": "8defd5d7-21d4-41d2-900c-807bf9eab40f", - "id": "B01.01", - "link": "https://learn.microsoft.com/azure/devops/organizations/settings/manage-teams?view=azure-devops", - "services": [], + "category": "Security", + "checklist": "Azure Container Registry Security Review", + "description": "Deploy container images to an ACR behind a Private endpoint within a trusted network", + "guid": "b3bec3d4-f343-47c1-936d-b55f27a71eee", + "id": "A02.06", + "services": [ + "ACR", + "EventHubs", + "PrivateLink", + "Entra" + ], "severity": "High", - "subcategory": "Team Planning", - "text": "Configure your teams" + "subcategory": "Identity and Access Control", + "text": "Deploy images from a trusted environment", + "waf": "Security" }, { - "category": "Azure Boards", - "checklist": "Azure DevOps", - "description": "Start scheduling sprints", - "guid": "9ed5b354-78d4-447a-a26c-2863c00f1cac", - "id": "B01.02", - "link": "https://learn.microsoft.com/azure/devops/boards/sprints/define-sprints?view=azure-devops", - "services": [], + "category": "Security", + "checklist": "Azure Container Registry Security Review", + "description": "Only tokens with an ACR audience can be used for authentication. Used when enabling Conditional access policies for ACR", + "guid": "3a041fd3-2947-498b-8288-b3c6a56ceb54", + "id": "A02.07", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-enable-conditional-access-policy", + "services": [ + "ACR", + "AzurePolicy", + "Entra" + ], "severity": "Medium", - "subcategory": "Team Planning", - "text": "Configure your sprints" + "subcategory": "Identity and Access Control", + "text": "Disable Azure ARM audience tokens for authentication", + "waf": "Security" }, { - "category": "Azure Boards", - "checklist": "Azure DevOps", - "description": "Set up your work item heirarchy", - "guid": "699ef1d5-a83d-4e5d-b36c-1c81870a0bc5", - "id": "B01.03", - "link": "https://learn.microsoft.com/azure/devops/organizations/settings/work/customize-process-work-item-type?view=azure-devops", - "services": [], - "severity": "Low", - "subcategory": "Team Planning", - "text": "Choose Work Item types" + "category": "Security", + "checklist": "Azure Container Registry Security Review", + "description": "Set up a diagnostic setting to send 'repositoryEvents' & 'LoginEvents' to Log Analytics as the central destination for logging and monitoring. This allows you to monitor control plane activity on the ACR resource itself.", + "guid": "8a488cde-c486-42bc-9bd2-1be77f26e5e6", + "id": "A03.01", + "link": "https://learn.microsoft.com/azure/container-registry/monitor-service", + "services": [ + "ACR", + "Monitor", + "Entra" + ], + "severity": "Medium", + "subcategory": "Logging and Monitoring", + "text": "Enable diagnostics logging", + "waf": "Security" }, { - "category": "Azure Boards", - "checklist": "Azure DevOps", - "description": "WIT Processes available in Azure DevOps", - "guid": "c1e43a18-658d-4285-aed6-7179b825546d", - "id": "B01.04", - "link": "https://learn.microsoft.com/azure/devops/boards/work-items/guidance/choose-process?view=azure-devops&tabs=agile-process", - "services": [], - "severity": "High", - "subcategory": "Team Planning", - "text": "Select a WIT Process" - }, - { - "category": "Azure Boards", - "checklist": "Azure DevOps", - "description": "Use Azure Boards with GitHub", - "guid": "f2aee455-3afc-4833-a248-726dd68c5b5c", - "id": "B02.01", - "link": "https://learn.microsoft.com/azure/devops/cross-service/github-integration?view=azure-devops", - "services": [], - "severity": "Low", - "subcategory": "Tool Integration", - "text": "GitHub Integration" - }, - { - "category": "Azure Boards", - "checklist": "Azure DevOps", - "description": "Understand the methologies", - "guid": "2925394b-69b9-4d37-aac4-3bc68d1d7665", - "id": "B03.01", - "link": "https://www.atlassian.com/agile/scrum/agile-vs-scrum", - "services": [], - "severity": "Medium", - "subcategory": "Process Planning", - "text": "Understand Agile Vs Scrum" - }, - { - "category": "Azure Boards", - "checklist": "Azure DevOps", - "description": "Create Dashboard and PowerBI reports", - "guid": "7246b448-564b-44dd-94a7-59c7633bd2a1", - "id": "B04.01", - "link": "https://learn.microsoft.com/azure/devops/report/dashboards/overview?view=azure-devops", - "services": [], - "severity": "Medium", - "subcategory": "Reporting", - "text": "Dashboard" - }, - { - "category": "Azure Boards", - "checklist": "Azure DevOps", - "description": "Set up backlog", - "guid": "a27a764a-90be-40e3-98ee-293c1bd363ca", - "id": "B04.02", - "link": "https://learn.microsoft.com/azure/devops/boards/backlogs/set-up-your-backlog?view=azure-devops", - "services": [], - "severity": "Medium", - "subcategory": "Reporting", - "text": "Refine your backlog" - }, - { - "category": "Azure Boards", - "checklist": "Azure DevOps", - "description": "Link your work items", - "guid": "aab75719-49ab-4919-9dc9-fc9d1bb84b37", - "id": "B04.03", - "link": "https://learn.microsoft.com/azure/devops/boards/queries/link-work-items-support-traceability?view=azure-devops&tabs=browser", - "services": [], - "severity": "Medium", - "subcategory": "Reporting", - "text": "Visualize Relationships" - }, - { - "category": "Azure Pipelines", - "checklist": "Azure DevOps", - "description": "View the velocity report", - "guid": "b5a67fcb-9ed5-4b35-978d-447a826c2863", - "id": "C01.01", - "link": "https://learn.microsoft.com/azure/devops/report/dashboards/team-velocity?view=azure-devops&tabs=in-context", - "services": [], - "severity": "Low", - "subcategory": "Reporting", - "text": "Review Team Velocity" - }, - { - "category": "Azure Pipelines", - "checklist": "Azure DevOps", - "description": "Create your first pipeline", - "guid": "c00f1cac-699e-4f1d-9a83-de5de36c1c81", - "id": "C02.01", - "link": "https://learn.microsoft.com/azure/devops/pipelines/create-first-pipeline?view=azure-devops&tabs=java%2Ctfs-2018-2%2Cbrowser", - "services": [], - "severity": "High", - "subcategory": "Continuous Integration", - "text": "Set up pipeline" - }, - { - "category": "Azure Pipelines", - "checklist": "Azure DevOps", - "description": "Specify events that trigger pipelines", - "guid": "870a0bc5-c1e4-43a1-a658-d2858ed67179", - "id": "C02.02", - "link": "https://learn.microsoft.com/azure/devops/pipelines/build/triggers?view=azure-devops", - "services": [], - "severity": "High", - "subcategory": "Continuous Integration", - "text": "Set Build triggers" - }, - { - "category": "Azure Pipelines", - "checklist": "Azure DevOps", - "description": "Use YAML to create build pipeline", - "guid": "b825546d-f2ae-4e45-93af-c8339248726d", - "id": "C02.03", - "link": "https://learn.microsoft.com/azure/devops/pipelines/customize-pipeline?view=azure-devops", - "services": [], - "severity": "Low", - "subcategory": "Continuous Integration", - "text": "Customize YAML Pipeline" - }, - { - "category": "Azure Pipelines", - "checklist": "Azure DevOps", - "description": "Use classic GUI editor to set up pipeline", - "guid": "d68c5b5c-2925-4394-a69b-9d379ac43bc6", - "id": "C02.04", - "link": "https://learn.microsoft.com/azure/devops/pipelines/get-started/pipelines-get-started?view=azure-devops&source=recommendations#define-pipelines-using-the-classic-interface", - "services": [], - "severity": "Medium", - "subcategory": "Continuous Integration", - "text": "Use GUI for pipeline" - }, - { - "category": "Azure Pipelines", - "checklist": "Azure DevOps", - "description": "Set up templates, parameters and expressions", - "guid": "8d1d7665-7246-4b44-a564-b4dd74a759c7", - "id": "C02.05", - "link": "https://learn.microsoft.com/azure/devops/pipelines/process/templates?view=azure-devops&pivots=templates-includes", - "services": [], - "severity": "Medium", - "subcategory": "Continuous Integration", - "text": "Configure Templates" - }, - { - "category": "Azure Pipelines", - "checklist": "Azure DevOps", - "description": "Set up jobs, stages and dependencies", - "guid": "633bd2a1-a27a-4764-a90b-e0e378ee293c", - "id": "C02.06", - "link": "https://learn.microsoft.com/azure/devops/pipelines/process/stages?view=azure-devops&tabs=yaml", - "services": [], - "severity": "High", - "subcategory": "Continuous Integration", - "text": "Jobs" - }, - { - "category": "Azure Pipelines", - "checklist": "Azure DevOps", - "description": "Set up conditions and Demands", - "guid": "1bd363ca-aab7-4571-a49a-b9193dc9fc9d", - "id": "C02.07", - "link": "https://learn.microsoft.com/azure/devops/pipelines/process/conditions?view=azure-devops&tabs=yaml%2Cstages", - "services": [], - "severity": "Medium", - "subcategory": "Continuous Integration", - "text": "Conditions and Demands" - }, - { - "category": "Azure Pipelines", - "checklist": "Azure DevOps", - "description": "Define Variables", - "guid": "1bb84b37-b5a6-47fc-a9ed-5b35478d447a", - "id": "C02.08", - "link": "https://learn.microsoft.com/azure/devops/pipelines/process/variables?view=azure-devops&tabs=yaml%2Cbatch", - "services": [], - "severity": "High", - "subcategory": "Continuous Integration", - "text": "Variables" - }, - { - "category": "Azure Pipelines", - "checklist": "Azure DevOps", - "description": "Set up your deployment pipeline", - "guid": "826c2863-c00f-41ca-a699-ef1d5a83de5d", - "id": "C03.01", - "link": "https://learn.microsoft.com/azure/devops/pipelines/process/create-multistage-pipeline?view=azure-devops", - "services": [], - "severity": "High", - "subcategory": "Continuous Deployment", - "text": "Deployment Pipeline" - }, - { - "category": "Azure Pipelines", - "checklist": "Azure DevOps", - "description": "Select correct branches to deploy from", - "guid": "e36c1c81-870a-40bc-9c1e-43a18658d285", - "id": "C03.02", - "link": "https://learn.microsoft.com/azure/devops/pipelines/release/deploy-multiple-branches?view=azure-devops", - "services": [], - "severity": "Medium", - "subcategory": "Continuous Deployment", - "text": "Release branch", - "training": "https://learn.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview" - }, - { - "category": "Azure Pipelines", - "checklist": "Azure DevOps", - "description": "use relevant template to deploy to azure", - "guid": "8ed67179-b825-4546-bf2a-ee4553afc833", - "id": "C03.03", - "link": "https://learn.microsoft.com/azure/devops/pipelines/overview-azure?view=azure-devops", - "services": [], - "severity": "Medium", - "subcategory": "Continuous Deployment", - "text": "Deploy to Azure" - }, - { - "category": "Azure Pipelines", - "checklist": "Azure DevOps", - "description": "Define Release Approvals and pre deployment checks", - "guid": "9248726d-d68c-45b5-a292-5394b69b9d37", - "id": "C03.04", - "link": "https://learn.microsoft.com/azure/devops/pipelines/process/approvals?view=azure-devops&tabs=check-pass", - "services": [], - "severity": "Medium", - "subcategory": "Continuous Deployment", - "text": "Approvals and Checks", - "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/" - }, - { - "category": "Azure Pipelines", - "checklist": "Azure DevOps", - "description": "Define Gates and post deployment checks", - "guid": "9ac43bc6-8d1d-4766-9724-6b448564b4dd", - "id": "C03.05", - "link": "https://learn.microsoft.com/azure/devops/pipelines/release/approvals/?view=azure-devops&tabs=yaml", - "services": [], - "severity": "Medium", - "subcategory": "Continuous Deployment", - "text": "Gates" - }, - { - "category": "Azure Pipelines", - "checklist": "Azure DevOps", - "description": "Define Azure Function and REST API Checks", - "guid": "74a759c7-633b-4d2a-8a27-a764a90be0e3", - "id": "C03.06", - "link": "https://learn.microsoft.com/azure/devops/pipelines/process/invoke-checks?view=azure-devops", - "services": [], - "severity": "Low", - "subcategory": "Continuous Deployment", - "text": "Azure Function Checks", - "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/" - }, - { - "category": "Azure Pipelines", - "checklist": "Azure DevOps", - "description": "Review pipeline reports", - "guid": "78ee293c-1bd3-463c-aaab-7571949ab919", - "id": "C03.07", - "link": "https://learn.microsoft.com/azure/devops/pipelines/reports/pipelinereport?view=azure-devops", - "services": [], - "severity": "High", - "subcategory": "Continuous Deployment", - "text": "Pipline Reports", - "training": "https://learn.microsoft.com/learn/modules/plan-implement-administer-conditional-access/" - }, - { - "category": "Azure Pipelines", - "checklist": "Azure DevOps", - "description": "configure Trend Result widget", - "guid": "3dc9fc9d-1bb8-44b3-9b5a-67fcb9ed5b35", - "id": "C04.01", - "link": "https://learn.microsoft.com/azure/devops/report/dashboards/analytics-widgets?toc=%2Fazure%2Fdevops%2Fpipelines%2Ftoc.json&view=azure-devops#test-results-trend-advanced", - "services": [], - "severity": "Medium", - "subcategory": "Analytics", - "text": "Pipeline Result Trend", - "training": "https://learn.microsoft.com/learn/modules/secure-aad-users-with-mfa/" - }, - { - "category": "Azure Pipelines", - "checklist": "Azure DevOps", - "description": "Connect with WIT to visualize work", - "guid": "478d447a-826c-4286-9c00-f1cac699ef1d", - "id": "C04.02", - "link": "https://learn.microsoft.com/azure/devops/pipelines/integrations/configure-pipelines-work-tracking?view=azure-devops&tabs=yaml", - "services": [], - "severity": "Medium", - "subcategory": "Analytics", - "text": "Work Tracking with Pipeline", - "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-identities-governance/" - }, - { - "category": "Azure Pipelines", - "checklist": "Azure DevOps", - "description": "Understand agent pools", - "guid": "5a83de5d-e36c-41c8-8870-a0bc5c1e43a1", - "id": "C05.01", - "link": "https://learn.microsoft.com/azure/devops/pipelines/agents/agents?view=azure-devops&tabs=yaml%2Cbrowser", - "services": [], - "severity": "Medium", - "subcategory": "Continuous Deployment", - "text": " Agents and agent pools", - "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/" - }, - { - "category": "Azure Pipelines", - "checklist": "Azure DevOps", - "description": "Understand and provision Deployment Groups when required", - "guid": "8658d285-8ed6-4717-ab82-5546df2aee45", - "id": "C05.02", - "link": "https://learn.microsoft.com/azure/devops/pipelines/release/deployment-groups/?view=azure-devops", - "services": [], - "severity": "Low", - "subcategory": "Continuous Deployment", - "text": "Deployment Groups", - "training": "https://learn.microsoft.com/learn/modules/explore-basic-services-identity-types/" - }, - { - "category": "Azure Pipelines", - "checklist": "Azure DevOps", - "description": "Understand Kubernetes Deployment", - "guid": "53afc833-9248-4726-bd68-c5b5c2925394", - "id": "C05.03", - "link": "https://learn.microsoft.com/azure/devops/pipelines/ecosystems/kubernetes/deploy?view=azure-devops", - "services": [ - "AKS" - ], - "severity": "Low", - "subcategory": "Continuous Deployment", - "text": "Deploy to Kubernetes", - "training": "https://learn.microsoft.com/learn/paths/manage-identity-and-access/" - }, - { - "category": "Azure Pipelines", - "checklist": "Azure DevOps", - "description": "Perform Dynamic Security Testing", - "guid": "b69b9d37-9ac4-43bc-98d1-d76657246b44", - "id": "C06.01", - "link": "https://devblogs.microsoft.com/premier-developer/azure-devops-pipelines-leveraging-owasp-zap-in-the-release-pipeline/", - "services": [], - "severity": "Medium", - "subcategory": "Security", - "text": "DAST Scan", - "training": "https://learn.microsoft.com/learn/modules/create-custom-azure-roles-with-rbac/" - }, - { - "category": "Azure Pipelines", - "checklist": "Azure DevOps", - "description": "Manage Service Connections", - "guid": "8564b4dd-74a7-459c-9633-bd2a1a27a764", - "id": "C06.02", - "link": "https://learn.microsoft.com/azure/devops/pipelines/library/service-endpoints?view=azure-devops&tabs=yaml", - "services": [], - "severity": "Medium", - "subcategory": "Security", - "text": "Service Connections", - "training": "https://learn.microsoft.com/learn/paths/secure-your-cloud-data/" - }, - { - "category": "Azure Pipelines", - "checklist": "Azure DevOps", - "description": "Set data retention policies for CI and CD", - "guid": "a90be0e3-78ee-4293-a1bd-363caaab7571", - "id": "C06.03", - "link": "https://learn.microsoft.com/azure/devops/pipelines/policies/retention?view=azure-devops&tabs=yaml", + "category": "Security", + "checklist": "Azure Container Registry Security Review", + "description": "Service supports disabling public network access either through using service-level IP ACL filtering rule (not NSG or Azure Firewall) or using a 'Disable Public Network Access' toggle switch", + "guid": "21d41d25-00b7-407a-b9ea-b40fd3290798", + "id": "A04.01", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-private-link", "services": [ - "AzurePolicy" - ], - "severity": "Medium", - "subcategory": "Security", - "text": "Retention Policies", - "training": "https://learn.microsoft.com/learn/modules/azure-active-directory/" - }, - { - "category": "Azure Pipelines", - "checklist": "Azure DevOps", - "description": "Set up and pay for concurrent pipelines", - "guid": "949ab919-3dc9-4fc9-b1bb-84b37b5a67fc", - "id": "C07.01", - "link": "https://learn.microsoft.com/azure/devops/pipelines/licensing/concurrent-jobs?view=azure-devops&tabs=ms-hosted", - "services": [], - "severity": "Low", - "subcategory": "Administration", - "text": "Parallel Pipelines", - "training": "https://learn.microsoft.com/learn/modules/implement-hybrid-identity-windows-server/" - }, - { - "category": "Azure Pipelines", - "checklist": "Azure DevOps", - "description": "Set pipeline permissions", - "guid": "b9ed5b35-478d-4447-a826-c2863c00f1ca", - "id": "C08.01", - "link": "https://learn.microsoft.com/azure/devops/pipelines/policies/permissions?view=azure-devops", - "services": [], - "severity": "Medium", - "subcategory": "Security", - "text": "Pipeline Permissions", - "training": "https://learn.microsoft.com/learn/paths/implement-windows-server-iaas-virtual-machine-identity/" - }, - { - "category": "Azure Pipelines", - "checklist": "Azure DevOps", - "description": "Add users to pipeline", - "guid": "c699ef1d-5a83-4de5-be36-c1c81870a0bc", - "id": "C08.02", - "link": "https://learn.microsoft.com/azure/devops/pipelines/policies/set-permissions?view=azure-devops", - "services": [], - "severity": "Low", - "subcategory": "Security", - "text": "Pipeline Users", - "training": "https://learn.microsoft.com/learn/paths/implement-applications-external-access-azure-ad/" - }, - { - "category": "Azure Artifact", - "checklist": "Azure DevOps", - "description": "Configure Artifacts", - "guid": "5c1e43a1-8658-4d28-98ed-67179b825546", - "id": "D01.01", - "link": "https://learn.microsoft.com/azure/devops/pipelines/artifacts/artifacts-overview?view=azure-devops&tabs=nuget", - "services": [], - "severity": "Medium", - "subcategory": "Configuration", - "text": "Artifact In Pipeline", - "training": "https://learn.microsoft.com/learn/modules/design-identity-security-strategy/" - }, - { - "category": "Azure Artifact", - "checklist": "Azure DevOps", - "description": "Publish and consume artifact in pipeline", - "guid": "df2aee45-53af-4c83-9924-8726dd68c5b5", - "id": "D01.02", - "link": "https://learn.microsoft.com/azure/devops/pipelines/artifacts/pipeline-artifacts?view=azure-devops&tabs=yaml", - "services": [], + "ACR", + "VNet", + "PrivateLink", + "Firewall" + ], "severity": "Medium", - "subcategory": "Configuration", - "text": "Publish and download Artifact", - "training": "https://learn.microsoft.com/azure/architecture/example-scenario/identity/adds-extend-domain" + "subcategory": "Network Security", + "text": "Control inbound network access with Private Link", + "waf": "Security" }, { - "category": "Azure Artifact", - "checklist": "Azure DevOps", - "description": "Publish NuGet packages with artifacts", - "guid": "c2925394-b69b-49d3-99ac-43bc68d1d766", - "id": "D01.03", - "link": "https://learn.microsoft.com/azure/devops/pipelines/artifacts/nuget?view=azure-devops&tabs=yaml", - "services": [], - "severity": "Low", - "subcategory": "Configuration", - "text": "NuGet", - "training": "https://learn.microsoft.com/azure/role-based-access-control/overview" + "category": "Security", + "checklist": "Azure Container Registry Security Review", + "description": "Disable public network access if inbound network access is secured using Private Link", + "guid": "cd289ced-6b17-4db8-8554-62f2aee4553a", + "id": "A04.02", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-access-selected-networks#disable-public-network-access", + "services": [ + "ACR", + "PrivateLink" + ], + "severity": "Medium", + "subcategory": "Network Security", + "text": "Disable Public Network access", + "waf": "Security" }, { - "category": "Azure Artifact", - "checklist": "Azure DevOps", - "description": "Publish Maven packages with artifacts", - "guid": "57246b44-8564-4b4d-b74a-759c7633bd2a", - "id": "D01.04", - "link": "https://learn.microsoft.com/azure/devops/pipelines/artifacts/publish-maven-artifacts?view=azure-devops", - "services": [], - "severity": "Low", - "subcategory": "Configuration", - "text": "Maven" + "category": "Security", + "checklist": "Azure Container Registry Security Review", + "description": "Only the ACR Premium SKU supports Private Link access", + "guid": "fc833934-8b26-42d6-ac5f-512925498f6d", + "id": "A04.03", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-skus", + "services": [ + "ACR", + "PrivateLink" + ], + "severity": "Medium", + "subcategory": "Network Security", + "text": "Use an Azure Container Registry SKU that supports Private Link (Premium SKU)", + "waf": "Security" }, { - "category": "Azure Artifact", - "checklist": "Azure DevOps", - "description": "Publish NPM packages with artifacts", - "guid": "1a27a764-a90b-4e0e-978e-e293c1bd363c", - "id": "D01.05", - "link": "https://learn.microsoft.com/azure/devops/pipelines/artifacts/npm?view=azure-devops&tabs=yaml", - "services": [], + "category": "Security", + "checklist": "Azure Container Registry Security Review", + "description": "Azure Defender for containers or equivalent service should be used to scan container images for vulnerabilities", + "guid": "bad37dac-43bc-46ce-8d7a-a9b24604489a", + "id": "A04.04", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-introduction", + "services": [ + "ACR", + "Defender" + ], "severity": "Low", - "subcategory": "Configuration", - "text": "NPM" + "subcategory": "Network Security", + "text": "Enable Defender for Containers to scan Azure Container Registry for vulnerabilities", + "waf": "Security" }, { - "category": "Azure Artifact", - "checklist": "Azure DevOps", - "description": "Best Practices to work with Azure Artifact", - "guid": "aaab7571-949a-4b91-a3dc-9fc9d1bb84b3", - "id": "D01.06", - "link": "https://learn.microsoft.com/azure/devops/artifacts/concepts/best-practices?view=azure-devops", - "services": [], + "category": "Security", + "checklist": "Azure Container Registry Security Review", + "description": "Deploy trusted code that was validated and scanned for vulnerabilities according to DevSecOps practices.", + "guid": "4451e1a2-d345-4293-a763-9637a551c5c0", + "id": "A05.01", + "services": [ + "ACR" + ], "severity": "Medium", - "subcategory": "Configuration", - "text": "Best Practices" + "subcategory": "Vulnerability Management", + "text": "Deploy validated container images", + "waf": "Security" }, { - "category": "DevOps Practice", - "checklist": "Azure DevOps", - "description": "What is monitoring?", - "guid": "7b5a67fc-b9ed-45b3-9478-d447a826c286", - "id": "E01.01", - "link": "https://learn.microsoft.com/devops/operate/what-is-monitoring", + "category": "Security", + "checklist": "Azure Container Registry Security Review", + "description": "Use the latest versions of supported platforms, programming languages, protocols, and frameworks.", + "guid": "4e401955-387e-45ce-b126-cd132af5b20c", + "id": "A05.02", "services": [ - "Monitor" + "ACR" ], "severity": "High", - "subcategory": "Practice", - "text": "What to monitor?" + "subcategory": "Vulnerability Management", + "text": "Use up-to-date platforms, languages, protocols and frameworks", + "waf": "Security" }, { - "category": "DevOps Practice", - "checklist": "Azure DevOps", - "description": "Progressive Exposure Strategy", - "guid": "3c00f1ca-c699-4ef1-b5a8-3de5de36c1c8", - "id": "E01.02", - "link": "https://learn.microsoft.com/devops/operate/safe-deployment-practices", - "services": [], + "category": "BCDR", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Ensure data repositories for the backup solution are stored outside of vSAN storage. Either in Azure native or on a disk pool-backed datastore", + "guid": "976f32a7-30d1-6caa-c2a0-207fdc26571b", + "id": "A01.01", + "link": "https://learn.microsoft.com/azure/azure-vmware/set-up-backup-server-for-azure-vmware-solution", + "services": [ + "AVS", + "Backup", + "Storage" + ], "severity": "Medium", - "subcategory": "Practice", - "text": "Safe Deployment Practices" - }, - { - "category": "DevOps Practice", - "checklist": "Azure DevOps", - "description": "Microsoft runs reliable systems with DevOps", - "guid": "1870a0bc-5c1e-443a-8865-8d2858ed6717", - "id": "E01.03", - "link": "https://learn.microsoft.com/devops/operate/how-microsoft-operates-devops", - "services": [], - "severity": "Low", - "subcategory": "Practice", - "text": "Case Study", - "training": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment" + "subcategory": "Backup", + "text": "Ensure backups are not stored on vSAN as vSAN is a finite resource", + "waf": "Reliability" }, { - "category": "DevOps Practice", - "checklist": "Azure DevOps", - "description": "Security in DevOps", - "guid": "9b825546-df2a-4ee4-953a-fc8339248726", - "id": "E01.04", - "link": "https://learn.microsoft.com/devops/operate/security-in-devops", - "services": [], + "category": "BCDR", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Microsoft backup service", + "guid": "fc8af7a1-c724-e255-c18d-4ca22a6f27f0", + "id": "A02.01", + "link": "https://docs.microsoft.com/azure/azure-vmware/set-up-backup-server-for-azure-vmware-solution", + "services": [ + "AVS", + "Backup" + ], "severity": "Medium", - "subcategory": "Practice", - "text": "DevSecOps" + "subcategory": "Business Continuity", + "text": "Use MABS as your backup solution", + "waf": "Reliability" }, { - "category": "DevOps Practice", - "checklist": "Azure DevOps", - "description": "Enable DevSecops with Azure And GitHub", - "guid": "dd68c5b5-c292-4539-9b69-b9d379ac43bc", - "id": "E01.05", - "link": "https://learn.microsoft.com/devops/devsecops/enable-devsecops-azure-github", - "services": [], - "severity": "Low", - "subcategory": "Practice", - "text": "DevSecops", - "training": "https://learn.microsoft.com/learn/paths/architect-infrastructure-operations/" + "category": "BCDR", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Best practice - this is Backup, not disaster recovery", + "guid": "be28860f-3d29-a79a-1a0e-36f1b23b36ae", + "id": "A02.02", + "link": "Best practice to deploy backup in the same region as your AVS deployment", + "services": [ + "AVS", + "ASR", + "Backup" + ], + "severity": "Medium", + "subcategory": "Business Continuity", + "text": "Deploy your backup solution in the same region as your Azure VMware Solution private cloud", + "waf": "Reliability" }, { - "category": "DevOps Practice", - "checklist": "Azure DevOps", - "description": "Mirror RBAC in DevOps", - "guid": "68d1d766-5724-46b4-9856-4b4dd74a759c", - "id": "E01.06", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/secure/best-practices/end-to-end-governance", + "category": "BCDR", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Best practice - in case AVS is unavailable", + "guid": "4d2f79a5-4ccf-0dfc-557c-49619b99a540", + "id": "A02.03", + "link": "https://docs.microsoft.com/azure/azure-vmware/set-up-backup-server-for-azure-vmware-solution", "services": [ - "RBAC" + "AVS" ], - "severity": "Low", - "subcategory": "Practice", - "text": "Secure DevOps Govenance", - "training": "https://learn.microsoft.com/learn/paths/architect-infrastructure-operations/" + "severity": "Medium", + "subcategory": "Business Continuity", + "text": "Preferably deploy MABS outside of the SDDC as native Azure IaaS", + "waf": "Reliability" }, { - "category": "DevOps Practice", - "checklist": "Azure DevOps", - "description": "Governance when using CI/CD", - "guid": "7633bd2a-1a27-4a76-9a90-be0e378ee293", - "id": "E01.07", - "link": "https://learn.microsoft.com/azure/architecture/example-scenario/governance/end-to-end-governance-in-azure", - "services": [], + "category": "BCDR", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Is a process in place to request a restore of the VMware components managed by the Azure Platform?", + "guid": "ff431c40-962c-5182-d536-0c2f0c4ce9e0", + "id": "A02.04", + "link": "Will Disaster Recovery Site Recovery, HCX Disaster Recovery, SRM or back tools be used?", + "services": [ + "AVS" + ], "severity": "Medium", - "subcategory": "Practice", - "text": "Azure DevOps Governance", - "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/" + "subcategory": "Business Continuity", + "text": "Escalation process with Microsoft in the event of a regional DR", + "waf": "Reliability" }, { - "category": "Business", - "checklist": "Multitenant architecture", - "guid": "41177955-fe8f-430b-ae72-20dc5b6880da", - "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/overview", + "category": "BCDR", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Compare SRM with HCX", + "guid": "f379436d-3051-daa0-01fb-dc4e0e04d677", + "id": "A03.01", + "link": "https://docs.microsoft.com/azure/azure-vmware/disaster-recovery-using-vmware-site-recovery-manager", "services": [ - "Entra" + "AVS", + "ASR" ], - "severity": "High", - "subcategory": "Business", - "text": "Understand what kind of solution you're creating, such as business-to-business (B2B), business-to-consumer (B2C), or your enterprise software, and how tenants are different from users." + "severity": "Medium", + "subcategory": "Disaster Recovery", + "text": "Use VMware Site Recovery Manager when both sites are Azure VMware Solution", + "waf": "Reliability" }, { - "category": "Business", - "checklist": "Multitenant architecture", - "guid": "2d33d1b7-697c-49f9-b944-afbeac0b2c8f", - "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/considerations/tenancy-models", - "services": [], - "severity": "High", - "subcategory": "Business", - "text": "Define your tenants. Understand how many tenants you will support initially, and your growth plans." + "category": "BCDR", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Recovery into Azure instead of Vmware solution", + "guid": "367f71d8-3cf6-51a0-91a5-3db3d570cc19", + "id": "A03.02", + "link": "https://docs.microsoft.com/azure/site-recovery/avs-tutorial-prepare-azure", + "services": [ + "AVS", + "ASR" + ], + "severity": "Medium", + "subcategory": "Disaster Recovery", + "text": "Use Azure Site Recovery when the Disaster Recovery technology is native Azure IaaS", + "waf": "Reliability" }, { - "category": "Business", - "checklist": "Multitenant architecture", - "guid": "a2111b8b-cc66-4aa2-9da6-c09fa23851b6", - "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/considerations/pricing-models", - "services": [], - "severity": "High", - "subcategory": "Business", - "text": "Define your pricing model and ensure it aligns with your tenants' consumption of Azure resources." + "category": "BCDR", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Avoid manual tasks as much as possible", + "guid": "ee02ada0-1887-bb3a-b84c-423f45a09ef9", + "id": "A03.03", + "link": "https://docs.microsoft.com/azure/site-recovery/avs-tutorial-prepare-azure", + "services": [ + "AVS", + "ASR" + ], + "severity": "Medium", + "subcategory": "Disaster Recovery", + "text": "Use Automated recovery plans with either of the Disaster solutions,", + "waf": "Reliability" }, { - "category": "Business", - "checklist": "Multitenant architecture", - "guid": "331e84a6-2d65-4359-92ff-a1870b062995", - "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/considerations/pricing-models", - "services": [], + "category": "BCDR", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Any other datacenter in the same region", + "guid": "0c2b74e5-9c28-780d-1df3-12d3de4aaa76", + "id": "A03.04", + "link": "https://docs.microsoft.com/azure/azure-vmware/connect-multiple-private-clouds-same-region", + "services": [ + "AVS", + "ASR" + ], "severity": "Medium", - "subcategory": "Business", - "text": "Understand whether you need to separate your tenants into different tiers. Tiers might have different pricing, features, performance promises, geographic locations, and so forth." + "subcategory": "Disaster Recovery", + "text": "Configure a secondary disaster recovery environment", + "waf": "Reliability" }, { - "category": "Business", - "checklist": "Multitenant architecture", - "guid": "90516b37-aab1-46ca-95bb-cc14a6a1608b", - "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/considerations/tenancy-models", - "services": [], + "category": "BCDR", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Use 2 different address spaces between the regions, for example: 10.0.0.0/16 and 192.168.0.0/16 for the different regions", + "guid": "c2a34ec4-2933-4e6c-dc36-e20e67abbe3f", + "id": "A03.05", + "link": "https://docs.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing", + "services": [ + "AVS", + "ASR" + ], "severity": "Medium", - "subcategory": "Business", - "text": "Based on your customers' requirements, decide on the tenancy models that are appropriate for various parts of your solution." + "subcategory": "Disaster Recovery", + "text": "Assign IP ranges unique to each region", + "waf": "Reliability" }, { - "category": "Business", - "checklist": "Multitenant architecture", - "guid": "f5d76ae1-7048-4ff5-abba-f1ca799578b9", - "link": "https://learn.microsoft.com/azure/marketplace/plan-saas-offer", + "category": "BCDR", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "ExpressRoute Global Reach can be used for connectivity between the primary and secondary Azure VMware Solution Private Clouds or routing must be done through network virtual appliances?", + "guid": "b44fb6ec-bfc1-3a8e-dba2-ca97f0991d2c", + "id": "A03.06", + "link": "This depends if you have multiple AVS Private Clouds. If so and they are in the same region then use AVS Interconnect. If they are in separate regions then use ExpressRoute Global Reach.", "services": [ - "Entra" + "AVS", + "ASR", + "NVA", + "ExpressRoute" ], "severity": "Medium", - "subcategory": "Business", - "text": "When you're ready, sell your B2B multitenant solution using the Microsoft Commercial Marketplace." + "subcategory": "Disaster Recovery", + "text": "Use Global Reach between DR regions", + "waf": "Reliability" }, { - "category": "Reliability", - "checklist": "Multitenant architecture", - "guid": "9e7cedd9-1e05-4aeb-a7b3-01fe695a394c", - "link": "https://learn.microsoft.com/azure/architecture/framework/resiliency/design-checklist", - "services": [], - "severity": "High", - "subcategory": "Reliability", - "text": "Review the Azure Well-Architected Reliability checklist, which is applicable to all workloads." + "category": "Connectivity", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "An ExR Global Reach connection will be established to the ExR circuit, no other connections", + "guid": "a2c12df2-07fa-3edd-2cec-fda0b55fb952", + "id": "B01.01", + "link": "https://learn.microsoft.com/azure/azure-vmware/tutorial-expressroute-global-reach-private-cloud", + "services": [ + "AVS", + "VWAN" + ], + "severity": "Medium", + "subcategory": "Direct (no vWAN, no H&S)", + "text": "Global Reach to ExR circuit - no Azure resources", + "waf": "Performance" }, { - "category": "Reliability", - "checklist": "Multitenant architecture", - "guid": "e9521a55-2a7c-425c-8f3e-c38fd0c4df75", - "link": "https://learn.microsoft.com/azure/architecture/antipatterns/noisy-neighbor/noisy-neighbor", - "services": [], - "severity": "High", - "subcategory": "Reliability", - "text": "Understand the Noisy Neighbor antipattern. Prevent individual tenants from impacting the system's availability for other tenants." + "category": "Connectivity", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Use ExR to connect on-premises (other) location to Azure", + "guid": "f62ce162-ba5a-429d-674e-fafa1af5f706", + "id": "B02.01", + "link": "https://learn.microsoft.com/azure/azure-vmware/tutorial-expressroute-global-reach-private-cloud", + "services": [ + "AVS", + "ExpressRoute" + ], + "severity": "Medium", + "subcategory": "ExpressRoute", + "text": "Connect to Azure using ExR", + "waf": "Performance" }, { - "category": "Reliability", - "checklist": "Multitenant architecture", - "guid": "2b99cb00-9abb-49b6-b11c-f2af9692f09e", - "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/approaches/overview", - "services": [], + "category": "Connectivity", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Use the migration assesment tool and timeline to determine bandwidth required", + "guid": "cf01c73b-1247-0a7a-740c-e1ea29bda340", + "id": "B02.02", + "link": "https://learn.microsoft.com/azure/expressroute/expressroute-introduction", + "services": [ + "AVS", + "ExpressRoute" + ], "severity": "Medium", - "subcategory": "Reliability", - "text": "Design your multitenant solution for the level of growth that you expect. But don't overengineer for unrealistic growth." + "subcategory": "ExpressRoute", + "text": "Bandwidth sizing", + "waf": "Performance" }, { - "category": "Reliability", - "checklist": "Multitenant architecture", - "guid": "7a634a0e-1c9d-42b1-aac2-5a5378f103f1", - "link": "https://learn.microsoft.com/azure/architecture/framework/resiliency/business-metrics", - "services": [], + "category": "Connectivity", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "What traffic is routed through a firewall, what goes directly into Azure", + "guid": "aab216ee-8941-315e-eada-c7e1f2243bd1", + "id": "B02.03", + "link": "https://learn.microsoft.com/azure/architecture/solution-ideas/articles/azure-vmware-solution-foundation-networking", + "services": [ + "AVS", + "ExpressRoute" + ], "severity": "Medium", - "subcategory": "Reliability", - "text": "Define service-level objectives (SLOs) and optionally service-level agreements (SLAs) for your solution. SLAs and SLOs should be based on the requirements of your tenants, as well as the composite SLA of the Azure resources in your architecture." + "subcategory": "ExpressRoute", + "text": "Traffic routing ", + "waf": "Performance" }, { - "category": "Reliability", - "checklist": "Multitenant architecture", - "guid": "45beeeaf-fc59-4079-8fca-65d5724abaa7", - "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/approaches/compute", - "services": [], - "severity": "High", - "subcategory": "Reliability", - "text": "Test the scale of your solution. Ensure that it performs well under all levels of load, and that it scales correctly as the number of tenants increases." + "category": "Connectivity", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "AVS to ExR circuit, no traffic inspection", + "guid": "1f956e45-f62d-5c95-3a95-3bab718907f8", + "id": "B02.04", + "link": "https://learn.microsoft.com/azure/architecture/solution-ideas/articles/azure-vmware-solution-foundation-networking", + "services": [ + "AVS", + "ExpressRoute" + ], + "severity": "Medium", + "subcategory": "ExpressRoute", + "text": "Global Reach ", + "waf": "Performance" }, { - "category": "Reliability", - "checklist": "Multitenant architecture", - "guid": "2ff55551-984b-4606-95eb-bfb9c8b36761", - "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/approaches/compute", - "services": [], + "category": "Connectivity", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Name of the vNet and a unique address space /24 minimum", + "guid": "91f7a87b-21ac-d712-959c-8df2ba034253", + "id": "B03.01", + "link": "https://learn.microsoft.com/azure/virtual-network/quick-create-portal", + "services": [ + "AVS", + "VNet" + ], "severity": "Medium", - "subcategory": "Reliability", - "text": "Apply chaos engineering principles to test the reliability of your solution." + "subcategory": "Hub & Spoke", + "text": "VNet name & address space", + "waf": "Performance" }, { - "category": "Security", - "checklist": "Multitenant architecture", - "guid": "8238c038-8eb2-4a02-8bd5-4908c9442c1c", - "link": "https://learn.microsoft.com/security/zero-trust", - "services": [], - "severity": "High", - "subcategory": "Security", - "text": "Apply the Zero Trust and least privilege principles in all layers of your solution." + "category": "Connectivity", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Subnet must be called GatewaySubnet", + "guid": "58a027e2-f37f-b540-45d5-e44843aba26b", + "id": "B03.02", + "link": "https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings", + "services": [ + "AVS", + "VNet", + "VPN", + "ExpressRoute" + ], + "severity": "Medium", + "subcategory": "Hub & Spoke", + "text": "Gateway subnet", + "waf": "Performance" }, { - "category": "Security", - "checklist": "Multitenant architecture", - "guid": "92160e00-6894-4102-97e0-615d4ed93c01", - "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/considerations/map-requests", + "category": "Connectivity", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Create a VPN gateway on the hub Gateway subnet", + "guid": "d4806549-0913-3e79-b580-ac2d3706e65a", + "id": "B03.03", + "link": "https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings", "services": [ - "Entra" + "AVS", + "ExpressRoute", + "VNet", + "VPN" ], - "severity": "High", - "subcategory": "Security", - "text": "Ensure that you can correctly map user requests to tenants. Consider including the tenant context as part of the identity system, or by using another means, like application-level tenant authorization." + "severity": "Medium", + "subcategory": "Hub & Spoke", + "text": "VPN Gateway", + "waf": "Performance" }, { - "category": "Security", - "checklist": "Multitenant architecture", - "guid": "3c1538b4-5676-4b85-b451-432befb37b4f", - "link": "https://learn.microsoft.com/azure/security/fundamentals/pen-testing", - "services": [], + "category": "Connectivity", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Create an ExR Gateway in the hub Gateway subnet.", + "guid": "864d7a8b-7016-c769-a717-61af6bfb73d2", + "id": "B03.04", + "link": "https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings", + "services": [ + "AVS", + "VNet", + "VPN", + "ExpressRoute" + ], "severity": "Medium", - "subcategory": "Security", - "text": "Perform ongoing penetration testing and security code reviews." + "subcategory": "Hub & Spoke", + "text": "ExR Gateway", + "waf": "Performance" }, { - "category": "Security", - "checklist": "Multitenant architecture", - "guid": "5fca45ce-cf2d-42c0-a62c-aac92ba31498", - "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/approaches/governance-compliance", - "services": [], - "severity": "High", - "subcategory": "Security", - "text": "Understand your tenants' compliance requirements, including data residency and any compliance or regulatory standards that they require you to meet." + "category": "Connectivity", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "How will Internet traffic be routes, Az Firewall, NVA, Secure Hub, On-Premises firewall?", + "guid": "cc2e11b9-7911-7da1-458c-d7fcef794aad", + "id": "B04.01", + "link": "https://learn.microsoft.com/azure/azure-vmware/enable-public-internet-access", + "services": [ + "AVS", + "NVA" + ], + "severity": "Medium", + "subcategory": "Internet", + "text": "Egress point", + "waf": "Performance" }, { - "category": "Security", - "checklist": "Multitenant architecture", - "guid": "30adb90d-83d4-4a2e-986e-327ffe04e7a5", - "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/considerations/domain-names", + "category": "Connectivity", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Allow remote connectivity to AVS via the portal, specifically to vCenter, NSX-T and HCX", + "guid": "71e68ce3-982e-5e56-0191-01100ad0e66f", + "id": "B05.01", + "link": "https://learn.microsoft.com/answers/questions/171195/how-to-create-jump-server-in-azure-not-bastion-paa.html", "services": [ - "DNS" + "AVS", + "Bastion" ], - "severity": "High", - "subcategory": "Security", - "text": "Correctly manage domain names and avoid vulnerabilities like dangling DNS and subdomain takeover attacks." + "severity": "Medium", + "subcategory": "Jumpbox & Bastion", + "text": "Remote connectivity to AVS", + "waf": "Performance" }, { - "category": "Security", - "checklist": "Multitenant architecture", - "guid": "72ded36d-c633-4e0d-bd41-799a29da3481", - "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/service/overview", - "services": [], + "category": "Connectivity", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Name the jumpbox and identify the subnet where it will be hosted", + "guid": "6f8e93a2-44b1-bb1d-28a1-4d5b3c2ea857", + "id": "B05.02", + "link": "https://learn.microsoft.com/azure/bastion/tutorial-create-host-portal", + "services": [ + "AVS", + "Bastion", + "VNet" + ], "severity": "Medium", - "subcategory": "Security", - "text": "Follow service-specific guidance for multitenancy." + "subcategory": "Jumpbox & Bastion", + "text": "Configure a jumbox and Azure Bastion", + "waf": "Performance" }, { - "category": "Cost Optimization", - "checklist": "Multitenant architecture", - "guid": "db30a9fc-9b1d-40f3-ab90-01f6a3e87fc8", - "link": "https://learn.microsoft.com/azure/architecture/framework/cost/design-checklist", + "category": "Connectivity", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Provides secure / seamless RDP/SSH connectivity to your vm's directly through the portal.", + "guid": "ba430d58-4541-085c-3641-068c00be9bc5", + "id": "B05.03", + "link": "https://learn.microsoft.com/azure/virtual-network/network-security-groups-overview", "services": [ - "Cost" + "AVS", + "Bastion", + "VM" ], "severity": "Medium", - "subcategory": "Cost Optimization", - "text": "Review the Azure Well-Architected Operational Excellence checklist, which is applicable to all workloads." + "subcategory": "Jumpbox & Bastion", + "text": "Security measure allowing RDP access via the portal", + "waf": "Performance" }, { - "category": "Cost Optimization", - "checklist": "Multitenant architecture", - "guid": "8533af39-52f6-45b6-a9c3-81b2a54a31e0", - "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/considerations/measure-consumption", + "category": "Connectivity", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Using a VPN to connect to Azure to enable VMware communications (HCX) (not recommended)", + "guid": "9988598f-2a9f-6b12-9b46-488415ceb325", + "id": "B06.01", + "link": "https://learn.microsoft.com/azure/azure-vmware/configure-site-to-site-vpn-gateway", "services": [ - "Cost" + "AVS", + "VPN" ], - "severity": "High", - "subcategory": "Cost Optimization", - "text": "Ensure you can adequately measure per-tenant consumption and correlate it with your infrastructure costs." + "severity": "Medium", + "subcategory": "VPN", + "text": "Connect to Azure using a VPN", + "waf": "Performance" }, { - "category": "Cost Optimization", - "checklist": "Multitenant architecture", - "guid": "c851fd44-7cf1-459c-95a4-f6455d75a981", - "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/approaches/cost-management-allocation", + "category": "Connectivity", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Use the migration assesment tool and timeline to determine bandwidth required (eg 3rd party tool in link)", + "guid": "956ce5e9-a862-fe2b-a50d-a22923569357", + "id": "B06.02", + "link": "https://www.omnicalculator.com/other/data-transfer#:~:text=To%20calculate%20the%20data%20transfer%20speed%3A%201%20Download,measured%20time%20to%20find%20the%20data%20transfer%20speed.", "services": [ - "Monitor", - "Cost" + "AVS", + "VPN" ], "severity": "Medium", - "subcategory": "Cost Optimization", - "text": "Avoid antipatterns. Antipatterns include failing to track costs, tracking costs with unnecessary precision, real-time measurement, and using monitoring tools for billing." + "subcategory": "VPN", + "text": "Bandwidth sizing", + "waf": "Performance" }, { - "category": "Operational Excellence", - "checklist": "Multitenant architecture", - "guid": "0d475a5a-2c0f-47ab-b1e1-701da68d3407", - "link": "https://learn.microsoft.com/azure/architecture/checklist/data-ops", - "services": [], - "severity": "High", - "subcategory": "Operational Excellence", - "text": "Review the Azure Well-Architected Operational Excellence checklist, which is applicable to all workloads." + "category": "Connectivity", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "What traffic is routed through a firewall, what goes directly into Azure", + "guid": "e095116f-0bdc-4b51-4d71-b9e469d56f59", + "id": "B06.03", + "link": "https://learn.microsoft.com/azure/architecture/solution-ideas/articles/azure-vmware-solution-foundation-networking", + "services": [ + "AVS", + "VPN" + ], + "severity": "Medium", + "subcategory": "VPN", + "text": "Traffic routing ", + "waf": "Performance" }, { - "category": "Operational Excellence", - "checklist": "Multitenant architecture", - "guid": "9f7fa7a9-47fc-4f04-81f6-9f9e87571ed3", - "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/considerations/tenant-lifecycle", - "services": [], + "category": "Connectivity", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Name and unique address space for the vWAN, name for the vWAN hub", + "guid": "4dc480ac-cecd-39c4-fdc6-680b300716ab", + "id": "B07.01", + "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-site-to-site-portal#openvwan", + "services": [ + "AVS", + "VWAN" + ], "severity": "Medium", - "subcategory": "Operational Excellence", - "text": "Use automation to manage the tenant lifecycle, such as onboarding, deployment, provisioning, and configuration." + "subcategory": "vWAN hub", + "text": "vWAN name, hub name and address space", + "waf": "Performance" }, { - "category": "Operational Excellence", - "checklist": "Multitenant architecture", - "guid": "e0bfceed-4f4e-492d-b9f5-898815faa363", - "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/considerations/updates", - "services": [], + "category": "Connectivity", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Select either boh or the appropriate connection type.", + "guid": "51d6affd-8e02-6aea-d3d4-0baf618b3076", + "id": "B07.02", + "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-point-to-site-portal", + "services": [ + "AVS", + "VWAN", + "VPN" + ], "severity": "Medium", - "subcategory": "Operational Excellence", - "text": "Find the right balance for deploying service updates. Consider both your tenants' requirements and your own operational requirements." + "subcategory": "vWAN hub", + "text": "ExR and/or VPN gateway provisioned", + "waf": "Performance" }, { - "category": "Operational Excellence", - "checklist": "Multitenant architecture", - "guid": "a3f80518-d428-4c02-b2cc-dfaef47db7e2", + "category": "Connectivity", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Add Azure firewall to vWAN (recommended)", + "guid": "e32a4c67-3dc0-c134-1c12-52d46dcbab5b", + "id": "B07.03", + "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-expressroute-portal", "services": [ - "Monitor" + "AVS", + "VWAN", + "Firewall" ], - "severity": "High", - "subcategory": "Operational Excellence", - "text": "Monitor the health of the overall system, as well as each tenant." + "severity": "Medium", + "subcategory": "vWAN hub", + "text": "Secure vWAN", + "waf": "Security" }, { - "category": "Operational Excellence", - "checklist": "Multitenant architecture", - "guid": "dfb42da5-f871-4953-9e5c-da6fda3f1411", + "category": "Identity", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Active directory or other identity provider servers", + "guid": "fbc47fbf-bc96-fa93-ed5d-8c9be63cd5c3", + "id": "C01.01", + "link": "https://learn.microsoft.com/azure/azure-vmware/configure-identity-source-vcenter", "services": [ - "Monitor" + "AVS", + "Entra" ], "severity": "Medium", - "subcategory": "Operational Excellence", - "text": "Configure and test alerts to notify you when specific tenants are experiencing issues or are exceeding their consumption limits." - }, - { - "category": "Operational Excellence", - "checklist": "Multitenant architecture", - "guid": "c0c72a1b-e34d-4b3d-b808-2e49f51ce47e", - "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/approaches/resource-organization", - "services": [], - "severity": "High", - "subcategory": "Operational Excellence", - "text": "Organize your Azure resources for isolation and scale." + "subcategory": "Access", + "text": "External Identity (user accounts)", + "waf": "Security" }, { - "category": "Operational Excellence", - "checklist": "Multitenant architecture", - "guid": "c5c5e22d-4b51-4cac-a980-f7aac1a4b427", - "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/approaches/deployment-configuration", - "services": [], + "category": "Identity", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Not required for LDAPS, required for Kerberos", + "guid": "b5db7975-f6bb-8ba3-ee5f-e3e805887997", + "id": "C01.02", + "link": "https://learn.microsoft.com/windows-server/identity/ad-ds/plan/understanding-active-directory-site-topology", + "services": [ + "AVS", + "Entra" + ], "severity": "Medium", - "subcategory": "Operational Excellence", - "text": "Avoid deployment and configuration antipatterns. Antipatterns include running separate versions of the solution for each tenant, hardcoding tenant-specific configurations or logic, and manual deployments." - }, - { - "category": "Performance Efficiency", - "checklist": "Multitenant architecture", - "guid": "f0b1fbd8-689c-4ab3-be1d-ad7607d2fbfd", - "link": "https://learn.microsoft.com/azure/architecture/framework/scalability/performance-efficiency", - "services": [], - "severity": "High", - "subcategory": "Performance Efficiency", - "text": "Review the Azure Well-Architected Performance Efficiency checklist, which is applicable to all workloads." - }, - { - "category": "Performance Efficiency", - "checklist": "Multitenant architecture", - "guid": "18911c4c-934c-49a8-839a-60c092afce30", - "link": "https://learn.microsoft.com/azure/architecture/antipatterns/noisy-neighbor/noisy-neighbor", - "services": [], - "severity": "High", - "subcategory": "Performance Efficiency", - "text": "If you use shared infrastructure, plan for how you'll mitigate Noisy Neighbor concerns. Ensure that one tenant can't reduce the performance of the system for other tenants." + "subcategory": "Access", + "text": "If using AD domain, ensure Sites & Services has been configured", + "waf": "Security" }, { - "category": "Performance Efficiency", - "checklist": "Multitenant architecture", - "guid": "6acf7eb5-24a3-47c7-ae87-1196cd96048e", - "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/approaches/compute", + "category": "Identity", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Authentication for users, must be secure.", + "guid": "c30749c4-e2af-558c-2eb9-0b6ae84881d1", + "id": "C01.03", + "link": "https://learn.microsoft.com/azure/azure-vmware/configure-identity-source-vcenter", "services": [ - "Storage" + "AVS", + "Entra" ], "severity": "Medium", - "subcategory": "Performance Efficiency", - "text": "Determine how you'll scale your compute, storage, networking, and other Azure resources to match the demands of your tenants." - }, - { - "category": "Performance Efficiency", - "checklist": "Multitenant architecture", - "guid": "ea55400d-f97d-45aa-b71b-34224bf91ed4", - "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/approaches/resource-organization", - "services": [], - "severity": "High", - "subcategory": "Performance Efficiency", - "text": "Consider each Azure resource's scale limits. Organize your resources appropriately, in order to avoid resource organization antipatterns. For example, don't over-architect your solution to work within unrealistic scale requirements." + "subcategory": "Access", + "text": "Use LDAPS not ldap ( vCenter)", + "waf": "Security" }, { - "category": "Defender For Cloud", - "checklist": "Azure Security Review Checklist", - "guid": "54174158-33fb-43ae-9c2d-e743165c3acb", - "link": "https://learn.microsoft.com/azure/security-center/security-center-get-started", + "category": "Identity", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Authentication for users, must be secure.", + "guid": "64cb9b5c-9edd-787e-1dd8-2b2338e51635", + "id": "C01.04", + "link": "https://learn.microsoft.com/azure/azure-vmware/configure-external-identity-source-nsx-t", "services": [ - "Defender", - "Subscriptions" + "AVS", + "Entra" ], - "severity": "High", - "subcategory": "Pricing & Settings", - "text": "Security Center/Defender enable in all subscriptions" + "severity": "Medium", + "subcategory": "Access", + "text": "Use LDAPS not ldap (NSX-T)", + "waf": "Security" }, { - "category": "Defender For Cloud", - "checklist": "Azure Security Review Checklist", - "guid": "349f0364-d28d-442e-abbb-c868255abc91", - "link": "https://learn.microsoft.com/azure/security-center/enable-azure-defender", + "category": "Identity", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "CN or SAN names, no wildcards, contains private key - CER or PFX", + "guid": "bec285ab-037e-d629-81d1-f61dac23cd4c", + "id": "C02.01", + "link": "https://youtu.be/4jvfbsrhnEs", "services": [ - "Defender", - "Monitor" + "AVS", + "Entra" ], - "severity": "High", - "subcategory": "Pricing & Settings", - "text": "Security Center/Defender enabled on all Log Analytics workspaces" + "severity": "Medium", + "subcategory": "Security", + "text": "Security certificate installed on LDAPS servers ", + "waf": "Security" }, { - "category": "Defender For Cloud", - "checklist": "Azure Security Review Checklist", - "guid": "64e9a19a-e28c-484c-93b6-b7818ca0e6c4", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/enable-data-collection?tabs=autoprovision-feature#what-event-types-are-stored-for-common-and-minimal", + "category": "Identity", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Standard Azure Roles Based Access Controls", + "guid": "4ba394a2-3c33-104c-8e34-2dadaba9cc73", + "id": "C02.02", + "link": "https://learn.microsoft.com/azure/azure-vmware/concepts-identity", "services": [ - "Defender" + "AVS", + "RBAC", + "Entra" ], "severity": "Medium", - "subcategory": "Pricing & Settings", - "text": "Data collection set to 'Common'" + "subcategory": "Security", + "text": "RBAC applied to Azure roles", + "waf": "Security" }, { - "category": "Defender For Cloud", - "checklist": "Azure Security Review Checklist", - "guid": "2149d414-a923-4c35-94d1-1029bd6aaf11", - "link": "https://learn.microsoft.com/azure/security-center/enable-azure-defender", + "category": "Identity", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Create roles in vCenter required to meet minimum viable access guidelines", + "guid": "b04ca129-83a9-3494-7512-347dd2d766db", + "id": "C02.03", + "link": "https://learn.microsoft.com/azure/azure-vmware/concepts-identity#view-the-vcenter-server-privileges", "services": [ - "Defender" + "AVS", + "RBAC", + "Entra" ], - "severity": "High", - "subcategory": "Pricing & Settings", - "text": "Defender for Cloud enhanced security features are all enabled" + "severity": "Medium", + "subcategory": "Security", + "text": "RBAC model in vCenter", + "waf": "Security" }, { - "category": "Defender For Cloud", - "checklist": "Azure Security Review Checklist", - "guid": "e6b84ee5-ef43-4d29-a248-1718d5d1f5f7", - "link": "https://learn.microsoft.com/azure/security-center/security-center-enable-data-collection", + "category": "Identity", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "CloudAdmin account in vCenter IdP is used only as an emergency account (break-glass)", + "guid": "8e477d2f-8004-3dd0-93d6-0aece9e1b2fb", + "id": "C02.04", + "link": "Best practice", "services": [ - "AzurePolicy", - "Defender" + "AVS", + "RBAC", + "Entra" ], "severity": "Medium", - "subcategory": "Pricing & Settings", - "text": "Auto-provisioning enabled as per company policy (policy must exist)" + "subcategory": "Security", + "text": "CloudAdmin role usage", + "waf": "Security" }, { - "category": "Defender For Cloud", - "checklist": "Azure Security Review Checklist", - "guid": "25759e35-680e-4782-9ac9-32213d027ff4", - "link": "https://learn.microsoft.com/azure/security-center/security-center-provide-security-contact-details", + "category": "Identity", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "For roles managing the Azure VMware Solution resource in the Azure Portal (no standing permissions allowed)", + "guid": "00e0b729-f9be-f600-8c32-5ec0e8f2ed63", + "id": "C03.01", + "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-configure", "services": [ - "AzurePolicy", - "Defender" + "AVS", + "RBAC", + "Entra" ], - "severity": "Low", - "subcategory": "Pricing & Settings", - "text": "Email notifications enabled as per company policy (policy must exist)" + "severity": "Medium", + "subcategory": "Security ", + "text": "Is Privileged Identity Management implemented", + "waf": "Security" }, { - "category": "Defender For Cloud", - "checklist": "Azure Security Review Checklist", - "guid": "12f70993-0631-4583-9ee7-9d6c6d363206", - "link": "https://learn.microsoft.com/azure/security-center/security-center-wdatp?WT.mc_id=Portal-Microsoft_Azure_Security_CloudNativeCompute&tabs=windows", + "category": "Identity", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "For the Azure VMware Solution PIM roles", + "guid": "0842d45f-41a8-8274-1155-2f6ed554d315", + "id": "C03.02", + "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-configure", "services": [ - "Defender" + "AVS", + "RBAC", + "Entra" ], "severity": "Medium", - "subcategory": "Pricing & Settings", - "text": "Enable integrations options are selected " + "subcategory": "Security ", + "text": "Is Privileged Identity Management audit reporting implemented", + "waf": "Security" }, { - "category": "Defender For Cloud", - "checklist": "Azure Security Review Checklist", - "guid": "5b7abae4-4aad-45e8-a79e-2e86667313c5", - "link": "https://learn.microsoft.com/azure/security-center/defender-for-container-registries-cicd", + "category": "Identity", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Best practice, also see Monitoring/Alerts", + "guid": "915cbcd7-0640-eb7c-4162-9f33775de559", + "id": "C03.03", + "link": "Best practice", + "services": [ + "AVS", + "Monitor", + "Entra" + ], + "severity": "Medium", + "subcategory": "Security ", + "text": "Limit use of CloudAdmin account to emergency access only", + "waf": "Security" + }, + { + "category": "Identity", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Operational procedure", + "guid": "7effa0c0-9172-e8e4-726a-67dbea8be40a", + "id": "C03.04", + "link": "https://learn.microsoft.com/azure/azure-vmware/rotate-cloudadmin-credentials?tabs=azure-portal", "services": [ - "Defender" + "AVS", + "Entra" ], "severity": "Medium", - "subcategory": "Pricing & Settings", - "text": "CI/CD integration is configured" + "subcategory": "Security ", + "text": "Is a process defined to regularly rotate cloudadmin (vCenter) and admin (NSX) credentials", + "waf": "Security" }, { - "category": "Defender For Cloud", - "checklist": "Azure Security Review Checklist", - "guid": "05675c5e-985b-4859-a774-f7e371623b87", - "link": "https://learn.microsoft.com/azure/security-center/continuous-export?tabs=azure-portal", + "category": "Management", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Use Azure ARC for Servers to properly govern workloads running on Azure VMware Solution using Azure native technologies (Azure ARC for Azure VMware Solution is not yet available)", + "guid": "8f426fd0-d73b-d398-1f6f-df0cbe262a82", + "id": "D01.01", + "link": "https://learn.microsoft.com/azure/azure-arc/vmware-vsphere/overview", "services": [ - "Defender", - "EventHubs" + "AVS", + "VM", + "Arc" ], - "severity": "High", - "subcategory": "Pricing & Settings", - "text": "Continuous export 'Event Hub' is enabled if using 3rd party SIEM" + "severity": "Medium", + "subcategory": "Operations", + "text": "AVS VM Management (Azure Arc)", + "waf": "Operations" }, { - "category": "Defender For Cloud", - "checklist": "Azure Security Review Checklist", - "guid": "5a917e1f-349f-4036-9d28-d42e8bbbc868", - "link": "https://learn.microsoft.com/azure/security-center/continuous-export?tabs=azure-portal", + "category": "Management", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Use Azure Policy to onboard Azure VMware Solution workloads in the Azure Management, Monitoring and Security solutions", + "guid": "11dbe773-e380-9191-1418-e886fa7a6fd0", + "id": "D01.02", + "link": "https://docs.microsoft.com/azure/governance/policy/overview", "services": [ - "Defender", - "Sentinel", - "Monitor" + "AVS", + "Monitor", + "AzurePolicy" ], "severity": "Medium", - "subcategory": "Pricing & Settings", - "text": "Continuous export 'Log Analytics Workspace' is enabled if not using Azure Sentinel" + "subcategory": "Operations", + "text": "Azure policy", + "waf": "Operations" }, { - "category": "Defender For Cloud", - "checklist": "Azure Security Review Checklist", - "guid": "255abc91-64e9-4a19-ae28-c84c43b6b781", - "link": "https://learn.microsoft.com/azure/security-center/quickstart-onboard-aws?WT.mc_id=Portal-Microsoft_Azure_Security", + "category": "Management", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "For manual deployments, consider implementing resource locks to prevent accidental actions on your Azure VMware Solution Private Cloud", + "guid": "1e59c639-9b7e-a60b-5e93-3798c1aff5db", + "id": "D01.03", + "link": "https://docs.microsoft.com/azure/azure-resource-manager/management/lock-resources?tabs=json#configure-locks", "services": [ - "Defender" + "AVS" ], - "severity": "High", - "subcategory": "Pricing & Settings", - "text": "Cloud connector enabled for AWS" + "severity": "Medium", + "subcategory": "Operations", + "text": "Resource locks", + "waf": "Operations" }, { - "category": "Defender For Cloud", - "checklist": "Azure Security Review Checklist", - "guid": "8ca0e6c4-2149-4d41-9a92-3c3574d11029", - "link": "https://learn.microsoft.com/azure/security-center/quickstart-onboard-gcp", + "category": "Management", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "For manual deployments, all configuration and deployments must be documented", + "guid": "8f2c46aa-ca1b-cad3-3ac9-213dfc0a265e", + "id": "D01.04", + "link": "Make sure to create your own runbook on the deployment of AVS.", "services": [ - "Defender" + "AVS" ], - "severity": "High", - "subcategory": "Pricing & Settings", - "text": "Cloud connector enabled for GCP" + "severity": "Medium", + "subcategory": "Operations", + "text": "Run books", + "waf": "Operations" }, { - "category": "Defender For Cloud", - "checklist": "Azure Security Review Checklist", - "guid": "cce9bdf6-b483-45a0-85ec-c8232b230652", - "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy-integrate-with-microsoft-cloud-application-security", + "category": "Management", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Implement human understandable names for ExR authorization keys to allow for easy identification of the keys purpose/use", + "guid": "86b314f9-1f1e-317a-4dfb-cf510ad4a030", + "id": "D01.05", + "link": "https://docs.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/resource-abbreviations", "services": [ - "Defender", - "Monitor", - "Entra" + "AVS", + "AKV" ], - "severity": "Low", - "subcategory": "Pricing & Settings", - "text": "If using Azure AD Application proxy, consider integrating with Microsoft Defender for Cloud Apps to monitor application access in real-time and apply advanced security controls." + "severity": "Medium", + "subcategory": "Operations", + "text": "Naming conventions for auth keys", + "waf": "Operations" }, { - "category": "Defender For Cloud", - "checklist": "Azure Security Review Checklist", - "guid": "df9cc234-18db-4611-9126-5f4bb47a393a", - "link": "https://learn.microsoft.com/azure/security-center/secure-score-security-controls", + "category": "Monitoring", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "For automatic alerting on Azure VMware Solution performance (CPU >80%, Avg Memory >80%, vSAN >70%)", + "guid": "e22a2d99-eb71-7d7c-07af-6d4cdb1d4443", + "id": "E01.01", + "link": "https://docs.microsoft.com/azure/azure-vmware/configure-alerts-for-azure-vmware-solution", "services": [ - "Defender" + "AVS", + "Monitor" ], "severity": "Medium", - "subcategory": "Recommendations", - "text": "All recommendations remediated or disabled if not required." + "subcategory": "Alerts", + "text": "Create warning alerts for critical thresholds ", + "waf": "Operations" }, { - "category": "Defender For Cloud", - "checklist": "Azure Security Review Checklist", - "description": "Microsoft minimum target for all customers is 70%", - "guid": "08032729-4798-4b15-98a2-19a46ceb5443", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/secure-score-security-controls", + "category": "Monitoring", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "for automatic alerting on Azure VMware Solution performance (CPU >80%, Avg Memory >80%, vSAN >70%)", + "guid": "6d02f159-627d-79bf-a931-fab6d947eda2", + "id": "E01.02", + "link": "https://docs.microsoft.com/azure/azure-vmware/configure-alerts-for-azure-vmware-solution", "services": [ - "Defender" + "AVS", + "Monitor" ], - "severity": "High", - "subcategory": "Recommendations", - "text": "Security Score>70%" + "severity": "Medium", + "subcategory": "Alerts", + "text": "Create critical alert vSAN consumption", + "waf": "Operations" }, { - "category": "Defender For Cloud", - "checklist": "Azure Security Review Checklist", - "guid": "50259226-4429-42bb-9285-37a55119bf8e", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/tutorial-security-incident", + "category": "Monitoring", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Provides platform alerts (generated by Microsoft)", + "guid": "1cc97b39-2c7e-246f-6d73-789cfebfe951", + "id": "E01.03", + "link": "https://www.virtualworkloads.com/2021/04/azure-vmware-solution-azure-service-health/", "services": [ - "Defender", + "AVS", "Monitor" ], "severity": "Medium", - "subcategory": "Security Alerts", - "text": "Security Alerts contain only those generated in the past 24 hours (remediate or disable older security alerts)" + "subcategory": "Alerts", + "text": "Configured for Azure Service Health alerts and notifications", + "waf": "Operations" }, { - "category": "Defender For Cloud", - "checklist": "Azure Security Review Checklist", - "guid": "8f585428-7d9c-4dc1-96cd-072af9b141a8", - "link": "https://learn.microsoft.com/azure/security-center/custom-dashboards-azure-workbooks", + "category": "Monitoring", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Ensure you have a documented and implemented backup policy and solution for Azure VMware Solution VM workloads", + "guid": "0962606c-e3b4-62a9-5661-e4ffd62a4509", + "id": "E02.01", + "link": "https://docs.microsoft.com/azure/azure-vmware/set-up-backup-server-for-azure-vmware-solution", "services": [ - "Defender" + "VM", + "AzurePolicy", + "AVS", + "Monitor", + "Backup" ], "severity": "Medium", - "subcategory": "Workbooks", - "text": "If continuous export is enabled, default workbooks published to custom security dashboard" + "subcategory": "Backup", + "text": "Backup policy", + "waf": "Operations" }, { - "category": "Defender For Cloud", - "checklist": "Azure Security Review Checklist", - "guid": "98a535e7-3789-47e7-8ca7-da7be9962a15", - "link": "https://techcommunity.microsoft.com/t5/microsoft-defender-for-cloud/bd-p/MicrosoftDefenderCloud", + "category": "Monitoring", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Keep in mind the lead time for requesting new nodes", + "guid": "4ec7ccfb-795e-897e-4a84-fd31c04eadc6", + "id": "E03.01", + "link": "https://docs.microsoft.com/azure/azure-vmware/configure-alerts-for-azure-vmware-solution", "services": [ - "Defender" + "AVS", + "Monitor", + "AzurePolicy" ], "severity": "Medium", - "subcategory": "Community", - "text": "Customer is aware of the value of the 'Community' page and has a regular cadence set up to review" + "subcategory": "Capacity", + "text": "Policy around ESXi host density and efficiency", + "waf": "Operations" }, { - "category": "Defender For Cloud", - "checklist": "Azure Security Review Checklist", - "description": "Customer Operational best practice - Transparency", - "guid": "93846da9-7cc3-4923-856b-22586f4a1641", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/enable-enhanced-security", + "category": "Monitoring", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Azure Cost Management can be used - one option, put AVS in it's own Subscription. ", + "guid": "7f8f175d-13f4-5298-9e61-0bc7e9fcc279", + "id": "E04.01", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/azure-vmware/govern", "services": [ - "Defender", + "AVS", + "Cost", + "Monitor", "Subscriptions" ], - "severity": "High", - "subcategory": "Secure Score", - "text": "All subscriptions protected by Security Center are shown (no subscription filter set)" + "severity": "Medium", + "subcategory": "Costs", + "text": "Ensure a good cost management process is in place for Azure VMware Solution - ", + "waf": "Operations" }, { - "category": "Defender For Cloud", - "checklist": "Azure Security Review Checklist", - "guid": "bdddea8a-487c-4deb-9861-bc3bc14aea6e", - "link": "https://learn.microsoft.com/azure/security-center/security-center-compliance-dashboard", + "category": "Monitoring", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Create dashboards to enable core Azure VMware Solution monitoring insights", + "guid": "01e689e0-7c6c-b58f-37bd-4d6b9b1b9c74", + "id": "E05.01", + "link": "https://docs.microsoft.com/azure/azure-portal/azure-portal-dashboards", "services": [ - "Defender" + "AVS", + "Monitor", + "NetworkWatcher" ], - "severity": "High", - "subcategory": "Regulatory Compliance", - "text": "Compliance controls are green for any required compliance requirements" + "severity": "Medium", + "subcategory": "Dashboard", + "text": "Connection monitor dashboard", + "waf": "Operations" }, { - "category": "Defender For Cloud", - "checklist": "Azure Security Review Checklist", - "description": "Customer Operational best practice - verify", - "guid": "65e8d9a3-aec2-418e-9436-b0736db55f57", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/remediate-vulnerability-findings-vm", + "category": "Monitoring", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Send to an Azure Storage account or Azure EventHub for processing (direct to Log Analytics is pending)", + "guid": "f9afdcc9-649d-d840-9fb5-a3c0edcc697d", + "id": "E06.01", + "link": "https://docs.microsoft.com/azure/azure-vmware/configure-vmware-syslogs", "services": [ - "VM", - "Defender" + "AVS", + "Monitor", + "Storage" ], - "severity": "High", - "subcategory": "Azure Defender", - "text": "High severity VM vulnerabilities is zero (empty)" + "severity": "Medium", + "subcategory": "Logs & Metrics", + "text": "Configure Azure VMware Solution logging ", + "waf": "Operations" }, { - "category": "Defender For Cloud", - "checklist": "Azure Security Review Checklist", - "guid": "9603334b-df9c-4c23-918d-b61171265f4b", - "link": "https://techcommunity.microsoft.com/t5/azure-network-security/azure-firewall-manager-is-now-integrated-with-azure-security/ba-p/2228679", + "category": "Monitoring", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Must be on-premises, implement if available", + "guid": "7cbac8c3-4eda-d5d9-9bda-c6b5abba9fb6", + "id": "E06.02", + "link": "Is vROPS or vRealize Network Insight going to be used? ", "services": [ - "Firewall", - "Defender" + "AVS", + "Monitor" ], "severity": "Medium", - "subcategory": "Firewall Manager", - "text": "Hubs are protected by an Azure Firewall" + "subcategory": "Logs & Metrics", + "text": "vRealize Operations", + "waf": "Operations" }, { - "category": "Defender For Cloud", - "checklist": "Azure Security Review Checklist", - "description": "Customer Operational best practice - verify", - "guid": "b47a393a-0803-4272-a479-8b1578a219a4", - "link": "https://learn.microsoft.com/azure/security/fundamentals/network-best-practices", + "category": "Monitoring", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Ensure workloads running on Azure VMware Solution are monitored using Azure Log Analytics and Azure Monitor", + "guid": "b243521a-644d-f865-7fb6-21f9019c0dd2", + "id": "E06.03", + "link": "https://docs.microsoft.com/azure/azure-vmware/configure-vmware-syslogs", "services": [ - "Firewall", - "VNet", - "Defender" + "AVS", + "VM", + "Monitor" ], "severity": "Medium", - "subcategory": "Firewall Manager", - "text": "Virtual Networks are protected by a Firewall" + "subcategory": "Logs & Metrics", + "text": "AVS VM logging", + "waf": "Operations" }, { - "category": "Defender For Cloud", - "checklist": "Azure Security Review Checklist", - "guid": "6ceb5443-5025-4922-9442-92bb628537a5", - "link": "https://azure.microsoft.com/blog/how-azure-security-center-detects-ddos-attack-using-cyber-threat-intelligence/", + "category": "Monitoring", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Between on-premises to Azure are monitored using 'connection monitor'", + "guid": "2ca97d91-dd36-7229-b668-01036ccc3cd3", + "id": "E07.01", + "link": "https://learn.microsoft.com/azure/network-watcher/connection-monitor-create-using-portal", "services": [ - "Firewall", - "Defender", - "DDoS" + "AVS", + "Monitor", + "ExpressRoute", + "VPN", + "NetworkWatcher" ], "severity": "Medium", - "subcategory": "Firewall Manager", - "text": "DDoS Standard enabled" + "subcategory": "Network", + "text": "Monitor ExpressRoute and/or VPN connections ", + "waf": "Operations" }, { - "category": "Defender For Cloud", - "checklist": "Azure Security Review Checklist", - "guid": "5119bf8e-8f58-4542-a7d9-cdc166cd072a", - "link": "https://learn.microsoft.com/azure/security-center/security-center-get-started?WT.mc_id=Portal-Microsoft_Azure_Security", + "category": "Monitoring", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "To monitor the Azure VMware Solution back-end ExpressRoute connection (Azure native to AVS)", + "guid": "99209143-60fe-19f0-5633-8b5671277ba5", + "id": "E07.02", + "link": "https://learn.microsoft.com/azure/network-watcher/connection-monitor-create-using-portal", "services": [ - "Defender", - "Subscriptions" + "AVS", + "Monitor", + "ExpressRoute" ], - "severity": "High", - "subcategory": "Coverage", - "text": "Verify that all subscriptions are covered (see pricing and settings to modify)" + "severity": "Medium", + "subcategory": "Network", + "text": "Monitor from an Azure native resource to an Azure VMware Solution VM", + "waf": "Operations" }, { - "category": "Azure Networking", - "checklist": "Azure Security Review Checklist", - "guid": "4df585ec-dce9-4793-a7bc-db3b51eb2eb0", - "link": "https://learn.microsoft.com/azure/virtual-network/ip-services/public-ip-addresses", + "category": "Monitoring", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "To monitor end-to-end, on-premises to AVS workloads", + "guid": "b9e5867c-57d3-036f-fb1b-3f0a71664efe", + "id": "E07.03", + "link": "https://learn.microsoft.com/azure/network-watcher/connection-monitor-create-using-portal", "services": [ - "VM", - "VNet" + "AVS", + "Monitor" ], - "severity": "High", - "subcategory": "Public IPs", - "text": "VM's with public IPs should be protected by NSG " + "severity": "Medium", + "subcategory": "Network", + "text": "Monitor from an on-premises resource to an Azure VMware Solution VM", + "waf": "Operations" }, { - "category": "Azure Networking", - "checklist": "Azure Security Review Checklist", - "description": "Customer operational best practice - verify", - "guid": "3dda6e59-d7c8-4a2e-bb11-7d6769af669c", - "link": "https://learn.microsoft.com/azure/virtual-network/ip-services/public-ip-addresses", + "category": "Monitoring", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Track requests to Azure VMware Solution and Azure VMware Solution based workloads", + "guid": "4af7c5f7-e5e9-bedf-a8cf-314b81735962", + "id": "E08.01", + "link": "Firewall logging and alerting rules are configured (Azure Firewall or 3rd party)", "services": [ - "Firewall", - "VM", - "EventHubs" + "AVS", + "Monitor" ], - "severity": "High", - "subcategory": "Public IPs", - "text": "VMs with public IPs are moved behind Azure Firewall Premium" + "severity": "Medium", + "subcategory": "Security", + "text": "Auditing and logging is implemented for inbound internet ", + "waf": "Operations" }, { - "category": "Azure Networking", - "checklist": "Azure Security Review Checklist", - "description": "Customer operational best practice - verify", - "guid": "a48e5a85-f222-43ec-b8bb-12308ca5017f", - "link": "https://learn.microsoft.com/azure/virtual-network/ip-services/default-outbound-access", + "category": "Monitoring", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Implemented for outbound internet connections from Azure VMware Solution or Azure VMware Solution based workloads to identify suspicious/malicious activity", + "guid": "74be60a3-cfac-f057-eda6-3ee087e805d5", + "id": "E08.02", + "link": "https://docs.microsoft.com/azure/cloud-adoption-framework/scenarios/azure-vmware/eslz-network-topology-connectivity", "services": [ - "VM" + "AVS", + "Monitor" ], - "severity": "High", - "subcategory": "Public IPs", - "text": "VM's that don't need public IPs do not have public IPs (i.e. internal RDP only)" + "severity": "Medium", + "subcategory": "Security", + "text": "Session monitoring ", + "waf": "Operations" }, { - "category": "Azure Networking", - "checklist": "Azure Security Review Checklist", - "guid": "158e3ea3-a93c-42de-9e31-65c3a87a04b7", - "link": "https://learn.microsoft.com/azure/virtual-network/network-security-groups-overview", + "category": "Monitoring", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Enable Diagnostic and metric logging on Azure VMware Solution", + "guid": "a434b3b5-f258-0845-cd76-d7df6ef5890e", + "id": "E09.01", + "link": "https://docs.microsoft.com/azure/azure-vmware/configure-vmware-syslogs", "services": [ - "VNet", - "RBAC" + "AVS", + "Monitor" ], "severity": "Medium", - "subcategory": "NSG", - "text": "NSG RBAC is used to restrict access to network security team" + "subcategory": "VMWare", + "text": "Logging and diagnostics", + "waf": "Operations" }, { - "category": "Azure Networking", - "checklist": "Azure Security Review Checklist", - "description": "Customer operational best practice - verify", - "guid": "a209939b-da47-4778-b24c-116785c2fa55", - "link": "https://learn.microsoft.com/azure/virtual-network/network-security-groups-overview", + "category": "Monitoring", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Monitor AVS workloads (each VM in AVS)", + "guid": "fb00b69a-83ec-ce72-446e-6c23a0cab09a", + "id": "E10.01", + "link": "https://docs.microsoft.com/azure/azure-monitor/agents/agent-windows?tabs=setup-wizard", "services": [ - "VNet" + "AVS", + "VM", + "Monitor" ], - "severity": "High", - "subcategory": "NSG", - "text": "NSG Inbound security rules do not contain a * (wildcard) in Source field" + "severity": "Medium", + "subcategory": "VMware", + "text": "Log Analytics Agents deployed on Azure VMware Solution guest VM workloads", + "waf": "Operations" }, { - "category": "Azure Networking", - "checklist": "Azure Security Review Checklist", - "description": "Customer operational best practice - verify", - "guid": "b56a9480-08be-47d7-b4c4-76b6d8bdcf59", - "link": "https://learn.microsoft.com/azure/virtual-network/network-security-groups-overview", + "category": "Networking", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Decision on traffic flow", + "guid": "a1354b87-e18e-bf5c-c50b-8ddf0540e971", + "id": "F01.01", + "link": "https://learn.microsoft.com/azure/azure-vmware/concepts-hub-and-spoke", "services": [ - "VNet" + "AVS" ], "severity": "Medium", - "subcategory": "NSG", - "text": "NSG outbound security rules are used to control traffic to specific IP addresses for traffic not routed through a Firewall" + "subcategory": "Hub & Spoke", + "text": "North/South routing through Az Firewall or 3rd party ", + "waf": "Security" }, { - "category": "Azure Networking", - "checklist": "Azure Security Review Checklist", - "description": "Customer operational best practice - verify", - "guid": "bce65de8-a13f-4988-9946-8d66a786d60f", - "link": "https://learn.microsoft.com/azure/virtual-network/network-security-groups-overview", + "category": "Networking", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Decision to route Azure to Azure traffic through Firewall, not E/W between AVS workloads (internal to AVS)", + "guid": "29a8a499-ec31-f336-3266-0895f035e379", + "id": "F01.02", + "link": "https://learn.microsoft.com/azure/azure-vmware/concepts-hub-and-spoke", "services": [ - "VNet" + "AVS" ], - "severity": "High", - "subcategory": "NSG", - "text": "NSG do not have Source as a * (wildcard) in place." + "severity": "Medium", + "subcategory": "Hub & Spoke", + "text": "East West (Internal to Azure)", + "waf": "Security" }, { - "category": "Azure Networking", - "checklist": "Azure Security Review Checklist", - "guid": "a6c97be9-955d-404c-9c49-c986cb2d1215", - "link": "https://learn.microsoft.com/azure/virtual-network/virtual-network-nsg-manage-log", + "category": "Networking", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Requires a 3rd party NVA with Azure Route server - Scenario 2 (see link)", + "guid": "ebd3cc3c-ac3d-4293-950d-cecd8445a523", + "id": "F01.03", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/azure-vmware/eslz-network-topology-connectivity", "services": [ - "VNet", - "Sentinel" + "AVS", + "ARS", + "NVA" ], "severity": "Medium", - "subcategory": "NSG", - "text": "NSG Diagnostics send NetworkSecurityGroupEvent and NetworkSecurityGroupRuleCounter traffic to Sentinel LAW" + "subcategory": "Hub & Spoke", + "text": "ExR without Global Reach", + "waf": "Operations" }, { - "category": "Azure Networking", - "checklist": "Azure Security Review Checklist", - "guid": "aa124b6e-4df5-485e-adce-9793b7bcdb3b", - "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview", + "category": "Networking", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "When route server is used, ensure no more then 200 routes are propagated from route server to ExR gateway to on-premises (ARS limit). Important when using MoN", + "guid": "ffb5c5ca-bd89-ff1b-8b73-8a54d503d506", + "id": "F01.04", + "link": "https://learn.microsoft.com/azure/route-server/route-server-faq", "services": [ - "VNet", - "RBAC" + "AVS", + "ARS" ], "severity": "Medium", - "subcategory": "UDR", - "text": "UDR RBAC is used to restrict access to the network security team" + "subcategory": "Hub & Spoke", + "text": "Route server ", + "waf": "Operations" }, { - "category": "Azure Networking", - "checklist": "Azure Security Review Checklist", - "guid": "51eb2eb0-3dda-46e5-ad7c-8a2edb117d67", - "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview", + "category": "Networking", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Via on-premises, Az Firewall, 3rd Party, NSX-T pubic IP", + "guid": "a4070dad-3def-818d-e9f7-be440d10e7de", + "id": "F02.01", + "link": "https://learn.microsoft.com/azure/azure-vmware/concepts-design-public-internet-access", "services": [ - "Firewall", - "VNet" + "AVS" ], - "severity": "High", - "subcategory": "UDR", - "text": "If Zero Trust, then UDR's are used to send all traffic to the Azure Firewall Premium" + "severity": "Medium", + "subcategory": "Internet", + "text": "Egress point(s)", + "waf": "Security" }, { - "category": "Azure Networking", - "checklist": "Azure Security Review Checklist", - "description": "Customer operational best practice - verify", - "guid": "69af669c-a48e-45a8-9f22-23ece8bb1230", - "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview", + "category": "Networking", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Az Firewall, 3rd party NVA, Application Gateway, Azure Frontdoor ", + "guid": "e942c03d-beaa-3d9f-0526-9b26cd5e9937", + "id": "F02.02", + "link": "Research and choose optimal solution for each application", "services": [ - "VNet" + "AVS", + "FrontDoor", + "AppGW", + "NVA" ], "severity": "Medium", - "subcategory": "UDR", - "text": "UDR's that do not send all traffic to AzureFirewallPremium are known and documented." + "subcategory": "Internet", + "text": "Internet facing applications", + "waf": "Security" }, { - "category": "Azure Networking", - "checklist": "Azure Security Review Checklist", - "guid": "8ca5017f-158e-43ea-9a93-c2de7e3165c3", - "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview#default", + "category": "Networking", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Ensure no more then 200 routes are propagated from route server to ExR gateway to on-premises (ARS limit). Important when using MoN", + "guid": "e778a2ec-b4d7-1d27-574c-14476b167d37", + "id": "F03.01", + "link": "https://docs.microsoft.com/azure/route-server/route-server-faq#route-server-limits", "services": [ - "VNet" + "AVS", + "ARS" ], - "severity": "High", - "subcategory": "Virtual Networks", - "text": "Customer is familiar with Azure networking defaults / SDN default routing in Azure" + "severity": "Medium", + "subcategory": "Routing", + "text": "When route server Route limit understood? ", + "waf": "Security" }, { - "category": "Azure Networking", - "checklist": "Azure Security Review Checklist", - "description": "Customer operational best practice - verify", - "guid": "a87a04b7-a209-4939-ada4-7778f24c1167", - "link": "https://github.com/MicrosoftDocs/azure-docs/issues/53672", + "category": "Networking", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "(VPN Gateway, AppGW, FrontDoor, Load balancer, VMs (etc) (Remove: enabled on ExR/VPN Gateway subnet in Azure)", + "guid": "66c97b30-81b9-139a-cc76-dd1d94aef42a", + "id": "F04.01", + "link": "https://docs.microsoft.com/azure/ddos-protection/manage-ddos-protection", "services": [ + "VM", + "LoadBalancer", + "AVS", + "ExpressRoute", + "FrontDoor", + "VPN", "VNet", - "RBAC" + "DDoS", + "AppGW" ], "severity": "Medium", - "subcategory": "Virtual Networks", - "text": "VNet RBAC is used to restrict access to the network security team" + "subcategory": "Security", + "text": "Is DDoS standard protection of public facing IP addresses? ", + "waf": "Security" }, { - "category": "Azure Networking", - "checklist": "Azure Security Review Checklist", - "guid": "85c2fa55-b56a-4948-808b-e7d7e4c476b6", - "link": "https://learn.microsoft.com/azure/virtual-network/policy-reference", + "category": "Networking", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "To manage Azure VMware Solution, vCenter, NSX manager and HCX manager", + "guid": "d43da920-4ecc-a4e9-dd45-a2986ce81d32", + "id": "F04.02", + "link": "Best practice: Bastion or 3rd party tool", "services": [ - "VNet" + "AVS" ], - "severity": "High", - "subcategory": "Virtual Networks", - "text": "VNet Security recommendations are remediated and there are no 'At-risk' VNets " + "severity": "Medium", + "subcategory": "Security", + "text": "Use a dedicated privileged access workstation (PAW)", + "waf": "Security" }, { - "category": "Azure Networking", - "checklist": "Azure Security Review Checklist", - "guid": "d8bdcf59-bce6-45de-aa13-f98879468d66", - "link": "https://learn.microsoft.com/azure/virtual-network/virtual-network-peering-overview", + "category": "Networking", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Use NSX-T for inter-vmware-traffic inspection", + "guid": "a2dac74f-5380-6e39-25e6-f13b99ece51f", + "id": "F05.01", + "link": "https://docs.vmware.com/en/VMware-NSX-T-Data-Center/3.2/administration/GUID-F6685367-7AA1-4771-927E-ED77727CFDA3.html", "services": [ - "VNet" + "AVS" ], - "severity": "High", - "subcategory": "Virtual Networks", - "text": "VNet Peering connections are understood and expected traffic flows are documented" + "severity": "Medium", + "subcategory": "Traffic Inspection", + "text": "East West (Internal to AVS)", + "waf": "Security" }, { - "category": "Azure Networking", - "checklist": "Azure Security Review Checklist", - "guid": "a786d60f-a6c9-47be-a955-d04c3c49c986", - "link": "https://learn.microsoft.com/azure/virtual-network/virtual-network-service-endpoints-overview", + "category": "Networking", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Decision on whether or not to use Secure hub for E/W and Internet traffic - requires Global Reach", + "guid": "3f621543-dfac-c471-54a6-7b2849b6909a", + "id": "F06.01", + "link": "https://learn.microsoft.com/azure/architecture/networking/hub-spoke-vwan-architecture", "services": [ - "VNet" + "AVS", + "VWAN", + "Firewall" ], - "severity": "High", - "subcategory": "Virtual Networks", - "text": "VNet Service Endpoints are in use, no legacy Public Service Endpoints exist" + "severity": "Medium", + "subcategory": "Virtual WAN", + "text": "Use Secure Hub (Azure Firewall or 3rd party)", + "waf": "Security" }, { - "category": "Azure Networking", - "checklist": "Azure Security Review Checklist", - "guid": "1f625659-ee55-480a-9824-9c931213dbd7", - "link": "https://learn.microsoft.com/azure/private-link/private-endpoint-overview", + "category": "Networking", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Decision to route Azure to Azure traffic through Firewall, not E/W between AVS workloads (internal to AVS)", + "guid": "d7af5670-1b39-d95d-6da2-8d660dfbe16b", + "id": "F06.02", + "link": "https://learn.microsoft.com/azure/firewall-manager/secure-cloud-network", "services": [ - "VNet", - "PrivateLink" + "AVS", + "VWAN" ], - "severity": "High", - "subcategory": "Virtual Networks", - "text": "VNet Private Endpoints are in use to allow access from on-premises environments, no legacy public endpoints exist" + "severity": "Medium", + "subcategory": "Virtual WAN", + "text": "East West (Internal to Azure)", + "waf": "Security" }, { - "category": "Azure Networking", - "checklist": "Azure Security Review Checklist", - "guid": "fb012f70-943f-4630-9722-ea39d2b1ce63", - "link": "https://learn.microsoft.com/azure/virtual-network/monitor-virtual-network", + "category": "Other Services/Operations", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "When intending to use automated scale-out, be sure to apply for sufficient Azure VMware Solution quota for the subscriptions running Azure VMware Solution", + "guid": "7d049005-eb35-4a93-50a5-3b31a9f61161", + "id": "G01.01", + "link": "https://docs.microsoft.com/azure/azure-vmware/configure-nsx-network-components-azure-portal", "services": [ - "VNet", - "Monitor" + "AVS", + "Subscriptions" ], - "severity": "High", - "subcategory": "Virtual Networks", - "text": "VNet Monitoring enabled" + "severity": "Medium", + "subcategory": "Automated Scale", + "text": "Scale out operations planning", + "waf": "Performance" }, { - "category": "Azure Networking", - "checklist": "Azure Security Review Checklist", - "guid": "2055b29b-ade4-4aad-8e8c-39ec94666731", - "link": "https://learn.microsoft.com/azure/virtual-network/kubernetes-network-policies", + "category": "Other Services/Operations", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "When intending to use automated scale-in, be sure to take storage policy requirements into account before performing such action", + "guid": "7242c1de-da37-27f3-1ddd-565ccccb8ece", + "id": "G01.02", + "link": "https://docs.microsoft.com/azure/cloud-adoption-framework/scenarios/azure-vmware/eslz-platform-automation-and-devops#automated-scale", "services": [ - "AzurePolicy", - "AKS", - "VNet" + "AVS", + "Storage", + "AzurePolicy" ], - "severity": "High", - "subcategory": "Virtual Networks", - "text": "Secure traffic between pods using network policies in Azure Kubernetes Service (AKS)" + "severity": "Medium", + "subcategory": "Automated Scale", + "text": "Scale in operations planning", + "waf": "Performance" }, { - "category": "Azure Networking", - "checklist": "Azure Security Review Checklist", - "guid": "3c005674-c1e9-445b-959c-373e7ed71623", - "link": "https://learn.microsoft.com/azure/virtual-network/virtual-network-scenario-udr-gw-nva", + "category": "Other Services/Operations", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Scaling operations always need to be serialized within a single SDDC as only one scale operation can be performed at a time (even when multiple clusters are used)", + "guid": "3233e49e-62ce-97f3-8737-8230e771b694", + "id": "G01.03", + "link": "https://docs.microsoft.com/azure/cloud-adoption-framework/scenarios/azure-vmware/eslz-platform-automation-and-devops#automated-scale", "services": [ - "VNet", - "NVA" + "AVS" ], - "severity": "High", - "subcategory": "Virtual Networks", - "text": "VNet NVA (appliances) customer follows published architecture pattern" + "severity": "Medium", + "subcategory": "Automated Scale", + "text": "Scale serialized operations planning", + "waf": "Performance" }, { - "category": "Azure Networking", - "checklist": "Azure Security Review Checklist", - "guid": "b375a917-ecbe-448f-ae64-dd7df2e8bbbc", - "link": "https://learn.microsoft.com/azure/virtual-network/monitor-virtual-network", + "category": "Other Services/Operations", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Consider and validate scaling operations on 3rd party solutions used in the architecture (supported or not)", + "guid": "68161d66-5707-319b-e77d-9217da892593", + "id": "G01.04", + "link": "Best practice (testing)", "services": [ - "VNet", - "Sentinel", - "Monitor" + "AVS" ], - "severity": "High", - "subcategory": "Virtual Networks", - "text": "VNet Diagnostic settings are enabled and sending VMProtectionAlerts to the Azure Sentinel LAW" + "severity": "Medium", + "subcategory": "Automated Scale", + "text": "Scale rd operations planning", + "waf": "Performance" }, { - "category": "Azure Networking", - "checklist": "Azure Security Review Checklist", - "guid": "468155ab-c916-44e9-a09a-ed8c44cf3b2b", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/connectivity-to-azure", + "category": "Other Services/Operations", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Define and enforce scale in/out maximum limits for your environment in the automations", + "guid": "c32cb953-e860-f204-957a-c79d61202669", + "id": "G01.05", + "link": "Operational planning - understand workload requirements", "services": [ - "ExpressRoute", - "VPN" + "AVS" ], - "severity": "High", - "subcategory": "Connectivity", - "text": "Use ExpressRoute or VPN to access Azure resources from on-premises environments" + "severity": "Medium", + "subcategory": "Automated Scale", + "text": "Scale maximum operations planning", + "waf": "Performance" }, { - "category": "Azure Networking", - "checklist": "Azure Security Review Checklist", - "guid": "bd8ac2aa-ebca-42a4-9da1-dbf3dd992481", - "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-about", + "category": "Other Services/Operations", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Implement monitoring rules to monitor automated scaling operations and monitor success and failure to enable appropriate (automated) responses", + "guid": "7bd65a5e-7b5d-652d-dbea-fc6f73a42857", + "id": "G01.06", + "link": "https://docs.microsoft.com/azure/cloud-adoption-framework/scenarios/azure-vmware/eslz-management-and-monitoring", "services": [ - "RBAC", - "VWAN" + "AVS", + "Monitor" ], - "severity": "High", - "subcategory": "Virtual WAN", - "text": "VWAN RBAC is used to restrict access to the network security team" + "severity": "Medium", + "subcategory": "Automated Scale", + "text": "Monitor scaling operations ", + "waf": "Performance" }, { - "category": "Azure Networking", - "checklist": "Azure Security Review Checklist", - "guid": "718d1dca-1f62-4565-aee5-580a38249c93", - "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-global-transit-network-architecture", + "category": "Other Services/Operations", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Consider the use of Azure Private-Link when using other Azure Native Services", + "guid": "95e374af-8a2a-2672-7ab7-b4a1be43ada7", + "id": "G02.01", + "link": "https://learn.microsoft.com/azure/private-link/private-link-overview", "services": [ - "Monitor", - "VWAN" + "AVS", + "PrivateLink" ], - "severity": "High", - "subcategory": "Virtual WAN", - "text": "VWAN Customer is using Secure Hub or external Firewall to route and monitor traffic." + "severity": "Medium", + "subcategory": "Networking", + "text": "Private link", + "waf": "Performance" }, { - "category": "Azure Networking", - "checklist": "Azure Security Review Checklist", - "guid": "1213dbd7-fb01-42f7-8943-f6304722ea39", - "link": "https://learn.microsoft.com/azure/web-application-firewall/overview", + "category": "Other Services/Operations", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "When performing automated configuration of NSX-T segments with a single Tier-1 gateway, use Azure Portal APIs instead of NSX-Manager APIs", + "guid": "71eff90d-5ad7-ac60-6244-2a6f7d3c51f2", + "id": "G02.02", + "link": "Best practice", "services": [ - "RBAC", - "AppGW" + "AVS" ], - "severity": "High", - "subcategory": "Application Gateway", - "text": "AppGW RBAC is used to restrict access to the network security team" + "severity": "Medium", + "subcategory": "Networking", + "text": "Provisioning Vmware VLANs", + "waf": "Performance" }, { - "category": "Azure Networking", - "checklist": "Azure Security Review Checklist", - "guid": "d2b1ce63-2055-4b29-aade-4aad1e8c39ec", - "link": "https://learn.microsoft.com/azure/application-gateway/configuration-front-end-ip", + "category": "Planning", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "In which region will AVS be deployed", + "guid": "04e3a2f9-83b7-968a-1044-2811811a924b", + "id": "H01.01", + "link": "https://learn.microsoft.com/windows-server/identity/ad-ds/plan/understanding-active-directory-site-topology", "services": [ - "AppGW", - "EventHubs", - "WAF" + "AVS" ], - "severity": "High", - "subcategory": "Application Gateway", - "text": "AppGW All external facing web services are behind Application Gateways with WAF enabled " + "severity": "Medium", + "subcategory": "Pre-deployment", + "text": "Region selected", + "waf": "Reliability" }, { - "category": "Azure Networking", - "checklist": "Azure Security Review Checklist", - "guid": "94666731-3c00-4567-9c1e-945b459c373e", - "link": "https://learn.microsoft.com/azure/application-gateway/configuration-front-end-ip", + "category": "Planning", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Are there regulatory or compliance policies in play", + "guid": "e52d1615-9cc6-565c-deb6-743ed7e90f4b", + "id": "H01.02", + "link": "Internal policy or regulatory compliance", "services": [ - "AppGW", - "EventHubs", - "WAF" + "AVS", + "AzurePolicy" ], - "severity": "High", - "subcategory": "Application Gateway", - "text": "AppGW All internal facing web services are behind Application Gateways with WAF enabled " + "severity": "Medium", + "subcategory": "Pre-deployment", + "text": "Data residency compliant with selected regions", + "waf": "Reliability" }, { - "category": "Azure Networking", - "checklist": "Azure Security Review Checklist", - "guid": "7ed71623-b375-4a91-9ecb-e48fbe64dd7d", - "link": "https://learn.microsoft.com/azure/application-gateway/ssl-overview", + "category": "Planning", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Request through the support blade", + "guid": "92bd5ad6-441f-a983-7aa9-05dd669d760b", + "id": "H01.03", + "link": "https://learn.microsoft.com/azure/migrate/concepts-azure-vmware-solution-assessment-calculation", "services": [ - "AppGW" + "AVS" ], - "severity": "High", - "subcategory": "Application Gateway", - "text": "AppGW - External facing has TLS/SSL enabled and redirects all traffic to 443 (no port 80 traffic)" + "severity": "Medium", + "subcategory": "Pre-deployment", + "text": "Request for number of AVS hosts submitted ", + "waf": "Reliability" }, { - "category": "Azure Networking", - "checklist": "Azure Security Review Checklist", - "guid": "f2e8bbbc-4681-455a-ac91-64e9909aed8c", - "link": "https://learn.microsoft.com/azure/frontdoor/", + "category": "Planning", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "PG approval for deployment", + "guid": "28370f63-1cb8-2e35-907f-c5516b6954fa", + "id": "H01.04", + "link": "Support request through portal or get help from Account Team", "services": [ - "FrontDoor", - "RBAC" + "AVS" ], - "severity": "High", - "subcategory": "FrontDoor", - "text": "Front Door RBAC is used to restrict access to the network security team" + "severity": "Medium", + "subcategory": "Pre-deployment", + "text": "Region and number of AVS nodes approved", + "waf": "Reliability" }, { - "category": "Azure Networking", - "checklist": "Azure Security Review Checklist", - "guid": "44cf3b2b-3818-4baf-a2cf-2149d013a923", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/front-door-security-baseline?toc=/azure/frontdoor/TOC.json", + "category": "Planning", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Portal/subscription/resource providers/ Microsoft.AVS", + "guid": "96c76997-30a6-bb92-024d-f4f93f5f57fa", + "id": "H01.05", + "link": "Done through the subscription/resource providers/ AVS register in the portal", "services": [ - "AzurePolicy", - "FrontDoor", - "WAF" + "AVS", + "Subscriptions" ], - "severity": "High", - "subcategory": "FrontDoor", - "text": "Front Door is associated with a WAF policy" + "severity": "Medium", + "subcategory": "Pre-deployment", + "text": "Resource provider for AVS registered", + "waf": "Reliability" }, { - "category": "Azure Networking", - "checklist": "Azure Security Review Checklist", - "guid": "ce574dcc-bd8a-4c2a-aebc-a2a44da1dbf3", - "link": "https://learn.microsoft.com/azure/frontdoor/front-door-custom-domain-https", + "category": "Planning", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Connectivity, subscription & governanace model", + "guid": "5898e3ff-5e6b-bee1-6f85-22fee261ce63", + "id": "H01.06", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/azure-vmware/enterprise-scale-landing-zone", "services": [ - "AzurePolicy", - "FrontDoor" + "AVS", + "Subscriptions" ], - "severity": "High", - "subcategory": "FrontDoor", - "text": "Front Door TLS/SSL policy is configured" + "severity": "Medium", + "subcategory": "Pre-deployment", + "text": "Landing zone architecture", + "waf": "Reliability" }, { - "category": "Azure Networking", - "checklist": "Azure Security Review Checklist", - "guid": "dd992481-718d-41dc-a1f6-25659ee5580a", - "link": "https://learn.microsoft.com/azure/frontdoor/front-door-url-redirect", + "category": "Planning", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "The name of the RG where AVS will exist", + "guid": "d0181fb8-9cb8-bf4b-f5e5-b5f9bf7ae4ea", + "id": "H01.07", + "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/manage-resource-groups-portal", "services": [ - "FrontDoor" + "AVS" ], - "severity": "High", - "subcategory": "FrontDoor", - "text": "Front Door redirect port 80 to port 443 is configured (listeners)" + "severity": "Medium", + "subcategory": "Pre-deployment", + "text": "Resource group name selected", + "waf": "Reliability" }, { - "category": "Azure Networking", - "checklist": "Azure Security Review Checklist", - "guid": "38249c93-1213-4dbd-9fb0-12f70943f630", - "link": "https://learn.microsoft.com/azure/frontdoor/front-door-diagnostics", + "category": "Planning", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Each resource created as part of the deployment will also utilize this prefix in the name", + "guid": "0f0d20c2-5a19-726c-de20-0984e070d9d6", + "id": "H01.08", + "link": "Best practice - naming standards", "services": [ - "FrontDoor", - "Sentinel" + "AVS" ], - "severity": "High", - "subcategory": "FrontDoor", - "text": "Front Door diagnostics logs send ApplicationGatewayAccessLog &ApplicationGateway FirewallLog to Sentinel LAW" + "severity": "Medium", + "subcategory": "Pre-deployment", + "text": "Deployment prefix selected", + "waf": "Reliability" }, { - "category": "Azure Networking", - "checklist": "Azure Security Review Checklist", - "guid": "4722ea39-d2b1-4ce6-9205-5b29bade4aad", - "link": "https://learn.microsoft.com/azure/security/fundamentals/ddos-best-practices", + "category": "Planning", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "/22 unique non-overlapping IPv4 address space", + "guid": "7fbf2ab7-a36c-5957-c27a-67038557af2a", + "id": "H01.09", + "link": "https://learn.microsoft.com/azure/azure-vmware/tutorial-network-checklist#routing-and-subnet-considerations", "services": [ - "DDoS" + "AVS" ], - "severity": "High", - "subcategory": "DDOS Protection", - "text": "Enabled for Firewall public IP's (all public IPs)" + "severity": "Medium", + "subcategory": "Pre-deployment", + "text": "Network space for AVS management layer", + "waf": "Reliability" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "346ad56f-bdb8-44db-8bcd-0a689af63f1e", - "link": "https://learn.microsoft.com/security/compass/identity#a-single-enterprise-directory", + "category": "Planning", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "vNets used by workloads running in AVS (non-stretched)", + "guid": "0c87f999-e517-21ef-f355-f210ad4134d2", + "id": "H01.10", + "link": "https://docs.vmware.com/en/VMware-NSX-T-Data-Center/3.2/installation/GUID-4B3860B8-1883-48CA-B2F3-7C2205D91D6D.html", "services": [ - "Entra" + "AVS", + "VNet" ], - "severity": "High", - "subcategory": "Tenant", - "text": "Establish a single enterprise directory for managing identities of full-time employees and enterprise resources." + "severity": "Medium", + "subcategory": "Pre-deployment", + "text": "Network space for AVS NSX-T segments", + "waf": "Reliability" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "a46108cd-6a76-4749-ae69-b7bf61410010", - "link": "https://learn.microsoft.com/security/compass/identity#synchronized-identity-systems", + "category": "Planning", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Choose AV36, AV36P, AV52, AV36T (AV36T = Trial)", + "guid": "946c8966-f902-6f53-4f37-00847e8895c2", + "id": "H01.11", + "link": "https://azure.microsoft.com/pricing/details/azure-vmware/", "services": [ - "Entra" + "AVS" ], - "severity": "High", - "subcategory": "Tenant", - "text": "Synchronize your cloud identity with your existing identity systems." + "severity": "Medium", + "subcategory": "Pre-deployment", + "text": "AVS SKU (region dependent)", + "waf": "Performance" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "a1ab96ceb-c149-4ce2-bcad-3bd375ebfc7f", - "link": "https://learn.microsoft.com/security/compass/identity#cloud-provider-identity-source-for-third-parties", + "category": "Planning", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Use the Azure migration assessment tool to determine the minimum number of nodes required (consider BCDR as well)", + "guid": "31833808-26ba-9c31-416f-d54a89a17f5d", + "id": "H01.12", + "link": "https://learn.microsoft.com/azure/migrate/how-to-assess", "services": [ - "Entra" + "AVS" ], - "severity": "High", - "subcategory": "Tenant", - "text": "Use cloud identity services to host non-employee accounts such as vendors, partners, and customers, rather than rather than including them in your on-premises directory." + "severity": "Medium", + "subcategory": "Pre-deployment", + "text": "Number of hosts to be deployed", + "waf": "Performance" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "343473ec-ed5c-49e1-98f4-cb09524a23cd", - "link": "https://learn.microsoft.com/security/compass/identity#block-legacy-authentication", + "category": "Planning", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Understand how and if you should be using reserved instances (cost control)", + "guid": "f2b73c4f-3d46-32c9-5df1-5b8dfcd3947f", + "id": "H01.13", + "link": "https://azure.microsoft.com/en-ca/pricing/details/azure-vmware/#:~:text=Azure%20VMware%20Solution%20%20%20%20Instance%20size,TB%20%28all%20NVMe%29%20%20%20N%2FA%20%2Fhour%20", "services": [ - "Entra" + "AVS", + "Cost" ], - "severity": "High", - "subcategory": "Tenant", - "text": "Disable insecure legacy protocols for internet-facing services." + "severity": "Medium", + "subcategory": "Pre-deployment", + "text": "Reserverd Instances", + "waf": "Cost" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "70dceb23-50c7-4d8d-bf53-8cc104c7dc44", - "link": "https://learn.microsoft.com/azure/security/fundamentals/identity-management-best-practices#enable-single-sign-on", + "category": "Planning", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Ensure that you have requested enough quota, ensuring you have considered growth and Disaster Recovery requirement", + "guid": "94ac48ab-ade5-3fa7-f800-263feeb97070", + "id": "H01.14", + "link": "https://docs.microsoft.com/azure/azure-vmware/concepts-storage#storage-policies-and-fault-tolerance", "services": [ - "Entra" + "AVS", + "ASR" ], - "severity": "High", - "subcategory": "Tenant", - "text": "Enable single sign-on" + "severity": "Medium", + "subcategory": "Pre-deployment", + "text": "Capacity ", + "waf": "Performance" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "87791be1-1eb0-48ed-8003-ad9bcf241b99", - "link": "https://learn.microsoft.com/security/compass/identity#no-on-premises-admin-accounts-in-cloud-identity-providers", + "category": "Planning", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Identify which of the networking scenarios make ", + "guid": "1f9d4bd5-14b8-928c-b4cb-eb211f9b8de5", + "id": "H01.15", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/azure-vmware/eslz-network-topology-connectivity", "services": [ - "Entra" + "AVS" ], - "severity": "High", - "subcategory": "Privileged administration", - "text": "Don’t synchronize accounts with the highest privilege access to on-premises resources as you synchronize your enterprise identity systems with cloud directories." + "severity": "Medium", + "subcategory": "Pre-deployment", + "text": "Networking & Connectivity See docs describing scenrario 1 through 5", + "waf": "Reliability" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "9e6efe9d-f28f-463b-9bff-b5080173e9fe", - "link": "https://learn.microsoft.com/azure/active-directory/roles/best-practices#5-limit-the-number-of-global-administrators-to-less-than-5", + "category": "Planning", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Ensure that access constraints to ESXi are understood, there are access limits which might affect 3rd party solutions.", + "guid": "070db19b-8a2a-fd6a-c39b-4488d8780da9", + "id": "H01.16", + "link": "Please Check Partner Ecosystem", "services": [ - "Entra" + "AVS" ], - "severity": "High", - "subcategory": "Privileged administration", - "text": "Limit the number of Global Administrators to less than 5" + "severity": "Medium", + "subcategory": "Pre-deployment", + "text": "3rd party application compatibility ", + "waf": "Reliability" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "e0d968d3-87f6-41fb-a4f9-d852f1673f4c", - "link": "https://learn.microsoft.com/azure/active-directory/roles/best-practices#6-use-groups-for-azure-ad-role-assignments-and-delegate-the-role-assignment", + "category": "Security", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "When in-guest encryption is used, store encryption keys in Azure Key vault when possible", + "guid": "70cfbddc-d3d4-9188-77c8-1cabaefef646", + "id": "I01.01", + "link": "General recommendation for storing encryption keys.", "services": [ - "RBAC", - "Entra" + "AVS", + "AKV" ], - "severity": "High", - "subcategory": "Privileged administration", - "text": "Use groups for Azure AD role assignments and delegate the role assignment" + "severity": "Medium", + "subcategory": "Encryption", + "text": "Use Azure Key Vault with in-guest encryption ", + "waf": "Security" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "00350863-4df6-4050-9cf1-cbaa6d58283e", - "link": "https://learn.microsoft.com/azure/architecture/framework/security/design-admins#managed-accounts-for-admins", + "category": "Security", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Ensure workloads on Azure VMware Solution use sufficient data encryption during run-time (like in-guest disk encryption and SQL TDE). (vSAN encryption at rest is default)", + "guid": "c1a81638-18df-0ce9-a73a-4b9a8a8dd392", + "id": "I01.02", + "link": "https://docs.microsoft.com/azure/azure-vmware/concepts-storage#data-at-rest-encryption", "services": [ - "AzurePolicy", - "Entra" + "AVS", + "SQL" ], - "severity": "High", - "subcategory": "Privileged administration", - "text": "Ensure all critical impact admins are managed by enterprise directory to follow organizational policy enforcement." + "severity": "Medium", + "subcategory": "Encryption", + "text": "Use in-guest encryption", + "waf": "Security" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "eae64d01-0d3a-4ae1-a89d-cc1c2ad3888f", - "link": "https://learn.microsoft.com/azure/active-directory/roles/best-practices#4-configure-recurring-access-reviews-to-revoke-unneeded-permissions-over-time", + "category": "Security", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Use Key vault to store secrets and authorization keys when separate Service Principles are used for deploying Azure VMware Solution and ExpressRoute", + "guid": "8d0a8f51-8d35-19cd-c2fe-4e3512fb467e", + "id": "I01.03", + "link": "https://docs.microsoft.com/azure/key-vault/general/authentication", "services": [ - "Entra" + "AVS", + "AKV", + "ExpressRoute" ], - "severity": "High", - "subcategory": "Privileged administration", - "text": "Configure recurring access reviews to revoke unneeded permissions over time" + "severity": "Medium", + "subcategory": "Encryption", + "text": "Keyvault use for secrets", + "waf": "Security" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "922ac19f-916d-4697-b8ea-ded26bdd186f", - "link": "https://learn.microsoft.com/azure/architecture/framework/security/design-admins#admin-workstation-security", + "category": "Security", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Older OS security patching configured for workloads running on Azure VMware Solution are eligible for ESU", + "guid": "4f8b20e9-a2a1-f80f-af9b-8aa3b26dca08", + "id": "I02.01", + "link": "https://docs.microsoft.com/windows-server/get-started/extended-security-updates-deploy", "services": [ - "Monitor", - "Entra" + "AVS" ], "severity": "Medium", - "subcategory": "Privileged administration", - "text": "Ensure critical impact admins use a workstation with elevated security protections and monitoring" + "subcategory": "Extended support", + "text": "Ensure extended security update support ", + "waf": "Security" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "1e8c39ec-9466-4673-83c0-05674c1e945b", - "link": "https://learn.microsoft.com/azure/active-directory/external-identities/compare-with-b2c", + "category": "Security", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Use a SIEM/SOAR", + "guid": "9bb22fec-4d00-3b95-7136-e225d0f5c63a", + "id": "I03.01", + "link": "https://learn.microsoft.com/azure/sentinel/overview", "services": [ - "Entra" + "AVS", + "Sentinel" ], - "severity": "High", - "subcategory": "External Identities", - "text": "Identity Providers: Verify external identity providers are known" + "severity": "Medium", + "subcategory": "Investigation", + "text": "Enable Azure Sentinel or 3rd party SIEM ", + "waf": "Security" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "459c373e-7ed7-4162-9b37-5a917ecbe48f", - "link": "https://learn.microsoft.com/azure/active-directory/external-identities/delegate-invitations", + "category": "Security", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "MS Defender For Cloud, for workloads running on Azure VMware Solution", + "guid": "f42b0b09-c591-238a-1580-2de3c485ebd2", + "id": "I04.01", + "link": "https://learn.microsoft.com/azure/azure-vmware/azure-security-integration#prerequisites", "services": [ - "Entra" + "AVS", + "Defender" ], - "severity": "High", - "subcategory": "External Identities", - "text": "External Collaboration Settings: Guest user access set to 'Guest user access is restricted?'" + "severity": "Medium", + "subcategory": "Security", + "text": "Enable Advanced Threat Detection ", + "waf": "Security" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "be64dd7d-f2e8-4bbb-a468-155abc9164e9", - "link": "https://learn.microsoft.com/azure/active-directory/external-identities/delegate-invitations", + "category": "Security", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Are the applicable policies enabled (compliance baselines added to MDfC)", + "guid": "bcdd2348-3d0e-c6bb-1092-aa4cd1a66d6b", + "id": "I04.02", + "link": "https://docs.microsoft.com/azure/azure-vmware/azure-security-integration", "services": [ - "RBAC", - "Entra" + "AVS", + "AzurePolicy" ], - "severity": "High", - "subcategory": "External Identities", - "text": "External Collaboration Settings: Guest invite settings set to 'Only users assigned to specific admin roles'" + "severity": "Medium", + "subcategory": "Security", + "text": "Policy & Regulatory Compliance", + "waf": "Security" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "909aed8c-44cf-43b2-a381-8bafa2cf2149", - "link": "https://learn.microsoft.com/azure/active-directory/external-identities/delegate-invitations", + "category": "VMware", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Azure to Azure (E/W), Azure to On-premises), AVS to Internet, AVS to Azure", + "guid": "607c1ca9-da92-ae19-5a4c-eb1e876acbe7", + "id": "J01.01", + "link": "https://techcommunity.microsoft.com/t5/azure-migration-and/firewall-integration-in-azure-vmware-solution/ba-p/2254961#:~:text=Azure%20VMware%20Solution%20customers%20have%20multiple%20security%20options,the%20box%20to%20provide%20East-West%20and%20North-South%20firewalling.", "services": [ - "Entra" + "AVS" ], - "severity": "High", - "subcategory": "External Identities", - "text": "External Collaboration Settings: Enable guest self-service sign up via flows set to 'Disabled' " + "severity": "Medium", + "subcategory": "Firewalls", + "text": "Azure / 3rd party firewall", + "waf": "Security" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "d013a923-ce57-44dc-abd8-ac2aaebca2a4", - "link": "https://learn.microsoft.com/azure/active-directory/external-identities/delegate-invitations", + "category": "VMware", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "To allow HCX appliance to connect/sync", + "guid": "1d87925c-c02b-7fde-a425-7e95ad846a27", + "id": "J01.02", + "link": "https://docs.vmware.com/en/VMware-Cloud-on-AWS/services/com.vmware.vmc-aws-networking-security/GUID-2CFE1654-9CC9-4EDB-A625-21317299E559.html", "services": [ - "Entra" + "AVS" ], - "severity": "High", - "subcategory": "External Identities", - "text": "External Collaboration Settings: Collaboration restrictions set to 'Allow invitations to the specified domains'" + "severity": "Medium", + "subcategory": "Firewalls", + "text": "Firewalls allow for East/West traffic inside AVS", + "waf": "Security" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "4da1dbf3-dd99-4248-8718-d1dca1f62565", - "link": "https://learn.microsoft.com/azure/active-directory/governance/deploy-access-reviews", + "category": "VMware", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Decision on which tool to use (SRM requires additional license - enables automation & other features)", + "guid": "468b3495-2f6e-b65a-38ef-3ba631bcaa46", + "id": "J02.01", + "link": "https://docs.vmware.com/en/VMware-HCX/4.2/hcx-user-guide/GUID-B842696B-89EF-4183-9C73-B77157F56055.html", "services": [ - "Entra" + "AVS" ], "severity": "Medium", - "subcategory": "External Identities", - "text": "Access Reviews: Enabled for all groups" + "subcategory": "Networking", + "text": "HCX and/or SRM", + "waf": "Reliability" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "9ee5580a-3824-49c9-9121-3dbd7fb012f7", - "link": "https://learn.microsoft.com/azure/active-directory/manage-apps/configure-user-consent", + "category": "VMware", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Read up on requirements for Service Mesh requirements and how HCX ", + "guid": "be2ced52-da08-d366-cf7c-044c19e29509", + "id": "J02.02", + "link": "https://docs.vmware.com/en/VMware-HCX/4.6/hcx-user-guide/GUID-76BCD059-A31A-4041-9105-ACFB56213E7C.html", "services": [ - "Entra" + "AVS" ], "severity": "Medium", - "subcategory": "Enterprise Applications", - "text": "Consent & Permissions: Allow user consent for apps from verified publishers" + "subcategory": "Networking", + "text": "Configuring and Managing the HCX Interconnect", + "waf": "Reliability" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "0943f630-4722-4ea3-ad2b-1ce632055b29", - "link": "https://learn.microsoft.com/azure/active-directory/manage-apps/configure-user-consent-groups", + "category": "VMware", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "If you are planning on using stretch networks ensure that your on-premises environment requirements", + "guid": "7dcac579-fc5c-5c9c-f1f7-9b1149ff2c37", + "id": "J02.03", + "link": "https://docs.vmware.com/en/VMware-HCX/4.2/hcx-user-guide/GUID-DBDB4D1B-60B6-4D16-936B-4AC632606909.html", "services": [ - "Entra" + "AVS" ], "severity": "Medium", - "subcategory": "Enterprise Applications", - "text": "Consent & Permissions: Allow group owner consent for selected group owners " + "subcategory": "Networking", + "text": "Restrictions and limitations for network extensions", + "waf": "Performance" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "bade4aad-1e8c-439e-a946-667313c00567", - "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy-configure-custom-domain", + "category": "VMware", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Do workloads require MoN?", + "guid": "cf45c0b9-6c4b-3bfb-86c5-62fe54061c73", + "id": "J02.04", + "link": "https://learn.microsoft.com/azure/azure-vmware/vmware-hcx-mon-guidance", "services": [ - "Entra" + "AVS" ], - "severity": "High", - "subcategory": "Custom Domains", - "text": "Only validated customer domains are registered" + "severity": "Medium", + "subcategory": "Networking", + "text": "Mobility optimized networking", + "waf": "Performance" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "4c1e945b-459c-4373-b7ed-71623b375a91", - "link": "https://learn.microsoft.com/azure/active-directory/authentication/tutorial-enable-sspr", + "category": "VMware", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Operating system level of Vmware environment", + "guid": "b7cf11f3-b12e-5189-991a-06df5250d2ca", + "id": "J03.01", + "link": "https://learn.microsoft.com/azure/site-recovery/vmware-physical-azure-support-matrix", "services": [ - "AzurePolicy", - "Entra" + "AVS" ], - "severity": "High", - "subcategory": "Password Reset", - "text": "Self-service password reset policy requirement verified compliant." + "severity": "Medium", + "subcategory": "On-premises pre-requisites", + "text": "Support matrix (OS versions etc).", + "waf": "Operations" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "7ecbe48f-be64-4dd7-bf2e-8bbbc468155a", - "link": "https://learn.microsoft.com/azure/active-directory/authentication/howto-sspr-deployment", + "category": "VMware", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Required that all switches are dynamic", + "guid": "45fe9252-aa1b-4e30-45c6-bc02f3b76acf", + "id": "J03.02", + "link": "https://docs.vmware.com/en/VMware-vSphere/7.0/vsan-network-design-guide/GUID-91E1CD6F-33A6-4AC6-BC22-3E4807296F86.html#:~:text=Migrate%20Management%20Network%201%20Add%20hosts%20to%20the,each%20host.%20...%204%20Finish%20the%20configuration.%20", "services": [ - "Entra" + "AVS" ], "severity": "Medium", - "subcategory": "Password Reset", - "text": "Set number of days before users are asked to re-confirm authentication information is not set to zero" + "subcategory": "On-premises pre-requisites", + "text": "Standard switches converted to dynamic switches", + "waf": "Operations" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "bc9164e9-909a-4ed8-a44c-f3b2b3818baf", - "link": "https://learn.microsoft.com/azure/active-directory/authentication/howto-sspr-deployment", + "category": "VMware", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "See sections on sizing and capacity in the link.", + "guid": "e9f6d736-ee44-e2ac-e7f9-e361f8c857f3", + "id": "J03.03", + "link": "https://learn.microsoft.com/azure/azure-vmware/plan-private-cloud-deployment", "services": [ - "Entra" + "AVS" ], - "severity": "High", - "subcategory": "Password Reset", - "text": "Set number of methods required to reset password are selected" + "severity": "Medium", + "subcategory": "On-premises pre-requisites", + "text": "Capacity for HCX appliance", + "waf": "Performance" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "a2cf2149-d013-4a92-9ce5-74dccbd8ac2a", - "link": "https://learn.microsoft.com/azure/active-directory/roles/delegate-app-roles", + "category": "VMware", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Check hardware restrictions to ensure compatibility with AVS/OS ", + "guid": "1be2cdd6-15a7-9a33-aea7-113859035ce9", + "id": "J03.04", + "link": "https://kb.vmware.com/s/article/2007240#:~:text=ESXi%2FESX%20hosts%20and%20compatible%20virtual%20machine%20hardware%20versions,%20Not%20Supported%20%204%20more%20rows", "services": [ - "Entra" + "AVS" ], - "severity": "High", - "subcategory": "User Setting", - "text": "Disable 'Users can register applications'" + "severity": "Medium", + "subcategory": "On-premises pre-requisites", + "text": "Hardware compatibility", + "waf": "Operations" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "aebca2a4-4da1-4dbf-9dd9-92481718d1dc", - "link": "https://learn.microsoft.com/azure/active-directory/fundamentals/users-default-permissions", + "category": "VMware", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Need to be converted", + "guid": "16ab821a-27c6-b6d3-6042-10dc4d6dfcb7", + "id": "J04.01", + "link": "https://docs.vmware.com/en/VMware-vSphere/7.0/com.vmware.vsphere.storage.doc/GUID-01D3CF47-A84A-4988-8103-A0487D6441AA.html", "services": [ - "Entra" + "AVS", + "Storage" ], - "severity": "High", - "subcategory": "User Setting", - "text": "Restrict access to Administrative portal (portal.azure.com) to administrators only" + "severity": "Medium", + "subcategory": "Storage", + "text": "VSAN RDM disks are converted - not supported.", + "waf": "Operations" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "a1f62565-9ee5-4580-a382-49c931213dbd", - "link": "https://learn.microsoft.com/azure/active-directory/enterprise-users/linkedin-integration", + "category": "VMware", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Need to be converted", + "guid": "eb2f9313-afb2-ab35-aa24-6d97a3cb0611", + "id": "J04.02", + "link": "3rd-Party tools", "services": [ - "Entra" + "AVS", + "VM", + "Storage" ], - "severity": "High", - "subcategory": "User Setting", - "text": "Disable 'LinkedIn account connection'" + "severity": "Medium", + "subcategory": "Storage", + "text": "VM with SCSI shared bus are not supported", + "waf": "Operations" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "7fb012f7-0943-4f63-8472-2ea39d2b1ce6", - "link": "https://learn.microsoft.com/azure/active-directory/reports-monitoring/overview-monitoring", + "category": "VMware", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Remove Direct IO before migration", + "guid": "3f2a5cff-c8a6-634a-1f1b-53ef9d321381", + "id": "J04.03", + "link": "Contact VMware", "services": [ - "Sentinel", - "Monitor", - "Entra" + "AVS", + "VM", + "Storage" ], - "severity": "High", - "subcategory": "Diagnostic Settings", - "text": "Enabled and send to Log Analytics workspace with Sentinel" + "severity": "Medium", + "subcategory": "Storage", + "text": "VM with Direct IO require removing DirectPath device", + "waf": "Operations" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "21e44a19-a9dd-4399-afd7-b28dc8355562", - "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-deployment-plan", + "category": "VMware", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Cannot migrate clusters ", + "guid": "efc8a311-74f8-0252-c6a0-4bac7610e266", + "id": "J04.04", + "link": "Contact VMware", "services": [ - "Entra" + "AVS", + "Storage" ], - "severity": "High", - "subcategory": "PIM enabled", - "text": "Privileged Identity Management enabled" + "severity": "Medium", + "subcategory": "Storage", + "text": "Shared VMDK files are not supported", + "waf": "Operations" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "46f4389a-7f42-4c78-b78c-06a63a21a495", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/just-in-time-access-usage?tabs=jit-config-asc%2Cjit-request-asc", + "category": "VMware", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Convert to a different format", + "guid": "ab6c89cd-a26f-b894-fe59-61863975458e", + "id": "J04.05", + "link": "Contact VMware", "services": [ - "Entra" + "AVS", + "Storage" ], - "severity": "High", - "subcategory": "PIM enabled", - "text": "Implement 'just in time' (JIT) access to further lower the exposure time for privileged accounts (reduce standing access)" + "severity": "Medium", + "subcategory": "Storage", + "text": "RDM with 'physical compatibility mode' are not supported.", + "waf": "Operations" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "6e6a8dc4-a20e-427b-9e29-711b1352beee", - "link": "https://learn.microsoft.com/azure/active-directory/conditional-access/concept-conditional-access-policy-common", + "category": "VMware", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Ensure the vSAN storage policy for VM's is NOT the default storage policy as this policy applies thick provisioning 'RAID-1 FTT-1' is default with Thin Provisioning", + "guid": "7628d446-6b10-9678-9cec-f407d990de43", + "id": "J04.06", + "link": "https://learn.microsoft.com/azure/azure-vmware/concepts-storage#storage-policies-and-fault-tolerance", "services": [ - "AzurePolicy", - "Entra" + "AVS", + "VM", + "Storage", + "AzurePolicy" ], - "severity": "High", - "subcategory": "Conditional Access Policies", - "text": "Configure conditional access policies / Access Controls" + "severity": "Medium", + "subcategory": "Storage", + "text": "Default storage policy", + "waf": "Operations" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "079b588d-efc4-4972-ac3c-d21bf77036e5", - "link": "https://learn.microsoft.com/azure/active-directory/conditional-access/location-condition", + "category": "VMware", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "The default storage policy is set to RAID-1 (Mirroring) FTT-1, with Object Space Reservation set to Thin provisioning.", + "guid": "37fef358-7ab9-43a9-542c-22673955200e", + "id": "J04.07", + "link": "https://learn.microsoft.com/azure/azure-vmware/configure-storage-policy", "services": [ - "AzurePolicy", - "Entra" + "AVS", + "VM", + "Storage", + "AzurePolicy" ], "severity": "Medium", - "subcategory": "Conditional Access Policies", - "text": "Conditions: Restricted Locations" + "subcategory": "Storage", + "text": "Ensure that the appropriate VM template storage policy is used", + "waf": "Operations" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "e6b4bed3-d5f3-4547-a134-7dc56028a71f", - "link": "https://learn.microsoft.com/azure/active-directory/authentication/tutorial-enable-azure-mfa", + "category": "VMware", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Ensure that the Failure-to-tolerate policy is in place to meet your vSAN storage needs", + "guid": "ebebd109-9f9d-d85e-1b2f-d302012843b7", + "id": "J04.08", + "link": "https://learn.microsoft.com/azure/azure-vmware/concepts-storage#storage-policies-and-fault-tolerance", "services": [ - "AzurePolicy", - "Entra" + "AVS", + "Storage", + "AzurePolicy" ], - "severity": "High", - "subcategory": "Conditional Access Policies", - "text": "Access Controls: MFA enabled for all users" + "severity": "Medium", + "subcategory": "Storage", + "text": "Failure to tolerate policy", + "waf": "Operations" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "fe1bd15d-d2f0-4d5e-972d-41e3611cc57b", - "link": "https://learn.microsoft.com/azure/active-directory/conditional-access/howto-conditional-access-policy-admin-mfa", + "category": "VMware", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "ANF can be used to extend storage for Azure VMware Solution,", + "guid": "1be821bd-4f37-216a-3e3d-2a5ac6996863", + "id": "J04.09", + "link": "https://learn.microsoft.com/azure/azure-vmware/netapp-files-with-azure-vmware-solution", "services": [ - "AzurePolicy", - "Entra" + "AVS", + "Storage" ], "severity": "Medium", - "subcategory": "Conditional Access Policies", - "text": "Access Controls: Require MFA for Administrators" + "subcategory": "Storage", + "text": "Use ANF for external storage", + "waf": "Operations" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "4a4b1410-d439-4589-ac22-89b3d6b57cfc", - "link": "https://learn.microsoft.com/azure/active-directory/conditional-access/howto-conditional-access-policy-azure-management", - "services": [ - "AzurePolicy", - "Entra" - ], - "severity": "High", - "subcategory": "Conditional Access Policies", - "text": "Access Controls: Require MFA for Azure Management " + "category": "Application Deployment", + "checklist": "Azure Spring Apps Review", + "cost": 1, + "guid": "6d8e32a8-3892-479d-a40b-10f6b4f6f298", + "link": "https://learn.microsoft.com/azure/spring-apps/concepts-blue-green-deployment-strategies", + "services": [], + "severity": "Medium", + "subcategory": "DevOps", + "text": "Azure Spring Apps permits two deployments for every app, only one of which receives production traffic. You can achieve zero downtime with blue green deployment strategies. Blue green deployment is only available in Standard and Enterprise tiers. You could automate deployment using CI/CD with ADO/GitHub actions", + "waf": "Reliability" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "645461e1-a3e3-4453-a3c8-639637a552d6", - "link": "https://learn.microsoft.com/azure/active-directory/conditional-access/howto-conditional-access-policy-block-legacy", + "category": "BC and DR", + "checklist": "Azure Spring Apps Review", + "cost": 1, + "guid": "fbcb40ac-9480-4a6d-bcf4-8081252a6716", + "link": "https://learn.microsoft.com/azure/architecture/web-apps/spring-apps/architectures/spring-apps-multi-region", "services": [ - "AzurePolicy", - "Entra" + "TrafficManager", + "FrontDoor", + "ASR" ], - "severity": "High", - "subcategory": "Conditional Access Policies", - "text": "Access Controls: Block Legacy Protocols" + "severity": "Medium", + "subcategory": "Disaster Recovery", + "text": "Azure Spring Apps instances could be created in multiple regions for your applications and traffic could be routed by Traffic Manager/Front Door.", + "waf": "Reliability" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "7ae9eab4-0fd3-4290-998b-c178bdc5a06c", - "link": "https://learn.microsoft.com/azure/active-directory/conditional-access/require-managed-devices", + "category": "BC and DR", + "checklist": "Azure Spring Apps Review", + "cost": 1, + "guid": "ff1ae6a7-9301-4feb-9d11-56cd72f1d4ef", + "link": "https://learn.microsoft.com/azure/reliability/reliability-spring-apps", "services": [ - "AzurePolicy", - "Entra" + "ACR" ], - "severity": "High", - "subcategory": "Conditional Access Policies", - "text": "Access Controls: Require devices to be marked as compliant" + "severity": "Medium", + "subcategory": "High Availability", + "text": "In supported region, Azure Spring Apps can be deployed as zone redundant, which means that instances are automatically distributed across availability zones. This feature is only available in Standard and Enterprise tiers.", + "waf": "Reliability" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "description": "Customer documented policy", - "guid": "a7144351-e19d-4d34-929e-b7228137a151", - "link": "https://devblogs.microsoft.com/premier-developer/azure-active-directory-automating-guest-user-management/", - "services": [ - "AzurePolicy", - "Entra" - ], + "category": "BC and DR", + "checklist": "Azure Spring Apps Review", + "cost": 1, + "guid": "ffc735ad-fbb1-4802-b43f-ad6387c4c066", + "link": "https://learn.microsoft.com/azure/spring-apps/concept-understand-app-and-deployment", + "services": [], "severity": "Medium", - "subcategory": "Guest users", - "text": "Is there a policy to track guest user accounts (i.e. usage/delete/disable)?" + "subcategory": "High Availability", + "text": "Use more than 1 app instance for your apps", + "waf": "Reliability" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "c5bb4e4f-1814-4287-b5ca-8c26c9b32ab5", - "link": "https://learn.microsoft.com/azure/active-directory/fundamentals/identity-secure-score", + "category": "Operations", + "checklist": "Azure Spring Apps Review", + "cost": 1, + "guid": "7504c230-6035-4183-95a5-85762acc6075", + "link": "https://learn.microsoft.com/azure/spring-apps/diagnostic-services", "services": [ - "Entra" + "Monitor" ], - "severity": "High", - "subcategory": "Identity Secure Score", - "text": "Implement Identity Secure Score based on best practices in your industry" + "severity": "Medium", + "subcategory": "Monitoring", + "text": "Monitor Azure Spring Apps with logs, metrics and tracing. Integrate ASA with application insights and track failures and create workbooks.", + "waf": "Reliability" }, { - "category": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "bcfc6998-a135-4e33-9897-e31c67d68cb6", - "link": "https://learn.microsoft.com/azure/active-directory/roles/security-emergency-access", - "services": [ - "AzurePolicy", - "Entra" - ], + "category": "Operations", + "checklist": "Azure Spring Apps Review", + "cost": 1, + "guid": "1eb48d58-3eec-4ef5-80b0-d2b0dde3f0c6", + "link": "https://learn.microsoft.com/azure/spring-apps/how-to-configure-enterprise-spring-cloud-gateway", + "services": [], "severity": "Medium", - "subcategory": "Break Glass Accounts", - "text": "At least two break glass accounts have been created and policy around their use exists" + "subcategory": "Scalability", + "text": "Set up autoscaling in Spring Cloud Gateway", + "waf": "Reliability" }, { - "category": "VM Security Checks", - "checklist": "Azure Security Review Checklist", - "guid": "0ac252b9-99a6-48af-a7c9-a8f821b8eb8c", - "link": "https://learn.microsoft.com/azure/governance/policy/overview", - "services": [ - "VM", - "AzurePolicy" - ], - "severity": "High", - "subcategory": "Access Control", - "text": "Control VM Access leveraging Azure Policy" + "category": "Operations", + "checklist": "Azure Spring Apps Review", + "cost": 1, + "guid": "97411607-b6fd-4335-99d1-9885faf4e392", + "link": "https://learn.microsoft.com/azure/spring-apps/how-to-setup-autoscale", + "services": [], + "severity": "Low", + "subcategory": "Scalability", + "text": "Enable autoscale for the apps with Standard consumption & dedicated plan.", + "waf": "Reliability" }, { - "category": "VM Security Checks", - "checklist": "Azure Security Review Checklist", - "guid": "0aa77e26-e4d5-4aea-a8dc-4e2436bc336d", - "link": "https://learn.microsoft.com/azure/azure-resource-manager/templates/syntax", - "services": [ - "VM" - ], + "category": "Operations", + "checklist": "Azure Spring Apps Review", + "cost": 1, + "guid": "dfcaffd1-d27c-4ef2-998d-64c1df3a7ac3", + "link": "https://learn.microsoft.com/azure/spring-apps/overview", + "services": [], "severity": "Medium", - "subcategory": "Access Control", - "text": "Reduce variability in your setup and deployment of VMs by leveraging templates" + "subcategory": "Support", + "text": "Use Enterprise plan for commercial support of spring boot for mission critical apps. With other tiers you get OSS support.", + "waf": "Reliability" }, { - "category": "VM Security Checks", - "checklist": "Azure Security Review Checklist", - "guid": "b5945bda-4333-44fd-b91c-234182b65275", - "link": "https://learn.microsoft.com/windows-server/identity/ad-ds/plan/security-best-practices/implementing-least-privilege-administrative-models", + "category": "Identity and Access Management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "d7e47431-76c8-4bdb-b55b-ce619e8a03f9", + "id": "A01.01", + "link": "https://learn.microsoft.com/azure/openshift/howto-create-service-principal?pivots=aro-azurecli", "services": [ - "VM" + "RBAC", + "Entra" ], - "severity": "Medium", - "subcategory": "Access Control", - "text": "Secure privileged access to deploy VMS by reducing who has access to Resources through Governance" + "severity": "High", + "subcategory": "Identity", + "text": "Create a service principal and its role assignments before creating the ARO clusters.", + "waf": "Security" }, { - "category": "VM Security Checks", - "checklist": "Azure Security Review Checklist", - "guid": "269440b4-be3d-43e0-a432-76d4bdc015bc", - "link": "https://learn.microsoft.com/azure/architecture/checklist/resiliency-per-service", + "category": "Identity and Access Management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "7879424d-6267-486d-90b9-6c97be985190", + "id": "A01.02", + "link": "https://learn.microsoft.com/azure/openshift/configure-azure-ad-ui", "services": [ - "VM" + "Entra" ], - "severity": "Medium", - "subcategory": "High Availability ", - "text": "Use multiple VMs for your workloads for better availability " + "severity": "High", + "subcategory": "Identity", + "text": "Use AAD to authenticate users in your ARO cluster.", + "waf": "Security" }, { - "category": "VM Security Checks", - "checklist": "Azure Security Review Checklist", - "guid": "f219e4a1-eb58-4879-935d-227886d30b66", - "link": "https://learn.microsoft.com/azure/backup/backup-azure-vms-first-look-arm", + "category": "Identity and Access Management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "adfec5f9-a82d-46e9-a8d1-5a0c7fed5d15", + "id": "A01.03", + "link": "https://docs.openshift.com/container-platform/4.14/authentication/remove-kubeadmin.html", "services": [ - "ASR", - "VM" + "Entra" ], - "severity": "Medium", - "subcategory": "High Availability ", - "text": "Deploy and test a disaster recovery solution " + "subcategory": "Identity", + "text": "When using AAD authentication, remove kubeadmin user from the cluster.", + "waf": "Security" }, { - "category": "VM Security Checks", - "checklist": "Azure Security Review Checklist", - "guid": "c57be595-1900-4838-95c5-86cb291ec16a", - "link": "https://learn.microsoft.com/azure/virtual-machines/availability-set-overview", + "category": "Identity and Access Management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "483835c9-86bb-4291-8155-a11475e39f54", + "id": "A01.04", + "link": "https://docs.openshift.com/container-platform/4.13/applications/projects/working-with-projects.html", "services": [ - "VM" + "RBAC", + "Entra" ], - "severity": "Medium", - "subcategory": "High Availability ", - "text": "Availability sets" + "severity": "High", + "subcategory": "Identity", + "text": "Define OpenShift projects to restrict RBAC privilege and isolate workloads in your cluster.", + "waf": "Security" }, { - "category": "VM Security Checks", - "checklist": "Azure Security Review Checklist", - "guid": "1d076ef9-f141-4acd-ae57-9377bcdb3751", - "link": "https://learn.microsoft.com/azure/availability-zones/az-overview?context=/azure/virtual-machines/context/context", + "category": "Identity and Access Management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "0acccd97-9376-4bcd-a375-0ab2ab039da6", + "id": "A01.05", + "link": "https://docs.openshift.com/container-platform/4.13/authentication/using-rbac.html", "services": [ - "VM" + "RBAC", + "Entra" ], "severity": "Medium", - "subcategory": "High Availability ", - "text": "Availability Zones" + "subcategory": "Identity", + "text": "Define the required RBAC roles in OpenShift are scoped to either a project or a cluster.", + "waf": "Security" }, { - "category": "VM Security Checks", - "checklist": "Azure Security Review Checklist", - "guid": "ab2ac1fa-d66e-415d-9d5a-2adb2c3e2326", - "link": "https://learn.microsoft.com/azure/architecture/resiliency/recovery-loss-azure-region", + "category": "Identity and Access Management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "d54d7c89-29db-4107-b532-5ae625ca44e4", + "id": "A01.06", + "link": "https://learn.microsoft.com/azure/cost-management-billing/manage/direct-ea-administration#manage-notification-contacts", "services": [ - "VM" + "AKV", + "Entra" ], "severity": "Medium", - "subcategory": "High Availability ", - "text": "Regional fault tolerance " + "subcategory": "Identity", + "text": "Minimize the number of users who have administrator rights and secrets access.", + "waf": "Security" }, { - "category": "VM Security Checks", - "checklist": "Azure Security Review Checklist", - "guid": "af225ca4-4e16-496f-bdde-ace4cb1deb4c", - "link": "https://learn.microsoft.com/azure/security/fundamentals/antimalware", + "category": "Identity and Access Management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "685e2223-ace8-4bb1-8307-ca5f16f154e3", + "id": "A01.07", + "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-configure", "services": [ - "VM" + "RBAC", + "Entra" ], - "severity": "High", - "subcategory": "Protect against malware", - "text": "Install antimalware solutions" + "severity": "Medium", + "subcategory": "Identity", + "text": "Use Privileged Identity Management in AAD for ARO users with privileged roles.", + "waf": "Security" }, { - "category": "VM Security Checks", - "checklist": "Azure Security Review Checklist", - "guid": "650c3fc1-4eeb-4b36-a382-9e3eec218368", - "link": "https://learn.microsoft.com/azure/security-center/security-center-partner-integration", + "category": "Network topology and connectivity", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "aa369282-9e7e-4216-8836-87af467a1f89", + "id": "B01.01", + "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", "services": [ - "VM", - "Defender" + "Firewall", + "Subscriptions", + "WAF", + "VNet", + "DDoS", + "Entra" ], - "severity": "High", - "subcategory": "Protect against malware", - "text": "Integrate antimalware solution with Security Center" + "severity": "Low", + "subcategory": "DDoS", + "text": "Use Azure DDoS Network/IP Protection to protect the virtual network you use for the ARO cluster unless you use Azure Firewall or WAF in a centralized subscription", + "waf": "Security" }, { - "category": "VM Security Checks", - "checklist": "Azure Security Review Checklist", - "guid": "7a0177a2-b594-45bd-a433-34fdf91c2341", - "link": "https://learn.microsoft.com/azure/automation/update-management/overview", - "services": [ - "VM" - ], + "category": "Network topology and connectivity", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "35bda433-24f1-4481-8533-182aa5174269", + "id": "B02.01", + "link": "https://docs.openshift.com/container-platform/4.13/networking/routes/secured-routes.html", + "services": [], "severity": "High", - "subcategory": "Manage VM Updates", - "text": "Keep VMs up to date using Update Management with Azure Automation" + "subcategory": "Encryption", + "text": "All web applications you configure to use an ingress should use TLS encryption and shouldn't allow access over unencrypted HTTP.", + "waf": "Security" }, { - "category": "VM Security Checks", - "checklist": "Azure Security Review Checklist", - "guid": "c6fa96b9-6ad8-4840-af37-2734c876ba28", - "link": "https://learn.microsoft.com/azure/virtual-machines/automatic-vm-guest-patching", + "category": "Network topology and connectivity", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "44008ae7-d7e4-4743-876c-8bdbf55bce61", + "id": "B03.01", + "link": "https://learn.microsoft.com/azure/frontdoor/front-door-overview", "services": [ - "VM" + "FrontDoor", + "WAF" ], "severity": "Medium", - "subcategory": "Manage VM Updates", - "text": "Ensure Windows images for deployment have the most recent level of updates " + "subcategory": "Internet", + "text": "Use Azure Front Door with WAF to securely publish ARO applications to the internet, especially in multi-region environments.", + "waf": "Security" }, { - "category": "VM Security Checks", - "checklist": "Azure Security Review Checklist", - "guid": "02145901-465d-438e-9309-ccbd979266bc", - "link": "https://learn.microsoft.com/azure/security-center/asset-inventory", + "category": "Network topology and connectivity", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "9e8a03f9-7879-4424-b626-786d60b96c97", + "id": "B03.02", + "link": "https://learn.microsoft.com/azure/openshift/howto-secure-openshift-with-front-door", "services": [ - "VM", - "Defender" + "FrontDoor", + "PrivateLink" ], - "severity": "High", - "subcategory": "Manage VM Updates", - "text": "Rapidly apply security updates to VMs using Microsoft Defender for Cloud" + "severity": "Medium", + "subcategory": "Internet", + "text": "If exposing an app on ARO with Azure Front Door, use private link to connect Front Door with the ARO router.", + "waf": "Security" }, { - "category": "VM Security Checks", - "checklist": "Azure Security Review Checklist", - "guid": "ca274faa-19bf-439d-a5d4-4c7c8919ca1f", - "link": "https://learn.microsoft.com/azure/virtual-machines/disk-encryption-overview", + "category": "Network topology and connectivity", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "be985190-4838-435c-a86b-b2912155a114", + "id": "B03.03", + "link": "https://learn.microsoft.com/azure/openshift/howto-restrict-egress", "services": [ - "VM" + "NVA", + "Firewall", + "AzurePolicy" ], - "severity": "High", - "subcategory": "Encrypt your VHDs", - "text": "Enable encryption on your VMs" + "severity": "Medium", + "subcategory": "Internet", + "text": "If your security policy requires you to inspect all outbound internet traffic that's generated in the ARO cluster, secure egress network traffic by using Azure Firewall or an NVA.", + "waf": "Security" }, { - "category": "VM Security Checks", - "checklist": "Azure Security Review Checklist", - "guid": "6d5315ae-524b-4a34-b458-5e12139bd7bb", - "link": "https://learn.microsoft.com/azure/virtual-machines/windows/disk-encryption-key-vault#set-up-a-key-encryption-key-kek", + "category": "Network topology and connectivity", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "75e39f54-0acc-4cd9-9937-6bcda3750ab2", + "id": "B04.01", + "link": "https://learn.microsoft.com/azure/openshift/howto-create-private-cluster-4x", "services": [ - "VM" + "AzurePolicy" ], "severity": "High", - "subcategory": "Encrypt your VHDs", - "text": "Add Key Encryption Key (KEK) for added layer of security for encryption " + "subcategory": "Private access", + "text": "If your security policy requires you to use a private IP address for the OpenShift API, deploy a private ARO cluster.", + "waf": "Security" }, { - "category": "VM Security Checks", - "checklist": "Azure Security Review Checklist", - "guid": "012f7b95-e06e-4154-b2aa-3592828e6e20", - "link": "https://learn.microsoft.com/azure/virtual-machines/windows/snapshot-copy-managed-disk", + "category": "Network topology and connectivity", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "ab039da6-d54d-47c8-a29d-b107d5325ae6", + "id": "B04.02", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-private-link", "services": [ - "VM", - "LoadBalancer" + "ACR", + "PrivateLink" ], "severity": "Medium", - "subcategory": "Encrypt your VHDs", - "text": "Take a snapshot of disks before encryption for rollback purposes" + "subcategory": "Private access", + "text": "Use Azure Private Link to secure network connections to managed Azure services, including to Azure Container Registry.", + "waf": "Security" }, { - "category": "VM Security Checks", - "checklist": "Azure Security Review Checklist", - "guid": "5173676a-e466-491e-a835-ad942223e138", - "link": "https://learn.microsoft.com/azure/role-based-access-control/built-in-roles", + "category": "Operations management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "25ca44e4-685e-4222-9ace-8bb12307ca5f", + "id": "C01.01", + "link": "https://learn.microsoft.com/azure/azure-monitor/containers/container-insights-enable-arc-enabled-clusters", "services": [ - "VM", - "Entra" + "Monitor" ], "severity": "High", - "subcategory": "Restrict direct internet connection ", - "text": "Ensure only the central networking group has permissions to networking resources " + "subcategory": "Operations", + "text": "Establish a monitoring process using the inbuilt Prometheus, OpenShift Logging or Container Insights integration.", + "waf": "Operations" }, { - "category": "VM Security Checks", - "checklist": "Azure Security Review Checklist", - "guid": "10523081-a941-4741-9833-ff7ad7c6d373", - "link": "https://learn.microsoft.com/azure/security-center/security-center-partner-integration", - "services": [ - "VM", - "Entra" - ], - "severity": "High", - "subcategory": "Restrict direct internet connection ", - "text": "Identity and remediate exposed VMs that allow access from 'ANY' source IP address" + "category": "Operations management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "16f154e3-aa36-4928-89e7-e216183687af", + "id": "C01.02", + "link": "https://docs.openshift.com/container-platform/4.13/cicd/pipelines/understanding-openshift-pipelines.html", + "services": [], + "severity": "Medium", + "subcategory": "Operations", + "text": "Automate the application delivery process through DevOps practices and CI/CD solutions, such as Pipelines/GitOps provided by OpenShift.", + "waf": "Operations" }, { - "category": "VM Security Checks", - "checklist": "Azure Security Review Checklist", - "guid": "75a91be1-f388-4f03-a4d2-cd463cbbbc86", - "link": "https://learn.microsoft.com/azure/security-center/security-center-just-in-time", + "category": "Operations management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "467a1f89-35bd-4a43-924f-14811533182a", + "id": "C01.03", + "link": "https://learn.microsoft.com/azure/architecture/guide/design-principles/managed-services", + "services": [], + "severity": "Low", + "subcategory": "Operations", + "text": "Whenever possible, remove the service state from inside containers. Instead, use an Azure platform as a service (PaaS) that supports multiregion replication.", + "waf": "Operations" + }, + { + "category": "Operations management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "1b7da8cf-aa66-4e15-b4d5-ada97dc3e232", + "id": "C01.04", + "link": "https://learn.microsoft.com/azure/openshift/howto-create-a-storageclass", "services": [ - "VM" + "Storage" ], + "severity": "Low", + "subcategory": "Operations", + "text": "Use RWX storage with inbuilt Azure Files storage class.", + "waf": "Operations" + }, + { + "category": "Operations management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "6bb235c7-05e1-4696-bded-fa8a4c8cdec4", + "id": "C02.01", + "link": "https://docs.openshift.com/container-platform/4.13/nodes/clusters/nodes-cluster-limit-ranges.html", + "services": [], + "severity": "Medium", + "subcategory": "Performance", + "text": "Use pod requests and limits to manage the compute resources within a cluster.", + "waf": "Performance" + }, + { + "category": "Operations management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "c620c30c-14ee-4b7f-9ae8-d9b3fec228e7", + "id": "C02.02", + "link": "https://docs.openshift.com/container-platform/4.13/applications/quotas/quotas-setting-per-project.html", + "services": [], + "severity": "Medium", + "subcategory": "Performance", + "text": "Enforce resource quotas on projects.", + "waf": "Performance" + }, + { + "category": "Operations management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "87ab177a-db59-4f6b-a613-334fd09dc234", + "id": "C02.03", + "link": "https://docs.openshift.com/container-platform/4.13/machine_management/applying-autoscaling.html", + "services": [], "severity": "High", - "subcategory": "Restrict direct internet connection ", - "text": "Restrict management ports (RDP, SSH) using Just-in-Time Access" + "subcategory": "Performance", + "text": "Define ClusterAutoScaler and MachineAutoScaler to scale machines when your cluster runs out of resources to support more deployments.", + "waf": "Performance" }, { - "category": "VM Security Checks", - "checklist": "Azure Security Review Checklist", - "guid": "8295abc9-1a4e-4da0-bae2-cc84c47b6b78", - "link": "http://learn.microsoft.com/answers/questions/171195/how-to-create-jump-server-in-azure-not-bastion-paa.html", + "category": "Operations management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "19db6128-1269-4040-a4ba-4d3e0804276d", + "id": "C03.01", + "link": "https://learn.microsoft.com/azure/openshift/support-policies-v4#supported-virtual-machine-sizes", "services": [ "VM" ], "severity": "High", - "subcategory": "Restrict direct internet connection ", - "text": "Remove internet access and implement jump servers for RDP" + "subcategory": "Reliability", + "text": "Use virtual machine sizes that are large enough to contain multiple container instances so you get the benefits of increased density, but not so large that your cluster can't handle the workload of a failing node.", + "waf": "Reliability" }, { - "category": "VM Security Checks", - "checklist": "Azure Security Review Checklist", - "guid": "1cbafe6c-4658-49d4-98a9-27c3974d1102", - "link": "https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-forced-tunneling", - "services": [ - "VM", - "VPN" - ], + "category": "Operations management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "4b98b15c-8b31-4aa5-aceb-58889135e227", + "id": "C03.02", + "link": "https://docs.openshift.com/container-platform/4.13/machine_management/deploying-machine-health-checks.html", + "services": [], "severity": "High", - "subcategory": "Restrict direct internet connection ", - "text": "Remove direct logging into servers using RDP/SSH from internet and implement VPN or express route" + "subcategory": "Reliability", + "text": "Deploy machine health checks to automatically repair damaged machines in a machine pool.", + "waf": "Reliability" }, { - "category": "VM Security Checks", - "checklist": "Azure Security Review Checklist", - "guid": "dad6aae1-1e6b-484e-b5df-47d2d92881b1", - "link": "https://learn.microsoft.com/azure/bastion/bastion-overview", + "category": "Operations management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "896d31b6-6c67-4ba5-a119-c08e8f5d587c", + "id": "C03.03", + "link": "https://learn.microsoft.com/azure/azure-monitor/containers/container-insights-metric-alerts", "services": [ - "VM", - "Bastion" + "Monitor" ], "severity": "High", - "subcategory": "Restrict direct internet connection ", - "text": "Leverage Azure Bastion as your RDP/SSH broker for added security and reduction in footprint" + "subcategory": "Reliability", + "text": "Use an alerting system to provide notifications when things need direct action: Container Insights metric alerts or in-built Alerting UI.", + "waf": "Reliability" }, { - "category": "Sentinel", - "checklist": "Azure Security Review Checklist", - "guid": "cd5d1e54-a297-459e-9968-0e78289c9356", - "link": "https://learn.microsoft.com/azure/sentinel/quickstart-onboard", - "services": [ - "Sentinel", - "Monitor" - ], + "category": "Operations management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "7e9ced16-acd1-476e-b9b2-41a998a57ae7", + "id": "C03.04", + "link": "https://learn.microsoft.com/azure/reliability/availability-zones-overview#availability-zones", + "services": [], "severity": "High", - "subcategory": "Architecture ", - "text": "All tenants contain have Sentinel enabled on at least one Log Analytics workspace" + "subcategory": "Reliability", + "text": "Ensure that the cluster is created in a region that supports AZs and create a machine set for each AZ.", + "waf": "Reliability" }, { - "category": "Sentinel", - "checklist": "Azure Security Review Checklist", - "guid": "57d02bff-4564-4b0d-a34a-359836ee79d6", - "link": "https://learn.microsoft.com/azure/sentinel/best-practices-workspace-architecture", + "category": "Operations management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "7b997e71-1b7d-4a8c-baa6-6e15d4d5ada9", + "id": "C03.05", + "link": "https://docs.openshift.com/container-platform/4.13/machine_management/creating-infrastructure-machinesets.html", "services": [ - "Sentinel" + "AKS" ], - "severity": "High", - "subcategory": "Architecture ", - "text": "Customer understands Sentinel architecture" + "severity": "Low", + "subcategory": "Reliability", + "text": "Create infrastructure machine sets to hold infrastructure components. Apply specific Kubernetes labels to these machines and then update the infrastructure components to run on only those machines.", + "waf": "Reliability" }, { - "category": "Sentinel", - "checklist": "Azure Security Review Checklist", - "guid": "e8f5c586-c7d9-4cdc-86ac-c075ef9b141a", - "link": "https://learn.microsoft.com/azure/sentinel/multiple-workspace-view", + "category": "Operations management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "7dc3e232-6bb2-435c-905e-1696fdedfa8a", + "id": "C03.06", + "link": "https://learn.microsoft.com/azure/openshift/howto-create-a-backup#create-a-backup-with-velero-to-include-snapshots", "services": [ - "ACR", - "Sentinel", - "Monitor" + "Backup" ], "severity": "Medium", - "subcategory": "Architecture ", - "text": "Customer knows how to monitor Incidents across multiple Sentinel instances" + "subcategory": "Reliability", + "text": "Create application backup and plan for restore and include persistent volumes in the backup.", + "waf": "Reliability" }, { - "category": "Sentinel", - "checklist": "Azure Security Review Checklist", - "guid": "8989579e-76b8-497e-910a-7da7be9966e1", - "link": "https://learn.microsoft.com/azure/sentinel/manage-soc-with-incident-metrics", - "services": [ - "Sentinel" - ], - "severity": "Medium", - "subcategory": "Overview", - "text": "No Incidents open more than 24 hours" + "category": "Operations management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "81c12318-1a64-4174-8583-3fb4ae3c2df7", + "id": "C03.07", + "link": "https://docs.openshift.com/container-platform/4.13/nodes/pods/nodes-pods-priority.html", + "services": [], + "severity": "Low", + "subcategory": "Reliability", + "text": "Use pod priorities, so that in case of limited resources the most critical pods will run.", + "waf": "Reliability" }, { - "category": "Sentinel", - "checklist": "Azure Security Review Checklist", - "guid": "5d3c4ada-97cb-43d1-925a-b225c6f4e068", - "link": "https://learn.microsoft.com/azure/sentinel/whats-new", + "category": "Operations management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "43166c3b-cbe0-45bb-b209-d4a0da577784", + "id": "C04.01", + "link": "https://docs.openshift.com/container-platform/4.13/architecture/admission-plug-ins.html", "services": [ - "Sentinel" + "AzurePolicy" ], "severity": "Low", - "subcategory": "News & Guides", - "text": "Customer have been shown the News & Guides tab" + "subcategory": "Security", + "text": "Regulate cluster functions using admission plug-ins, which are commonly used to enforce security policy, resource limitations, or configuration requirements.", + "waf": "Security" }, { - "category": "Sentinel", - "checklist": "Azure Security Review Checklist", - "guid": "5edddea8-a4b7-4cde-a4c6-1fc3fc14eea6", - "link": "https://learn.microsoft.com/azure/sentinel/enable-entity-behavior-analytics", + "category": "Operations management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "24d21678-5d2f-4a56-a56a-d48408fe8273", + "id": "C04.02", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-geo-replication", "services": [ - "Sentinel" + "ACR" ], + "severity": "Low", + "subcategory": "Security", + "text": "Store your container images in Azure Container Registry and geo-replicate the registry to each region.", + "waf": "Security" + }, + { + "category": "Operations management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "4c486ba2-80dc-4059-8cf7-5ee8e1309ccc", + "id": "C05.01", + "link": "https://docs.openshift.com/container-platform/4.13/nodes/pods/nodes-pods-vertical-autoscaler.html", + "services": [], "severity": "Medium", - "subcategory": "UEBA ", - "text": "UEBA Configured (Sentinel/Settings/Settings/Configure UEBA)" + "subcategory": "Workload", + "text": "Optimize the CPU and memory request values, and maximize the efficiency of the cluster resources using vertical pod autoscaler.", + "waf": "Performance" }, { - "category": "Sentinel", - "checklist": "Azure Security Review Checklist", - "guid": "e69d8d9a-3eec-4218-b687-ab077adb49e5", - "link": "https://learn.microsoft.com/azure/sentinel/connect-azure-active-directory", + "category": "Operations management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "d579366b-cda2-4750-aa1a-bfe9d55d14c3", + "id": "C05.02", + "link": "https://docs.openshift.com/container-platform/4.13/applications/application-health.html", "services": [ - "Sentinel", - "Entra" + "Monitor" ], - "severity": "High", - "subcategory": "Data Connectors", - "text": "Azure Active Directory in configured and 'Last Log Received' shows today" + "severity": "Medium", + "subcategory": "Workload", + "text": "Add health probes to your pods to monitor application health. Make sure pods contain livenessProbe and readinessProbe. Use Startup probes to determine the point at which the application has started up.", + "waf": "Reliability" }, { - "category": "Sentinel", - "checklist": "Azure Security Review Checklist", - "guid": "b9603334-fdf8-4cc2-9318-db61171269f4", - "link": "https://learn.microsoft.com/azure/sentinel/data-connectors-reference#azure-active-directory-identity-protection", - "services": [ - "Sentinel", - "Entra" - ], - "severity": "High", - "subcategory": "Data Connectors", - "text": "Azure Active Directory Identity Protection is configured and 'Last Log Received' shows today" + "category": "Operations management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "c4929cb1-b3d1-4325-ae12-4ba34d0685ed", + "id": "C05.03", + "link": "https://docs.openshift.com/container-platform/4.13/nodes/pods/nodes-pods-autoscaling.html", + "services": [], + "severity": "Medium", + "subcategory": "Workload", + "text": "Scale pods to meet demand using horizontal pod autoscaler.", + "waf": "Reliability" }, { - "category": "Sentinel", - "checklist": "Azure Security Review Checklist", - "guid": "0b4aa3d3-e070-4327-9d4b-98b15b8a219a", - "link": "https://learn.microsoft.com/azure/sentinel/data-connectors-reference#azure-activity", + "category": "Operations management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "dce9be3b-b0dd-4b3b-95fb-2ec14eeaa359", + "id": "C05.04", + "link": "https://docs.openshift.com/container-platform/4.13/nodes/pods/nodes-pods-configuring.html#nodes-pods-pod-distruption-about_nodes-pods-configuring", "services": [ - "Sentinel" + "Cost" ], - "severity": "High", - "subcategory": "Data Connectors", - "text": "Azure Activity is configured is configured and 'Last Log Received' shows today" + "severity": "Medium", + "subcategory": "Workload", + "text": "Use disruption budgets to ensure the required number of pod replicas exist to handle expected application load.", + "waf": "Reliability" }, { - "category": "Sentinel", - "checklist": "Azure Security Review Checklist", - "guid": "8e13f9cc-bd46-4826-9abc-a264f9a19bfe", - "link": "https://learn.microsoft.com/azure/sentinel/connect-defender-for-cloud", - "services": [ - "Defender", - "Sentinel" - ], - "severity": "High", - "subcategory": "Data Connectors", - "text": "Microsoft Defender for Cloud is configured and 'Last Log Received' shows today" + "category": "Operations management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "2829e2ed-b217-4367-9aff-6791b4935ada", + "id": "C05.05", + "link": "https://docs.openshift.com/container-platform/4.13/nodes/scheduling/nodes-scheduler-pod-topology-spread-constraints.html", + "services": [], + "severity": "Medium", + "subcategory": "Workload", + "text": "Use pod topology constraints to automatically schedule pods on nodes throughout the cluster.", + "waf": "Reliability" }, { - "category": "Sentinel", - "checklist": "Azure Security Review Checklist", - "guid": "9d55d04c-3c49-419c-a1b2-d1215ae114b9", - "link": "https://learn.microsoft.com/azure/sentinel/data-connectors-reference#azure-firewall", - "services": [ - "Firewall", - "Sentinel" - ], - "severity": "High", - "subcategory": "Data Connectors", - "text": "Azure Firewall is configured and 'Last Log Received' shows today" + "category": "Platform Automation", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "42324ece-81c1-4231-a1a6-417415833fb4", + "id": "D01.01", + "link": "https://docs.openshift.com/container-platform/4.13/applications/deployments/route-based-deployment-strategies.html", + "services": [], + "severity": "Low", + "subcategory": "Workload", + "text": "Consider blue/green or canary strategies to deploy new releases of application.", + "waf": "Operations" }, { - "category": "Sentinel", - "checklist": "Azure Security Review Checklist", - "guid": "34df585e-cccd-49bd-9ba0-cdb3b54eb2eb", - "link": "https://learn.microsoft.com/azure/sentinel/data-connectors-reference#windows-firewall", - "services": [ - "Sentinel" - ], + "category": "Platform Automation", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "ae3c2df7-4316-46c3-acbe-05bbe209d4a0", + "id": "D01.02", + "link": "https://docs.openshift.com/container-platform/4.13/cicd/gitops/understanding-openshift-gitops.html", + "services": [], + "severity": "Low", + "subcategory": "Workload", + "text": "Consider using Red Hat OpenShift GitOps. Red Hat OpenShift GitOps uses Argo CD to maintain cluster resources and support application CI/CD.", + "waf": "Operations" + }, + { + "category": "Security", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "da577784-24d2-4167-a5d2-fa56c56ad484", + "id": "E01.01", + "link": "https://learn.microsoft.com/azure/openshift/support-lifecycle", + "services": [], "severity": "High", - "subcategory": "Data Connectors", - "text": "Windows Firewall is configured and 'Last Log Received' shows today" + "subcategory": "Control plane", + "text": "Keep your clusters on the latest OpenShift version to avoid potential security or upgrade issues.", + "waf": "Security" }, { - "category": "Sentinel", - "checklist": "Azure Security Review Checklist", - "guid": "03ddaa25-9271-48d2-bdb1-0725769ef669", - "link": "https://learn.microsoft.com/azure/sentinel/data-connectors-reference#windows-security-events-via-ama", + "category": "Security", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "08fe8273-4c48-46ba-880d-c0591cf75ee8", + "id": "E01.02", + "link": "https://learn.microsoft.com/azure/azure-arc/kubernetes/quickstart-connect-cluster", "services": [ - "Sentinel" + "AKS", + "Arc" ], "severity": "High", - "subcategory": "Data Connectors", - "text": "Security Events is configured with AMA and 'Last Log Received' shows today" + "subcategory": "Control plane", + "text": "Connect Azure Red Hat OpenShift clusters to Azure Arc-enabled Kubernetes.", + "waf": "Security" + }, + { + "category": "Security", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "e1309ccc-d579-4366-acda-2750aa1abfe9", + "id": "E02.01", + "link": "https://docs.openshift.com/container-platform/4.10/security/encrypting-etcd.html", + "services": [], + "severity": "Low", + "subcategory": "Encryption", + "text": "For Azure Red Hat OpenShift 4 clusters, etcd data isn't encrypted by default, but it's recommended to enable etcd encryption to provide another layer of data security.", + "waf": "Security" }, { - "category": "Sentinel", - "checklist": "Azure Security Review Checklist", - "guid": "1a4834ac-9322-423e-ae80-b123081a5417", - "link": "https://learn.microsoft.com/azure/sentinel/data-connectors-reference", + "category": "Security", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "d55d14c3-c492-49cb-8b3d-1325ae124ba3", + "id": "E03.01", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-introduction", "services": [ - "Sentinel" + "Arc", + "AKS", + "Defender" ], - "severity": "High", - "subcategory": "Data Connectors", - "text": "Security Events - verify Azure computers are connected and sending data to the workspace" + "severity": "Medium", + "subcategory": "Posture", + "text": "Use Microsoft Defender for Containers supported via Arc-enabled Kubernetes to secure clusters, containers, and applications.", + "waf": "Security" }, { - "category": "Sentinel", - "checklist": "Azure Security Review Checklist", - "guid": "859c773e-7e26-4162-9b77-5a917e1f348e", - "link": "https://learn.microsoft.com/azure/sentinel/data-connectors-reference", + "category": "Security", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "4d0685ed-dce9-4be3-ab0d-db3b55fb2ec1", + "id": "E04.01", + "link": "https://learn.microsoft.com/azure/azure-arc/kubernetes/tutorial-akv-secrets-provider", "services": [ - "Sentinel" + "AKS", + "AKV", + "Arc" ], - "severity": "High", - "subcategory": "Data Connectors", - "text": "Security Events - verify non-Azure computers are connected and sending data to the workspace" + "severity": "Medium", + "subcategory": "Secrets", + "text": "For applications that require access to sensitive information, use a service principal and the AKV Secrets Provider with the extension for Arc-enabled Kubernetes clusters.", + "waf": "Security" }, { - "category": "Sentinel", - "checklist": "Azure Security Review Checklist", - "guid": "f354c27d-42e8-4bba-a868-155abb9163e9", - "link": "https://learn.microsoft.com/azure/sentinel/connect-aws?tabs=s3", - "services": [ - "Sentinel" - ], - "severity": "High", - "subcategory": "Data Connectors", - "text": "Connector for AWS" + "category": "Security", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "4eeaa359-2829-4e2e-bb21-73676aff6791", + "id": "E05.01", + "link": "https://learn.microsoft.com/azure/aks/developer-best-practices-pod-security#secure-pod-access-to-resources", + "services": [], + "severity": "Medium", + "subcategory": "Workload", + "text": "Secure pod access to resources. Provide the least number of permissions, and avoid using root or privileged escalation.", + "waf": "Security" }, { - "category": "Sentinel", - "checklist": "Azure Security Review Checklist", - "guid": "909ae28c-84c3-43b6-a780-8bafe6c42149", - "link": "https://learn.microsoft.com/azure/sentinel/data-connectors-reference", + "category": "Security", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "b4935ada-4232-44ec-b81c-123181a64174", + "id": "E05.02", + "link": "https://learn.microsoft.com/azure/governance/policy/concepts/policy-for-kubernetes#install-azure-policy-extension-for-azure-arc-enabled-kubernetes", "services": [ - "Sentinel" + "Monitor", + "AzurePolicy" ], - "severity": "High", - "subcategory": "Data Connectors", - "text": "Connector for GCP" + "severity": "Medium", + "subcategory": "Workload", + "text": "Monitor and enforce configuration by using the Azure Policy Extension.", + "waf": "Security" }, { - "category": "Sentinel", - "checklist": "Azure Security Review Checklist", - "guid": "d413a923-c357-44d1-8028-ac6aae01e6a8", - "link": "https://learn.microsoft.com/azure/sentinel/detect-threats-built-in", + "category": "Security", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "15833fb4-ae3c-42df-9431-66c3bcbe05bb", + "id": "E05.03", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-introduction", "services": [ - "Sentinel" + "Defender" ], "severity": "High", - "subcategory": "Analytics Rules", - "text": "Customer has enabled Analytics rules and configured Incidents " + "subcategory": "Workload", + "text": "Scan your images for vulnerabilities with Microsoft Defender or any other image scanning solution.", + "waf": "Security" }, { - "category": "Sentinel", - "checklist": "Azure Security Review Checklist", - "guid": "4de5df43-d299-4248-8718-d5d1e5f62565", - "link": "https://azure.microsoft.com/updates/controlling-data-volume-and-retention-in-log-analytics-2/", + "category": "Security", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "e209d4a0-da57-4778-924d-216785d2fa56", + "id": "E05.04", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-private-link", "services": [ - "Sentinel" + "ACR", + "Subscriptions" ], - "severity": "Medium", - "subcategory": "Settings", - "text": "Customer does not have a daily cap enabled" + "severity": "Low", + "subcategory": "Workload", + "text": "Deploy a dedicated and private instance of Azure Container Registry to each landing zone subscription.", + "waf": "Security" }, { - "category": "Azure Firewall", - "checklist": "Azure Security Review Checklist", - "guid": "9e3558fd-7724-49c9-9111-2d027fe412f7", - "link": "https://learn.microsoft.com/azure/firewall/premium-features", + "category": "Security", + "checklist": "Azure Service Bus Review", + "description": "Azure Service Bus Premium provides encryption of data at rest. If you use your own key, the data is still encrypted using the Microsoft-managed key, but in addition the Microsoft-managed key will be encrypted using the customer-managed key. ", + "guid": "87af4a79-1f89-439b-ba47-768e14c11567", + "link": "https://learn.microsoft.com/azure/service-bus-messaging/configure-customer-managed-key", "services": [ - "Firewall" + "ServiceBus" ], - "severity": "High", - "subcategory": "Configuration", - "text": "Azure Firewall Premium deployed" + "severity": "Low", + "subcategory": "Data Protection", + "text": "Use customer-managed key option in data at rest encryption when required", + "training": "https://learn.microsoft.com/learn/modules/plan-implement-administer-conditional-access/" }, { - "category": "Azure Firewall", - "checklist": "Azure Security Review Checklist", - "guid": "4dc74a74-8b66-433a-b2a0-916a764980ad", - "link": "https://learn.microsoft.com/azure/firewall/tutorial-firewall-deploy-portal#create-a-default-route", + "category": "Security", + "checklist": "Azure Service Bus Review", + "description": "Communication between a client application and an Azure Service Bus namespace is encrypted using Transport Layer Security (TLS). Azure Service Bus namespaces permit clients to send and receive data with TLS 1.0 and above. To enforce stricter security measures, you can configure your Service Bus namespace to require that clients send and receive data with a newer version of TLS.", + "guid": "5c1ea55b-46a9-448f-b8ae-7d7e4b475b6c", + "link": "https://learn.microsoft.com/azure/service-bus-messaging/transport-layer-security-enforce-minimum-version", "services": [ - "Firewall" + "ServiceBus" ], - "severity": "High", - "subcategory": "Configuration", - "text": "Quad zero/force tunning enabled through Azure Firewall" + "severity": "Medium", + "subcategory": "Data Protection", + "text": "Enforce a minimum required version of Transport Layer Security (TLS) for requests ", + "training": "https://learn.microsoft.com/learn/modules/secure-aad-users-with-mfa/" }, { - "category": "Azure Firewall", - "checklist": "Azure Security Review Checklist", - "guid": "0e278ee2-93c1-4bc3-92ba-aab7571849ab", - "link": "https://techcommunity.microsoft.com/t5/azure-network-security/role-based-access-control-for-azure-firewall/ba-p/2245598", + "category": "Security", + "checklist": "Azure Service Bus Review", + "description": "When you create a Service Bus namespace, a SAS rule named RootManageSharedAccessKey is automatically created for the namespace. This policy has Manage permissions for the entire namespace. It's recommended that you treat this rule like an administrative root account and don't use it in your application. Using AAD as an authentication provider with RBAC is recommended. ", + "guid": "8bcbf59b-ce65-4de8-a03f-97879468d66a", + "link": "https://learn.microsoft.com/azure/service-bus-messaging/service-bus-sas#shared-access-authorization-policies", "services": [ - "Firewall", - "RBAC" + "TrafficManager", + "AzurePolicy", + "RBAC", + "ServiceBus", + "Entra" ], "severity": "Medium", - "subcategory": "Access Control", - "text": "RBAC set to enable only authorized users" + "subcategory": "Identity and Access Management", + "text": "Avoid using root account when it is not necessary", + "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-identities-governance/" }, { - "category": "Azure Firewall", - "checklist": "Azure Security Review Checklist", - "guid": "8093dc9f-c9d1-4bb7-9b36-a5a67fbb9ed5", - "link": "https://learn.microsoft.com/azure/firewall/firewall-diagnostics", + "category": "Security", + "checklist": "Azure Service Bus Review", + "description": "A Service Bus client app running inside an Azure App Service application or in a virtual machine with enabled managed entities for Azure resources support does not need to handle SAS rules and keys, or any other access tokens. The client app only needs the endpoint address of the Service Bus Messaging namespace. ", + "guid": "786d60f9-6c96-4ad8-a55d-04c2b39c986b", + "link": "https://learn.microsoft.com/azure/service-bus-messaging/service-bus-managed-service-identity", "services": [ - "Firewall", - "Monitor" + "VM", + "AKV", + "Storage", + "AppSvc", + "ServiceBus", + "Entra" ], "severity": "Medium", - "subcategory": "Diagnostic Settings", - "text": "Diagnostics enabled and sending metrics to a Log Analytics workspace " + "subcategory": "Identity and Access Management", + "text": "When possible, your application should be using a managed identity to authenticate to Azure Service Bus. If not, consider having the storage credential (SAS, service principal credential) in Azure Key Vault or an equivalent service", + "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/" }, { - "category": "Azure Firewall", - "checklist": "Azure Security Review Checklist", - "guid": "b35478c3-4798-416b-8863-cffe1cac599e", - "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview", + "category": "Security", + "checklist": "Azure Service Bus Review", + "description": "When creating permissions, provide fine-grained control over a client's access to Azure Service Bus. Permissions in Azure Service Bus can and should be scoped to the individual resource level e.g. queue, topic or subscription. ", + "guid": "f615658d-e558-4f93-9249-b831112dbd7e", + "link": "https://learn.microsoft.com/azure/service-bus-messaging/authenticate-application#azure-built-in-roles-for-azure-service-bus", "services": [ - "Firewall", - "VNet" + "RBAC", + "Storage", + "ServiceBus", + "Subscriptions", + "Entra" ], "severity": "High", - "subcategory": "Firewall Manager", - "text": "Hubs and virtual networks are protected or connected through Firewall Premium" + "subcategory": "Identity and Access Management", + "text": "Use least privilege data plane RBAC", + "training": "https://learn.microsoft.com/learn/modules/explore-basic-services-identity-types/" }, { - "category": "Azure Firewall", - "checklist": "Azure Security Review Checklist", - "guid": "f0d5a73d-d4de-436c-8c81-770afbc4c0e4", - "link": "https://techcommunity.microsoft.com/t5/azure-network-security/role-based-access-control-for-azure-firewall/ba-p/2245598", + "category": "Security", + "checklist": "Azure Service Bus Review", + "description": "Azure Service Bus resource logs include operational logs, virtual network and IP filtering logs. Runtime audit logs capture aggregated diagnostic information for various data plane access operations (such as send or receive messages) in Service Bus.", + "guid": "af12e7f9-43f6-4304-922d-929c2b1cd622", + "link": "https://learn.microsoft.com/azure/service-bus-messaging/monitor-service-bus-reference", "services": [ - "Firewall", - "AzurePolicy", - "RBAC" + "Monitor", + "VNet", + "ServiceBus" ], - "severity": "High", - "subcategory": "Firewall Manager", - "text": "Policy: Access controls are configured (RBAC)" + "severity": "Medium", + "subcategory": "Monitoring", + "text": "Enable logging for security investigation. Use Azure Monitor to trace resource logs and runtime audit logs (currently available only in the premium tier)", + "training": "https://learn.microsoft.com/learn/paths/manage-identity-and-access/" }, { - "category": "Azure Firewall", - "checklist": "Azure Security Review Checklist", - "guid": "5c3a87af-4a79-41f8-a39b-da47768e14c1", - "link": "https://learn.microsoft.com/azure/firewall-manager/policy-overview", + "category": "Security", + "checklist": "Azure Service Bus Review", + "description": "Azure Service Bus by default has a public IP address and is Internet-reachable. Private endpoints allow traffic between your virtual network and Azure Service Bus traverses over the Microsoft backbone network. In addition to that, you should disable public endpoints if those are not used. ", + "guid": "9ae669ca-48e4-4a85-b222-3ece8bb12307", + "link": "https://learn.microsoft.com/azure/service-bus-messaging/private-link-service", + "services": [ + "VNet", + "ServiceBus", + "PrivateLink" + ], + "severity": "Medium", + "subcategory": "Networking", + "text": "Consider using private endpoints to access Azure Service Bus and disable public network access when applicable.", + "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/" + }, + { + "category": "Security", + "checklist": "Azure Service Bus Review", + "description": "With IP firewall, you can restrict the public endpoint further to only a set of IPv4 addresses or IPv4 address ranges in CIDR (Classless Inter-Domain Routing) notation. ", + "guid": "ca5f06f1-58e3-4ea3-a92c-2de7e2165c3a", + "link": "https://learn.microsoft.com/azure/service-bus-messaging/service-bus-ip-filtering", "services": [ - "Firewall", - "AzurePolicy" + "ServiceBus" ], - "severity": "High", - "subcategory": "Firewall Manager", - "text": "Policy: Parent policy is configured " + "severity": "Medium", + "subcategory": "Networking", + "text": "Consider only allowing access to Azure Service Bus namespace from specific IP addresses or ranges", + "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/" }, { - "category": "Azure Firewall", - "checklist": "Azure Security Review Checklist", - "guid": "15675c1e-a55b-446a-a48f-f8ae7d7e4b47", - "link": "https://learn.microsoft.com/azure/firewall/rule-processing", + "category": "Security", + "checklist": "Azure App Security Review", + "description": "Use Azure Key Vault to store any secrets the application needs. Key Vault provides a safe and audited environment for storing secrets and is well-integrated with App Service through the Key Vault SDK or App Service Key Vault References.", + "guid": "834ac932-223e-4ce8-8b12-3071a5416415", + "id": "A01.01", + "link": "https://learn.microsoft.com/azure/app-service/app-service-key-vault-references", "services": [ - "Firewall", - "AzurePolicy" + "AppSvc", + "AKV" ], "severity": "High", - "subcategory": "Firewall Manager", - "text": "Policy: Rule collections are defined" + "subcategory": "Data Protection", + "text": "Use Key Vault to store secrets", + "waf": "Security" }, { - "category": "Azure Firewall", - "checklist": "Azure Security Review Checklist", - "guid": "5b6c8bcb-f59b-4ce6-9de8-a03f97879468", - "link": "https://learn.microsoft.com/azure/firewall/rule-processing", + "category": "Security", + "checklist": "Azure App Security Review", + "description": "Use a Managed Identity to connect to Key Vault either using the Key Vault SDK or through App Service Key Vault References.", + "guid": "833ea3ad-2c2d-4e73-8165-c3acbef4abe1", + "id": "A01.02", + "link": "https://learn.microsoft.com/azure/app-service/app-service-key-vault-references", "services": [ - "Firewall", - "AzurePolicy" + "AppSvc", + "AKV", + "Entra" ], "severity": "High", - "subcategory": "Firewall Manager", - "text": "Policy: DNAT policies are defined" + "subcategory": "Data Protection", + "text": "Use Managed Identity to connect to Key Vault", + "waf": "Security" }, { - "category": "Azure Firewall", - "checklist": "Azure Security Review Checklist", - "guid": "d66a786d-60e9-46c9-9ad8-855d04c2b39c", - "link": "https://learn.microsoft.com/azure/firewall/rule-processing", + "category": "Security", + "checklist": "Azure App Security Review", + "description": "Store the App Service TLS certificate in Key Vault.", + "guid": "f8d39fda-4776-4831-9c11-5775c2ea55b4", + "id": "A01.03", + "link": "https://learn.microsoft.com/azure/app-service/configure-ssl-certificate", "services": [ - "Firewall", - "AzurePolicy" + "AppSvc", + "AKV" ], "severity": "High", - "subcategory": "Firewall Manager", - "text": "Policy: Network rules are defined" + "subcategory": "Data Protection", + "text": "Use Key Vault to store TLS certificate.", + "waf": "Security" }, { - "category": "Azure Firewall", - "checklist": "Azure Security Review Checklist", - "guid": "986bb2c1-2149-4a11-9b5e-3df574ecccd9", - "link": "https://learn.microsoft.com/azure/firewall/features", + "category": "Security", + "checklist": "Azure App Security Review", + "description": "Systems that process sensitive information should be isolated. To do so, use separate App Service Plans or App Service Environments and consider the use of different subscriptions or management groups.", + "guid": "6ad48408-ee72-4734-a475-ba18fdbf590c", + "id": "A01.04", + "link": "https://learn.microsoft.com/azure/app-service/overview-hosting-plans", "services": [ - "Firewall", - "AzurePolicy" + "Subscriptions", + "AppSvc" ], - "severity": "High", - "subcategory": "Firewall Manager", - "text": "Policy: Application rules are defined" + "severity": "Medium", + "subcategory": "Data Protection", + "text": "Isolate systems that process sensitive information", + "waf": "Security" }, { - "category": "Azure Firewall", - "checklist": "Azure Security Review Checklist", - "guid": "793a6bcd-a3b5-40eb-8eb0-3dd95d58d7c8", - "link": "https://learn.microsoft.com/azure/firewall/dns-details", + "category": "Security", + "checklist": "Azure App Security Review", + "description": "Local disks on App Service are not encrypted and sensitive data should not be stored on those. (For example: D:\\\\Local and %TMP%).", + "guid": "e65de8e0-3f9b-4cbd-9682-66abca264f9a", + "id": "A01.05", + "link": "https://learn.microsoft.com/azure/app-service/operating-system-functionality#file-access", "services": [ - "Firewall", - "DNS" + "TrafficManager", + "AppSvc" ], "severity": "Medium", - "subcategory": "Firewall Manager", - "text": "DNS: Feature understood and applied or not applied" + "subcategory": "Data Protection", + "text": "Do not store sensitive data on local disk", + "waf": "Security" }, { - "category": "Azure Firewall", - "checklist": "Azure Security Review Checklist", - "guid": "d622f54b-29ba-4de3-aad1-e8c28ec93666", - "link": "https://learn.microsoft.com/azure/firewall-manager/threat-intelligence-settings", + "category": "Security", + "checklist": "Azure App Security Review", + "description": "For authenticated web application, use a well established Identity Provider like Azure AD or Azure AD B2C. Leverage the application framework of your choice to integrate with this provider or use the App Service Authentication / Authorization feature.", + "guid": "919ca0b2-c121-459e-814b-933df574eccc", + "id": "A02.01", + "link": "https://learn.microsoft.com/azure/app-service/overview-authentication-authorization", "services": [ - "Firewall" + "AppSvc", + "Entra" ], - "severity": "High", - "subcategory": "Firewall Manager", - "text": "Threat Intelligence: Set to Alert & Deny" + "severity": "Medium", + "subcategory": "Identity and Access Control", + "text": "Use an established Identity Provider for authentication", + "waf": "Security" }, { - "category": "Azure Firewall", - "checklist": "Azure Security Review Checklist", - "guid": "7313b005-674b-41e9-94a4-59c373e7ed61", - "link": "https://learn.microsoft.com/azure/firewall-manager/threat-intelligence-settings#allowlist-addresses", + "category": "Security", + "checklist": "Azure App Security Review", + "description": "Deploy code to App Service from a controlled and trusted environment, like a well-managed and secured DevOps deployment pipeline. This avoids code that was not version controlled and verified to be deployed from a malicious host.", + "guid": "3f9bcbd4-6826-46ab-aa26-4f9a19aed9c5", + "id": "A02.02", + "link": "https://learn.microsoft.com/azure/app-service/deploy-best-practices", "services": [ - "Firewall" + "AppSvc", + "Entra" ], "severity": "High", - "subcategory": "Firewall Manager", - "text": "Threat Intelligence: Allowed list (justify if they are being used - ie performance)" + "subcategory": "Identity and Access Control", + "text": "Deploy from a trusted environment", + "waf": "Security" }, { - "category": "Azure Firewall", - "checklist": "Azure Security Review Checklist", - "guid": "623b365a-917e-4cbe-98eb-d54cd7df2e8b", - "link": "https://learn.microsoft.com/azure/firewall/premium-certificates", + "category": "Security", + "checklist": "Azure App Security Review", + "description": "Disable basic authentication for both FTP/FTPS and for WebDeploy/SCM. This disables access to these services and enforces the use of Azure AD secured endpoints for deployment. Note that the SCM site can also be opened using Azure AD credentials.", + "guid": "5d04c2c3-919c-4a0b-8c12-159e114b933d", + "id": "A02.03", + "link": "https://learn.microsoft.com/azure/app-service/deploy-configure-credentials#disable-basic-authentication", "services": [ - "Firewall" + "Entra" ], "severity": "High", - "subcategory": "Firewall Manager", - "text": "TLS enabled" + "subcategory": "Identity and Access Control", + "text": "Disable basic authentication", + "waf": "Security" }, { - "category": "Azure Firewall", - "checklist": "Azure Security Review Checklist", - "guid": "bac35715-59ab-4915-9e99-08aed8c44ce3", - "link": "https://learn.microsoft.com/azure/firewall/rule-processing", + "category": "Security", + "checklist": "Azure App Security Review", + "description": "Where possible use Managed Identity to connect to Azure AD secured resources. If this is not possible, store secrets in Key Vault and connect to Key Vault using a Managed Identity instead.", + "guid": "f574eccc-d9bd-43ba-bcda-3b54eb2eb03d", + "id": "A02.04", + "link": "https://learn.microsoft.com/azure/app-service/overview-managed-identity?tabs=portal%2Chttp", "services": [ - "Firewall" + "AKV", + "Entra" ], "severity": "High", - "subcategory": "Firewall Manager", - "text": "IDPS enabled" + "subcategory": "Identity and Access Control", + "text": "Use Managed Identity to connect to resources", + "waf": "Security" }, { - "category": "Azure Firewall", - "checklist": "Azure Security Review Checklist", - "guid": "b2b3808b-9fa1-4cf1-849d-003a923ce474", - "link": "https://learn.microsoft.com/azure/firewall/snat-private-range", + "category": "Security", + "checklist": "Azure App Security Review", + "description": "Where using images stored in Azure Container Registry, pull these using a Managed Identity.", + "guid": "d9a25827-18d2-4ddb-8072-5769ee6691a4", + "id": "A02.05", + "link": "https://learn.microsoft.com/azure/app-service/configure-custom-container#use-managed-identity-to-pull-image-from-azure-container-registry", "services": [ - "Firewall" + "ACR", + "Entra" ], "severity": "High", - "subcategory": "Firewall Manager", - "text": "SNAT: Configured " + "subcategory": "Identity and Access Control", + "text": "Pull containers using a Managed Identity", + "waf": "Security" }, { - "category": "Azure Firewall", - "checklist": "Azure Security Review Checklist", - "guid": "dbcbd8ac-2aae-4bca-8a43-da1dae2cc992", - "link": "https://learn.microsoft.com/azure/security/fundamentals/ddos-best-practices", + "category": "Security", + "checklist": "Azure App Security Review", + "description": "By configuring the diagnostic settings of App Service, you can send all telemetry to Log Analytics as the central destination for logging and monitoring. This allows you to monitor runtime activity of App Service such as HTTP logs, application logs, platform logs, ...", + "guid": "47768314-c115-4775-a2ea-55b46ad48408", + "id": "A03.01", + "link": "https://learn.microsoft.com/azure/app-service/troubleshoot-diagnostic-logs", "services": [ - "Firewall", - "DDoS" + "Monitor", + "AppSvc", + "Entra" ], "severity": "Medium", - "subcategory": "DDOS Protection", - "text": "Enabled for Firewall public IP's" + "subcategory": "Logging and Monitoring", + "text": "Send App Service runtime logs to Log Analytics", + "waf": "Security" }, { - "category": "BCDR", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Ensure that your backups are protected against attacks. This should include encryption of the backups to protect against loss of confidentiality. For regular Azure service backup, backup data is automatically encrypted using Azure platform-managed keys. You can also choose to encrypt the backup using a customer-managed key. In this case, ensure this customer-managed key in the key vault is also in the backup scope.", - "guid": "676f6951-0368-49e9-808d-c33a692c9a64", - "id": "A01.01", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/sql-database-security-baseline#br-2-encrypt-backup-data", + "category": "Security", + "checklist": "Azure App Security Review", + "description": "Set up a diagnostic setting to send the activity log to Log Analytics as the central destination for logging and monitoring. This allows you to monitor control plane activity on the App Service resource itself.", + "guid": "ee72734b-475b-4a18-bdbf-590ce65de8e0", + "id": "A03.02", + "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", "services": [ - "Backup", - "SQL", - "AKV" + "Monitor", + "AppSvc", + "Entra" ], "severity": "Medium", - "subcategory": "Azure Key Vault", - "text": "Protect your backup data with encryption and store keys safely in Azure Key Vault", + "subcategory": "Logging and Monitoring", + "text": "Send App Service activity logs to Log Analytics", "waf": "Security" }, - { - "category": "BCDR", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Azure SQL Database uses SQL Server technology to create full backups every week, differential backup every 12-24 hours, and transaction log backup every 5 to 10 minutes. By default, SQL Database stores data in geo-redundant storage blobs that are replicated to a paired region.", - "guid": "e2518261-b3bc-4bd1-b331-637fb2df833f", - "id": "A02.01", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/sql-database-security-baseline#br-1-ensure-regular-automated-backups", + { + "category": "Security", + "checklist": "Azure App Security Review", + "description": "Control outbound network access using a combination of regional VNet integration, network security groups and UDR's. Traffic should be routed to an NVA such as Azure Firewall. Ensure to monitor the Firewall's logs.", + "guid": "c12159e1-14b9-433d-b574-ecccd9bd3baf", + "id": "A04.01", + "link": "https://learn.microsoft.com/azure/app-service/overview-vnet-integration", "services": [ - "Backup", - "Storage", - "SQL" + "NVA", + "VNet", + "Monitor", + "Firewall" ], "severity": "Medium", - "subcategory": "Backup", - "text": "Configure Azure SQL Database automated backups", + "subcategory": "Network Security", + "text": "Outbound network access should be controlled", "waf": "Security" }, { - "category": "BCDR", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "By default, SQL Database stores data in geo-redundant storage blobs that are replicated to a paired region. For SQL Database, the backup storage redundancy can be configured at the time of database creation or can be updated for an existing database; the changes made to an existing database apply to future backups only.", - "guid": "f8c7cda2-3ed7-43fb-a100-85dcd12a0ee4", - "id": "A02.02", - "link": "https://learn.microsoft.com/azure/azure-sql/database/automated-backups-overview?tabs=single-database&view=azuresql#backup-storage-redundancy", + "category": "Security", + "checklist": "Azure App Security Review", + "description": "You can provide a stable outbound IP by using VNet integration and using a VNet NAT Gateway or an NVA like Azure Firewall. This allows the receiving party to allow-list based on IP, should that be needed. Note that for communications towards Azure Services often there's no need to depend on the IP address and mechanics like Service Endpoints should be used instead. (Also the use of private endpoints on the receiving end avoids for SNAT to happen and provides a stable outbound IP range.)", + "guid": "cda3b54e-b2eb-403d-b9a2-582718d2ddb1", + "id": "A04.02", + "link": "https://learn.microsoft.com/azure/app-service/networking/nat-gateway-integration", "services": [ - "Backup", + "PrivateLink", + "Firewall", "Storage", - "SQL" + "NVA", + "VNet" ], "severity": "Low", - "subcategory": "Backup", - "text": "Enable geo-redundant backup storage to protect against single region failure and data loss", + "subcategory": "Network Security", + "text": "Ensure a stable IP for outbound communications towards internet addresses", "waf": "Security" }, { - "category": "Code", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Malicious code can potentially circumvent security controls. Before deploying custom code to production, it is essential to review what's being deployed. Use a database tool like Azure Data Studio that supports source control. Implement tools and logic for code analysis, vulnerability and credential scanning.", - "guid": "7ca9f006-d2a9-4652-951c-de8e4ac5e76e", - "id": "B01.01", - "link": "https://learn.microsoft.com/azure/azure-sql/database/transparent-data-encryption-byok-create-server", + "category": "Security", + "checklist": "Azure App Security Review", + "description": "Control inbound network access using a combination of App Service Access Restrictions, Service Endpoints or Private Endpoints. Different access restrictions can be required and configured for the web app itself and the SCM site.", + "guid": "0725769e-e669-41a4-a34a-c932223ece80", + "id": "A04.03", + "link": "https://learn.microsoft.com/azure/app-service/networking-features#access-restrictions", "services": [ - "SQL" + "PrivateLink", + "AppSvc" ], - "severity": "Medium", - "subcategory": "Source Control and Code Review", - "text": "Use Source Control systems to store, maintain and review application code deployed inside Azure SQLDB Database", + "severity": "High", + "subcategory": "Network Security", + "text": "Inbound network access should be controlled", "waf": "Security" }, { - "category": "Data Discovery and Classification", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "In case of classification requirements Purview is the preferred option. Only use SQL Data Discovery & Classification in case Purview is not an option. Discover columns that potentially contain sensitive data. What is considered sensitive data heavily depends on the customer, compliance regulation, etc., and needs to be evaluated by the users in charge of that data. Classify the columns to use advanced sensitivity-based auditing and protection scenarios. Review results of automated discovery and finalize the classification if necessary.", - "guid": "d401509b-2629-4484-9a7f-af0d29a7778f", - "id": "C01.01", - "link": "https://learn.microsoft.com/azure/azure-sql/database/data-discovery-and-classification-overview?view=azuresql#faq---advanced-classification-capabilities", + "category": "Security", + "checklist": "Azure App Security Review", + "description": "Protect against malicious inbound traffic using a Web Application Firewall like Application Gateway or Azure Front Door. Make sure to monitor the WAF's logs.", + "guid": "b123071a-5416-4415-a33e-a3ad2c2de732", + "id": "A04.04", + "link": "https://learn.microsoft.com/azure/app-service/networking/app-gateway-with-service-endpoints", "services": [ - "SQL" + "Monitor", + "AppSvc", + "FrontDoor", + "WAF", + "AppGW" ], - "severity": "Low", - "subcategory": "Data Discovery and Classification", - "text": "Plan and configure Data Discovery & Classification to protect the sensitive data", + "severity": "High", + "subcategory": "Network Security", + "text": "Use a WAF in front of App Service", "waf": "Security" }, { - "category": "Data Masking", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Usage of this feature is recommended only if column encryption is not an option and there is a specific requirement to preserve data types and formats. Dynamic data masking limits sensitive data exposure by masking it to non-privileged users. Dynamic data masking helps prevent unauthorized access to sensitive data by enabling customers to designate how much of the sensitive data to reveal with minimal impact on the application layer.", - "guid": "9391fd50-135e-453e-90a7-c1a23f88cc13", - "id": "D01.01", - "link": "https://learn.microsoft.com/azure/azure-sql/database/dynamic-data-masking-overview", + "category": "Security", + "checklist": "Azure App Security Review", + "description": "Make sure the WAF cannot be bypassed by locking down access to only the WAF. Use a combination of Access Restrictions, Service Endpoints and Private Endpoints.", + "guid": "165c3acb-ef4a-4be1-b8d3-9fda47768314", + "id": "A04.05", + "link": "https://learn.microsoft.com/azure/app-service/networking-features#access-restrictions", "services": [ - "SQL" + "PrivateLink", + "WAF" ], - "severity": "Low", - "subcategory": "Data Masking", - "text": "Use Data Masking to prevent unauthorized non-admin users data access if no encryption is possible", + "severity": "High", + "subcategory": "Network Security", + "text": "Avoid for WAF to be bypassed", "waf": "Security" }, { - "category": "Defender", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "SQL Advanced Threat Detection (ATP) provides a layer of security that detects potential vulnerabilities and anomalous activity in databases such as SQL injection attacks and unusual behavior patterns. When a potential threat is detected Threat Detection sends an actionable real-time alert by email and in Microsoft Defender for Cloud, which includes clear investigation and remediation steps for the specific threat.", - "guid": "4e52d73f-5d37-428f-b3a2-e6997e835979", - "id": "E01.01", - "link": "https://learn.microsoft.com/azure/azure-sql/database/threat-detection-configure", + "category": "Security", + "checklist": "Azure App Security Review", + "description": "Set minimum TLS policy to 1.2 in App Service configuration.", + "graph": "appserviceresources | where type =~ 'microsoft.web/sites/config' | extend compliant = (properties.MinTlsVersion>=1.2) | distinct id,compliant", + "guid": "c115775c-2ea5-45b4-9ad4-8408ee72734b", + "id": "A04.06", + "link": "https://learn.microsoft.com/azure/app-service/configure-ssl-bindings#enforce-tls-versions", "services": [ - "Defender", - "SQL", - "EventHubs" + "AzurePolicy", + "AppSvc" ], - "severity": "High", - "subcategory": "Advanced Threat Protection", - "text": "Review and complete Advanced Threat Protection (ATP) configuration", + "severity": "Medium", + "subcategory": "Network Security", + "text": "Set minimum TLS policy to 1.2", "waf": "Security" }, { - "category": "Defender", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Enable Microsoft Defender for Azure SQL at the subscription level to automatically onboard and protect all existing and future servers and databases. When you enable on the subscription level, all databases in Azure SQL Database and Azure SQL Managed Instance are protected. You can then disable them individually if you choose. If you want to manually manage which databases are protected, disable at the subscription level and enable each database that you want protected.", - "guid": "dff87489-9edb-4cef-bdda-86e8212b2aa1", - "id": "E02.01", - "link": "https://learn.microsoft.com/azure/azure-sql/database/azure-defender-for-sql?view=azuresql#enable-microsoft-defender-for-sql ", + "category": "Security", + "checklist": "Azure App Security Review", + "description": "Configure App Service to use HTTPS only. This causes App Service to redirect from HTTP to HTTPS. Strongly consider the use of HTTP Strict Transport Security (HSTS) in your code or from your WAF, which informs browsers that the site should only be accessed using HTTPS.", + "graph": "where (type=='microsoft.web/sites' and (kind == 'app' or kind == 'app,linux' )) | extend compliant = (properties.httpsOnly==true) | distinct id,compliant", + "guid": "475ba18f-dbf5-490c-b65d-e8e03f9bcbd4", + "id": "A04.07", + "link": "https://learn.microsoft.com/azure/app-service/configure-ssl-bindings#enforce-https", "services": [ - "Defender", - "SQL", - "Subscriptions" + "WAF", + "AppSvc" ], "severity": "High", - "subcategory": "Defender for Azure SQL", - "text": "Enable Microsoft Defender for Azure SQL", + "subcategory": "Network Security", + "text": "Use HTTPS only", "waf": "Security" }, { - "category": "Defender", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Microsoft Defender for Azure SQL ATP detects anomalous activities indicating unusual and potentially harmful attempts to access or exploit databases. Alerts can be configured and generated and will be reported in the Defender for console.", - "guid": "ca342fdf-d25a-4427-b105-fcd50ff8a0ea", - "id": "E02.02", - "link": "https://learn.microsoft.com/azure/azure-sql/database/threat-detection-configure", + "category": "Security", + "checklist": "Azure App Security Review", + "description": "Do not use wildcards in your CORS configuration, as this allows all origins to access the service (thereby defeating the purpose of CORS). Specifically only allow the origins that you expect to be able to access the service.", + "guid": "68266abc-a264-4f9a-89ae-d9c55d04c2c3", + "id": "A04.08", + "link": "https://learn.microsoft.com/azure/app-service/app-service-web-tutorial-rest-api", "services": [ - "Defender", - "SQL", - "Monitor" + "Storage" ], "severity": "High", - "subcategory": "Defender for Azure SQL", - "text": "Prepare a security response plan to promptly react to Microsoft Defender for Azure SQL alerts", + "subcategory": "Network Security", + "text": "Wildcards must not be used for CORS", "waf": "Security" }, { - "category": "Defender", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Azure SQLDB vulnerability assessment is a service that provides visibility into your security state. Vulnerability assessment includes actionable steps to resolve security issues and enhance your database security. It can help you to monitor a dynamic database environment where changes are difficult to track and improve your SQL security posture.", - "guid": "a6101ae7-534c-45ab-86fd-b34c55ea21ca", - "id": "E03.01", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/sql-azure-vulnerability-assessment-overview", - "services": [ - "Defender", - "SQL", - "Monitor" - ], + "category": "Security", + "checklist": "Azure App Security Review", + "description": "Remote debugging must not be turned on in production as this opens additional ports on the service which increases the attack surface. Note that the service does turn of remote debugging automatically after 48 hours.", + "graph": "appserviceresources | where type =~ 'microsoft.web/sites/config' | extend compliant = (properties.RemoteDebuggingEnabled == false) | distinct id,compliant", + "guid": "d9bd3baf-cda3-4b54-bb2e-b03dd9a25827", + "id": "A04.09", + "link": "https://learn.microsoft.com/azure/app-service/configure-common#configure-general-settings", + "services": [], "severity": "High", - "subcategory": "Vulnerability Assessment", - "text": "Configure Vulnerability Assessment (VA) findings and review recommendations", + "subcategory": "Network Security", + "text": "Turn off remote debugging", "waf": "Security" }, { - "category": "Defender", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Microsoft Defender for Cloud provides vulnerability assessment for your Azure SQL Databases. Vulnerability assessment scans your databases for software vulnerabilities and provides a list of findings. You can use the findings to remediate software vulnerabilities and disable findings.", - "guid": "c8c5f112-1e50-4f77-9264-8195b4cd61ac", - "id": "E03.02", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/sql-azure-vulnerability-assessment-find?view=azuresql", + "category": "Security", + "checklist": "Azure App Security Review", + "description": "Enable Defender for App Service. This (amongst other threats) detects communications to known malicious IP addresses. Review the recommendations from Defender for App Service as part of your operations.", + "guid": "18d2ddb1-0725-4769-be66-91a4834ac932", + "id": "A04.10", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-app-service-introduction", "services": [ - "Defender", - "SQL" + "AppSvc", + "Defender" ], - "severity": "High", - "subcategory": "Vulnerability Assessment", - "text": "Regularly review of Vulnerability Assessment (VA) findings and recommendations and prepare a plan to fix", + "severity": "Medium", + "subcategory": "Network Security", + "text": "Enable Defender for Cloud - Defender for App Service", "waf": "Security" }, { - "category": "Encryption", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Always Encrypted with Secure Enclaves expands confidential computing capabilities of Always Encrypted by enabling in-place encryption and richer confidential queries. Always Encrypted with Secure Enclaves addresses these limitations by allowing some computations on plaintext data inside a secure enclave on the server side. Usage of this feature is recommended for the cases where you need to limit administrator access and need your queries to support more than equality matching of encrypted columns.", - "guid": "65d7e54a-10a6-4094-b673-9ff3809c9277", - "id": "F01.01", - "link": "https://learn.microsoft.com/sql/relational-databases/security/encryption/always-encrypted-enclaves", + "category": "Security", + "checklist": "Azure App Security Review", + "description": "Azure provides DDoS Basic protection on its network, which can be improved with intelligent DDoS Standard capabilities which learns about normal traffic patterns and can detect unusual behavior. DDoS Standard applies to a Virtual Network so it must be configured for the network resource in front of the app, such as Application Gateway or an NVA.", + "guid": "223ece80-b123-4071-a541-6415833ea3ad", + "id": "A04.11", + "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", "services": [ - "SQL" + "EventHubs", + "WAF", + "NVA", + "VNet", + "DDoS", + "AppGW" ], "severity": "Medium", - "subcategory": "Always Encrypted", - "text": "If protecting sensitive PII data from admin users is a key requirement, but Column Encryption limitations cannot be tolerated, consider the adoption of Always Encrypted with Secure Enclaves", + "subcategory": "Network Security", + "text": "Enable DDOS Protection Standard on the WAF VNet", "waf": "Security" }, { - "category": "Encryption", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "With Azure SQL Database, you can apply symmetric encryption to a column of data by using Transact-SQL. This approach is called column encryption, because you can use it to encrypt specific columns with different encryption keys. Doing so gives you more granular encryption capability than TDE, which encrypts data in pages. Using Always Encrypted to ensure sensitive data isn't exposed in plaintext in Azure SQL Database or SQL Managed Instance, even in memory/in use. Always Encrypted protects the data from Database Administrators (DBAs) and cloud admins (or bad actors who can impersonate high-privileged but unauthorized users) and gives you more control over who can access your data.", - "guid": "c03ce136-e3d5-4e17-bf25-ed955ee480d3", - "id": "F02.01", - "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#control-access-of-application-users-to-sensitive-data-through-encryption", - "services": [ - "Storage", - "SQL", - "AKV" + "category": "Security", + "checklist": "Azure App Security Review", + "description": "Where using images stored in Azure Container Registry, pull these over a virtual network from Azure Container Registry using its private endpoint and the app setting 'WEBSITE_PULL_IMAGE_OVER_VNET'.", + "guid": "2c2de732-165c-43ac-aef4-abe1f8d39fda", + "id": "A04.12", + "link": "https://learn.microsoft.com/azure/app-service/configure-custom-container#use-an-image-from-a-network-protected-registry", + "services": [ + "ACR", + "VNet", + "PrivateLink" ], - "severity": "Low", - "subcategory": "Column Encryption", - "text": "To protect sensitive PII data from non-admin users in specific table columns, consider using Column Encryption", + "severity": "Medium", + "subcategory": "Network Security", + "text": "Pull containers over a Virtual Network", "waf": "Security" }, { - "category": "Encryption", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Enabled by default, Transparent data encryption (TDE) helps to protect the database files against information disclosure by performing real-time encryption and decryption of the database, associated backups, and transaction log files 'at rest', without requiring changes to the application.", - "guid": "c614ac47-bebf-4061-b0a1-43e0c6b5e00d", - "id": "F03.01", - "link": "https://learn.microsoft.com/azure/azure-sql/database/transparent-data-encryption-byok-create-server", - "services": [ - "Backup", - "Storage", - "SQL" - ], - "severity": "High", - "subcategory": "Transparent Data Encryption", - "text": "Ensure Transparent Data Encryption (TDE) is kept enabled", + "category": "Security", + "checklist": "Azure App Security Review", + "description": "Conduct a penetration test on the web application following the penetration testing rules of engagement.", + "guid": "eb2eb03d-d9a2-4582-918d-2ddb10725769", + "id": "A05.01", + "link": "https://learn.microsoft.com/azure/security/fundamentals/pen-testing", + "services": [], + "severity": "Medium", + "subcategory": "Penetration Testing", + "text": "Conduct a penetration test", "waf": "Security" }, { - "category": "Encryption", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "If separation of duties in the management of keys and data within the organization is required, leverage Customer Managed Keys (CMK) for Transparent Data Encryption (TDE) for your Azure SQLDB and use Azure Key Vault to store (refer to its checklist). Leverage this feature when you have strict security requirements which cannot be met by the managed service keys.", - "guid": "2edb4165-4f54-47cc-a891-5c82c2f21e25", - "id": "F03.02", - "link": "https://learn.microsoft.com/azure/azure-sql/database/transparent-data-encryption-byok-overview", - "services": [ - "SQL", - "AKV" - ], + "category": "Security", + "checklist": "Azure App Security Review", + "description": "Deploy trusted code that was validated and scanned for vulnerabilities according to DevSecOps practices.", + "guid": "19aed9c5-5d04-4c2c-9919-ca0b2c12159e", + "id": "A06.01", + "link": "https://learn.microsoft.com/azure/architecture/solution-ideas/articles/devsecops-in-azure", + "services": [], "severity": "Medium", - "subcategory": "Transparent Data Encryption", - "text": "Use customer-managed keys (CMK) in Azure Key Vault (AKV) if you need increased transparency and granular control over the TDE protection", + "subcategory": "Vulnerability Management", + "text": "Deploy validated code", "waf": "Security" }, { - "category": "Encryption", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "The minimal Transport Layer Security (TLS) version setting allows customers to choose which version of TLS their SQL database uses. It's possible to change the minimum TLS version by using the Azure portal, Azure PowerShell, and the Azure CLI.", - "guid": "7754b605-57fd-4bcb-8213-52c39d8e8225", - "id": "F04.01", - "link": "https://learn.microsoft.com/azure/azure-sql/database/connectivity-settings?source=recommendations&view=azuresql&tabs=azure-portal#minimal-tls-version", - "services": [ - "SQL" - ], + "category": "Security", + "checklist": "Azure App Security Review", + "description": "Use the latest versions of supported platforms, programming languages, protocols, and frameworks.", + "guid": "114b933d-f574-4ecc-ad9b-d3bafcda3b54", + "id": "A06.02", + "link": "https://learn.microsoft.com/azure/app-service/overview-patch-os-runtime", + "services": [], "severity": "High", - "subcategory": "Transport Layer Security", - "text": "Enforce minimum TLS version to the latest available", + "subcategory": "Vulnerability Management", + "text": "Use up-to-date platforms, languages, protocols and frameworks", "waf": "Security" }, { - "category": "Identity", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Use Azure Active Directory (Azure AD) authentication for centralized identity management. Use SQL Authentication only if really necessary and document as exceptions.", - "guid": "c9b8b6bf-2c6b-453d-b400-de9a43a549d7", - "id": "G01.01", - "link": "https://learn.microsoft.com/azure/azure-sql/database/authentication-aad-overview", + "category": "SQL Server on Azure VM", + "checklist": "SQL Migration Review", + "description": "When you are creating a SQL Server on Azure VM, carefully consider the type of workload necessary. If you are migrating an existing environment, collect a performance baseline to determine your SQL Server on Azure VM requirements. If this is a new VM, then create your new SQL Server VM based on your vendor requirements.", + "guid": "1fc3fc14-eea6-4e69-b8d9-a3eec218e687", + "id": "A01.01", + "link": "https://learn.microsoft.com/sql/dma/dma-sku-recommend-sql-db?view=sql-server-ver16", "services": [ - "SQL", - "Entra" + "VM", + "SQL" ], - "severity": "Medium", - "subcategory": "Azure Active Directory", - "text": "Leverage Azure AD authentication for connections to Azure SQL Databases", - "waf": "Security" + "severity": "High", + "subcategory": "VM Size", + "text": "Collect the target workload's performance characteristics and use them to determine the appropriate VM size for your business.", + "waf": "Performance" }, { - "category": "Identity", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Using Azure AD groups simplifies permission management and both the group owner, and the resource owner can add/remove members to/from the group. Create a separate group for Azure AD administrators for each logical server. Monitor Azure AD group membership changes using Azure AD audit activity reports.", - "guid": "29820254-1d14-4778-ae90-ff4aeba504a3", - "id": "G01.02", - "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#central-management-for-identities", + "category": "SQL Server on Azure VM", + "checklist": "SQL Migration Review", + "description": "The memory optimized virtual machine sizes are a primary target for SQL Server VMs and the recommended choice by Microsoft. The memory optimized virtual machines offer stronger memory-to-CPU ratios and medium-to-large cache options.Consider Ebdsv5-series series first for most SQL Server workloads.", + "guid": "e04abe1f-8d39-4fda-9776-8424c116775c", + "id": "A01.02", + "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/performance-guidelines-best-practices-vm-size?view=azuresql#memory-optimized", "services": [ - "SQL", - "Monitor", - "Entra" + "VM", + "SQL" ], "severity": "Medium", - "subcategory": "Azure Active Directory", - "text": "Create a separate Azure AD group with two admin accounts for each Azure SQL Database logical server", - "waf": "Security" + "subcategory": "VM Size", + "text": "Use memory optimized virtual machine sizes for the best performance of SQL Server workloads.", + "waf": "Performance" }, { - "category": "Identity", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Ensure that distinct system and user assigned managed identities, that are dedicated to the function, with least permissions assigned, are used for communication from Azure services and applications to the Azure SQLDB databases.", - "guid": "df3a09ee-03bb-4198-8637-d141acf5f289", - "id": "G01.03", - "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#minimize-the-use-of-password-based-authentication-for-applications", + "category": "SQL Server on Azure VM", + "checklist": "SQL Migration Review", + "description": "To find the most effective configuration for SQL Server workloads on an Azure VM, start by measuring the storage performance of your business application. Once storage requirements are known, select a virtual machine that supports the necessary IOPS and throughput with the appropriate memory-to-vCore ratio.", + "guid": "2ea55b56-ad48-4408-be72-734b476ba18f", + "id": "A02.01", + "link": "https://learn.microsoft.com/azure/virtual-machines/premium-storage-performance#counters-to-measure-application-performance-requirements", "services": [ - "SQL", - "Entra" + "VM", + "Storage", + "SQL" ], "severity": "Medium", - "subcategory": "Azure Active Directory", - "text": "Minimize the use of password-based authentication for applications", - "waf": "Security" + "subcategory": "Storage", + "text": "Determine storage bandwidth and latency requirements for SQL Server data, log, and tempdb files before choosing the disk type.", + "waf": "Performance" }, { - "category": "Identity", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "System or User assigned managed identities enable Azure SQLDB to authenticate to other cloud services (e.g. Azure Key Vault) without storing credentials in code. Once enabled, all necessary permissions can be granted via Azure role-based-access-control to the specific Azure SQLDB instance. Do not share user assigned managed identities across multiple services if not strictly required.", - "guid": "69891194-5074-4e30-8f69-4efc3c580900", - "id": "G02.01", - "link": "https://learn.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview", + "category": "SQL Server on Azure VM", + "checklist": "SQL Migration Review", + "description": "This provides more dedicated disk IOPS and throughput on the disk level and also allows you to configure the Azure disk host caching setting for each disk to the optimal setting for that data type.", + "guid": "dbf590ce-65de-48e0-9f9c-cbd468266abc", + "id": "A02.02", + "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/performance-guidelines-best-practices-checklist?view=azuresql#storage", "services": [ - "ACR", - "RBAC", - "AKV", - "Entra", + "Storage", "SQL" ], - "severity": "Low", - "subcategory": "Managed Identities", - "text": "Assign Azure SQL Database a managed identity for outbound resource access", - "waf": "Security" + "severity": "High", + "subcategory": "Storage", + "text": "Place data, log, and tempdb files on separate drives", + "waf": "Performance" }, { - "category": "Identity", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Use an Azure AD integrated authentication that eliminates the use of passwords. Password-based authentication methods are a weaker form of authentication. Credentials can be compromised or mistakenly given away. Use single sign-on authentication using Windows credentials. Federate the on-premises AD domain with Azure AD and use integrated Windows authentication (for domain-joined machines with Azure AD).", - "guid": "88287d4a-8bb8-4640-ad78-03f51354d003", - "id": "G03.01", - "link": "https://learn.microsoft.com/azure/azure-sql/database/authentication-aad-configure?view=azuresql&tabs=azure-powershell#active-directory-integrated-authentication", + "category": "SQL Server on Azure VM", + "checklist": "SQL Migration Review", + "description": "Premium SSD is always recommend as a minimum for SQL Server in order to obtain better performance and lower latency. P30 and P40 are recommended because disk caching is not supported for disks 4 TiB and larger ( P50 and above) and they provide the optimal price to performance ratio", + "guid": "e6a84de5-df43-4d19-a248-1718d5d1e5f6", + "id": "A02.03", + "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/performance-guidelines-best-practices-checklist?view=azuresql#storage", "services": [ - "SQL", - "Entra" + "Storage", + "SQL" ], - "severity": "Medium", - "subcategory": "Passwords", - "text": "Minimize the use of password-based authentication for users", - "waf": "Security" + "severity": "High", + "subcategory": "Storage", + "text": "For the data drive, use premium P30 and P40 or smaller disks to ensure the availability of cache support", + "waf": "Performance" }, { - "category": "Ledger", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "The hash of the latest block in the database ledger is called the database digest. It represents the state of all ledger tables in the database at the time when the block was generated. Generating a database digest is efficient, because it involves computing only the hashes of the blocks that were recently appended. Azure Confidential Ledger is one of the supported store, it can be used and supports automatic generation and storage of database digests. Azure Ledger provides advanced security features like Blockchain Ledger Proof and Confidential Hardware Enclaves. Use it only if advanced security features are required, otherwise revert to Azure storage.", - "guid": "0e853380-50ba-4bce-b2fd-5c7391c85ecc", - "id": "H01.01", - "link": "https://learn.microsoft.com/azure/architecture/guide/technology-choices/multiparty-computing-service#confidential-ledger-and-azure-blob-storage", + "category": "SQL Server on Azure VM", + "checklist": "SQL Migration Review", + "description": "Log files have primarily write-heavy operations. Therefore, they do not benefit from the ReadOnly cache. Hence evaluate your price vs performance vs capacity and chose the right storage disk.", + "guid": "25659d35-58fd-4772-99c9-31112d027fe4", + "id": "A02.04", + "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/performance-guidelines-best-practices-checklist?view=azuresql#storage", "services": [ + "Cost", "Storage", "SQL" ], - "severity": "Medium", - "subcategory": "Database Digest", - "text": "Use Azure Confidential Ledger to store database digests only if advanced security features are required", - "waf": "Security" + "severity": "High", + "subcategory": "Storage", + "text": "For the log drive plan for capacity and test performance versus cost while evaluating the premium P30 - P80 disks", + "waf": "Performance" }, { - "category": "Ledger", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "The hash of the latest block in the database ledger is called the database digest. It represents the state of all ledger tables in the database at the time when the block was generated. Generating a database digest is efficient, because it involves computing only the hashes of the blocks that were recently appended. Azure Blob Storage with Immutable Storage feature can be used and supports automatic generation and storage of database digests. To prevent tampering of your digest files, configure and lock a retention policy for your container.", - "guid": "afefb2d3-95da-4ac9-acf5-33d18b32ef9a", - "id": "H01.02", - "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-digest-management", + "category": "SQL Server on Azure VM", + "checklist": "SQL Migration Review", + "description": "Placing TempDB on the D drive can help performance. Consider the size required and always test performance.", + "guid": "12f70983-f630-4472-8ee6-9d6b5c2622f5", + "id": "A02.05", + "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/performance-guidelines-best-practices-checklist?view=azuresql#storage", "services": [ - "AzurePolicy", + "VM", "Storage", "SQL" ], "severity": "Medium", - "subcategory": "Database Digest", - "text": "If Azure storage account is used to store database digests, ensure security is properly configured", - "waf": "Security" + "subcategory": "Storage", + "text": "Place tempdb on the local ephemeral SSD (default D:\\) drive for most SQL Server workloads that are not part of Failover Cluster Instance (FCI) after choosing the optimal VM size.", + "waf": "Performance" }, { - "category": "Ledger", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Ledger provides a form of data integrity called forward integrity, which provides evidence of data tampering on data in your ledger tables. The database verification process takes as input one or more previously generated database digests. It then recomputes the hashes stored in the database ledger based on the current state of the ledger tables. If the computed hashes don't match the input digests, the verification fails. The failure indicates that the data has been tampered with. The verification process reports all inconsistencies that it detects.", - "guid": "f8d4ffda-8aac-4cc6-b72b-c81cb8625420", - "id": "H02.01", - "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-database-verification", + "category": "SQL Server on Azure VM", + "checklist": "SQL Migration Review", + "description": "Striping Data and Log disk can increase bandwidth. Ensure that VM size also matches expected output", + "guid": "4b69bad3-4aad-45e8-a78e-1d76667313c4", + "id": "A02.06", + "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/performance-guidelines-best-practices-checklist?view=azuresql#storage", "services": [ + "VM", "Storage", "SQL" ], - "severity": "Medium", - "subcategory": "Integrity", - "text": "Schedule the Ledger verification process regularly to verify data integrity", - "waf": "Security" + "severity": "High", + "subcategory": "Storage", + "text": "Stripe multiple Azure data disks using Storage Spaces to increase I/O bandwidth", + "waf": "Performance" }, { - "category": "Ledger", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "The Ledger feature provides tamper-evidence capabilities in your database. You can cryptographically attest to other parties, such as auditors or other business parties, that your data hasn't been tampered with. Ledger helps protect data from any attacker or high-privileged user, including database administrators (DBAs), system administrators, and cloud administrators.", - "guid": "2563f498-e2d3-42ea-9e7b-5517881a06a2", - "id": "H03.01", - "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-overview", + "category": "SQL Server on Azure VM", + "checklist": "SQL Migration Review", + "description": "Your storage caching policy varies depending on the type of SQL Server data files that are hosted on the drive.Enable Read-only caching for the disks hosting SQL Server data files.Reads from cache will be faster than the uncached reads from the data disk.Set the caching policy to None for disks hosting the transaction log. There is no performance benefit to enabling caching for the Transaction log disk.", + "guid": "05674b5e-985b-4859-a773-e7e261623b77", + "id": "A02.07", + "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/performance-guidelines-best-practices-checklist?view=azuresql#storage", "services": [ + "Storage", + "AzurePolicy", "SQL" ], - "severity": "Medium", - "subcategory": "Ledger", - "text": "If cryptographic proof of data integrity is a critical requirement, Ledger feature should be considered", - "waf": "Security" + "severity": "High", + "subcategory": "Storage", + "text": "Set host caching to read-only for data file disks and none for log file disks.", + "waf": "Performance" }, { - "category": "Ledger", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Depending on the type of tampering, there are cases where you can repair the ledger without losing data. In the article contained in the --More Info-- column, different scenarios and recovery techniques are described.", - "guid": "804fc554-6554-4842-91c1-713b32f99902", - "id": "H04.01", - "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-how-to-recover-after-tampering", + "category": "SQL Server on Azure VM", + "checklist": "SQL Migration Review", + "description": "Check that you storage is in the same region as your VM. For exaplme if your VM is in EAST US 2 ensure your storage is in East US 2.", + "guid": "5a917e1f-348e-4f35-9c27-d42e8bbac868", + "id": "A02.08", + "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/performance-guidelines-best-practices-checklist?view=azuresql#storage", "services": [ + "VM", + "Storage", "SQL" ], - "severity": "Medium", - "subcategory": "Recovery", - "text": "Prepare a response plan to investigate and repair a database after a tampering event", - "waf": "Security" + "severity": "High", + "subcategory": "Storage", + "text": "Provision the storage account in the same region as the SQL Server VM", + "waf": "Performance" }, { - "category": "Logging", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Azure SQL Database Auditing tracks database events and writes them to an audit log in your Azure storage account. Auditing helps you understand database activity and gain insight into discrepancies and anomalies that could indicate business concerns or suspected security violations as well as helps you meet regulatory compliance. By default auditing policy includes all actions (queries, stored procedures and successful and failed logins) against the databases, which may result in high volume of audit logs. It's recommended for customers to configure auditing for different types of actions and action groups using PowerShell.", - "guid": "4082e31d-35f4-4a49-8507-d3172cc930a6", - "id": "I01.01", - "link": "https://learn.microsoft.com/azure/azure-sql/database/auditing-overview", + "category": "SQL Server on Azure VM", + "checklist": "SQL Migration Review", + "description": "SQL Server uses extents to store data. These are 64KB in size. Therefore, on a SQL Server machine, the NTFS allocation unit size for hosting SQL database files should be 64 KB.", + "guid": "155abb91-63e9-4908-ae28-c84c33b6b780", + "id": "A02.09", + "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/performance-guidelines-best-practices-checklist?view=azuresql#storage", "services": [ - "AzurePolicy", "Storage", "SQL" ], - "severity": "Medium", - "subcategory": "Auditing", - "text": "Ensure that Azure SQL Database Auditing is enabled at the server level", - "waf": "Security" + "severity": "High", + "subcategory": "Storage", + "text": "Format your data disk to use 64 KB block size (allocation unit size) for all data files placed on a drive other than the temporary D:\\ drive", + "waf": "Performance" }, { - "category": "Logging", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Azure SQL Database Auditing logs can be written to external storage accounts, Log Analytics workspace or Event Hub. Be sure to protect the target repository using backups and secured configuration. Use Azure SQL Database Managed Identity to access the storage and set an explicit retention period. Do not grant permissions to administrators to the audit log repository. Use a different target storage for --Enabling Auditing of Microsoft support operations--. ", - "guid": "9b64bc50-b60f-4035-bf7a-28c4806dfb46", - "id": "I01.02", - "link": "https://learn.microsoft.com/azure/azure-sql/database/auditing-overview", + "category": "SQL Server on Azure VM", + "checklist": "SQL Migration Review", + "description": "It is recommended that you determine BCDR needs and requirements ensuring that you are able to meet you SLAs of the environment.", + "guid": "8b9fe5c4-2049-4d41-9a92-3c3474d11028", + "id": "A03.01", + "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/business-continuity-high-availability-disaster-recovery-hadr-overview?view=azuresql#azure-only-disaster-recovery-solutions", "services": [ - "EventHubs", - "Entra", - "SQL", - "Monitor", - "Backup", - "Storage" + "VM", + "SQL" ], - "severity": "Low", - "subcategory": "Auditing", - "text": "Ensure that Azure SQL Database Auditing logs are backed up and secured in the selected repository type", - "waf": "Security" + "severity": "Medium", + "subcategory": "HADR", + "text": "Determine HA/DR requirements for each VM to be migrated.", + "waf": "Reliability" }, { - "category": "Logging", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "The Azure Monitor activity log is a platform log in Azure that provides insight into subscription-level events. The activity log includes information like when a resource is modified. It is recommended to send this activity log to the same external storage repository as the Azure SQL Database Audit Log (storage account, Log Analytics workspace, Event Hub).", - "guid": "fcd34708-87ac-4efc-aaf6-57a47f76644a", - "id": "I01.03", - "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", + "category": "SQL Server on Azure VM", + "checklist": "SQL Migration Review", + "description": "When depoying High Availability you need to use availability sets or availability zones to avoid unexpected outages.", + "guid": "ac6aae01-e6a8-44de-9df4-3d1992481718", + "id": "A03.02", + "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/business-continuity-high-availability-disaster-recovery-hadr-overview?view=azuresql#high-availability-nodes-in-an-availability-set", "services": [ - "EventHubs", - "SQL", - "Monitor", - "Storage", - "Subscriptions" + "VM", + "SQL" ], - "severity": "Medium", - "subcategory": "Auditing", - "text": "Ensure that Azure SQL Database Activity Log is collected and integrated with Auditing logs", - "waf": "Security" + "severity": "High", + "subcategory": "HADR", + "text": "Place your VMs in an availability set or different availability zones.", + "waf": "Reliability" }, { - "category": "Logging", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Forward any logs from Azure SQL to your Security Information and Event Management (SIEM) and Security Orchestration Automation and Response (SOAR). Ensure that you are monitoring different types of Azure assets for potential threats and anomalies. Focus on getting high-quality alerts to reduce false positives for analysts to sort through. Alerts can be sourced from log data, agents, or other data.", - "guid": "f96e127e-9572-453a-b325-ff89ae9f6b44", - "id": "I02.01", - "link": "https://learn.microsoft.com/azure/azure-sql/database/auditing-overview", + "category": "SQL Server on Azure VM", + "checklist": "SQL Migration Review", + "description": "Prefered option when deploying an Availability Group. The recommended solution is to use multi-subnets when deploying Always on Availability Groups.", + "guid": "d5d1e5f6-2565-49d3-958f-d77249c93111", + "id": "A03.03", + "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/availability-group-azure-portal-configure?view=azuresql&tabs=azure-cli", "services": [ - "SQL", - "Monitor" + "VM", + "VNet", + "LoadBalancer", + "SQL" ], "severity": "Medium", - "subcategory": "SIEM/SOAR", - "text": "Ensure that Azure SQL Database Auditing logs are being presented in to your organizations SIEM/SOAR", - "waf": "Security" + "subcategory": "HADR", + "text": "Deploy your SQL Server VMs to multiple subnets whenever possible to avoid the dependency on an Azure Load Balancer or a distributed network name (DNN) to route traffic to your HADR solution. ( If one is implementing FCI or AG)", + "waf": "Reliability" }, { - "category": "Logging", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Forward any logs from Azure SQL to your Security Information and Event Management (SIEM) and Security Orchestration Automation and Response (SOAR), which can be used to set up custom threat detections. Ensure that you are monitoring different types of Azure assets for potential threats and anomalies. Focus on getting high-quality alerts to reduce false positives for analysts to sort through. Alerts can be sourced from log data, agents, or other data.", - "guid": "41503bf8-73da-4a10-af9f-5f7fceb5456f", - "id": "I02.02", - "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", + "category": "SQL Server on Azure VM", + "checklist": "SQL Migration Review", + "description": "High availability and disaster recovery (HADR) features, such as the Always On availability group and the failover cluster instance rely on underlying Windows Server Failover Cluster technology. Review the best practices for modifying your HADR settings to better support the cloud environment.", + "guid": "2d027fe4-12f7-4098-9f63-04722ee69d6b", + "id": "A03.04", + "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/performance-guidelines-best-practices-checklist?view=azuresql-vm#hadr-configuration", "services": [ - "SQL", - "Monitor" + "ASR", + "SQL" ], - "severity": "Medium", - "subcategory": "SIEM/SOAR", - "text": "Ensure that Azure SQL Database Activity Log data is presented in to your SIEM/SOAR", - "waf": "Security" + "severity": "High", + "subcategory": "HADR", + "text": "Change the cluster to less aggressive parameters to avoid unexpected outages from transient network failures or Azure platform maintenance. ( If one is implementing FCI or AG)", + "waf": "Reliability" }, { - "category": "Logging", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Security Operation Center (SOC) team should create an incident response plan (playbooks or manual responses) to investigate and mitigate tampering, malicious activities, and other anomalous behaviors.", - "guid": "19ec7c97-c563-4e1d-82f0-54d6ec12e754", - "id": "I02.03", - "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", + "category": "SQL Server on Azure VM", + "checklist": "SQL Migration Review", + "description": "Ensure that quorum is set correct for the number of instances deployed.", + "guid": "5c2622f5-4b69-4bad-94aa-d5e8c78e1d76", + "id": "A03.05", + "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/hadr-cluster-best-practices?view=azuresql-vm&tabs=windows2012#quorum-voting", "services": [ - "SQL", - "EventHubs" + "SQL" ], - "severity": "Medium", - "subcategory": "SIEM/SOAR", - "text": "Ensure that you have response plans for malicious or aberrant audit logging events", - "waf": "Security" + "severity": "High", + "subcategory": "HADR", + "text": "Configure cluster quorum voting to use 3 or more odd number of votes. Don't assign votes to DR regions. ( If one is implementing FCI or AG)", + "waf": "Reliability" }, { - "category": "Networking", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "When you create a logical server from the Azure portal for Azure SQL Database, the result is a public endpoint that is visible and reachable over the public network (Public Access). You can then limit connectivity based on firewall rules and Service Endpoint. You can also configure private connectivity only limiting connections to internal networks using Private Endpoint (Private Access). Private Access using Private Endpoint should be the default unless a business case or performance/technical reason applies that cannot support it. Usage of Private Endpoints has performance implications that need to be considered and assessed.", - "guid": "2c6d356a-1784-475b-a42c-ec187dc8c925", - "id": "J01.01", - "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview", + "category": "SQL Server on Azure VM", + "checklist": "SQL Migration Review", + "description": "On Azure virtual machines, clusters use a load balancer to hold an IP address that needs to be on one cluster node at a time. In this solution, the load balancer holds the IP address for the virtual network name (VNN) listener for the Always On availability group when the SQL Server VMs are in a single subnet.", + "guid": "667313c4-0567-44b5-b985-b859c773e7e2", + "id": "A03.06", + "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/availability-group-vnn-azure-load-balancer-configure?view=azuresql-vm&tabs=ilb", "services": [ - "PrivateLink", + "VNet", + "LoadBalancer", + "VM", "SQL" ], "severity": "High", - "subcategory": "Connectivity", - "text": "Review Public vs. Private Access connectivity methods and select the appropriate one for the workload", - "waf": "Security" + "subcategory": "HADR", + "text": "When using the virtual network name (VNN) and Azure Load Balancer to connect to your HADR solution, specify MultiSubnetFailover = true in the connection string, even if your cluster only spans one subnet. ( If one is implementing FCI or AG)", + "waf": "Reliability" }, { - "category": "Networking", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "IMPORTANT: Connections to private endpoint only support Proxy as the connection policy. When using private endpoints connections are proxied via the Azure SQL Database gateway to the database nodes. Clients will not have a direct connection.", - "guid": "557b3ce5-bada-4296-8d52-a2d447bc1718", - "id": "J01.02", - "link": "https://learn.microsoft.com/azure/azure-sql/database/connectivity-architecture", + "category": "SQL Server on Azure VM", + "checklist": "SQL Migration Review", + "description": "SQL Server, Azure SQL Database, and Azure SQL Managed Instance support row and page compression for rowstore tables and indexes, and support columnstore and columnstore archival compression for columnstore tables and indexes.", + "guid": "61623b77-5a91-47e1-b348-ef354c27d42e", + "id": "A04.01", + "link": "https://learn.microsoft.com/sql/relational-databases/data-compression/data-compression?view=sql-server-ver16", "services": [ - "AzurePolicy", - "SQL", - "PrivateLink" + "Storage", + "SQL" ], "severity": "Low", - "subcategory": "Connectivity", - "text": "Keep default Azure SQL Database Connection Policy if not differently required and justified", - "waf": "Security" + "subcategory": "SQL Server", + "text": "Enable database page compression where appropriate.", + "waf": "Performance" }, { - "category": "Networking", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "This option configures the firewall to allow all connections from Azure, including connections from the subscriptions of other customers. If you select this option, make sure that your login and user permissions limit access to authorized users only. If not strictly required, keep this setting to OFF.", - "guid": "f48efacf-4405-4e8d-9dd0-16c5302ed082", - "id": "J01.03", - "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview", + "category": "SQL Server on Azure VM", + "checklist": "SQL Migration Review", + "description": "By default, data and log files are initialized to overwrite any existing data left on the disk from previously deleted files. Data and log files are first initialized by zeroing the files (filling with zeros).In SQL Server, for data files only, instant file initialization (IFI) allows for faster execution of the previously mentioned file operations, since it reclaims used disk space without filling that space with zeros. Instead, disk content is overwritten as new data is written to the files.", + "guid": "8bbac868-155a-4bb9-863e-9908ae28c84c", + "id": "A04.02", + "link": "https://learn.microsoft.com/sql/relational-databases/databases/database-instant-file-initialization?view=sql-server-ver16", "services": [ - "SQL", - "Subscriptions" + "Storage", + "SQL" ], "severity": "High", - "subcategory": "Connectivity", - "text": "Ensure Allow Azure Services and Resources to Access this Server setting is disabled in Azure SQL Database firewall", - "waf": "Security" + "subcategory": "SQL Server", + "text": "Enable instant file initialization for data files.", + "waf": "Operations" }, { - "category": "Networking", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Azure SQL Database has a new built-in feature that allows native integration with external REST endpoints. This means that integration of Azure SQL Database with Azure Functions, Azure Logic Apps, Cognitive Services, Event Hubs, Event Grid, Azure Containers, API Management and in general any REST or even GraphQL endpoint. If not properly restricted, code inside an Azure SQL Database database could leverage this mechanism to exfiltrate data. If not strictly required, it is recommended to block or restrict this feature using Outbound Firewall Rules.", - "guid": "cb3274a7-e36d-46f6-8de5-46d30c8dde8e", - "id": "J02.01", - "link": "https://learn.microsoft.com/sql/relational-databases/system-stored-procedures/sp-invoke-external-rest-endpoint-transact-sql", + "category": "SQL Server on Azure VM", + "checklist": "SQL Migration Review", + "description": "Recommended for best performance and availability migrate all databases to data and log disks", + "guid": "33b6b780-8b9f-4e5c-9204-9d413a923c34", + "id": "A04.03", + "link": "https://learn.microsoft.com/sql/relational-databases/databases/move-database-files?view=sql-server-ver16", "services": [ - "SQL", - "EventHubs", - "APIM" + "SQL" ], "severity": "Medium", - "subcategory": "Outbound Control", - "text": "Block or restrict outbound REST API calls to external endpoints", - "waf": "Security" + "subcategory": "SQL Server", + "text": "Move all databases to data disks, including system databases.", + "waf": "Operations" }, { - "category": "Networking", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Outbound firewall rules limit network traffic from the Azure SQL Database logical server to a customer defined list of Azure Storage accounts and Azure SQL Database logical servers. Any attempt to access storage accounts or databases not in this list is denied.", - "guid": "a566dd3d-314e-4a94-9378-102c42d82b38", - "id": "J02.02", - "link": "https://learn.microsoft.com/azure/azure-sql/database/outbound-firewall-rule-overview", + "category": "SQL Server on Azure VM", + "checklist": "SQL Migration Review", + "description": "Part of the SQL Server Feature checklist in the link that is recommended when SQL Server Instance is in an Azure VM.", + "guid": "b824546c-e1ae-4e34-93ae-c8239248725d", + "id": "A04.04", + "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/performance-guidelines-best-practices-checklist?view=azuresql-vm#sql-server-features", "services": [ + "VM", "Storage", "SQL" ], - "severity": "Medium", - "subcategory": "Outbound Control", - "text": "If outbound network access is required, it is recommended to configure outbound networking restrictions using built-in Azure SQL Database control feature", - "waf": "Security" + "severity": "Low", + "subcategory": "SQL Server", + "text": "Move SQL Server error log and trace file directories to data disks.", + "waf": "Operations" }, { - "category": "Networking", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Private Endpoint is created inside a subnet in an Azure Virtual Network. Proper security configuration must be applied also to the containing network environment, including NSG/ASG, UDR, firewall, monitoring and auditing.", - "guid": "246cd832-f550-4af0-9c74-ca9baeeb8860", - "id": "J03.01", - "link": "https://learn.microsoft.com/azure/azure-sql/database/private-endpoint-overview?view=azuresql#disable-public-access-to-your-logical-server", + "category": "SQL Server on Azure VM", + "checklist": "SQL Migration Review", + "description": "Part of the SQL Server Feature checklist in the link that is recommended when SQL Server Instance is in an Azure VM.", + "guid": "d68c5b5c-2925-4394-a69a-9d2799c42bb6", + "id": "A04.05", + "link": "https://learn.microsoft.com/sql/database-engine/configure-windows/server-memory-server-configuration-options#use-", "services": [ - "SQL", - "Monitor", - "Firewall", - "VNet", - "PrivateLink" + "VM", + "SQL" ], - "severity": "Medium", - "subcategory": "Private Access", - "text": "If Private Access connectivity is used, ensure that you are using the Private Endpoint, Azure Virtual Network, Azure Firewall, and Azure Network Security Group checklists", - "waf": "Security" + "severity": "High", + "subcategory": "SQL Server", + "text": "Set max SQL Server memory limit to leave enough memory for the Operating System.", + "waf": "Performance" }, { - "category": "Networking", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "When adding a Private Endpoint connection, public routing to your logical server isn't blocked by default. In the --Firewall and virtual networks-- pane, the setting --Deny public network access-- is not selected by default. To disable public network access, ensure that you select --Deny public network access--.", - "guid": "3a0808ee-ea7a-47ab-bdce-920a6a2b3881", - "id": "J03.02", - "link": "https://learn.microsoft.com/azure/azure-sql/database/private-endpoint-overview?view=azuresql#disable-public-access-to-your-logical-server", + "category": "SQL Server on Azure VM", + "checklist": "SQL Migration Review", + "description": "Part of the SQL Server Feature checklist in the link that is recommended when SQL Server Instance is in an Azure VM.", + "guid": "8d1d7555-6246-4b43-a563-b4dc74a748b6", + "id": "A04.06", + "link": "https://learn.microsoft.com/sql/database-engine/configure-windows/enable-the-lock-pages-in-memory-option-windows", "services": [ - "PrivateLink", - "VNet", + "VM", "SQL" ], "severity": "High", - "subcategory": "Private Access", - "text": "If Private Endpoint (Private Access) is used, consider disabling Public Access connectivity", - "waf": "Security" + "subcategory": "SQL Server", + "text": "Enable lock pages in memory.", + "waf": "Performance" }, { - "category": "Networking", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Network Security Group (NSG) and Application Security Group (ASG) can be now applied to subnet containing Private Endpoints to restrict connections to Azure SQLDB based on internal source IP ranges.", - "guid": "8600527e-e8c4-4424-90ef-1f0dca0224f2", - "id": "J03.03", - "link": "https://learn.microsoft.com/azure/private-link/private-endpoint-overview#network-security-of-private-endpoints", + "category": "SQL Server on Azure VM", + "checklist": "SQL Migration Review", + "description": "Part of the SQL Server Feature checklist in the link that is recommended when SQL Server Instance is in an Azure VM.", + "guid": "633ad2a0-916a-4664-a8fa-d0e278ee293c", + "id": "A04.07", + "link": "https://learn.microsoft.com/sql/relational-databases/performance/monitoring-performance-by-using-the-query-store", "services": [ - "PrivateLink", - "VNet", + "VM", "SQL" ], - "severity": "Medium", - "subcategory": "Private Access", - "text": "If Private Endpoint (Private Access) is used, apply NSG and eventually ASG to limit incoming source IP address ranges", - "waf": "Security" + "severity": "Low", + "subcategory": "SQL Server", + "text": "Enable Query Store on all production SQL Server databases following best practices.", + "waf": "Performance" }, { - "category": "Networking", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "A Managed Instance (SQL MI) can be isolated inside a virtual network to prevent external access. Applications and tools that are in the same or peered virtual network in the same region could access it directly. Applications and tools that are in different region could use virtual-network-to-virtual-network connection or ExpressRoute circuit peering to establish connection. Customer should use Network Security Groups (NSG), and eventually internal firewalls, to restrict access over port 1433 only to resources that require access to a managed instance.", - "guid": "18123ef4-a0a6-45e3-87fe-7f454f65d975", - "id": "J03.04", - "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/connectivity-architecture-overview", + "category": "SQL Server on Azure VM", + "checklist": "SQL Migration Review", + "description": "Part of the SQL Server Feature checklist in the link that is recommended when SQL Server Instance is in an Azure VM.", + "guid": "1bc352ba-aab7-4571-a49a-b8093dc9ec9d", + "id": "A04.08", + "link": "https://learn.microsoft.com/sql/relational-databases/databases/tempdb-database#optimizing-tempdb-performance-in-sql-server", "services": [ - "VNet", - "SQL", - "ExpressRoute" + "VM", + "SQL" ], - "severity": "Medium", - "subcategory": "Private Access", - "text": "Apply Network Security Groups (NSG) and firewall rules to restrict access to Azure SQL Managed Instance internal subnet", - "waf": "Security" + "severity": "High", + "subcategory": "SQL Server", + "text": "Ensure that all tempdb best practices are followed.", + "waf": "Performance" }, { - "category": "Networking", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Azure Virtual Network Service Endpoint is preferred solution if you want to establish a direct connection to the Azure SQL Database backend nodes using Redirect policy. This will allow access in high performance mode and is the recommended approach from a performance perspective.", - "guid": "55187443-6852-4fbd-99c6-ce303597ca7f", - "id": "J04.01", - "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview?view=azuresql#ip-vs-virtual-network-firewall-rules", + "category": "SQL Server on Azure VM", + "checklist": "SQL Migration Review", + "description": "Part of the SQL Server Feature checklist in the link that is recommended when SQL Server Instance is in an Azure VM.", + "guid": "1bb73b36-a5a6-47fb-a9ed-5b35478c3479", + "id": "A04.09", + "link": "https://docs.microsoft.com/azure/governance/management-groups/how-to/protect-resource-hierarchy#setting---require-authorization", "services": [ - "AzurePolicy", - "VNet", + "VM", "SQL" ], "severity": "High", - "subcategory": "Public Access", - "text": "If Public Access connectivity is used, leverage Service Endpoint to restrict access from selected Azure Virtual Networks", - "waf": "Security" + "subcategory": "SQL Server", + "text": "Schedule SQL Server Agent jobs to run DBCC CHECKDB, index reorganize, index rebuild, and update statistics jobs.", + "waf": "Operations" }, { - "category": "Networking", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "The Azure SQL Database firewall allows you to specify IP address ranges from which communications are accepted. This approach is fine for stable IP addresses that are outside the Azure private network.", - "guid": "a73e32da-b3f4-4960-b5ec-2f42a557bf31", - "id": "J04.02", - "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview", + "category": "SQL Server on Azure VM", + "checklist": "SQL Migration Review", + "description": "Part of the SQL Server Feature checklist in the link that is recommended when SQL Server Instance is in an Azure VM.", + "guid": "816b2863-cffe-41ca-a599-ef0d5a73dd4c", + "id": "A04.10", + "link": "https://docs.microsoft.com/azure/governance/management-groups/how-to/protect-resource-hierarchy#setting---require-authorization", "services": [ - "Storage", + "VM", "SQL" ], "severity": "Medium", - "subcategory": "Public Access", - "text": "If Public Access connectivity is used, ensure that only specific known IPs are added to the firewall", - "waf": "Security" + "subcategory": "SQL Server", + "text": "Limit autogrowth of the database and Disable autoshrink", + "waf": "Operations" }, { - "category": "Networking", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "We recommend that you use database-level IP firewall rules whenever possible. This practice enhances security and makes your database more portable. Use server-level IP firewall rules for administrators. Also use them when you have many databases that have the same access requirements, and you don't want to configure each database individually.", - "guid": "e0f31ac9-35c8-4bfd-9865-edb60ffc6768", - "id": "J04.03", - "link": "https://learn.microsoft.com/azure/azure-sql/database/firewall-configure", + "category": "SQL Server on Azure VM", + "checklist": "SQL Migration Review", + "description": "Constrained vCPU virtual machines (VMs) are a type of VM where the vCPU count can be constrained to a half or a quarter of the original VM size. This allows customers to reduce the cost of software licensing while maintaining the same memory, storage, and I/O bandwidth", + "guid": "e36c1c81-770a-4fbc-9c0d-43918648d285", + "id": "A05.01", + "link": "https://learn.microsoft.com/azure/virtual-machines/constrained-vcpu", "services": [ + "VM", + "Cost", "Storage", "SQL" ], "severity": "Low", - "subcategory": "Public Access", - "text": "If Public Access connectivity is used and controlled by Azure SQL Database firewall rules, use database-level over server-level IP rules", - "waf": "Security" + "subcategory": "Cost Optimization", + "text": "Optimize SQL Server License cost with Constrained vCPU VM's", + "training": "https://learn.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview", + "waf": "Cost" }, { - "category": "Networking", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "A Managed Instance (SQL MI) can be isolated inside a virtual network to prevent external access. The Managed Instance public endpoint is not enabled by default, must be explicitly enabled, only if strictly required. If company policy disallows the use of public endpoints, use Azure Policy to prevent enabling public endpoints in the first place.", - "guid": "b8435656-143e-41a8-9922-61d34edb751a", - "id": "J04.04", - "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/public-endpoint-overview", + "category": "SQL Server on Azure VM", + "checklist": "SQL Migration Review", + "description": "Azure Hybrid Benefit allows you to exchange your existing licenses for discounted rates on Azure SQL Database and Azure SQL Managed Instance. Y", + "guid": "7ed67178-b824-4546-ae1a-ee3453aec823", + "id": "A05.02", + "link": "https://azure.microsoft.com/en-ca/pricing/hybrid-benefit/", "services": [ - "AzurePolicy", - "VNet", + "Cost", "SQL" ], - "severity": "High", - "subcategory": "Public Access", - "text": "Do not enable Azure SQL Managed Instance public endpoint", - "waf": "Security" + "severity": "Low", + "subcategory": "Cost Optimization", + "text": "Leverage Azure Hybrid benefit to maximize the value of your on premises licenses in the cloud", + "waf": "Cost" }, { - "category": "Networking", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "A Managed Instance (SQL MI) public endpoint is not enabled by default, must be explicitly enabled, only if strictly required. In this case, it is recommended to apply a Network Security Groups (NSG) to restrict access to port 3342 only to trusted source IP addresses.", - "guid": "057dd298-8726-4aa6-b590-1f81d2e30421", - "id": "J04.05", - "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/public-endpoint-overview", + "category": "SQL Server on Azure VM", + "checklist": "SQL Migration Review", + "description": "The SQL Server IaaS Agent extension (SqlIaasExtension) runs on SQL Server on Azure Windows Virtual Machines (VMs) to automate management and administration tasks.", + "guid": "9248725d-d68c-45b5-a292-5394a69a9d27", + "id": "A06.01", + "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/sql-agent-extension-automatic-registration-all-vms?view=azuresql-vm&tabs=azure-cli", "services": [ - "VNet", + "VM", "SQL" ], - "severity": "High", - "subcategory": "Public Access", - "text": "Restrict access if Azure SQL Managed Instance public endpoint is required", - "waf": "Security" - }, - { - "category": "Privileged Access", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Most operations, support, and troubleshooting performed by Microsoft personnel and sub-processors do not require access to customer data. In those rare circumstances where such access is required, Customer Lockbox for Microsoft Azure provides an interface for customers to review and approve or reject customer data access requests. In support scenarios where Microsoft needs to access customer data, Azure SQL Database supports Customer Lockbox to provide an interface for you to review and approve or reject customer data access requests.", - "guid": "37b6eb0f-553d-488f-8a8a-cb9bf97388ff", - "id": "K01.01", - "link": "https://learn.microsoft.com/azure/security/fundamentals/customer-lockbox-overview", + "severity": "Medium", + "subcategory": "Azure", + "text": "Register with the SQL IaaS Agent Extension to unlock a number of feature benefits.", + "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/", + "waf": "Operations" + }, + { + "category": "SQL Server on Azure VM", + "checklist": "SQL Migration Review", + "description": "Accelerated Networking provides consistent ultra-low network latency via Azure's in-house programmable hardware and technologies", + "guid": "99c42bb6-8d1d-4755-9624-6b438563b4dc", + "id": "A06.02", + "link": "https://learn.microsoft.com/azure/virtual-network/accelerated-networking-overview?tabs=redhat", "services": [ + "VM", "SQL" ], - "severity": "Low", - "subcategory": "Lockbox", - "text": "Review and enable Customer Lockbox for Azure SQL Database access by Microsoft personnel", - "waf": "Security" + "severity": "High", + "subcategory": "Azure", + "text": "Ensure Accelerated Networking is enabled on the virtual machine.", + "waf": "Operations" }, { - "category": "Privileged Access", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "The principle of least privilege states that users shouldn't have more privileges than needed to complete their tasks. High-privileged database and server users can perform many configuration and maintenance activities on the database and can also drop databases in Azure SQL instance. Tracking database owners and privileged accounts is important to avoid having excessive permission.", - "guid": "5fe5281f-f0f9-4842-a682-8baf18bd8316", - "id": "K02.01", - "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#implement-principle-of-least-privilege", + "category": "SQL Server on Azure VM", + "checklist": "SQL Migration Review", + "description": "Microsoft Defender detects anomalous activities indicating unusual and potentially harmful attempts to access or exploit databases on the SQL server.", + "guid": "74a748b6-633a-4d2a-8916-a66498fad0e2", + "id": "A06.03", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/secure-score-security-controls", "services": [ + "VM", + "Defender", "SQL" ], - "severity": "Medium", - "subcategory": "Permissions", - "text": "Ensure that users are assigned the minimum level of access necessarily to complete their job functions", + "severity": "High", + "subcategory": "Azure", + "text": "Leverage Microsoft Defender for Cloud to improve the overall security posture of your virtual machine deployment.", + "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", "waf": "Security" }, { - "category": "Privileged Access", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Identities (both Users and SPNs) should be scoped to the least amount of access needed to perform the function. A higher number of tightly scoped SPNs should be used, instead of having one SPN with multiple sets of unrelated permissions. For example, if there are three external web applications hosted on-prem that make queries to the Azure SQL Database, they should not all use the same SPN for these activities. Instead, they should each have their own tightly scoped SPN.", - "guid": "7b5b55e5-4750-4920-be97-eb726c256a5c", - "id": "K02.02", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/sql-database-security-baseline#im-3-use-azure-ad-single-sign-on-sso-for-application-access", + "category": "SQL Managed Instance", + "checklist": "SQL Migration Review", + "description": "There are some PaaS limitations that are introduced in SQL Managed Instance and some behavior changes compared to SQL Server. It is important to review and understand these differences.", + "guid": "78ee293c-1bc3-452b-aaab-7571849ab809", + "id": "B01.01", + "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/transact-sql-tsql-differences-sql-server?view=azuresql", "services": [ - "SQL", - "Entra" + "EventHubs", + "SQL" ], - "severity": "Low", - "subcategory": "Permissions", - "text": "Ensure that distinct applications will be assigned different credentials with minimal permissions to access Azure SQL Database", - "waf": "Security" + "severity": "High", + "subcategory": "Pre Migration", + "text": "Review the major differences between SQL Server and Managed Instance", + "training": "https://learn.microsoft.com/learn/modules/plan-implement-administer-conditional-access/", + "waf": "Operations" }, { - "category": "Identity and Access Management", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "d7e47431-76c8-4bdb-b55b-ce619e8a03f9", - "id": "A01.01", - "link": "https://learn.microsoft.com/azure/openshift/howto-create-service-principal?pivots=aro-azurecli", + "category": "SQL Managed Instance", + "checklist": "SQL Migration Review", + "description": "SQL Managed Instance has characteristics and resource limits that depend on the underlying infrastructure and architecture. It is important to review these limits.", + "guid": "3dc9ec9d-1bb7-43b3-9a5a-67fba9ed5b35", + "id": "B01.02", + "link": "https://docs.microsoft.com/azure/azure-sql/managed-instance/resource-limits", "services": [ - "RBAC", - "Entra" + "SQL" ], "severity": "High", - "subcategory": "Identity", - "text": "Create a service principal and its role assignments before creating the ARO clusters.", - "waf": "Security" + "subcategory": "Pre Migration", + "text": "Review capacity limits for SQL MI", + "training": "https://learn.microsoft.com/learn/modules/secure-aad-users-with-mfa/", + "waf": "Performance" }, { - "category": "Identity and Access Management", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "7879424d-6267-486d-90b9-6c97be985190", - "id": "A01.02", - "link": "https://learn.microsoft.com/azure/openshift/configure-azure-ad-ui", + "category": "SQL Managed Instance", + "checklist": "SQL Migration Review", + "description": "The instance settings between managed instance and your source SQL Server can be different . It is important to review those differences that can impact performance.", + "guid": "8bc178bd-c5a0-46ca-9144-351e19dd3442", + "id": "B01.03", + "link": "https://medium.com/azure-sqldb-managed-instance/compare-environment-settings-on-sql-server-and-azure-sql-that-may-impact-performance-e90c21fa9b08", "services": [ - "Entra" + "SQL" ], "severity": "High", - "subcategory": "Identity", - "text": "Use AAD to authenticate users in your ARO cluster.", - "waf": "Security" + "subcategory": "Pre Migration", + "text": "Compare instance settings on SQL Server and Azure SQL MI that may impact performance", + "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-identities-governance/", + "waf": "Performance" }, { - "category": "Identity and Access Management", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "adfec5f9-a82d-46e9-a8d1-5a0c7fed5d15", - "id": "A01.03", - "link": "https://docs.openshift.com/container-platform/4.14/authentication/remove-kubeadmin.html", + "category": "SQL Managed Instance", + "checklist": "SQL Migration Review", + "description": "Assess on-premises SQL Server instance(s) migrating to Azure SQL Managed Instance. The assessment workflow helps you to detect issues that block the migration itself and also partially supported and unsupported features", + "guid": "9eb72281-37a1-451c-9bb4-e4f1814287d5", + "id": "B01.04", + "link": "https://docs.microsoft.com/azure/dms/ads-sku-recommend", "services": [ - "Entra" + "SQL" ], - "subcategory": "Identity", - "text": "When using AAD authentication, remove kubeadmin user from the cluster.", - "waf": "Security" + "severity": "High", + "subcategory": "Pre Migration", + "text": "Run Data Migration assistant or Azure Data Studio Migration Extension to detect compatibility issues that can impact database functionality on Managed Instance", + "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/", + "waf": "Operations" }, { - "category": "Identity and Access Management", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "483835c9-86bb-4291-8155-a11475e39f54", - "id": "A01.04", - "link": "https://docs.openshift.com/container-platform/4.13/applications/projects/working-with-projects.html", + "category": "SQL Managed Instance", + "checklist": "SQL Migration Review", + "description": "The SKU recommendation feature can evaluate the source SQL Server performance and utilization characteristics to recommend a right-sized Azure SQL Managed Instance to assist with your migration journey.", + "guid": "ca8c26c9-b32a-4b5b-afc6-898a135e3378", + "id": "B01.05", + "link": "https://learn.microsoft.com/azure/dms/ads-sku-recommend", "services": [ - "RBAC", - "Entra" + "SQL" ], "severity": "High", - "subcategory": "Identity", - "text": "Define OpenShift projects to restrict RBAC privilege and isolate workloads in your cluster.", - "waf": "Security" + "subcategory": "Pre Migration", + "text": "Select the right compute resources for your workload by leveraging the SKU recommendation tools.", + "training": "https://learn.microsoft.com/learn/modules/explore-basic-services-identity-types/", + "waf": "Performance" }, { - "category": "Identity and Access Management", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "0acccd97-9376-4bcd-a375-0ab2ab039da6", - "id": "A01.05", - "link": "https://docs.openshift.com/container-platform/4.13/authentication/using-rbac.html", + "category": "SQL Managed Instance", + "checklist": "SQL Migration Review", + "description": "Review Unsupported Features, Migration Blockers and Breaking Changes for each database from the Assessment", + "guid": "97e31c67-d68c-4b69-82ac-19f906d697c8", + "id": "B01.06", + "link": "https://learn.microsoft.com/azure/dms/ads-sku-recommend", "services": [ - "RBAC", - "Entra" + "SQL" ], - "severity": "Medium", - "subcategory": "Identity", - "text": "Define the required RBAC roles in OpenShift are scoped to either a project or a cluster.", - "waf": "Security" + "severity": "High", + "subcategory": "Pre Migration", + "text": "Review and address the issues highlighted in DMA/Azure Data Studio", + "training": "https://learn.microsoft.com/learn/paths/manage-identity-and-access/", + "waf": "Operations" }, { - "category": "Identity and Access Management", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "d54d7c89-29db-4107-b532-5ae625ca44e4", - "id": "A01.06", - "link": "https://learn.microsoft.com/azure/cost-management-billing/manage/direct-ea-administration#manage-notification-contacts", + "category": "SQL Managed Instance", + "checklist": "SQL Migration Review", + "description": "The SQL Managed Instance default DNS zone .database.windows.net can be changed with your own. However, the managed instance hostname part of its FQDN should remain the same.", + "guid": "eaded26b-dd18-46f0-ac25-1b999a68af87", + "id": "B01.07", + "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/frequently-asked-questions-faq?view=azuresql-mi#can-a-managed-instance-have-the-same-name-as-a-sql-server-on-premises-instance", "services": [ - "AKV", - "Entra" + "DNS", + "SQL" ], - "severity": "Medium", - "subcategory": "Identity", - "text": "Minimize the number of users who have administrator rights and secrets access.", - "waf": "Security" + "severity": "High", + "subcategory": "Pre Migration", + "text": "Plan for connection string changes as changing a managed instance name is not supported", + "training": "https://learn.microsoft.com/learn/modules/create-custom-azure-roles-with-rbac/", + "waf": "Operations" }, { - "category": "Identity and Access Management", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "685e2223-ace8-4bb1-8307-ca5f16f154e3", - "id": "A01.07", - "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-configure", + "category": "SQL Managed Instance", + "checklist": "SQL Migration Review", + "description": "There are addional requirements in configuring a vnet and subnet hosting the managed instance.", + "guid": "c9a7f821-b8eb-48c0-aa77-e25e4d5aeaa8", + "id": "B01.08", + "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/vnet-existing-add-subnet?view=azuresql-mi", "services": [ - "RBAC", - "Entra" + "VNet", + "SQL" ], "severity": "Medium", - "subcategory": "Identity", - "text": "Use Privileged Identity Management in AAD for ARO users with privileged roles.", - "waf": "Security" + "subcategory": "Pre Migration", + "text": "Review managed instance VNet requirements", + "training": "https://learn.microsoft.com/learn/paths/secure-your-cloud-data/", + "waf": "Operations" }, { - "category": "Network topology and connectivity", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "aa369282-9e7e-4216-8836-87af467a1f89", - "id": "B01.01", - "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", + "category": "SQL Managed Instance", + "checklist": "SQL Migration Review", + "description": "Though it's possible to deploy managed instances to a subnet with a number of IP addresses that's less than the output of the subnet formula, always consider using bigger subnets instead. Using a bigger subnet can help avoid future issues stemming from a lack of IP addresses, such as the inability to create additional instances within the subnet or scale existing instances.", + "guid": "dc4e2436-bb33-46d7-85f1-7960eee0b9b5", + "id": "B02.01", + "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/vnet-subnet-determine-size?view=azuresql-mi", "services": [ - "DDoS", - "Entra", - "WAF", - "Firewall", "VNet", - "Subscriptions" + "SQL" ], - "severity": "Low", - "subcategory": "DDoS", - "text": "Use Azure DDoS Network/IP Protection to protect the virtual network you use for the ARO cluster unless you use Azure Firewall or WAF in a centralized subscription", - "waf": "Security" - }, - { - "category": "Network topology and connectivity", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "35bda433-24f1-4481-8533-182aa5174269", - "id": "B02.01", - "link": "https://docs.openshift.com/container-platform/4.13/networking/routes/secured-routes.html", - "services": [], "severity": "High", - "subcategory": "Encryption", - "text": "All web applications you configure to use an ingress should use TLS encryption and shouldn't allow access over unencrypted HTTP.", - "waf": "Security" + "subcategory": "Deployment", + "text": "Ensure managed instance subnet has sufficient IP addresses available", + "training": "https://learn.microsoft.com/learn/modules/azure-active-directory/", + "waf": "Operations" }, { - "category": "Network topology and connectivity", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "44008ae7-d7e4-4743-876c-8bdbf55bce61", + "category": "SQL Managed Instance", + "checklist": "SQL Migration Review", + "description": "SQL Managed Instance has characteristics and resource limits that depend on the underlying infrastructure and architecture. SQL Managed Instance can be deployed on multiple hardware configurations.", + "guid": "c8defc4d-721d-431d-850f-b707ae9eab40", "id": "B03.01", - "link": "https://learn.microsoft.com/azure/frontdoor/front-door-overview", + "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/resource-limits?view=azuresql-mi#service-tier-characteristics", "services": [ - "FrontDoor", - "WAF" + "SQL" ], - "severity": "Medium", - "subcategory": "Internet", - "text": "Use Azure Front Door with WAF to securely publish ARO applications to the internet, especially in multi-region environments.", - "waf": "Security" + "severity": "High", + "subcategory": "Pre Migration", + "text": "Plan between General Purpose and Business Critical tiers of MI", + "training": "https://learn.microsoft.com/learn/modules/implement-hybrid-identity-windows-server/", + "waf": "Performance" }, { - "category": "Network topology and connectivity", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "9e8a03f9-7879-4424-b626-786d60b96c97", + "category": "SQL Managed Instance", + "checklist": "SQL Migration Review", + "description": "The auto-failover groups feature allows you to manage the replication and failover of user databases in a managed instance to a managed instance in another Azure region. Auto-failover groups are designed to simplify deployment and management of geo-replicated databases at scale.", + "guid": "ed329079-8bc1-478b-bc5a-06ca7144351e", "id": "B03.02", - "link": "https://learn.microsoft.com/azure/openshift/howto-secure-openshift-with-front-door", + "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/auto-failover-group-sql-mi?view=azuresql-mi&tabs=azure-powershell", "services": [ - "FrontDoor", - "PrivateLink" + "SQL" ], - "severity": "Medium", - "subcategory": "Internet", - "text": "If exposing an app on ARO with Azure Front Door, use private link to connect Front Door with the ARO router.", - "waf": "Security" + "severity": "High", + "subcategory": "Pre Migration", + "text": "Based on your RPO/RTO's , determine if Auto failover Group needs to be implemented. If so, plan for the deployment attributes of the second instance.", + "training": "https://learn.microsoft.com/learn/paths/implement-windows-server-iaas-virtual-machine-identity/", + "waf": "Reliability" }, { - "category": "Network topology and connectivity", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "be985190-4838-435c-a86b-b2912155a114", + "category": "SQL Managed Instance", + "checklist": "SQL Migration Review", + "description": "There are multiple ways to connect your application to the managed instance. Review and understand the pros and cons and decide on the best approach for your application.", + "guid": "5d226886-d30b-466c-97be-595190f83845", "id": "B03.03", - "link": "https://learn.microsoft.com/azure/openshift/howto-restrict-egress", + "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/connect-application-instance?view=azuresql-mi", "services": [ - "Firewall", - "AzurePolicy", - "NVA" + "SQL" ], - "severity": "Medium", - "subcategory": "Internet", - "text": "If your security policy requires you to inspect all outbound internet traffic that's generated in the ARO cluster, secure egress network traffic by using Azure Firewall or an NVA.", - "waf": "Security" + "severity": "Low", + "subcategory": "Pre Migration", + "text": "Review the Connectivity Design between Database and Application, test & validate it", + "training": "https://learn.microsoft.com/learn/paths/implement-applications-external-access-azure-ad/", + "waf": "Operations" }, { - "category": "Network topology and connectivity", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "75e39f54-0acc-4cd9-9937-6bcda3750ab2", - "id": "B04.01", - "link": "https://learn.microsoft.com/azure/openshift/howto-create-private-cluster-4x", + "category": "SQL Managed Instance", + "checklist": "SQL Migration Review", + "description": "Compare migration options to choose the path that's appropriate to your business needs.", + "guid": "c586cb29-1ec1-46a1-b076-ef9f141acdce", + "id": "B03.04", + "link": "https://learn.microsoft.com/azure/azure-sql/migration-guides/managed-instance/sql-server-to-managed-instance-overview?view=azuresql-mi#migration-tools", "services": [ - "AzurePolicy" + "SQL" ], - "severity": "High", - "subcategory": "Private access", - "text": "If your security policy requires you to use a private IP address for the OpenShift API, deploy a private ARO cluster.", - "waf": "Security" + "severity": "Medium", + "subcategory": "Pre Migration", + "text": "Plan for the Migration Method. Depending on the DB Size and Application downtime window, select the preferred Migration Method.", + "training": "https://learn.microsoft.com/learn/modules/design-identity-security-strategy/", + "waf": "Operations" }, { - "category": "Network topology and connectivity", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "ab039da6-d54d-47c8-a29d-b107d5325ae6", - "id": "B04.02", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-private-link", + "category": "SQL Managed Instance", + "checklist": "SQL Migration Review", + "description": "After you verify that data is the same on both source and target, you can cut over from the source to the target environment. It's important to plan the cutover process with business / application teams to ensure minimal interruption during cutover doesn't affect business continuity.", + "guid": "579377bc-db37-451a-a2ac-1fad66e15d4d", + "id": "B03.05", + "link": "https://learn.microsoft.com/azure/dms/tutorial-sql-server-managed-instance-online#performing-migration-cutover", "services": [ - "ACR", - "PrivateLink" + "SQL" ], "severity": "Medium", - "subcategory": "Private access", - "text": "Use Azure Private Link to secure network connections to managed Azure services, including to Azure Container Registry.", - "waf": "Security" + "subcategory": "Pre Migration", + "text": "Plan the cutover process with business / application teams to ensure minimal interruption during cutover and it does not affect business continuity.", + "training": "https://learn.microsoft.com/azure/architecture/example-scenario/identity/adds-extend-domain", + "waf": "Reliability" }, { - "category": "Operations management", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "25ca44e4-685e-4222-9ace-8bb12307ca5f", - "id": "C01.01", - "link": "https://learn.microsoft.com/azure/azure-monitor/containers/container-insights-enable-arc-enabled-clusters", + "category": "SQL Managed Instance", + "checklist": "SQL Migration Review", + "description": "A time zone of a managed instance can be set during instance creation only. The default time zone is UTC", + "guid": "4a2adb1c-3d23-426a-b225-ca44e1695fdd", + "id": "B04.01", + "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/timezones-overview?view=azuresql#set-a-time-zone", "services": [ - "Monitor" + "SQL" ], "severity": "High", - "subcategory": "Operations", - "text": "Establish a monitoring process using the inbuilt Prometheus, OpenShift Logging or Container Insights integration.", + "subcategory": "Deployment", + "text": "Ensure you customize your time zone setting at the instance creation time. One cannot change it later.", + "training": "https://learn.microsoft.com/azure/role-based-access-control/overview", "waf": "Operations" }, { - "category": "Operations management", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "16f154e3-aa36-4928-89e7-e216183687af", - "id": "C01.02", - "link": "https://docs.openshift.com/container-platform/4.13/cicd/pipelines/understanding-openshift-pipelines.html", - "services": [], - "severity": "Medium", - "subcategory": "Operations", - "text": "Automate the application delivery process through DevOps practices and CI/CD solutions, such as Pipelines/GitOps provided by OpenShift.", + "category": "SQL Managed Instance", + "checklist": "SQL Migration Review", + "description": "Server-level collation in Azure SQL Managed Instance can be specified when the instance is created and cannot be changed later.Default server-level collation is SQL_Latin1_General_CP1_CI_AS.", + "guid": "deace4cb-1deb-44c6-90c3-fc14eebb3693", + "id": "B04.02", + "link": "https://learn.microsoft.com/sql/relational-databases/collations/set-or-change-the-server-collation?view=sql-server-ver16", + "services": [ + "SQL" + ], + "severity": "High", + "subcategory": "Deployment", + "text": "Ensure you select the right collation setting at the instance creation time. One cannot change it later", "waf": "Operations" }, { - "category": "Operations management", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "467a1f89-35bd-4a43-924f-14811533182a", - "id": "C01.03", - "link": "https://learn.microsoft.com/azure/architecture/guide/design-principles/managed-services", - "services": [], - "severity": "Low", - "subcategory": "Operations", - "text": "Whenever possible, remove the service state from inside containers. Instead, use an Azure platform as a service (PaaS) that supports multiregion replication.", + "category": "SQL Managed Instance", + "checklist": "SQL Migration Review", + "description": "When you're migrating a database protected by Transparent Data Encryption (TDE) to Azure SQL Managed Instance using the native restore option, the corresponding certificate from the SQL Server instance needs to be migrated before database restore.", + "guid": "829e3eec-2183-4687-a007-7a2b5945bda4", + "id": "B04.03", + "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/tde-certificate-migrate?view=azuresql-mi&tabs=azure-powershell", + "services": [ + "VM", + "SQL" + ], + "severity": "Medium", + "subcategory": "Deployment", + "text": "For TDE Enabled Database, corresponding certificate from the on-premises or Azure VM SQL Server needs to be migrated before database restore", "waf": "Operations" }, { - "category": "Operations management", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "1b7da8cf-aa66-4e15-b4d5-ada97dc3e232", - "id": "C01.04", - "link": "https://learn.microsoft.com/azure/openshift/howto-create-a-storageclass", + "category": "SQL Managed Instance", + "checklist": "SQL Migration Review", + "description": "System databases can be restored only from backups that are created on the version of SQL Server that the server instance is currently running. This is not the case when you are migrating to SQL Managed Instance.Azure PowerShell and DBATools PowerShell libraries enable you to easily script and automate and customize all parts of the migration process.", + "guid": "3334fdf9-1c23-4418-8b65-275269440b4b", + "id": "B05.01", + "link": "https://learn.microsoft.com/azure/azure-sql/migration-guides/managed-instance/sql-server-to-managed-instance-guide?view=azuresql-mi#backup-and-restore", "services": [ - "Storage" + "Backup", + "SQL" ], "severity": "Low", - "subcategory": "Operations", - "text": "Use RWX storage with inbuilt Azure Files storage class.", + "subcategory": "Migration", + "text": "Restore of system databases is not supported. To migrate instance-level objects (stored in master or msdb databases), we recommend to script them out and run T-SQL scripts on the destination instance.", "waf": "Operations" }, { - "category": "Operations management", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "6bb235c7-05e1-4696-bded-fa8a4c8cdec4", - "id": "C02.01", - "link": "https://docs.openshift.com/container-platform/4.13/nodes/clusters/nodes-cluster-limit-ranges.html", - "services": [], - "severity": "Medium", - "subcategory": "Performance", - "text": "Use pod requests and limits to manage the compute resources within a cluster.", - "waf": "Performance" - }, - { - "category": "Operations management", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "c620c30c-14ee-4b7f-9ae8-d9b3fec228e7", - "id": "C02.02", - "link": "https://docs.openshift.com/container-platform/4.13/applications/quotas/quotas-setting-per-project.html", - "services": [], - "severity": "Medium", - "subcategory": "Performance", - "text": "Enforce resource quotas on projects.", - "waf": "Performance" - }, - { - "category": "Operations management", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "87ab177a-db59-4f6b-a613-334fd09dc234", - "id": "C02.03", - "link": "https://docs.openshift.com/container-platform/4.13/machine_management/applying-autoscaling.html", - "services": [], + "category": "SQL Managed Instance", + "checklist": "SQL Migration Review", + "description": "When using migration options that continuously replicate / sync data changes from source to the target, the source data and schema can change and drift from the target. During data sync, ensure that all changes on the source are captured and applied to the target during the migration process.", + "guid": "e3d3e084-3276-4d4b-bc01-5bcf219e4a1e", + "id": "B05.02", + "services": [ + "SQL" + ], "severity": "High", - "subcategory": "Performance", - "text": "Define ClusterAutoScaler and MachineAutoScaler to scale machines when your cluster runs out of resources to support more deployments.", - "waf": "Performance" + "subcategory": "Migration", + "text": "Ensure that all changes on the source are captured and applied to the target during the migration process.", + "waf": "Operations" }, { - "category": "Operations management", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "19db6128-1269-4040-a4ba-4d3e0804276d", - "id": "C03.01", - "link": "https://learn.microsoft.com/azure/openshift/support-policies-v4#supported-virtual-machine-sizes", + "category": "SQL Managed Instance", + "checklist": "SQL Migration Review", + "description": "Ensure that the application is able to succesffuly connect to the managed instance post migration of the databases.", + "guid": "b5887952-5d22-4688-9d30-b66c57be5951", + "id": "B05.03", + "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/connect-application-instance?view=azuresql-mi", "services": [ - "VM" + "SQL" ], - "severity": "High", - "subcategory": "Reliability", - "text": "Use virtual machine sizes that are large enough to contain multiple container instances so you get the benefits of increased density, but not so large that your cluster can't handle the workload of a failing node.", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "Migration", + "text": "Test Application Connectivity to MI and Databases", + "waf": "Operations" }, { - "category": "Operations management", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "4b98b15c-8b31-4aa5-aceb-58889135e227", - "id": "C03.02", - "link": "https://docs.openshift.com/container-platform/4.13/machine_management/deploying-machine-health-checks.html", - "services": [], + "category": "SQL Managed Instance", + "checklist": "SQL Migration Review", + "description": "High availability is a fundamental part of SQL Managed Instance platform that works transparently for your database applications. Failovers from primary to secondary nodes in case of node degradation or fault detection, or during regular monthly software updates are an expected occurrence for all applications using SQL Managed Instance in Azure.", + "guid": "90f83845-c586-4cb2-a1ec-16a1d076ef9f", + "id": "B06.01", + "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/user-initiated-failover?view=azuresql", + "services": [ + "SQL" + ], "severity": "High", - "subcategory": "Reliability", - "text": "Deploy machine health checks to automatically repair damaged machines in a machine pool.", + "subcategory": "Post Migration", + "text": "Consider executing a manual failover on SQL Managed Instance to test for fault and failover resiliency.", + "training": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", "waf": "Reliability" }, { - "category": "Operations management", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "896d31b6-6c67-4ba5-a119-c08e8f5d587c", - "id": "C03.03", - "link": "https://learn.microsoft.com/azure/azure-monitor/containers/container-insights-metric-alerts", + "category": "SQL Managed Instance", + "checklist": "SQL Migration Review", + "description": "Ensuring that your applications are failover resilient prior to deploying to production will help mitigate the risk of application faults in production and will contribute to application availability for your customers.", + "guid": "141acdce-5793-477b-adb3-751ab2ac1fad", + "id": "B06.02", + "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/auto-failover-group-configure-sql-mi?view=azuresql&tabs=azure-portal#test-failover", "services": [ - "Monitor" + "EventHubs", + "LoadBalancer", + "SQL" ], "severity": "High", - "subcategory": "Reliability", - "text": "Use an alerting system to provide notifications when things need direct action: Container Insights metric alerts or in-built Alerting UI.", + "subcategory": "Post Migration", + "text": "If failover groups have been implemented, Test Manual Failover and Failback and test application connectivity behavior during failover/failback", "waf": "Reliability" }, { - "category": "Operations management", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "7e9ced16-acd1-476e-b9b2-41a998a57ae7", - "id": "C03.04", - "link": "https://learn.microsoft.com/azure/reliability/availability-zones-overview#availability-zones", - "services": [], + "category": "SQL Managed Instance", + "checklist": "SQL Migration Review", + "description": "This provides more dedicated disk IOPS and throughput", + "guid": "aa359272-8e6e-4205-8726-76ae46691e88", + "id": "B06.03", + "link": "https://techcommunity.microsoft.com/t5/azure-sql-blog/storage-performance-best-practices-and-considerations-for-azure/ba-p/305525", + "services": [ + "Storage", + "SQL" + ], "severity": "High", - "subcategory": "Reliability", - "text": "Ensure that the cluster is created in a region that supports AZs and create a machine set for each AZ.", - "waf": "Reliability" + "subcategory": "Post Migration", + "text": "Optimize Storage Performance for General Purpose Managed Instance", + "training": "https://learn.microsoft.com/learn/paths/architect-infrastructure-operations/", + "waf": "Performance" }, { - "category": "Operations management", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "7b997e71-1b7d-4a8c-baa6-6e15d4d5ada9", - "id": "C03.05", - "link": "https://docs.openshift.com/container-platform/4.13/machine_management/creating-infrastructure-machinesets.html", + "category": "SQL Managed Instance", + "checklist": "SQL Migration Review", + "description": "Many organizations have policies that require that certificates or encryption keys be created and managed internally. If your organization has a similar policy, this architecture might apply to you. If your customers require internal management of these items, the architecture also might apply to you.", + "guid": "35ad9422-23e1-4381-8523-081a94174158", + "id": "B06.04", + "link": "https://learn.microsoft.com/azure/architecture/example-scenario/data/sql-managed-instance-cmk", "services": [ - "AKS" + "Backup", + "AzurePolicy", + "AKV", + "SQL" ], "severity": "Low", - "subcategory": "Reliability", - "text": "Create infrastructure machine sets to hold infrastructure components. Apply specific Kubernetes labels to these machines and then update the infrastructure components to run on only those machines.", - "waf": "Reliability" + "subcategory": "Post Migration", + "text": "Enable Customer managed TDE for taking your own copy only full backups", + "training": "https://learn.microsoft.com/learn/paths/architect-infrastructure-operations/", + "waf": "Security" }, { - "category": "Operations management", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "7dc3e232-6bb2-435c-905e-1696fdedfa8a", - "id": "C03.06", - "link": "https://learn.microsoft.com/azure/openshift/howto-create-a-backup#create-a-backup-with-velero-to-include-snapshots", + "category": "SQL Managed Instance", + "checklist": "SQL Migration Review", + "description": "The maintenance window feature provides you with the ability to onboard Azure SQL resource to prescheduled time blocks outside of business hours.", + "guid": "33ef7ad7-c6d3-4733-865c-7acbe44bbe60", + "id": "B06.05", + "link": "https://learn.microsoft.com/azure/azure-sql/database/planned-maintenance?view=azuresql", "services": [ - "Backup" + "SQL" ], "severity": "Medium", - "subcategory": "Reliability", - "text": "Create application backup and plan for restore and include persistent volumes in the backup.", - "waf": "Reliability" + "subcategory": "Post Migration", + "text": "Plan for Azure maintenance events", + "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", + "waf": "Operations" }, { - "category": "Operations management", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "81c12318-1a64-4174-8583-3fb4ae3c2df7", - "id": "C03.07", - "link": "https://docs.openshift.com/container-platform/4.13/nodes/pods/nodes-pods-priority.html", - "services": [], + "category": "SQL Managed Instance", + "checklist": "SQL Migration Review", + "description": "By using the long-term retention (LTR) feature, you can store specified SQL Database and SQL Managed Instance full backups in Azure Blob storage with configured redundancy for up to 10 years.", + "guid": "9d89f2e8-7778-4424-b516-785c6fa96b96", + "id": "B06.06", + "link": "https://learn.microsoft.com/azure/azure-sql/database/long-term-retention-overview?view=azuresql-mi", + "services": [ + "Backup", + "Storage", + "ARS", + "SQL" + ], "severity": "Low", - "subcategory": "Reliability", - "text": "Use pod priorities, so that in case of limited resources the most critical pods will run.", + "subcategory": "Post Migration", + "text": "Configure Long Term backup retention, view backups and restore from backups", + "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-compute-resources/", "waf": "Reliability" }, { - "category": "Operations management", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "43166c3b-cbe0-45bb-b209-d4a0da577784", - "id": "C04.01", - "link": "https://docs.openshift.com/container-platform/4.13/architecture/admission-plug-ins.html", + "category": "SQL Managed Instance", + "checklist": "SQL Migration Review", + "description": "By using Azure Hybrid Benefit, you can achieve cost savings, modernise and maintain a flexible hybrid environment while optimising business applications.", + "guid": "ad88408f-3727-434c-a76b-a28021459014", + "id": "B06.07", + "link": "https://azure.microsoft.com/en-gb/pricing/hybrid-benefit/#overview", "services": [ - "AzurePolicy" + "Cost", + "SQL" ], "severity": "Low", - "subcategory": "Security", - "text": "Regulate cluster functions using admission plug-ins, which are commonly used to enforce security policy, resource limitations, or configuration requirements.", - "waf": "Security" + "subcategory": "Post Migration", + "text": "Take advantage of Azure Hybrid Benefit and Azure Reservations where applicable.", + "training": "https://learn.microsoft.com/learn/modules/configure-network-watcher/", + "waf": "Cost" }, { - "category": "Operations management", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "24d21678-5d2f-4a56-a56a-d48408fe8273", - "id": "C04.02", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-geo-replication", + "category": "SQL Managed Instance", + "checklist": "SQL Migration Review", + "description": "If you don't have threat protection Advanced Threat Protection is part of the Microsoft Defender for SQL offering, which is a unified package for advanced SQL security capabilities.", + "guid": "65d38e53-f9cc-4bd8-9926-6acca274faa1", + "id": "B06.08", + "link": "https://learn.microsoft.com/azure/azure-sql/database/threat-detection-overview?view=azuresql", "services": [ - "ACR" + "Defender", + "SQL" ], - "severity": "Low", - "subcategory": "Security", - "text": "Store your container images in Azure Container Registry and geo-replicate the registry to each region.", + "severity": "Medium", + "subcategory": "Post Migration", + "text": "Leverage Microsoft Defender for Cloud to improve the overall security posture", + "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", "waf": "Security" }, { - "category": "Operations management", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "4c486ba2-80dc-4059-8cf7-5ee8e1309ccc", - "id": "C05.01", - "link": "https://docs.openshift.com/container-platform/4.13/nodes/pods/nodes-pods-vertical-autoscaler.html", - "services": [], + "category": "Business Continuity and Disaster Recovery", + "checklist": "Azure Landing Zone Review", + "guid": "aff6691b-4935-4ada-9222-3ece81b12318", + "link": "https://learn.microsoft.com/azure/active-directory/reports-monitoring/overview-reports", + "services": [ + "ASR" + ], "severity": "Medium", - "subcategory": "Workload", - "text": "Optimize the CPU and memory request values, and maximize the efficiency of the cluster resources using vertical pod autoscaler.", - "waf": "Performance" + "subcategory": " ", + "text": "Do not combine ASCS and Database cluster on to single/same VM" }, { - "category": "Operations management", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "d579366b-cda2-4750-aa1a-bfe9d55d14c3", - "id": "C05.02", - "link": "https://docs.openshift.com/container-platform/4.13/applications/application-health.html", + "category": "Business Continuity and Disaster Recovery", + "checklist": "Azure Landing Zone Review", + "guid": "1a541741-5833-4fb4-ae3c-2df743165c3a", + "link": "https://learn.microsoft.com/azure/azure-monitor/logs/logs-data-export?tabs=portal", + "services": [ + "ASR", + "LoadBalancer" + ], + "severity": "Medium", + "subcategory": " ", + "text": "Make sure the Floating IP is enabled on the Load balancer" + }, + { + "category": "Business Continuity and Disaster Recovery", + "checklist": "Azure Landing Zone Review", + "guid": "cbe05bbe-209d-4490-ba47-778424d11678", + "link": "https://learn.microsoft.com/azure/security-center/", + "services": [ + "RBAC", + "VM", + "ASR", + "Entra" + ], + "severity": "Medium", + "subcategory": " ", + "text": "Do not mix servers of different roles in the same availability set. Keep central services VMs, database VMs, application VMs in their own availability sets" + }, + { + "category": "Business Continuity and Disaster Recovery", + "checklist": "Azure Landing Zone Review", + "guid": "5d2fa56c-56ad-4484-88fe-72734c486ba2", + "link": "https://learn.microsoft.com/azure/security-center/", + "services": [ + "ACR", + "ASR", + "SAP" + ], + "severity": "Medium", + "subcategory": " ", + "text": "Use one proximity placement group per SAP SID. Groups don't span across Availability Zones or Azure regions" + }, + { + "category": "Business Continuity and Disaster Recovery", + "checklist": "Azure Landing Zone Review", + "guid": "80dc0591-cf65-4de8-b130-9cccd579266b", + "link": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", + "services": [ + "VM", + "ASR", + "Entra" + ], + "severity": "Medium", + "subcategory": " ", + "text": "Azure doesn't currently support combining ASCS and db HA in the same Linux Pacemaker cluster; separate them into individual clusters. However, you can combine up to five multiple central-services clusters into a pair of VMs." + }, + { + "category": "Business Continuity and Disaster Recovery", + "checklist": "Azure Landing Zone Review", + "guid": "cca275fa-a1ab-4fe9-b55d-04c3c4919cb1", + "link": "https://learn.microsoft.com/security/benchmark/azure/security-control-incident-response", + "services": [ + "ASR", + "LoadBalancer" + ], + "severity": "Medium", + "subcategory": " ", + "text": "Use a Standard Load Balancer SKU in front of ASCS and DB clusters" + }, + { + "category": "Business Continuity and Disaster Recovery", + "checklist": "Azure Landing Zone Review", + "guid": "b3d1325a-e124-4ba3-9df6-85eddce9bd3b", + "link": "https://www.microsoft.com/itshowcase/implementing-a-zero-trust-security-model-at-microsoft", "services": [ - "Monitor" + "VM", + "ASR", + "Storage" ], "severity": "Medium", - "subcategory": "Workload", - "text": "Add health probes to your pods to monitor application health. Make sure pods contain livenessProbe and readinessProbe. Use Startup probes to determine the point at which the application has started up.", - "waf": "Reliability" + "subcategory": " ", + "text": "Both VMs in the HA pair should be deployed in an availability set, or Availability Zones should be the same size and have the same storage configuration" }, { - "category": "Operations management", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "c4929cb1-b3d1-4325-ae12-4ba34d0685ed", - "id": "C05.03", - "link": "https://docs.openshift.com/container-platform/4.13/nodes/pods/nodes-pods-autoscaling.html", - "services": [], + "category": "Business Continuity and Disaster Recovery", + "checklist": "Azure Landing Zone Review", + "guid": "b0cdb3b5-5eb2-4ec1-9eea-a3592829e2ed", + "link": "https://learn.microsoft.com/security/benchmark/azure/security-control-incident-response", + "services": [ + "ASR" + ], "severity": "Medium", - "subcategory": "Workload", - "text": "Scale pods to meet demand using horizontal pod autoscaler.", - "waf": "Reliability" + "subcategory": " ", + "text": "Native database replication technology should be used to synchronize the database in a HA pair." }, { - "category": "Operations management", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "dce9be3b-b0dd-4b3b-95fb-2ec14eeaa359", - "id": "C05.04", - "link": "https://docs.openshift.com/container-platform/4.13/nodes/pods/nodes-pods-configuring.html#nodes-pods-pod-distruption-about_nodes-pods-configuring", + "category": "Business Continuity and Disaster Recovery", + "checklist": "Azure Landing Zone Review", + "guid": "b2173676-aff6-4691-a493-5ada42223ece", + "link": "https://learn.microsoft.com/security/benchmark/azure/security-control-incident-response", "services": [ - "Cost" + "ASR", + "SAP" ], "severity": "Medium", - "subcategory": "Workload", - "text": "Use disruption budgets to ensure the required number of pod replicas exist to handle expected application load.", - "waf": "Reliability" + "subcategory": " ", + "text": "Perform a point-in-time recovery for your production databases at any point and in a time frame that meets your RTO; point-in-time recovery typically includes operator errors deleting data either on the DBMS layer or through SAP, incidentally" }, { - "category": "Operations management", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "2829e2ed-b217-4367-9aff-6791b4935ada", - "id": "C05.05", - "link": "https://docs.openshift.com/container-platform/4.13/nodes/scheduling/nodes-scheduler-pod-topology-spread-constraints.html", - "services": [], + "category": "Business Continuity and Disaster Recovery", + "checklist": "Azure Landing Zone Review", + "guid": "81b12318-1a54-4174-8583-3fb4ae3c2df7", + "services": [ + "VNet", + "ASR" + ], "severity": "Medium", - "subcategory": "Workload", - "text": "Use pod topology constraints to automatically schedule pods on nodes throughout the cluster.", - "waf": "Reliability" + "subcategory": " ", + "text": "The CIDR for the primary virtual network (VNet) shouldn't conflict or overlap with the CIDR of the DR site's Vnet" }, { - "category": "Platform Automation", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "42324ece-81c1-4231-a1a6-417415833fb4", - "id": "D01.01", - "link": "https://docs.openshift.com/container-platform/4.13/applications/deployments/route-based-deployment-strategies.html", - "services": [], - "severity": "Low", - "subcategory": "Workload", - "text": "Consider blue/green or canary strategies to deploy new releases of application.", - "waf": "Operations" + "category": "Business Continuity and Disaster Recovery", + "checklist": "Azure Landing Zone Review", + "guid": "43165c3a-cbe0-45bb-b209-d490da477784", + "services": [ + "VM", + "ASR", + "Entra" + ], + "severity": "Medium", + "subcategory": " ", + "text": "Use Site Recovery to replicate an application server to a DR site. Site Recovery can also help with replicating central-services cluster VMs to the DR site. When you invoke DR, you'll need to reconfigure the Linux Pacemaker cluster on the DR site (for example, replace the VIP or SBD, run corosync.conf, and more)." }, { - "category": "Platform Automation", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "ae3c2df7-4316-46c3-acbe-05bbe209d4a0", - "id": "D01.02", - "link": "https://docs.openshift.com/container-platform/4.13/cicd/gitops/understanding-openshift-gitops.html", - "services": [], - "severity": "Low", - "subcategory": "Workload", - "text": "Consider using Red Hat OpenShift GitOps. Red Hat OpenShift GitOps uses Argo CD to maintain cluster resources and support application CI/CD.", - "waf": "Operations" + "category": "Business Continuity and Disaster Recovery", + "checklist": "Azure Landing Zone Review", + "guid": "24d11678-5d2f-4a56-a56a-d48408fe7273", + "services": [ + "ASR" + ], + "severity": "Medium", + "subcategory": " ", + "text": "Native database replication should be used to synchronize data to the DR site, rather than Azure Site Recovery" }, { - "category": "Security", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "da577784-24d2-4167-a5d2-fa56c56ad484", - "id": "E01.01", - "link": "https://learn.microsoft.com/azure/openshift/support-lifecycle", - "services": [], - "severity": "High", - "subcategory": "Control plane", - "text": "Keep your clusters on the latest OpenShift version to avoid potential security or upgrade issues.", - "waf": "Security" + "category": "Compute", + "checklist": "Azure Landing Zone Review", + "guid": "2829e2ed-b217-4367-9aff-6691b4935ada", + "services": [ + "VM" + ], + "severity": "Medium", + "subcategory": " ", + "text": "Make quota requests for correct VM SKU and Zones" }, { - "category": "Security", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "08fe8273-4c48-46ba-880d-c0591cf75ee8", - "id": "E01.02", - "link": "https://learn.microsoft.com/azure/azure-arc/kubernetes/quickstart-connect-cluster", + "category": "Identity and Access", + "checklist": "Azure Landing Zone Review", + "guid": "fda1dbf3-dc95-4d48-a7c7-91dca0f6c565", + "link": "https://learn.microsoft.com/azure/well-architected/sap/design-areas/security", "services": [ - "Arc", - "AKS" + "RBAC", + "Subscriptions", + "Entra" ], "severity": "High", - "subcategory": "Control plane", - "text": "Connect Azure Red Hat OpenShift clusters to Azure Arc-enabled Kubernetes.", - "waf": "Security" + "subcategory": "Identity", + "text": "Enforce a RBAC model for management groups, subscriptions, resource groups and resources", + "training": "https://learn.microsoft.com/training/paths/implement-resource-mgmt-security/" }, { - "category": "Security", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "e1309ccc-d579-4366-acda-2750aa1abfe9", - "id": "E02.01", - "link": "https://docs.openshift.com/container-platform/4.10/security/encrypting-etcd.html", - "services": [], - "severity": "Low", - "subcategory": "Encryption", - "text": "For Azure Red Hat OpenShift 4 clusters, etcd data isn't encrypted by default, but it's recommended to enable etcd encryption to provide another layer of data security.", - "waf": "Security" + "category": "Identity and Access", + "checklist": "Azure Landing Zone Review", + "guid": "45911475-e39e-4530-accc-d979366bcda2", + "link": "https://learn.microsoft.com/azure/active-directory/fundamentals/scenario-azure-first-sap-identity-integration", + "services": [ + "SAP", + "Entra" + ], + "severity": "Medium", + "subcategory": "Identity", + "text": "Enforce Principle propagation for forwarding the identity from SAP cloud application to SAP on-premises (Including IaaS) through cloud connector", + "training": "https://learn.microsoft.com/training/modules/explore-identity-services/2-explore-azure-virtual-machine-auth-access-control" }, { - "category": "Security", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "d55d14c3-c492-49cb-8b3d-1325ae124ba3", - "id": "E03.01", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-introduction", + "category": "Identity and Access", + "checklist": "Azure Landing Zone Review", + "guid": "750ab1ab-039d-495d-94c7-c8929cb107d5", + "link": "https://learn.microsoft.com/azure/active-directory/fundamentals/scenario-azure-first-sap-identity-integration", "services": [ - "Arc", - "AKS", - "Defender" + "SAP", + "Entra" ], "severity": "Medium", - "subcategory": "Posture", - "text": "Use Microsoft Defender for Containers supported via Arc-enabled Kubernetes to secure clusters, containers, and applications.", - "waf": "Security" + "subcategory": "Identity", + "text": "Implement SSO to SAP SaaS applications like SAP Analytics Cloud, SAP Cloud Platform, Business by design, SAP Qualtrics and SAP C4C with Azure AD using SAML." }, { - "category": "Security", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "4d0685ed-dce9-4be3-ab0d-db3b55fb2ec1", - "id": "E04.01", - "link": "https://learn.microsoft.com/azure/azure-arc/kubernetes/tutorial-akv-secrets-provider", + "category": "Identity and Access", + "checklist": "Azure Landing Zone Review", + "guid": "325ae525-ba34-4d46-a5e2-213ace7bb122", + "link": "https://learn.microsoft.com/azure/active-directory/saas-apps/sap-netweaver-tutorial", "services": [ - "Arc", - "AKS", - "AKV" + "SAP", + "Entra" ], "severity": "Medium", - "subcategory": "Secrets", - "text": "For applications that require access to sensitive information, use a service principal and the AKV Secrets Provider with the extension for Arc-enabled Kubernetes clusters.", - "waf": "Security" + "subcategory": "Identity", + "text": "Implement SSO to SAP NetWeaver-based web applications like SAP Fiori and SAP Web GUI by using SAML.", + "training": "https://learn.microsoft.com/training/modules/explore-identity-services/8-exercise-integrate-azure-active-directory-sap-netweaver" }, { - "category": "Security", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "4eeaa359-2829-4e2e-bb21-73676aff6791", - "id": "E05.01", - "link": "https://learn.microsoft.com/azure/aks/developer-best-practices-pod-security#secure-pod-access-to-resources", - "services": [], + "category": "Identity and Access", + "checklist": "Azure Landing Zone Review", + "guid": "9eb54dad-7861-4e1c-973a-f3bb003fc9c1", + "services": [ + "SAP", + "Entra" + ], "severity": "Medium", - "subcategory": "Workload", - "text": "Secure pod access to resources. Provide the least number of permissions, and avoid using root or privileged escalation.", - "waf": "Security" + "subcategory": "Identity", + "text": "Implement SSO to SAP NetWeaver-based web applications like SAP Fiori and SAP Web GUI by using SAML.", + "training": "https://learn.microsoft.com/training/modules/explore-identity-services/6-exercise-integrate-azure-active-directory-sap-fiori" }, { - "category": "Security", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "b4935ada-4232-44ec-b81c-123181a64174", - "id": "E05.02", - "link": "https://learn.microsoft.com/azure/governance/policy/concepts/policy-for-kubernetes#install-azure-policy-extension-for-azure-arc-enabled-kubernetes", + "category": "Identity and Access", + "checklist": "Azure Landing Zone Review", + "guid": "f29676ef-0c9c-4c4d-ab21-a55504c0c829", + "link": "https://learn.microsoft.com/azure/active-directory/saas-apps/sap-netweaver-tutorial", "services": [ - "AzurePolicy", - "Monitor" + "SAP", + "Entra" ], "severity": "Medium", - "subcategory": "Workload", - "text": "Monitor and enforce configuration by using the Azure Policy Extension.", - "waf": "Security" + "subcategory": "Identity", + "text": "You can implement SSO to SAP GUI by using SAP NetWeaver SSO or a partner solution.", + "training": "https://learn.microsoft.com/training/modules/explore-identity-services/8-exercise-integrate-azure-active-directory-sap-netweaver" }, { - "category": "Security", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "15833fb4-ae3c-42df-9431-66c3bcbe05bb", - "id": "E05.03", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-introduction", + "category": "Identity and Access", + "checklist": "Azure Landing Zone Review", + "guid": "23181aa4-1742-4694-9ff8-ae7d7d474317", "services": [ - "Defender" - ], - "severity": "High", - "subcategory": "Workload", - "text": "Scan your images for vulnerabilities with Microsoft Defender or any other image scanning solution.", - "waf": "Security" + "SAP", + "AKV", + "Entra" + ], + "severity": "Medium", + "subcategory": "Identity", + "text": "For SSO for SAP GUI and web browser access, implement SNC – Kerberos/SPNEGO (simple and protected GSSAPI negotiation mechanism) due to its ease of configuration and maintenance. For SSO with X.509 client certificates, consider the SAP Secure Login Server, which is a component of the SAP SSO solution.", + "training": "https://learn.microsoft.com/training/modules/explore-identity-services/9-exercise-integrate-active-directory-sap-single-sign-on" }, { - "category": "Security", - "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "e209d4a0-da57-4778-924d-216785d2fa56", - "id": "E05.04", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-private-link", + "category": "Identity and Access", + "checklist": "Azure Landing Zone Review", + "guid": "6c8bcbf4-5bbe-4609-b8a0-3e97778424d6", + "link": "https://blogs.sap.com/2017/07/12/sap-single-sign-on-protect-your-sap-landscape-with-x.509-certificates/", "services": [ - "ACR", - "Subscriptions" + "SAP", + "AKV", + "Entra" ], - "severity": "Low", - "subcategory": "Workload", - "text": "Deploy a dedicated and private instance of Azure Container Registry to each landing zone subscription.", - "waf": "Security" + "severity": "Medium", + "subcategory": "Identity", + "text": "For SSO for SAP GUI and web browser access, implement SNC – Kerberos/SPNEGO (simple and protected GSSAPI negotiation mechanism) due to its ease of configuration and maintenance. For SSO with X.509 client certificates, consider the SAP Secure Login Server, which is a component of the SAP SSO solution." }, { - "category": "Storage", - "checklist": "Azure Stack HCI Review", - "guid": "9f519499-5820-4060-88fe-cab4538c9dd0", - "id": "01.01.01", - "link": "https://learn.microsoft.com/windows-server/storage/storage-spaces/storage-spaces-direct-hardware-requirements", + "category": "Identity and Access", + "checklist": "Azure Landing Zone Review", + "guid": "16785d6f-a96c-496a-b885-18f482734c88", + "link": "https://learn.microsoft.com/azure/active-directory/saas-apps/sap-netweaver-tutorial#configure-sap-netweaver-for-oauth", "services": [ - "Storage" + "SAP", + "Entra" ], "severity": "Medium", - "subcategory": "Physical", - "text": "All planned storage pools should use direct-attached storage (SATA, SAS, NVMe)", - "waf": "Performance" + "subcategory": "Identity", + "text": "Implement SSO by using OAuth for SAP NetWeaver to allow third-party or custom applications to access SAP NetWeaver OData services." }, { - "category": "Storage", - "checklist": "Azure Stack HCI Review", - "guid": "f7c015e0-7d97-4283-b006-567afeb2b5ca", - "id": "01.01.02", - "link": "https://learn.microsoft.com/azure-stack/hci/concepts/drive-symmetry-considerations#understand-capacity-imbalance", + "category": "Identity and Access", + "checklist": "Azure Landing Zone Review", + "guid": "a747c350-8d4c-449c-93af-393dbca77c48", + "link": "https://learn.microsoft.com/azure/active-directory/saas-apps/saphana-tutorial", "services": [ - "ACR", - "Storage" + "SAP", + "Entra" ], "severity": "Medium", - "subcategory": "Physical", - "text": "Disks are symmetrical across all nodes", - "waf": "Performance" + "subcategory": "Identity", + "text": "Implement SSO to SAP HANA" }, { - "category": "Storage", - "checklist": "Azure Stack HCI Review", - "guid": "f785b143-2c1e-4466-9baa-dde8ba4c7aaa", - "id": "01.02.01", - "link": "https://learn.microsoft.com/azure-stack/hci/concepts/fault-tolerance#parity", + "category": "Identity and Access", + "checklist": "Azure Landing Zone Review", + "guid": "c7bae5bf-daf9-4761-9c56-f92891890aa4", + "link": "https://learn.microsoft.com/azure/sap/workloads/rise-integration#connectivity-with-sap-rise", "services": [ - "Backup", - "Storage" + "SAP", + "Entra" ], "severity": "Medium", - "subcategory": "S2D", - "text": "Parity type disk redundancy should only be used for low I/O volumes (backup/archive)", - "waf": "Performance" + "subcategory": "Identity", + "text": "Consider Azure AD an identity provider for SAP systems hosted on RISE. For more information, see Integrating the Service with Azure AD." }, { - "category": "Storage", - "checklist": "Azure Stack HCI Review", - "guid": "8a705965-9840-43cc-93b3-06d089406bb4", - "id": "01.02.02", - "link": "https://learn.microsoft.com/windows-server/storage/storage-spaces/storage-spaces-direct-hardware-requirements#physical-deployments", + "category": "Identity and Access", + "checklist": "Azure Landing Zone Review", + "guid": "e4e48226-ce54-44b6-bb6b-bfa15bd8f753", + "link": "https://github.com/azuredevcollege/SAP/blob/master/sap-oauth-saml-flow/README.md", "services": [ - "Storage" + "SAP", + "Entra" ], "severity": "Medium", - "subcategory": "S2D", - "text": "Ensure there at least 2 capacity disks with available capacity in the Storage Pool", - "waf": "Reliability" + "subcategory": "Identity", + "text": "For applications that access SAP, you might want to use principal propagation to establish SSO." }, { - "category": "Storage", - "checklist": "Azure Stack HCI Review", - "guid": "2a4f629a-d623-4610-a8e3-d6fd66057d8e", - "id": "01.02.03", - "link": "https://learn.microsoft.com/windows-server/storage/storage-spaces/delimit-volume-allocation", + "category": "Identity and Access", + "checklist": "Azure Landing Zone Review", + "guid": "59921095-4980-4fc1-a5b6-524a5a560c79", + "link": "https://learn.microsoft.com/azure/active-directory/saas-apps/sap-hana-cloud-platform-identity-authentication-tutorial", "services": [ - "Storage" + "SAP", + "Entra" ], - "severity": "Low", - "subcategory": "S2D", - "text": "'Delimited allocation' has been considered to improve volume resiliency in a multi-node failure", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "Identity", + "text": "If you're using SAP BTP services or SaaS solutions that require SAP Identity Authentication Service (IAS), consider implementing SSO between SAP Cloud Identity Authentication Services and Azure AD to access those SAP services. This integration lets SAP IAS act as a proxy identity provider and forwards authentication requests to Azure AD as the central user store and identity provider." }, { - "category": "Storage", - "checklist": "Azure Stack HCI Review", - "guid": "960eb9be-1f0f-4fc1-9b31-fcf1cf9e34e6", - "id": "01.02.04", - "link": "https://learn.microsoft.com/azure-stack/hci/concepts/plan-volumes#choosing-how-many-volumes-to-create", + "category": "Identity and Access", + "checklist": "Azure Landing Zone Review", + "guid": "a709c664-317e-41e4-9e34-67d9016a86f4", + "link": "https://learn.microsoft.com/azure/active-directory/saas-apps/sap-hana-cloud-platform-tutorial", "services": [ - "Storage" + "SAP", + "Entra" ], "severity": "Medium", - "subcategory": "S2D", - "text": "CSVs are created in multiples of node count", - "waf": "Performance" + "subcategory": "Identity", + "text": "Implement SSO to SAP BTP" }, { - "category": "Storage", - "checklist": "Azure Stack HCI Review", - "guid": "859ba2b9-a3a8-4ca1-bb61-165effbf1c03", - "id": "01.02.05", - "link": "https://learn.microsoft.com/azure-stack/hci/concepts/cache", + "category": "Identity and Access", + "checklist": "Azure Landing Zone Review", + "guid": "01f11b7f-38df-4251-9c76-4dec19abd3e8", + "link": "https://learn.microsoft.com/azure/active-directory/saas-apps/sap-successfactors-inbound-provisioning-cloud-only-tutorial", "services": [ - "Storage" + "SAP", + "Entra" ], "severity": "Medium", - "subcategory": "S2D", - "text": "If a cache tier is implemented, the number of capacity drives is a multiple of the number of cache drives", - "waf": "Performance" + "subcategory": "Identity", + "text": "If you're using SAP SuccessFactors, consider using the Azure AD automated user provisioning. With this integration, as you add new employees to SAP SuccessFactors, you can automatically create their user accounts in Azure AD. Optionally, you can create user accounts in Microsoft 365 or other SaaS applications that are supported by Azure AD. Use write-back of the email address to SAP SuccessFactors." }, { - "category": "Storage", - "checklist": "Azure Stack HCI Review", - "guid": "d8a65f05-db06-461d-81dc-7899ad3f8f1e", - "id": "01.02.06", - "link": "https://learn.microsoft.com/azure-stack/hci/concepts/plan-volumes#reserve-capacity", + "category": "Management Group and Subscriptions", + "checklist": "Azure Landing Zone Review", + "guid": "6ba28021-4591-4147-9e39-e5309cccd979", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/resource-org-management-groups", "services": [ - "Storage" + "SAP", + "Subscriptions", + "AzurePolicy" ], "severity": "Medium", - "subcategory": "S2D", - "text": "A minimum of 1 type of each disk type per node has been factored as a reserve disk", - "waf": "Reliability" + "subcategory": "Subscriptions", + "text": "enforce existing Management Group policies to SAP Subscriptions", + "training": "https://learn.microsoft.com/training/modules/enterprise-scale-organization/4-management-group-subscription-organization" }, { - "category": "Storage", - "checklist": "Azure Stack HCI Review", - "description": "VMFleet is a tool that can be used to measure the performance of a storage subsystem, best used to baseline performance prior to workload deployment", - "guid": "9d138f1d-5363-476e-bbd7-acfa500bdc0c", - "id": "01.02.07", - "link": "https://github.com/microsoft/diskspd/wiki/VMFleet", + "category": "Management Group and Subscriptions", + "checklist": "Azure Landing Zone Review", + "guid": "366bcda2-750a-4b1a-a039-d95d54c7c892", + "link": "https://learn.microsoft.com/azure/architecture/guide/sap/sap-whole-landscape", "services": [ - "Storage" + "SAP", + "Subscriptions" ], - "severity": "Low", - "subcategory": "S2D", - "text": "VMFleet has been run prior to workload deployment to baseline storage performance", - "waf": "Performance" + "severity": "High", + "subcategory": "Subscriptions", + "text": "Integrate tightly coupled applications into the same SAP subscription to avoid additional routing and management complexity", + "training": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/resource-org-subscriptions" }, { - "category": "Storage", - "checklist": "Azure Stack HCI Review", - "guid": "13c12e2a-c938-4dd1-9223-507d5e17f9c5", - "id": "01.03.01", + "category": "Management Group and Subscriptions", + "checklist": "Azure Landing Zone Review", + "guid": "9cb107d5-325a-4e52-9ba3-4d4685e2213a", + "link": "https://learn.microsoft.com/azure/architecture/guide/sap/sap-whole-landscape", "services": [ - "Storage" + "Subscriptions" ], - "severity": "Medium", - "subcategory": "Host OS", - "text": "OS drives use a dedicated storage controller", - "waf": "Reliability" + "severity": "High", + "subcategory": "Subscriptions", + "text": "Leverage Subscription as scale unit and scaling our resources, consider deploying subscription per environment eg. Sandbox, non-prod, prod ", + "training": "https://learn.microsoft.com/training/modules/configure-subscriptions/?source=recommendations" }, { - "category": "Storage", - "checklist": "Azure Stack HCI Review", - "guid": "a631e7dc-8879-45bd-b0a7-e5927b805428", - "id": "01.03.02", - "link": "https://learn.microsoft.com/azure-stack/hci/manage/use-csv-cache", + "category": "Management Group and Subscriptions", + "checklist": "Azure Landing Zone Review", + "guid": "ce7bb122-f7c9-45f0-9e15-4e3aa3592829", + "link": "https://learn.microsoft.com/azure/quotas/quotas-overview", "services": [ - "Storage" + "VM", + "Subscriptions" ], - "severity": "Medium", - "subcategory": "Host OS", - "text": "CSV in-memory read caching is enabled and properly configured", - "waf": "Performance" + "severity": "High", + "subcategory": "Subscriptions", + "text": "Ensure quota increase as a part of subscription provisioning (e.g. total available VM cores within a subscription)", + "training": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits" }, { - "category": "Networking", - "checklist": "Azure Stack HCI Review", - "guid": "c062cd9a-f1db-4f83-aab3-9cb03f56c140", - "id": "02.01.01", - "link": "https://learn.microsoft.com/azure-stack/hci/concepts/host-network-requirements#switch-embedded-teaming-set", + "category": "Management Group and Subscriptions", + "checklist": "Azure Landing Zone Review", + "guid": "ce4fab2f-433a-4d59-a5a9-3d1032e03ebc", + "link": "https://learn.microsoft.com/rest/api/reserved-vm-instances/quotaapi?branch=capacity", "services": [ - "ACR" + "Subscriptions" ], - "severity": "Medium", - "subcategory": "Host", - "text": "NICs are symmetrical across nodes", - "waf": "Reliability" + "severity": "Low", + "subcategory": "Subscriptions", + "text": "The Quota API is a REST API that you can use to view and manage quotas for Azure services. Consider using it if necessary." }, { - "category": "Networking", - "checklist": "Azure Stack HCI Review", - "guid": "ea8054db-a558-4533-80c8-5d9cf447ba19", - "id": "02.01.02", + "category": "Management Group and Subscriptions", + "checklist": "Azure Landing Zone Review", + "guid": "cbfad17b-f240-42bf-a1d8-f4f4cee661c8", + "link": "https://learn.microsoft.com/azure/quotas/quickstart-increase-quota-portal", "services": [ - "Storage" + "VM", + "Subscriptions" ], "severity": "High", - "subcategory": "Host", - "text": "Storage networking is redundant", - "waf": "Reliability" - }, - { - "category": "Networking", - "checklist": "Azure Stack HCI Review", - "guid": "15d976c5-e267-49a1-8b00-62010bfa5188", - "id": "02.01.03", - "link": "https://learn.microsoft.com/azure-stack/hci/deploy/network-atc", - "services": [], - "severity": "Medium", - "subcategory": "Host", - "text": "Host networking configuration is managed by Network ATC and intents are healthy", - "waf": "Reliability" + "subcategory": "Subscriptions", + "text": "If deploying to an availability zone, ensure that the VM's zone deployment is available once the quota has been approved. Submit a support request with the subscription, VM series, number of CPUs and availability zone required." }, { - "category": "Networking", - "checklist": "Azure Stack HCI Review", - "guid": "676c53ad-b29a-4de1-9d03-d7d2674405b8", - "id": "02.01.04", - "link": "https://learn.microsoft.com/azure-stack/hci/concepts/network-hud-overview", - "services": [], - "severity": "Low", - "subcategory": "Host", - "text": "Network HUD has been configured", - "waf": "Reliability" + "category": "Management Group and Subscriptions", + "checklist": "Azure Landing Zone Review", + "guid": "e6e20617-3686-4af4-9791-f8935ada4332", + "link": "https://azure.microsoft.com/explore/global-infrastructure/products-by-region/", + "services": [ + "Subscriptions" + ], + "severity": "High", + "subcategory": "Subscriptions", + "text": "Ensure required services and features are available within the chosen deployment regions eg. ANF , Zone etc.", + "training": "https://learn.microsoft.com/azure/cloud-adoption-framework/migrate/azure-best-practices/multiple-regions?source=recommendations" }, { - "category": "Networking", - "checklist": "Azure Stack HCI Review", - "guid": "8f6d58d9-6c1a-4ec1-b2d7-b2c6ba8f3949", - "id": "02.01.05", - "link": "https://learn.microsoft.com/azure-stack/hci/concepts/host-network-requirements", + "category": "Management Group and Subscriptions", + "checklist": "Azure Landing Zone Review", + "guid": "4e138115-2318-41aa-9174-26943ff8ae7d", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/sap/eslz-resource-organization", "services": [ - "Storage", - "VNet" + "TrafficManager", + "Cost", + "Subscriptions" ], "severity": "Medium", - "subcategory": "Host", - "text": "Storage NICs are assigned static IP addresses on separate subnets and VLANs", - "waf": "Reliability" + "subcategory": "Subscriptions", + "text": "Leverage Azure resource tag for cost categorization and resource grouping (: BillTo, Department (or Business Unit), Environment (Production, Stage, Development), Tier (Web Tier, Application Tier), Application Owner, ProjectName)", + "training": "https://learn.microsoft.com/training/paths/implement-resource-mgmt-security/" }, { - "category": "Networking", - "checklist": "Azure Stack HCI Review", - "guid": "824e53ec-953e-40c2-a6b8-52970b5b0f74", - "id": "02.01.06", - "link": "https://learn.microsoft.com/azure-stack/hci/plan/two-node-switched-converged", - "services": [], - "severity": "Medium", - "subcategory": "Host", - "text": "For switchless designs, dual link full mesh connectivity has been implemented", - "waf": "Reliability" + "category": "Management and Monitoring", + "checklist": "Azure Landing Zone Review", + "guid": "2f7c95f0-6e15-44e3-aa35-92829e6e2061", + "link": "https://learn.microsoft.com/azure/backup/sap-hana-database-about", + "services": [ + "Monitor", + "Backup" + ], + "severity": "High", + "subcategory": "BCDR", + "text": "Help protect your HANA database by using the Azure Backup service.", + "training": "https://learn.microsoft.com/training/modules/implement-azure-backup-sap-workloads-azure-virtual-machines/?source=recommendations" }, { - "category": "Networking", - "checklist": "Azure Stack HCI Review", - "guid": "dbc85d0e-0ebd-4589-a789-0fa8ceb1d0f0", - "id": "02.01.07", - "link": "https://learn.microsoft.com/azure-stack/hci/concepts/physical-network-requirements#using-switchless", + "category": "Management and Monitoring", + "checklist": "Azure Landing Zone Review", + "guid": "302a2fbf-3745-4a5f-a365-c9d1a16ca22c", + "link": "https://learn.microsoft.com/azure/azure-netapp-files/azacsnap-introduction", "services": [ - "Storage" + "Monitor", + "VM", + "Storage", + "Entra" ], "severity": "Medium", - "subcategory": "Host", - "text": "If the cluster is made up of more than 3 nodes, a switched storage network has been implemented", - "waf": "Reliability" + "subcategory": "BCDR", + "text": "If you deploy Azure NetApp Files for your HANA, Oracle, or DB2 database, use the Azure Application Consistent Snapshot tool (AzAcSnap) to take application-consistent snapshots. AzAcSnap also supports Oracle databases. Consider using AzAcSnap on a central VM rather than on individual VMs." }, { - "category": "Networking", - "checklist": "Azure Stack HCI Review", - "guid": "603c6d71-59d2-419c-a312-8edc6e799c6a", - "id": "02.01.08", + "category": "Management and Monitoring", + "checklist": "Azure Landing Zone Review", + "guid": "42d37218-a3a7-45df-bff6-1173e7f249ea", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/sap/eslz-management-and-monitoring", "services": [ - "Storage" + "Monitor", + "SAP" ], "severity": "High", - "subcategory": "Host", - "text": "RDMA is enabled on the Storage networking", - "waf": "Performance" - }, - { - "category": "Networking", - "checklist": "Azure Stack HCI Review", - "guid": "9e260eae-bca1-4827-a259-76ee63fda8d6", - "id": "02.01.09", - "link": "https://github.com/microsoft/SDN/blob/master/Diagnostics/Test-Rdma.ps1", - "services": [], - "severity": "Medium", - "subcategory": "Host", - "text": "Test-RDMA.ps1 has been run to validate the RDMA configuration", - "waf": "Performance" + "subcategory": "Management", + "text": "Ensure time-zone matches between the operating system and the SAP system." }, { - "category": "Networking", - "checklist": "Azure Stack HCI Review", - "description": "This ensures that Management traffic is not exposed to the VM traffic", - "guid": "abc85d0e-0ebd-4589-a777-0fa8ceb1d0f0", - "id": "02.01.10", - "link": "", + "category": "Management and Monitoring", + "checklist": "Azure Landing Zone Review", + "guid": "c3c7abc0-716c-4486-893c-40e181d65539", + "link": "https://learn.microsoft.com/azure/sap/workloads/high-availability-guide-rhel-multi-sid", "services": [ - "VM" + "Monitor", + "Entra" ], "severity": "Medium", - "subcategory": "Host", - "text": "If a VMSwitch is shared for Compute and Management traffic, require that Management traffic is tagged with a VLAN ID", - "waf": "Security" + "subcategory": "Management", + "text": "Don't group different application services in the same cluster. For example, don't combine DRBD and central services clusters on the same cluster. However, you can use the same Pacemaker cluster to manage approximately five different central services (multi-SID cluster).", + "training": "https://learn.microsoft.com/training/modules/implement-ha-sap-netweaver-anydb/?source=recommendations" }, { - "category": "Networking", - "checklist": "Azure Stack HCI Review", - "description": "This ensures you have at least 3 NCs active at all times during NC upgrades.", - "guid": "eb36f5f4-0fa7-4a2c-85f3-1b1c7c7817c0", - "id": "02.02.01", + "category": "Management and Monitoring", + "checklist": "Azure Landing Zone Review", + "guid": "a491dfc4-9353-4213-9217-eef0949f9467", + "link": "https://azure.microsoft.com/pricing/offers/dev-test/", "services": [ - "VM" + "Monitor", + "Cost" ], - "severity": "Medium", - "subcategory": "SDN", - "text": "There are at least 3 Network Controller VMs deployed", - "waf": "Reliability" + "severity": "Low", + "subcategory": "Management", + "text": "Consider running dev/test systems in a snooze model to save and optimize Azure run costs." }, { - "category": "Networking", - "checklist": "Azure Stack HCI Review", - "guid": "8bc78c85-6028-4a43-af2d-082a0a344909", - "id": "02.02.02", - "link": "https://learn.microsoft.com/windows-server/networking/sdn/manage/update-backup-restore", + "category": "Management and Monitoring", + "checklist": "Azure Landing Zone Review", + "guid": "b7056168-6199-4732-a514-cdbb2d5c9c54", + "link": "https://learn.microsoft.com/azure/lighthouse/overview", "services": [ - "Backup" + "Monitor", + "SAP", + "Entra" ], - "severity": "High", - "subcategory": "SDN", - "text": "Backups of SDN infrastructure are configured and tested", - "waf": "Operations" + "severity": "Medium", + "subcategory": "Management", + "text": "If you partner with customers by managing their SAP estates, consider Azure Lighthouse. Azure Lighthouse allows managed service providers to use Azure native identity services to authenticate to the customers' environment. It puts the control in the hands of customers, because they can revoke access at any time and audit service providers' actions." }, { "category": "Management and Monitoring", - "checklist": "Azure Stack HCI Review", - "guid": "51eaa4b6-b9a7-43e1-a7dc-634d3107bc6d", - "id": "03.01.01", + "checklist": "Azure Landing Zone Review", + "guid": "4d116785-d2fa-456c-96ad-48408fe72734", + "link": "https://learn.microsoft.com/azure/update-manager/scheduled-patching?tabs=schedule-updates-single-machine%2Cschedule-updates-scale-overview", "services": [ - "Monitor" + "Monitor", + "VM" ], "severity": "Medium", - "subcategory": "Cluster", - "text": "SCOM Managed Instance has been considered for more complex monitoring and alerting scenarios", - "waf": "Operations" + "subcategory": "Management", + "text": "Use Azure Update Manager to check the status of available updates for a single VM or multiple VMs and consider scheduling regular patching.", + "training": "https://learn.microsoft.com/training/modules/keep-your-virtual-machines-updated/?source=recommendations" }, { "category": "Management and Monitoring", - "checklist": "Azure Stack HCI Review", - "guid": "831f5aca-99ef-41e7-8263-9509f5093b43", - "id": "03.01.02", - "link": "https://learn.microsoft.com/azure-stack/hci/manage/setup-hci-system-alerts", + "checklist": "Azure Landing Zone Review", + "guid": "76c8bcbf-45bb-4e60-ad8a-03e97778424d", + "link": "https://learn.microsoft.com/azure/sap/workloads/lama-installation", "services": [ - "Monitor" + "Monitor", + "SAP" ], - "severity": "High", - "subcategory": "Cluster", - "text": "Alerts have been configured for the cluster, either using Azure Monitor, SCOM, or a third-party solution", - "waf": "Operations" + "severity": "Low", + "subcategory": "Management", + "text": "Optimize and manage SAP Basis operations by using SAP Landscape Management (LaMa). Use the SAP LaMa connector for Azure to relocate, copy, clone, and refresh SAP systems.", + "training": "https://learn.microsoft.com/training/modules/explore-azure-remote-management/?source=recommendations" }, { "category": "Management and Monitoring", - "checklist": "Azure Stack HCI Review", - "guid": "f95d0e7e-9f61-476d-bf65-59f2454d1d39", - "id": "03.01.03", - "link": "https://learn.microsoft.com/azure-stack/hci/manage/monitor-hci-single?tabs=22h2-and-later", + "checklist": "Azure Landing Zone Review", + "guid": "14591147-5e39-4e53-89cc-cd979366bcda", + "link": "https://learn.microsoft.com/azure/sap/monitor/about-azure-monitor-sap-solutions", "services": [ - "Monitor" + "Monitor", + "SAP", + "SQL" ], "severity": "Medium", - "subcategory": "Cluster", - "text": "Insights has been enabled at the cluster level and all nodes are reporting data", - "waf": "Operations" + "subcategory": "Monitoring", + "text": "Use Azure Monitor for SAP solutions to monitor your SAP workloads(SAP HANA, high-availability SUSE clusters, and SQL systems) on Azure. Consider supplementing Azure Monitor for SAP solutions with SAP Solution Manager.", + "training": "https://learn.microsoft.com/training/modules/implement-azure-monitoring-sap-workloads-azure-virtual-machines/?source=recommendations" }, { "category": "Management and Monitoring", - "checklist": "Azure Stack HCI Review", - "guid": "f4250fcb-ff53-40c9-b304-3560464fd90c", - "id": "03.01.04", - "link": "https://learn.microsoft.com/azure-stack/hci/manage/monitor-hci-single?tabs=22h2-and-later", + "checklist": "Azure Landing Zone Review", + "guid": "2750ab1a-b039-4d95-b54c-7c8929cb107d", + "link": "https://learn.microsoft.com/azure/sap/workloads/vm-extension-for-sap", "services": [ - "Monitor" + "Monitor", + "VM", + "SAP", + "Entra" ], - "severity": "Medium", - "subcategory": "Cluster", - "text": "Azure Monitoring Agent has been deployed to hosts and an appropriate Data Collection Rule has been configured", - "waf": "Operations" + "severity": "High", + "subcategory": "Monitoring", + "text": "Run a VM Extension for SAP check. VM Extension for SAP uses the assigned managed identity of a virtual machine (VM) to access VM monitoring and configuration data. The check ensures that all performance metrics in your SAP application come from the underlying Azure Extension for SAP.", + "training": "https://learn.microsoft.com/training/modules/configure-azure-enhanced-monitoring-extension-for-sap/?source=recommendations" }, { "category": "Management and Monitoring", - "checklist": "Azure Stack HCI Review", - "guid": "6143af1d-0d1a-4163-b1c9-662f7459bb98", - "id": "03.02.01", + "checklist": "Azure Landing Zone Review", + "guid": "5325ae52-5ba3-44d4-985e-2213ace7bb12", + "link": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", "services": [ - "Monitor" + "Monitor", + "AzurePolicy" ], "severity": "Medium", - "subcategory": "Hardware", - "text": "Relevant hardware monitoring has been configured", - "waf": "Operations" + "subcategory": "Monitoring", + "text": "Use Azure Policy for access control and compliance reporting. Azure Policy provides the ability to enforce organization-wide settings to ensure consistent policy adherence and fast violation detection. ", + "training": "https://learn.microsoft.com/learn/paths/architect-infrastructure-operations/" }, { "category": "Management and Monitoring", - "checklist": "Azure Stack HCI Review", - "guid": "9cbdf225-549a-41cf-9c97-794766a6f2b0", - "id": "03.02.02", - "link": "https://learn.microsoft.com/azure-stack/hci/manage/health-service-overview", + "checklist": "Azure Landing Zone Review", + "guid": "523181aa-4174-4269-93ff-8ae7d7d47431", + "link": "https://learn.microsoft.com/azure/network-watcher/connection-monitor-overview", "services": [ - "Monitor" + "Monitor", + "NetworkWatcher", + "SAP" ], "severity": "Medium", - "subcategory": "Hardware", - "text": "Relevant hardware alerting has been configured", - "waf": "Operations" - }, - { - "category": "Operations", - "checklist": "Azure Stack HCI Review", - "guid": "c0da5bbd-0f0d-4a26-98ec-38c9cc42b323", - "id": "04.01.01", - "services": [ - "VM" - ], - "severity": "Low", - "subcategory": "VM Management - Resource Bridge", - "text": "The Azure CLI has been installed on every node to enable RB management from WAC", - "waf": "Operations" + "subcategory": "Monitoring", + "text": "Use Connection Monitor in Azure Network Watcher to monitor latency metrics for SAP databases and application servers. Or collect and display network latency measurements by using Azure Monitor.", + "training": "https://techcommunity.microsoft.com/t5/running-sap-applications-on-the/collecting-and-displaying-niping-network-latency-measurements/ba-p/1833979" }, { - "category": "Networking", - "checklist": "Azure Stack HCI Review", - "guid": "a8ecf23c-c048-4fa9-b87b-51ebfb409863", - "id": "04.01.02", + "category": "Management and Monitoring", + "checklist": "Azure Landing Zone Review", + "guid": "d89fd98d-23e4-4b40-a92e-32db9365522c", + "link": "https://learn.microsoft.com/azure/site-recovery/site-recovery-monitor-and-troubleshoot", "services": [ - "VM" + "Monitor", + "ASR", + "SAP" ], - "severity": "Low", - "subcategory": "VM Management - Resource Bridge", - "text": "DHCP is available in the cluster to support Guest Configuration at VM deployment from Azure", - "waf": "Operations" + "severity": "High", + "subcategory": "Monitoring", + "text": "Use Azure Site Recovery monitoring to maintain the health of the disaster recovery service for SAP application servers.", + "training": "https://learn.microsoft.com/training/modules/protect-on-premises-infrastructure-with-azure-site-recovery/?source=recommendations" }, { - "category": "Backup and Disaster Recovery", - "checklist": "Azure Stack HCI Review", - "guid": "074541e3-fe08-458a-8062-32d13dcc10c6", - "id": "05.01.01", - "link": "https://learn.microsoft.com/azure/backup/back-up-azure-stack-hyperconverged-infrastructure-virtual-machines", + "category": "Management and Monitoring", + "checklist": "Azure Landing Zone Review", + "guid": "73686af4-6791-4f89-95ad-a43324e13811", + "link": "https://github.com/Azure/SAP-on-Azure-Scripts-and-Utilities/tree/main/QualityCheck", "services": [ - "Backup", + "Monitor", "VM", - "ASR" + "SAP" ], - "severity": "High", - "subcategory": "VM", - "text": "Backups of HCI VMs have been configured using MABS or a third-party solution", - "waf": "Operations" - }, - { - "category": "Operations", - "checklist": "Azure Stack HCI Review", - "guid": "48f7ae57-1035-4101-8a38-fbe163d03e8a", - "id": "06.01.01", - "services": [], - "severity": "High", - "subcategory": "Cluster Configuration", - "text": "Cluster configuration or a configuration script has been documented and maintained", - "waf": "Operations" - }, - { - "category": "Operations", - "checklist": "Azure Stack HCI Review", - "guid": "f2a6a19a-ffe6-444d-badb-cb336c8e7b50", - "id": "06.01.02", - "link": "https://learn.microsoft.com/azure-stack/hci/manage/witness", - "services": [], - "severity": "High", - "subcategory": "Cluster Configuration", - "text": "A cluster witness has been configured for clusters with less than 5 nodes", - "waf": "Reliability" - }, - { - "category": "Operations", - "checklist": "Azure Stack HCI Review", - "guid": "a47339fe-62c5-44a0-bb83-3d46ef16292f", - "id": "06.01.03", - "link": "https://learn.microsoft.com/azure-stack/hci/manage/update-cluster", - "services": [], "severity": "Medium", - "subcategory": "Cluster Configuration", - "text": "Cluster-Aware Updating has been configured for Windows and hardware updates (if available)", - "waf": "Operations" + "subcategory": "Monitoring", + "text": "Perform a quality check for SAP HANA on the provisioned Azure infrastructure to verify that provisioned VMs comply with SAP HANA on Azure best practices." }, { - "category": "Operations", - "checklist": "Azure Stack HCI Review", - "guid": "7f1d6fe8-3079-44ea-8ea6-14494d1aa470", - "id": "06.01.04", - "link": "https://learn.microsoft.com/azure-stack/hci/deploy/validate", - "services": [], + "category": "Management and Monitoring", + "checklist": "Azure Landing Zone Review", + "guid": "616785d6-fa96-4c96-ad88-518f482734c8", + "link": "https://learn.microsoft.com/azure/sap/workloads/high-availability-zones", + "services": [ + "Monitor", + "SAP", + "Subscriptions" + ], "severity": "High", - "subcategory": "Cluster Configuration", - "text": "Cluster validation has been run against the configured cluster", - "waf": "Reliability" + "subcategory": "Monitoring", + "text": "For each Azure subscription, run a latency test on Azure availability zones before zonal deployment to choose low-latency zones for deployment of SAP on Azure.", + "training": "https://github.com/Azure/SAP-on-Azure-Scripts-and-Utilities/tree/main/AvZone-Latency-Test" }, { - "category": "Operations", - "checklist": "Azure Stack HCI Review", - "guid": "81693af0-5638-4aa2-a153-1d6189df30a7", - "id": "06.01.05", - "link": "https://learn.microsoft.com/azure-stack/hci/manage/azure-benefits", + "category": "Management and Monitoring", + "checklist": "Azure Landing Zone Review", + "guid": "410adcba-db46-424f-a6c4-05ecde75c52e", + "link": "https://learn.microsoft.com/azure/advisor/advisor-how-to-improve-reliability", "services": [ - "VM" + "Monitor", + "ASR", + "Storage" ], "severity": "Medium", - "subcategory": "Cluster Configuration", - "text": "Azure Benefits has been enabled at the cluster and VM levels", - "waf": "Cost" - }, - { - "category": "Operations", - "checklist": "Azure Stack HCI Review", - "guid": "8c967ee8-8170-4537-a28d-33431cd3632a", - "id": "06.01.06", - "link": "https://learn.microsoft.com/azure-stack/hci/manage/use-environment-checker", - "services": [], - "severity": "Medium", - "subcategory": "Cluster Configuration", - "text": "The Environment Checker module has been run to validate the environment", - "waf": "Reliability" + "subcategory": "Monitoring", + "text": "Run the Resiliency Report to ensure that the configuration of the entire provisioned Azure infrastructure (Compute, Database, Networking, Storage, Site Recovery) complies with the configuration defined by Cloud Adaption Framework for Azure.", + "training": "https://learn.microsoft.com/training/paths/azure-well-architected-framework/" }, { - "category": "Operations", - "checklist": "Azure Stack HCI Review", - "guid": "43ffbfab-766e-4950-a102-78b479136e4d", - "id": "06.02.01", - "link": "https://learn.microsoft.com/azure-stack/hci/manage/azure-benefits", + "category": "Management and Monitoring", + "checklist": "Azure Landing Zone Review", + "guid": "86ba2802-1459-4114-95e3-9e5309cccd97", + "link": "https://learn.microsoft.com/azure/sentinel/sap/deployment-overview", "services": [ - "AzurePolicy" + "Monitor", + "SAP", + "Sentinel" ], "severity": "Medium", - "subcategory": "Cluster Configuration", - "text": "Group Policy inheritance on the HCI cluster and node Active Directory organizational unit has been blocked or applied policies have been evaluated for compatibility issues (usually WinRM and PowerShell execution policy)", - "waf": "Operations" - }, - { - "category": "Operations", - "checklist": "Azure Stack HCI Review", - "guid": "e6a3f3a7-4a7d-49e2-985a-6e39dd284027", - "id": "06.02.02", - "services": [], - "severity": "Medium", - "subcategory": "Cluster Configuration", - "text": "WAC is on the latest release and configured to automatically upgrade extensions", - "waf": "Reliability" + "subcategory": "Monitoring", + "text": "Implement threat protection by using the Microsoft Sentinel solution for SAP. Use this solution to monitor your SAP systems and detect sophisticated threats throughout the business logic and application layers.", + "training": "https://learn.microsoft.com/training/modules/plan-microsoft-sentinel-deployment-sap/?source=recommendations" }, { - "category": "Networking", - "checklist": "Azure Stack HCI Review", - "guid": "d1caa31f-cc26-42b2-b92f-2b667c0e6020", - "id": "07.01.01", - "link": "https://learn.microsoft.com/azure/architecture/hybrid/azure-stack-hci-dr", + "category": "Management and Monitoring", + "checklist": "Azure Landing Zone Review", + "guid": "579266bc-ca27-45fa-a1ab-fe9d55d04c3c", + "link": "https://learn.microsoft.com/azure/cost-management-billing/costs/enable-tag-inheritance", "services": [ - "Entra" + "Monitor", + "Cost" ], "severity": "Medium", - "subcategory": "Stretch Clustering", - "text": "There is sub 5ms latency between each site if synchronous replication is being configured AAD", - "waf": "Performance" + "subcategory": "Monitoring", + "text": "Azure tagging can be leveraged to logically group and track resources, automate their deployments, and most importantly, provide visibility on the incurred costs.", + "training": "https://learn.microsoft.com/training/modules/analyze-costs-create-budgets-azure-cost-management/?source=recommendations" }, { - "category": "Networking", - "checklist": "Azure Stack HCI Review", - "guid": "3277558e-3155-4088-b49a-78594cb4ce1a", - "id": "07.01.02", + "category": "Management and Monitoring", + "checklist": "Azure Landing Zone Review", + "guid": "04b8e5e5-13cb-4b22-af62-5a8ecfcf0337", + "link": "https://learn.microsoft.com/azure/virtual-network/virtual-network-test-latency?tabs=windows", "services": [ - "Storage", - "VNet" + "Monitor", + "VM" ], - "severity": "High", - "subcategory": "Stretch Clustering", - "text": "Management, Replication and Storage networks excluded from stretched VLANs configurations, are routed, and in different subnets", - "waf": "Reliability" - }, - { - "category": "Operations", - "checklist": "Azure Stack HCI Review", - "guid": "baed6066-8531-44ba-bd94-38cbabbf4099", - "id": "07.02.01", - "services": [], - "severity": "High", - "subcategory": "Stretch Clustering", - "text": "There is a plan detailed for site failure and recovery", - "waf": "Operations" + "severity": "Low", + "subcategory": "Performance", + "text": "Use inter-VM latency monitoring for latency-sensitive applications." }, { - "category": "Networking", - "checklist": "Azure Stack HCI Review", - "guid": "8e62945f-b9ac-4a5c-a4e4-836f527010b4", - "id": "07.02.02", + "category": "Management and Monitoring", + "checklist": "Azure Landing Zone Review", + "guid": "07e5ed53-3d96-43d8-87ea-631b77da5aba", + "link": "https://learn.microsoft.com/azure/sap/workloads/planning-guide-storage", "services": [ - "ACR" + "Monitor", + "ASR", + "SAP" ], "severity": "Medium", - "subcategory": "Stretch Clustering", - "text": "Separate vLANs and networks are used for each replication network across both sites", - "waf": "Reliability" + "subcategory": "Performance", + "text": "Use Azure Site Recovery monitoring to maintain the health of the disaster recovery service for SAP application servers.", + "training": "https://learn.microsoft.com/training/modules/explore-azure-storage/?source=recommendations" }, { - "category": "Operations", - "checklist": "Azure Stack HCI Review", - "guid": "8e62945f-b9ac-4a5c-a4e4-836f527010b5", - "id": "07.02.03", - "link": "https://learn.microsoft.com/azure/architecture/hybrid/azure-stack-hci-dr#cost-optimization", + "category": "Management and Monitoring", + "checklist": "Azure Landing Zone Review", + "guid": "abb6af9c-982c-4cf1-83fb-329fafd1ee56", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/sap/eslz-management-and-monitoring", "services": [ + "Monitor", + "SAP", "Storage" ], - "severity": "High", - "subcategory": "Stretch Clustering", - "text": "Use either a cloud witness or a file share witness in a third site for cluster quorum for clusters with less than 5 nodes", - "waf": "Reliability" - }, - { - "category": "Operations", - "checklist": "Azure Stack HCI Review", - "guid": "8e62945f-b9ac-4a5c-a4e4-836f527010b6", - "id": "07.02.04", - "link": "https://learn.microsoft.com/azure/architecture/hybrid/azure-stack-hci-dr#cost-optimization", - "services": [], - "severity": "High", - "subcategory": "Stretch Clustering", - "text": "When using data deduplication, only enable it on the primary/source volumes", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "Performance", + "text": "Exclude all the database file systems and executable programs from antivirus scans. Including them could lead to performance problems. Check with the database vendors for prescriptive details on the exclusion list. For example, Oracle recommends excluding /oracle//sapdata from antivirus scans." }, { - "category": "Operations", - "checklist": "Azure Stack HCI Review", - "guid": "ac527887-f6f4-40a3-b883-e04d704f013b", - "id": "07.02.04", - "link": "https://learn.microsoft.com/windows-server/storage/storage-replica/stretch-cluster-replication-using-shared-storage#provision-operating-system-features-roles-storage-and-network", + "category": "Management and Monitoring", + "checklist": "Azure Landing Zone Review", + "guid": "c027f893-f404-41a9-b33d-39d625a14964", + "link": "https://sapit-forme-prod.authentication.eu11.hana.ondemand.com/login", "services": [ - "Storage" + "Monitor", + "SAP" ], - "severity": "High", - "subcategory": "Stretch Clustering", - "text": "Storage backing log volumes must be faster (ideally) or at least as fast as capacity storage", - "waf": "Reliability" + "severity": "Low", + "subcategory": "Performance", + "text": "Consider collecting full database statistics for non-HANA databases after migration. For example, implement SAP note 1020260 - Delivery of Oracle statistics." }, { - "category": "Backup and Disaster Recovery", - "checklist": "Azure Stack HCI Review", - "guid": "8ea49f70-1038-4283-b0c4-230165d3eabc", - "id": "08.01.01", - "link": "https://learn.microsoft.com/azure-stack/hci/manage/azure-site-recovery", + "category": "Management and Monitoring", + "checklist": "Azure Landing Zone Review", + "guid": "fdafb1f5-3eee-4354-a8c9-deb8127ebc2e", + "link": "https://learn.microsoft.com/azure/virtual-machines/workloads/oracle/configure-oracle-asm", "services": [ - "ASR", - "Backup" + "Monitor", + "SAP", + "Storage" ], "severity": "Medium", - "subcategory": "Disaster Recovery", - "text": "Azure Site Recovery has been considered for DR purposes", - "waf": "Operations" - }, - { - "category": "Security", - "checklist": "Azure Stack HCI Review", - "guid": "03e65fdc-2628-4a1a-ba2e-a5174340ba52", - "id": "09.01.01", - "link": "https://learn.microsoft.com/windows/security/operating-system-security/data-protection/bitlocker/protecting-cluster-shared-volumes-and-storage-area-networks-with-bitlocker", - "services": [], - "severity": "Medium", - "subcategory": "Host", - "text": "BitLocker has been enabled on CSVs for volume encryption, where appropriate", - "waf": "Security" - }, - { - "category": "Security", - "checklist": "Azure Stack HCI Review", - "guid": "9645d2e6-ba28-453c-b6d5-d9ef29fc34be", - "id": "09.01.02", - "link": "https://learn.microsoft.com/windows-server/storage/file-server/smb-security", - "services": [], - "severity": "Medium", - "subcategory": "Host", - "text": "SMB encryption has been enabled, where appropriate", - "waf": "Security" + "subcategory": "Performance", + "text": "Consider using Oracle Automatic Storage Management (ASM) for all Oracle deployments that use SAP on Azure.", + "training": "https://learn.microsoft.com/training/paths/administer-infrastructure-resources-in-azure/?source=recommendations" }, { - "category": "Security", - "checklist": "Azure Stack HCI Review", - "guid": "8f03437a-5068-4486-9a78-0402ce771298", - "id": "09.01.03", - "link": "https://learn.microsoft.com/microsoft-365/security/defender-endpoint/microsoft-defender-antivirus-on-windows-server", + "category": "Management and Monitoring", + "checklist": "Azure Landing Zone Review", + "guid": "33c5d5bf-daf3-4f0d-bd50-6010fdcec22e", + "link": "https://techcommunity.microsoft.com/t5/running-sap-applications-on-the/announcement-sap-on-azure-oracle-performance-efficiency-scripts/ba-p/3725178", "services": [ - "Defender" + "Monitor", + "SAP", + "SQL" ], "severity": "Medium", - "subcategory": "Host", - "text": "Microsoft Defender Antivirus has been enabled on all nodes", - "waf": "Security" + "subcategory": "Performance", + "text": "For SAP on Azure running Oracle, a collection of SQL scripts can help you diagnose performance problems. Automatic Workload Repository (AWR) reports contain valuable information for diagnosing problems in the Oracle system. We recommend that you run an AWR report during several sessions and choose peak times for it, to ensure broad coverage for the analysis.", + "training": "https://learn.microsoft.com/ja-jp/azure/well-architected/oracle-iaas/performance-efficiency" }, { - "category": "Security", - "checklist": "Azure Stack HCI Review", - "guid": "dba6b211-fc02-43b3-b7c8-f163c188332e", - "id": "09.01.04", - "link": "https://learn.microsoft.com/windows/security/identity-protection/credential-guard/credential-guard-manage", - "services": [], + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "5ba34d46-85e2-4213-ace7-bb122f7c95f0", + "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", + "services": [ + "AzurePolicy", + "WAF", + "AppGW" + ], "severity": "Medium", - "subcategory": "Host", - "text": "Credential Guard has been configured, where appropriate", - "waf": "Security" + "subcategory": "App delivery", + "text": "For secure delivery of HTTP/S apps, use Application Gateway v2 and ensure that WAF protection and policies are enabled.", + "training": "https://learn.microsoft.com/training/modules/introduction-azure-web-application-firewall/" }, { - "category": "Cleanup", - "checklist": "Cost Optimization Checklist", - "guid": "a95b86ad-8840-48e3-9273-4b875ba18f20", - "id": "A01.01", - "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/considerations/tenancy-models", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "fa9d30bc-1b82-4e4b-bfdf-6b017938b9e6", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/sap/eslz-network-topology-and-connectivity", "services": [ - "Monitor", - "Cost" + "VM", + "SAP", + "DNS" ], - "subcategory": "Azure Monitor - enforce data collection rules", - "text": "Data collection rules in Azure Monitor -https://learn.microsoft.com/azure/azure-monitor/essentials/data-collection-rule-overview", - "training": "https://azure.microsoft.com/pricing/reservations/" + "severity": "Medium", + "subcategory": "DNS", + "text": "If the virtual machine's DNS or virtual name is not changed during migration to Azure, Background DNS and virtual names connect many system interfaces in the SAP landscape, and customers are only sometimes aware of the interfaces that developers define over time. Connection challenges arise between various systems when virtual or DNS names change after migrations, and it's recommended to retain DNS aliases to prevent these types of difficulties.", + "training": "https://learn.microsoft.com/training/modules/explore-azure-networking/4-explore-name-resolution" }, { - "category": "Cleanup", - "checklist": "Cost Optimization Checklist", - "guid": "45901365-d38e-443f-abcb-d868266abca2", - "id": "A02.01", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/multi-tenant/automation", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "a2858f78-105b-4f52-b7a9-5b0f4439743b", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/sap/eslz-network-topology-and-connectivity", "services": [ - "Backup", - "Cost" + "VNet", + "SAP", + "DNS" ], - "subcategory": "Backup", - "text": "check backup instances with the underlying datasource not found" + "severity": "Medium", + "subcategory": "DNS", + "text": "Use different DNS zones to distinguish each environment (sandbox, development, preproduction, and production) from each other. The exception is for SAP deployments with their own VNet; here, private DNS zones might not be necessary.", + "training": "https://learn.microsoft.com/training/modules/explore-azure-networking/4-explore-name-resolution" }, { - "category": "Cleanup", - "checklist": "Cost Optimization Checklist", - "guid": "64f9a19a-f29c-495d-94c6-c7919ca0f6c5", - "id": "A03.01", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/multi-tenant/lighthouse", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "a3592829-e6e2-4061-9368-6af46791f893", + "link": "https://learn.microsoft.com/azure/virtual-network/virtual-network-peering-overview", "services": [ - "Cost" + "ACR", + "VNet", + "SAP" ], - "subcategory": "delete/archive", - "text": "delete or archive unassociated services (disks, nics, ip addresses etc)" + "severity": "Medium", + "subcategory": "Hybrid", + "text": "Local and global VNet peering provide connectivity and are the preferred approaches to ensure connectivity between landing zones for SAP deployments across multiple Azure regions", + "training": "https://learn.microsoft.com/training/modules/configure-vnet-peering/?source=recommendations" }, { - "category": "Cleanup", - "checklist": "Cost Optimization Checklist", - "guid": "659d3958-fd77-4289-a835-556df2bfe456", - "id": "A03.02", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "41742694-3ff8-4ae7-b7d4-743176c8bcbf", + "link": "https://learn.microsoft.com/azure/sap/workloads/planning-guide", "services": [ - "Cost" + "NVA", + "SAP" ], - "subcategory": "delete/archive", - "text": "consider snooze and stop technique (snooze a service after x days, stop after 2x, delete/deallocate after 3x)" + "severity": "High", + "subcategory": "Hybrid", + "text": "It is not supported to deploy any NVA between SAP application and SAP Database server", + "training": "https://me.sap.com/notes/2731110" }, { - "category": "Cleanup", - "checklist": "Cost Optimization Checklist", - "guid": "3b0d834a-3487-426d-b69c-6b5c2a26494b", - "id": "A03.03", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "7d4bc7d2-c34a-452e-8f1d-6ae3c8eafcc3", + "link": "https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/?source=recommendations", "services": [ - "Backup", - "Storage", - "Cost" + "ACR", + "VWAN", + "SAP" ], - "subcategory": "delete/archive", - "text": "delete or archive unused resources (old backups, logs, storage accounts, etc...)" + "severity": "Medium", + "subcategory": "Hybrid", + "text": "Use Virtual WAN for Azure deployments in new, large, or global networks where you need global transit connectivity across Azure regions and on-premises locations. With this approach, you won't need to manually set up transitive routing for Azure networking, and you can follow a standard for SAP on Azure deployments.", + "training": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-about" }, { - "category": "Cleanup", - "checklist": "Cost Optimization Checklist", - "guid": "69bad37a-ad53-4cc7-ae1d-76667357c449", - "id": "A03.04", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "0cedb1f6-ae6c-492b-8b17-8061f50b16d3", + "link": "https://learn.microsoft.com/azure/well-architected/services/networking/network-virtual-appliances/reliability", "services": [ - "Backup", - "ASR", - "Storage", - "Cost" + "NVA", + "VNet" ], - "subcategory": "delete/archive", - "text": "consider a good balance between site recovery storage and backup for non mission critical applications" + "severity": "Medium", + "subcategory": "Hybrid", + "text": "Consider deploying network virtual appliances (NVAs) between regions only if partner NVAs are used. NVAs between regions or VNets aren't required if native NVAs are present. When you're deploying partner networking technologies and NVAs, follow the vendor's guidance to verify conflicting configurations with Azure networking.", + "training": "https://learn.microsoft.com/training/modules/control-network-traffic-flow-with-routes/?source=recommendations" }, { - "category": "Cleanup", - "checklist": "Cost Optimization Checklist", - "guid": "674b5ed8-5a85-49c7-933b-e2a1a27b765a", - "id": "A04.01", - "link": "https://learn.microsoft.com/azure/cost-management-billing/manage/direct-ea-administration#manage-notification-contacts", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "facc08c6-ea95-4641-91cd-fa09e573adbd", + "link": "https://learn.microsoft.com/azure/architecture/networking/hub-spoke-vwan-architecture", "services": [ - "Monitor", - "Cost" + "NVA", + "VNet", + "VWAN", + "SAP" ], - "subcategory": "Log Analytics retention for workspaces", - "text": "check spending and savings opportunities among the 40 different log analytics workspaces- use different retention and data collection for nonprod workspaces-create daily cap for awareness and tier sizing - If you do set a daily cap, in addition to creating an alert when the cap is reached,ensure that you also create an alert rule to be notified when some percentage has been reached (90% for example). - consider workspace transformation if possible - https://learn.microsoft.com/azure/azure-monitor/essentials/data-collection-transformations#workspace-transformation-dcr ", - "training": "https://learn.microsoft.com/azure/cost-management-billing/costs/understand-work-scopes" + "severity": "Medium", + "subcategory": "Hybrid", + "text": "Virtual WAN manages connectivity between spoke VNets for virtual-WAN-based topologies (no need to set up user-defined routing [UDR] or NVAs), and maximum network throughput for VNet-to-VNet traffic in the same virtual hub is 50 gigabits per second. If necessary, SAP landing zones can use VNet peering to connect to other landing zones and overcome this bandwidth limitation.", + "training": "https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/?source=recommendations" }, { - "category": "Cleanup", - "checklist": "Cost Optimization Checklist", - "guid": "91be1f38-8ef3-494c-8bd4-63cbbac75819", - "id": "A05.01", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-enterprise-agreement#design-considerations", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "82734c88-6ba2-4802-8459-11475e39e530", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing", "services": [ - "AzurePolicy", - "Storage", - "Cost" + "VM", + "VNet", + "SAP" ], - "subcategory": "Policy", - "text": "enforce a purging log policy and automation (if needed, logs can be moved to cold storage)", - "training": "https://www.youtube.com/watch?v=nHQYcYGKuyw" + "severity": "High", + "subcategory": "IP plan", + "text": "Public I.P assignment to VM running SAP Workload is not recommended.", + "training": "https://learn.microsoft.com/training/modules/design-ip-addressing-for-azure/?source=recommendations" }, { - "category": "Cleanup", - "checklist": "Cost Optimization Checklist", - "guid": "59bb91a3-ed90-4cae-8cc8-4c37b6b780cb", - "id": "A06.01", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-enterprise-agreement#design-considerations", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "9cccd979-366b-4cda-8750-ab1ab039d95d", + "link": "https://learn.microsoft.com/training/modules/protect-on-premises-infrastructure-with-azure-site-recovery/?source=recommendations", "services": [ - "Cost" + "VNet", + "ASR" ], - "subcategory": "run orphaned resources workbook - delete or snooze ghost items", - "text": "https://github.com/dolevshor/azure-orphan-resources", - "training": "https://learn.microsoft.com/azure/cost-management-billing/costs/tutorial-acm-create-budgets" + "severity": "High", + "subcategory": "IP plan", + "text": "Consider reserving I.P address on DR side when configuring ASR", + "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/" }, { - "category": "Cleanup", - "checklist": "Cost Optimization Checklist", - "guid": "9fe5c464-89d4-457a-a27c-3874d0102cac", - "id": "A07.01", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-enterprise-agreement#design-considerations", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "54c7c892-9cb1-407d-9325-ae525ba34d46", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing", "services": [ - "Cost" + "VNet" ], - "subcategory": "shutdown/deallocate", - "text": "shutdown underutilized instances", - "training": "https://learn.microsoft.com/azure/cost-management-billing/understand/analyze-unexpected-charges" + "severity": "High", + "subcategory": "IP plan", + "text": "Avoid using overlapping IP address ranges for production and DR sites.", + "training": "https://learn.microsoft.com/training/modules/design-ip-addressing-for-azure/?source=recommendations" }, { - "category": "Cleanup", - "checklist": "Cost Optimization Checklist", - "guid": "6aae01e6-a84d-4e5d-b36d-1d92881a1bd5", - "id": "A08.01", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-enterprise-agreement#design-considerations", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "6e154e3a-a359-4282-ae6e-206173686af4", + "link": "https://learn.microsoft.com/azure/azure-netapp-files/azure-netapp-files-delegate-subnet", "services": [ - "Backup", - "VM", - "Storage", - "Cost" + "VNet", + "Storage" ], - "subcategory": "stopped/deallocated VMs: check disks", - "text": "check that the disks are really needed, if not: delete. If they are needed, find lower storage tiers or use backup -", - "training": "https://learn.microsoft.com/azure/cost-management-billing/costs/manage-automation" + "severity": "Medium", + "subcategory": "IP plan", + "text": "While Azure does help you to create multiple delegated subnets in a VNet, only one delegated subnet can exist in a VNet for Azure NetApp Files. Attempts to create a new volume will fail if you use more than one delegated subnet for Azure NetApp Files.", + "training": "https://learn.microsoft.com/azure/azure-netapp-files/azure-netapp-files-network-topologies?source=recommendations" }, { - "category": "Cleanup", - "checklist": "Cost Optimization Checklist", - "guid": "d1e44a19-659d-4395-afd7-7289b835556d", - "id": "A09.01", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-enterprise-agreement#design-considerations", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "d8a03e97-7784-424d-9167-85d6fa96c96a", + "link": "https://learn.microsoft.com/azure/well-architected/services/networking/azure-firewall?toc=%2Fazure%2Ffirewall%2Ftoc.json&bc=%2Fazure%2Ffirewall%2Fbreadcrumb%2Ftoc.json", "services": [ - "AzurePolicy", - "Storage", - "Cost" + "Firewall" ], - "subcategory": "storage accounts lifecycle policy", - "text": "consider moving unused storage to lower tier, with customized rule - https://learn.microsoft.com/azure/storage/blobs/lifecycle-management-policy-configure ", - "training": "https://learn.microsoft.com/azure/cost-management-billing/costs/enable-tag-inheritance" + "severity": "Medium", + "subcategory": "Internet", + "text": "Use Azure Firewall to govern Azure outbound traffic to the internet, non-HTTP/S inbound connections, and East/West traffic filtering (if the organization requires it)", + "training": "https://learn.microsoft.com/training/paths/secure-networking-infrastructure/" }, { - "category": "Cleanup", - "checklist": "Cost Optimization Checklist", - "guid": "f2bfe456-3b0d-4834-a348-726de69c6b5c", - "id": "A10.01", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "91a65e40-be90-45b3-9f73-f3edbf8dc324", + "link": "https://learn.microsoft.com/azure/sap/workloads/expose-sap-process-orchestration-on-azure", "services": [ - "Cost" + "SAP", + "WAF", + "AppGW" ], - "subcategory": "Tagging", - "text": "use specific tags for temporary items with 'delete by DATE' format - and automate monthly cleanup" + "severity": "Medium", + "subcategory": "Internet", + "text": "Application Gateway and Web Application Firewall have limitations when Application Gateway serves as a reverse proxy for SAP web apps, as shown in the comparison between Application Gateway, SAP Web Dispatcher, and other third-party services.", + "training": "https://help.sap.com/docs/SUPPORT_CONTENT/si/3362959506.html" }, { - "category": "DB/APP tuning", - "checklist": "Cost Optimization Checklist", - "guid": "2a26494b-69ba-4d37-aad5-3cc78e1d7666", - "id": "B01.01", - "link": "https://learn.microsoft.com/azure/cost-management-billing/manage/mca-section-invoice", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "5e39e530-9ccc-4d97-a366-bcda2750ab1a", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", "services": [ - "Cost" + "ACR", + "FrontDoor", + "AzurePolicy", + "WAF" ], - "subcategory": "db optimization", - "text": "plan for db optimization with the intent of downsizing the related services (and improve performance)" + "severity": "Medium", + "subcategory": "Internet", + "text": "Use Azure Front Door and WAF policies to provide global protection across Azure regions for inbound HTTP/S connections to a landing zone.", + "training": "https://learn.microsoft.com/training/paths/secure-application-delivery/" }, { - "category": "DB/APP tuning", - "checklist": "Cost Optimization Checklist", - "guid": "7357c449-674b-45ed-a5a8-59c7733be2a1", - "id": "B02.01", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "b039d95d-54c7-4c89-89cb-107d5325ae52", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/afds-overview", "services": [ - "Cost" + "FrontDoor", + "AzurePolicy", + "WAF", + "AppGW" ], - "subcategory": "app modernization", - "text": "modernizing the app towards a microservices architecture will have the effect of letting the app scale according to the single service and not the entire stack" + "severity": "Medium", + "subcategory": "Internet", + "text": "Take advantage of Web Application Firewall policies in Azure Front Door when you're using Azure Front Door and Application Gateway to protect HTTP/S applications. Lock down Application Gateway to receive traffic only from Azure Front Door.", + "training": "https://learn.microsoft.com/training/modules/introduction-azure-web-application-firewall/?source=recommendations" }, { - "category": "DB/APP tuning", - "checklist": "Cost Optimization Checklist", - "guid": "a27b765a-91be-41f3-a8ef-394c2bd463cb", - "id": "B03.01", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "5ada4332-4e13-4811-9231-81aa41742694", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", "services": [ - "VM", - "Storage", - "Cost" + "LoadBalancer", + "WAF", + "AppGW" ], - "subcategory": "db optimization", - "text": "optimizing the DB queries will increase performance and allow better right-sizing of storage and VMs" + "severity": "Medium", + "subcategory": "Internet", + "text": "Use a web application firewall to scan your traffic when it's exposed to the internet. Another option is to use it with your load balancer or with resources that have built-in firewall capabilities like Application Gateway or third-party solutions.", + "training": "https://learn.microsoft.com/training/modules/introduction-azure-web-application-firewall/?source=recommendations" }, { - "category": "DB/APP tuning", - "checklist": "Cost Optimization Checklist", - "guid": "bac75819-59bb-491a-9ed9-0cae2cc84c37", - "id": "B04.01", - "link": "https://learn.microsoft.com/azure/governance/policy/overview", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "e73de7d5-6f36-4217-a526-e1a621ecddde", + "link": "https://learn.microsoft.com/azure/frontdoor/front-door-overview", "services": [ - "Cost" + "ACR", + "VWAN", + "SAP" ], - "subcategory": "demand shaping", - "text": "using demand shaping on PaaS services will optimize costs and performances" + "severity": "Medium", + "subcategory": "Internet", + "text": "Use Virtual WAN for Azure deployments in new, large, or global networks where you need global transit connectivity across Azure regions and on-premises locations. With this approach, you won't need to manually set up transitive routing for Azure networking, and you can follow a standard for SAP on Azure deployments.", + "training": "https://learn.microsoft.com/training/modules/explore-azure-networking/10-explore-azure-front-door" }, { - "category": "Process Administration", - "checklist": "Cost Optimization Checklist", - "guid": "b6b780cb-9fe5-4c46-989d-457a927c3874", - "id": "C01.01", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/naming-and-tagging", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "3c536a3e-1b6b-4e87-95ca-15edb47251c0", + "link": "https://learn.microsoft.com/azure/virtual-network/vnet-integration-for-azure-services", "services": [ - "Entra", - "Cost" + "PrivateLink", + "Storage", + "ACR", + "VNet", + "Backup" ], - "subcategory": "Advisor", - "text": "Start from the Azure Advisor page suggestions." + "severity": "Medium", + "subcategory": "Internet", + "text": "To prevent data leakage, use Azure Private Link to securely access platform as a service resources like Azure Blob Storage, Azure Files, Azure Data Lake Storage Gen2, Azure Data Factory, and more. Azure Private Endpoint can also help to secure traffic between VNets and services like Azure Storage, Azure Backup, and more. Traffic between your VNet and the Private Endpoint enabled service travels across the Microsoft global network, which prevents its exposure to the public internet.", + "training": "https://learn.microsoft.com/training/modules/design-implement-private-access-to-azure-services/?source=recommendations" }, { - "category": "Process Administration", - "checklist": "Cost Optimization Checklist", - "guid": "d0102cac-6aae-401e-9a84-de5de36d1d92", - "id": "C01.02", - "link": "https://learn.microsoft.com/azure/governance/policy/overview", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "85e2213a-ce7b-4b12-8f7c-95f06e154e3a", + "link": "https://learn.microsoft.com/azure/virtual-network/accelerated-networking-overview?tabs=redhat", "services": [ "VM", - "Cost" + "SAP" ], - "subcategory": "Advisor", - "text": "make sure advisor is configured for VM right sizing " + "severity": "High", + "subcategory": "Segmentation", + "text": "Make sure that Azure accelerated networking is enabled on the VMs used in the SAP application and DBMS layers.", + "training": "https://learn.microsoft.com/training/paths/azure-fundamentals-describe-azure-architecture-services/?source=recommendations" }, { - "category": "Process Administration", - "checklist": "Cost Optimization Checklist", - "guid": "881a1bd5-d1e4-44a1-a659-d3958fd77289", - "id": "C02.01", - "link": "https://learn.microsoft.com/azure/governance/policy/overview", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "3ff8ae7d-7d47-4431-96c8-bcbf45bbe609", + "link": "https://learn.microsoft.com/azure/load-balancer/load-balancer-multivip-overview", "services": [ - "Cost" + "LoadBalancer" ], - "subcategory": "Automation", - "text": "consider implementing IAC scripts or devops pipelines to match the cost governance process" + "severity": "Medium", + "subcategory": "Segmentation", + "text": "Make sure that internal deployments for Azure Load Balancer are set up to use Direct Server Return (DSR). This setting will reduce latency when internal load balancer configurations are used for high-availability configurations on the DBMS layer.", + "training": "https://learn.microsoft.com/ja-jp/training/modules/load-balancing-non-https-traffic-azure/?source=recommendations" }, { - "category": "Process Administration", - "checklist": "Cost Optimization Checklist", - "guid": "b835556d-f2bf-4e45-93b0-d834a348726d", - "id": "C02.02", - "link": "https://learn.microsoft.com/azure/governance/policy/overview", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "6791f893-5ada-4433-84e1-3811523181aa", + "link": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", "services": [ - "Monitor", - "Cost" + "VM", + "VNet", + "SAP" ], - "subcategory": "Automation", - "text": "set up cost alerts for applications that have variable costs (ideally for all of them)" + "severity": "Medium", + "subcategory": "Segmentation", + "text": "You can use application security group (ASG) and NSG rules to define network security access-control lists between the SAP application and DBMS layers. ASGs group virtual machines to help manage their security.", + "training": "https://learn.microsoft.com/training/modules/configure-network-security-groups/?source=recommendations" }, { - "category": "Process Administration", - "checklist": "Cost Optimization Checklist", - "guid": "e69c6b5c-2a26-4494-a69b-ad37aad53cc7", - "id": "C02.03", - "link": "https://learn.microsoft.com/security/benchmark/azure/mcsb-asset-management#am-2-use-only-approved-services", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "45bbe609-d8a0-43e9-9778-424d616785d6", + "link": "https://me.sap.com/notes/2015553", "services": [ - "Cost" + "VNet", + "SAP" ], - "subcategory": "Automation", - "text": "Use Azure Automation: Automate repetitive tasks can help you save time and resources, reducing costs in the process. " + "severity": "High", + "subcategory": "Segmentation", + "text": "Placing of the SAP application layer and SAP DBMS in different Azure VNets that aren't peered isn't supported.", + "training": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/sap/eslz-network-topology-and-connectivity" }, { - "category": "Process Administration", - "checklist": "Cost Optimization Checklist", - "guid": "8e1d7666-7357-4c44-a674-b5ed85a859c7", - "id": "C02.04", - "link": "https://learn.microsoft.com/azure/governance/policy/overview", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "fa96c96a-d885-418f-9827-34c886ba2802", + "link": "https://learn.microsoft.com/azure/sap/workloads/proximity-placement-scenarios", "services": [ - "Cost" + "SAP" ], - "subcategory": "Automation", - "text": "run orphaned resources workbook" + "severity": "Medium", + "subcategory": "Segmentation", + "text": "For optimal network latency with SAP applications, consider using Azure proximity placement groups.", + "training": "https://learn.microsoft.com/azure/virtual-machines/co-location#planned-maintenance-and-proximity-placement-groups" }, { - "category": "Process Administration", - "checklist": "Cost Optimization Checklist", - "guid": "733be2a1-a27b-4765-a91b-e1f388ef394c", - "id": "C03.01", - "link": "https://learn.microsoft.com/azure/governance/policy/overview#azure-rbac-permissions-in-azure-policy", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "18c8b61c-855a-4405-b6ed-266455e4f4ce", + "link": "https://me.sap.com/notes/2015553", "services": [ - "Storage", - "Cost" + "SAP" ], - "subcategory": "Baseline", - "text": "try and establish a baseline of monthly spending and an acceptable saving target against the baseline (new services will not be optimized at this stage)" + "severity": "High", + "subcategory": "Segmentation", + "text": "It is NOT supported at all to run an SAP Application Server layer and DBMS layer split between on-premise and Azure. Both layers need to completely reside either on-premise or in Azure.", + "training": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/sap/eslz-network-topology-and-connectivity" }, { - "category": "Process Administration", - "checklist": "Cost Optimization Checklist", - "guid": "2bd463cb-bac7-4581-a59b-b91a3ed90cae", - "id": "C03.02", - "link": "https://learn.microsoft.com/azure/governance/policy/overview", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "b65c878b-4b14-4f4e-92d8-d873936493f2", + "link": "https://me.sap.com/notes/2015553", "services": [ - "AzurePolicy", - "Cost" + "VNet", + "Cost", + "SAP" ], - "subcategory": "Baseline", - "text": "establish a cost optimization baseline by using a policy that tags every new resource as #NEW" + "severity": "High", + "subcategory": "Segmentation", + "text": "It isn't recommended to host the database management system (DBMS) and application layers of SAP systems in different VNets and connect them with VNet peering because of the substantial costs that excessive network traffic between the layers can produce. Recommend using subnets within the Azure virtual network to separate the SAP application layer and DBMS layer.", + "training": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/sap/eslz-network-topology-and-connectivity" }, { - "category": "Process Administration", - "checklist": "Cost Optimization Checklist", - "guid": "2cc84c37-b6b7-480c-a9fe-5c46489d457a", - "id": "C03.03", - "link": "https://learn.microsoft.com/azure/automation/automation-solution-vm-management-config", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "85e2213a-ce7b-4b12-8f7c-95f06e154e3a", + "link": "https://learn.microsoft.com/azure/virtual-network/accelerated-networking-overview?tabs=redhat", "services": [ - "Cost" + "VM", + "SAP" ], - "subcategory": "Baseline", - "text": "Organize resources to maximize cost insights and accountability" + "severity": "High", + "subcategory": "Segmentation", + "text": "Make sure that Azure accelerated networking is enabled on the VMs used in the SAP application and DBMS layers.", + "training": "https://learn.microsoft.com/training/paths/azure-fundamentals-describe-azure-architecture-services/?source=recommendations" }, { - "category": "Process Administration", - "checklist": "Cost Optimization Checklist", - "guid": "927c3874-d010-42ca-a6aa-e01e6a84de5d", - "id": "C04.01", - "link": "https://learn.microsoft.com/azure/cost-management-billing/costs/tutorial-acm-create-budgets?bc=%2Fazure%2Fcloud-adoption-framework%2F_bread%2Ftoc.json&toc=%2Fazure%2Fcloud-adoption-framework%2Ftoc.json", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "402a9846-d515-4061-aff8-cd30088693fa", + "link": "https://learn.microsoft.com/azure/sap/workloads/high-availability-guide-rhel", "services": [ - "Cost" + "LoadBalancer" ], - "subcategory": "Budgets", - "text": "Create budgets" + "severity": "High", + "subcategory": "Segmentation", + "text": "If using Load Balancer with Linux guest operating systems, check that the Linux network parameter net.ipv4.tcp_timestamps is set to 0.", + "training": "https://learn.microsoft.com/training/modules/implement-ha-sap-netweaver-anydb/?source=recommendations" }, { - "category": "Process Administration", - "checklist": "Cost Optimization Checklist", - "guid": "e36d1d92-881a-41bd-9d1e-44a19659d395", - "id": "C05.01", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/identity-access-landing-zones#identity-and-access-management-in-the-azure-landing-zone-accelerator", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "87585797-5551-4d53-bb7d-a94ee415734d", + "link": "https://learn.microsoft.com/azure/sap/workloads/rise-integration", "services": [ - "Cost" + "VNet", + "SAP" ], - "subcategory": "Cost Analysis", - "text": "in cost analysis - use daily granularity, grouped by service name to analyze the spending of the past 3 months and identify the top 3 spenders" + "severity": "Medium", + "subcategory": "Segmentation", + "text": "For SAP RISE/ECS deployments, virtual peering is the preferred way to establish connectivity with customer’s existing Azure environment. Both the SAP vnet and customer vnet(s) are protected with network security groups (NSG), enabling communication on SAP and database ports through the vnet peering" }, { - "category": "Process Administration", - "checklist": "Cost Optimization Checklist", - "guid": "8fd77289-b835-4556-bf2b-fe4563b0d834", - "id": "C05.02", - "link": "https://learn.microsoft.com/azure/active-directory/hybrid/how-to-connect-sync-staging-server", + "category": "Security, Governance and Compliance", + "checklist": "Azure Landing Zone Review", + "guid": "209d490d-a477-4784-84d1-16785d2fa56c", + "link": "https://learn.microsoft.com/azure/governance/policy/overview", "services": [ - "Cost" + "RBAC", + "SAP", + "Subscriptions" ], - "subcategory": "Cost Analysis", - "text": "check daily for cost spikes and anomalies (ideally with automatic billing exports)" + "severity": "High", + "subcategory": "Governance", + "text": "Customize role-based access control (RBAC) roles for SAP on Azure spoke subscriptions to avoid accidental network-related changes" }, { - "category": "Process Administration", - "checklist": "Cost Optimization Checklist", - "guid": "a348726d-e69c-46b5-a2a2-6494b69bad37", - "id": "C05.03", - "link": "https://learn.microsoft.com/azure/active-directory/roles/security-emergency-access", + "category": "Security, Governance and Compliance", + "checklist": "Azure Landing Zone Review", + "guid": "56ad4840-8fe7-4273-9c48-6ba280dc0591", + "link": "https://learn.microsoft.com/azure/governance/policy/overview", "services": [ - "Cost" + "NVA", + "PrivateLink", + "SAP" ], - "subcategory": "Cost Analysis", - "text": "automate cost retrieval for deep analysis or integration" + "severity": "Medium", + "subcategory": "Governance", + "text": "Isolate DMZs and NVAs from the rest of the SAP estate, configure Azure Private Link, and securely manage and control the SAP on Azure resources" }, { - "category": "Process Administration", - "checklist": "Cost Optimization Checklist", - "guid": "aad53cc7-8e1d-4766-9735-7c449674b5ed", - "id": "C06.01", - "link": "https://learn.microsoft.com/azure/active-directory/reports-monitoring/concept-activity-logs-azure-monitor", + "category": "Security, Governance and Compliance", + "checklist": "Azure Landing Zone Review", + "guid": "cf65de8e-1309-4ccc-b579-266bcca275fa", + "link": "https://learn.microsoft.com/azure/governance/policy/overview", "services": [ - "ACR", - "Cost" + "Backup", + "SAP", + "Storage", + "SQL" ], - "subcategory": "free services", - "text": "Take advantage of Azure free services: Azure offers a number of free services, such as DevOps, Azure Container Registry, and Azure Logic Apps, that can help you save costs on development and operations. " + "severity": "Medium", + "subcategory": "Governance", + "text": "For SAP database server encryption, use the SAP HANA native encryption technology. If you're using Azure SQL Database, use Transparent Data Encryption (TDE) offered by the DBMS provider to secure your data and log files, and ensure the backups are also encrypted." }, { - "category": "Process Administration", - "checklist": "Cost Optimization Checklist", - "guid": "96c96ad8-844c-4f3b-8b38-c886ba2c0214", - "id": "C07.01", - "link": "https://learn.microsoft.com/azure/role-based-access-control/overview", + "category": "Security, Governance and Compliance", + "checklist": "Azure Landing Zone Review", + "guid": "a1abfe9d-55d0-44c3-a491-9cb1b3d1325a", + "link": "https://learn.microsoft.com/azure/governance/policy/overview", "services": [ - "Cost" + "Storage" ], - "subcategory": "Tagging", - "text": "Tag shared resources" + "severity": "Medium", + "subcategory": "Governance", + "text": "Azure Storage encryption is enabled by default" + }, + { + "category": "Security, Governance and Compliance", + "checklist": "Azure Landing Zone Review", + "guid": "e124ba34-df68-45ed-bce9-bd3bb0cdb3b5", + "link": "https://learn.microsoft.com/azure/governance/policy/overview", + "services": [], + "severity": "Medium", + "subcategory": "Governance", + "text": " " }, { - "category": "Process Administration", - "checklist": "Cost Optimization Checklist", - "guid": "99014a5d-3ce5-474d-acbd-9792a6bcca2b", - "id": "C07.02", - "link": "https://learn.microsoft.com/azure/active-directory/conditional-access/overview", + "category": "Security, Governance and Compliance", + "checklist": "Azure Landing Zone Review", + "guid": "5eb2ec14-eeaa-4359-8829-e2edb2173676", + "link": "https://learn.microsoft.com/azure/governance/policy/overview", + "services": [], + "severity": "Medium", + "subcategory": "Governance", + "text": " " + }, + { + "category": "Security, Governance and Compliance", + "checklist": "Azure Landing Zone Review", + "guid": "ce9bd3bb-0cdb-43b5-9eb2-ec14eeaa3592", + "link": "https://learn.microsoft.com/azure/key-vault/general/overview", "services": [ - "Cost" + "AKV" ], - "subcategory": "Tagging", - "text": "consider using tags to all services for cost allocation" + "severity": "High", + "subcategory": "Secrets", + "text": "Use Azure Key Vault to store your secrets and credentials" }, { - "category": "reservations", - "checklist": "Cost Optimization Checklist", - "guid": "4fea1dbf-3dd9-45d4-ac7c-891dcb1f7d57", - "id": "D01.01", - "link": "https://learn.microsoft.com/azure/active-directory/authentication/concept-mfa-howitworks", + "category": "Security, Governance and Compliance", + "checklist": "Azure Landing Zone Review", + "guid": "829e2edb-2173-4676-aff6-691b4935ada4", + "link": "https://learn.microsoft.com/azure/key-vault/general/overview-throttling", "services": [ - "Cost" + "AKV" ], - "subcategory": "automation", - "text": "consider Reservation automation to track and promptly react to changes" + "severity": "Medium", + "subcategory": "Secrets", + "text": "It is recommended to LOCK the Azure Resources post successful deployment to safeguard against unauthorized changes" }, { - "category": "reservations", - "checklist": "Cost Optimization Checklist", - "description": "check by searching the Meter Category Licenses in the Cost analysys", - "guid": "59ae568b-a38d-4498-9e22-13dbd7bb012f", - "id": "D02.01", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/manage/centralize-operations", + "category": "Security, Governance and Compliance", + "checklist": "Azure Landing Zone Review", + "guid": "2223ece8-1b12-4318-8a54-17415833fb4a", + "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "services": [ - "VM", - "SQL", - "Cost", - "AzurePolicy" + "AzurePolicy", + "AKV" ], - "subcategory": "check AHUB is applied to all Windows VMs, RHEL and SQL", - "text": "run the script on all windows VMs https://learn.microsoft.com/azure/virtual-machines/windows/hybrid-use-benefit-licensing?ref=andrewmatveychuk.com#convert-an-existing-vm-using-azure-hybrid-benefit-for-windows-server- consider implementing a policy if windows VMs are created frequently" + "severity": "Medium", + "subcategory": "Secrets", + "text": "Provision Azure Key Vault with the soft delete and purge policies enabled to allow retention protection for deleted objects." }, { - "category": "reservations", - "checklist": "Cost Optimization Checklist", - "guid": "7b95e06e-158e-42ea-9992-c2de6e2065b3", - "id": "D03.01", - "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-configure", + "category": "Security, Governance and Compliance", + "checklist": "Azure Landing Zone Review", + "guid": "e3c2df74-3165-4c3a-abe0-5bbe209d490d", + "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "services": [ - "LoadBalancer", - "Cost" + "RBAC", + "AzurePolicy", + "AKV" ], - "subcategory": "check Red Hat Licences if applicable", - "text": " this can be also put under AHUB if you already have licenses https://learn.microsoft.com/azure/virtual-machines/linux/azure-hybrid-benefit-linux?tabs=rhelpayg%2Crhelbyos%2CrhelEnablebyos%2Crhelcompliance" + "severity": "Medium", + "subcategory": "Secrets", + "text": "Based on existing requirements, regulatory and compliance controls (internal/external) - Determine what Azure Policies and Azure RBAC role are needed" }, { - "category": "reservations", - "checklist": "Cost Optimization Checklist", - "guid": "a76af4a6-91e8-4839-ada4-6667e13c1056", - "id": "D04.01", - "link": "https://learn.microsoft.com/azure/active-directory/roles/security-planning#identify-microsoft-accounts-in-administrative-roles-that-need-to-be-switched-to-work-or-school-accounts", + "category": "Security, Governance and Compliance", + "checklist": "Azure Landing Zone Review", + "guid": "a4777842-4d11-4678-9d2f-a56c56ad4840", + "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "services": [ - "AppSvc", - "Cost" + "SAP", + "AzurePolicy", + "AKV", + "Defender" ], - "subcategory": "Functions", - "text": "saving plans will provide 17% on select app service plans" + "severity": "Medium", + "subcategory": "Secrets", + "text": "When you enable Microsoft Defender for Cloud Standard for SAP, make sure to exclude the SAP database servers from any policy that installs endpoint protection." }, { - "category": "reservations", - "checklist": "Cost Optimization Checklist", - "guid": "75c1e945-b459-4837-bf7a-e7c6d3b475a5", - "id": "D05.01", - "link": "https://learn.microsoft.com/azure/active-directory/fundamentals/active-directory-groups-create-azure-portal", + "category": "Security, Governance and Compliance", + "checklist": "Azure Landing Zone Review", + "guid": "8fe72734-c486-4ba2-a0dc-0591cf65de8e", + "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "services": [ - "VM", - "Cost" + "RBAC", + "SAP", + "AKV" ], - "subcategory": "planning", - "text": "consolidate reserved VM families with flexibility option (no more than 4-5 families)", - "training": "https://learn.microsoft.com/azure/automation/automation-solution-vm-management" + "severity": "Medium", + "subcategory": "Secrets", + "text": "Delegate an SAP admin custom role with just-in-time access." }, { - "category": "reservations", - "checklist": "Cost Optimization Checklist", - "guid": "c7acbe49-bbe6-44dd-a9f2-e87778468d55", - "id": "D06.01", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/identity-access#prerequisites-for-a-landing-zone---design-recommendations", + "category": "Security, Governance and Compliance", + "checklist": "Azure Landing Zone Review", + "guid": "1309cccd-5792-466b-aca2-75faa1abfe9d", + "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "services": [ - "VM", - "Cost", - "ARS" + "SAP", + "AKV" ], - "subcategory": "reservations/savings plans", - "text": "Utilize Azure Reserved Instances: This feature allows you to reserve VMs for a period of 1 or 3 years, providing significant cost savings compared to PAYG prices." + "severity": "Medium", + "subcategory": "Secrets", + "text": "encrypt data in transit by integrating the third-party security product with secure network communications (SNC) for DIAG (SAP GUI), RFC, and SPNEGO for HTTPS" }, { - "category": "reservations", - "checklist": "Cost Optimization Checklist", - "guid": "a785c6fe-96c9-46ad-a844-cf3b2b38c886", - "id": "D06.02", - "link": "https://azure.microsoft.com/resources/achieving-compliant-data-residency-and-security-with-azure/", + "category": "Security, Governance and Compliance", + "checklist": "Azure Landing Zone Review", + "guid": "55d04c3c-4919-4cb1-a3d1-325ae124ba34", + "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "services": [ - "Cost" + "SAP", + "AKV", + "Entra" ], - "subcategory": "reservations/savings plans", - "text": "plan for Azure Savings Plans for all the workloads that are dynamic and need maximum flexibility" + "severity": "Medium", + "subcategory": "Secrets", + "text": "Azure Active Directory (Azure AD) with SAML 2.0 can also provide SSO to a range of SAP applications and platforms like SAP NetWeaver, SAP HANA, and the SAP Cloud Platform" }, { - "category": "reservations", - "checklist": "Cost Optimization Checklist", - "guid": "ba2c0214-9901-44a5-b3ce-574dccbd9792", - "id": "D06.03", - "link": "https://learn.microsoft.com/azure/active-directory-domain-services/overview", + "category": "Security, Governance and Compliance", + "checklist": "Azure Landing Zone Review", + "guid": "df685edd-ce9b-4d3b-a0cd-b3b55eb2ec14", + "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "services": [ - "Cost" + "SAP", + "AKV" ], - "subcategory": "reservations/savings plans", - "text": "plan for Azure Reservations for all the workloads that are less dynamic and won't change much" + "severity": "Medium", + "subcategory": "Secrets", + "text": "Make sure you harden the operating system to eradicate vulnerabilities that could lead to attacks on the SAP database." }, { - "category": "reservations", - "checklist": "Cost Optimization Checklist", - "guid": "a6bcca2b-4fea-41db-b3dd-95d48c7c891d", - "id": "D07.01", - "link": "https://learn.microsoft.com/azure/active-directory-domain-services/overview", + "category": "Security, Governance and Compliance", + "checklist": "Azure Landing Zone Review", + "guid": "eeaa3592-829e-42ed-a217-3676aff6691b", + "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "services": [ - "Storage", - "Cost" + "AKV" ], - "subcategory": "reserve storage", - "text": "only larger disks can be reserved =>1TiB -" + "severity": "Medium", + "subcategory": "Secrets", + "text": "Default to Microsoft-managed keys for principal encryption functionality and use customer-managed keys when required." }, { - "category": "reservations", - "checklist": "Cost Optimization Checklist", - "guid": "cb1f7d57-59ae-4568-aa38-d4985e2213db", - "id": "D08.01", - "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/identity/adds-extend-domain", + "category": "Security, Governance and Compliance", + "checklist": "Azure Landing Zone Review", + "guid": "4935ada4-2223-4ece-a1b1-23181a541741", + "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "services": [ - "VM", - "Cost" + "AKV" ], - "subcategory": "reserve VMs with normalized and rationalized sizes", - "text": "after the right-sizing optimization" + "severity": "Medium", + "subcategory": "Secrets", + "text": "Use an Azure Key Vault per application per environment per region." }, { - "category": "reservations", - "checklist": "Cost Optimization Checklist", - "guid": "d7bb012f-7b95-4e06-b158-e2ea3992c2de", - "id": "D09.01", - "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy", + "category": "Security, Governance and Compliance", + "checklist": "Azure Landing Zone Review", + "guid": "5833fb4a-e3c2-4df7-9316-5c3acbe05bbe", + "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "services": [ - "AzurePolicy", - "SQL", - "Cost" + "AKV" ], - "subcategory": "SQL Database AHUB", - "text": "check if applicable and enforce policy/change https://learn.microsoft.com/azure/azure-sql/azure-hybrid-benefit?view=azuresql&tabs=azure-portalhttps://learn.microsoft.com/azure/cost-management-billing/scope-level/create-sql-license-assignments?source=recommendations" + "severity": "Medium", + "subcategory": "Secrets", + "text": " " }, { - "category": "reservations", - "checklist": "Cost Optimization Checklist", - "guid": "6e2065b3-a76a-4f4a-991e-8839ada46667", - "id": "D10.01", - "link": "https://learn.microsoft.com/azure/active-directory/roles/best-practices", + "category": "Storage", + "checklist": "Azure Landing Zone Review", + "guid": "d579266b-cca2-475f-aa1a-bfe9d55d04c3", "services": [ - "VM", - "SQL", - "Cost" + "Storage", + "SQL" ], - "subcategory": "SQL Database Reservations", - "text": "the VM + licence part discount (ahub+3YRI) is around 70% discount" + "severity": "Medium", + "subcategory": " ", + "text": "Disk config for Oracle, SQL, HANA" }, { - "category": "reservations", - "checklist": "Cost Optimization Checklist", - "guid": "e13c1056-75c1-4e94-9b45-9837ff7ae7c6", - "id": "D11.01", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/identity-access-landing-zones#managed-identities", + "category": "Business Continuity and Disaster Recovery", + "checklist": "Azure Virtual Desktop Review", + "description": "AVD control plane does not offer a financially backed service level agreement. We strive to attain at least 99.9% availability for the Azure Virtual Desktop service URLs. The availability of the session host virtual machines in your subscription is covered by the Virtual Machines SLA. Dependent resources/services and infrastructure availability must be also considered to properly satisfy global high-availability requirements.", + "guid": "56c57ba5-9119-4bf8-b8f5-c586c7d9cdc1", + "id": "A01.01", + "link": "https://azure.microsoft.com/support/legal/sla/virtual-desktop/v1_0/", "services": [ - "Cost" + "ASR", + "AVD", + "Subscriptions", + "VM" ], - "subcategory": "tracking", - "text": "Make sure you Azure Reservations and Savings plans are close to 100% utilization or make the necessary changes to reach it." + "severity": "High", + "subcategory": "Compute", + "text": "Determine the expected High Availability SLA for applications/desktops published through AVD", + "waf": "Reliability" }, { - "category": "reservations", - "checklist": "Cost Optimization Checklist", - "guid": "d3b475a5-c7ac-4be4-abbe-64dd89f2e877", - "id": "D11.02", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/identity-access-landing-zones#rbac-recommendations", + "category": "Business Continuity and Disaster Recovery", + "checklist": "Azure Virtual Desktop Review", + "description": "'Active-Active' model can be achieved with multiple host pools in different regions. A single Host Pool with VMs from different regions is not recommended. If multiple pools for same users will be used, the problem of how to synchronize/replicate user profiles must be solved. FSLogix Cloud Cache could be used, but need to be carefully reviewed and planned, or customers can decide to do not synchronize/replicate at all. 'Active-Passive' can be achieved using Azure Site Recovery (ASR) or on-demand Pool deployment with automated mechanism. For a detailed discussion on multi-region BCDR, please read the companion article in the 'More Info' column and this FSLogix related page: https://learn.microsoft.com/fslogix/concepts-container-recovery-business-continuity.", + "guid": "6acc076e-f9b1-441a-a989-579e76b897e7", + "id": "A01.02", + "link": "https://learn.microsoft.com/azure/architecture/example-scenario/wvd/azure-virtual-desktop-multi-region-bcdr", "services": [ - "AzurePolicy", - "Cost" + "ASR", + "AVD", + "Storage", + "VM" ], - "subcategory": "tracking", - "text": "make sure that your reservations usage is close to 100%. If not, either enforce an allowed SKU policy or exchange the reservation" + "severity": "Medium", + "subcategory": "Compute", + "text": "Assess Geo Disaster Recovery requirements for AVD Host Pools", + "waf": "Reliability" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "78468d55-a785-4c6f-b96c-96ad8844cf3b", - "id": "E01.01", - "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-create-roles-and-resource-roles-review", + "category": "Business Continuity and Disaster Recovery", + "checklist": "Azure Virtual Desktop Review", + "description": "Before approaching Azure Virtual Desktop BCDR planning and design, it is important to initially consider which applications consumed through AVD are critical. You may want to separate them from non-critical apps and use a separate Host Pool with a different disaster recovery approach and capabilities.", + "guid": "10a7da7b-e996-46e1-9d3c-4ada97cc3d13", + "id": "A01.03", + "link": "https://docs.microsoft.com/azure/virtual-desktop/disaster-recovery", "services": [ - "AzurePolicy", - "Cost" + "ASR", + "AVD" ], - "subcategory": "Automation", - "text": "plan and enforce a ON/OFF policy for production services, where possible" + "severity": "Low", + "subcategory": "Compute", + "text": "Separate critical applications in different AVD Host Pools", + "waf": "Reliability" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "2b38c886-ba2c-4021-9990-14a5d3ce574d", - "id": "E01.02", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#add-diagnostic-settings-to-save-your-wafs-logs", + "category": "Business Continuity and Disaster Recovery", + "checklist": "Azure Virtual Desktop Review", + "description": "Each Host Pool can be deployed using Availability Zones (AZ) or Availability Set (AS). To maximize resiliency, usage of AZ is recommended: at Host Pool creation time you can decide to spread Host Pool Session Hosts across all available AZ. Usage of AS will not protect from single datacenter failure, then should be used only in regions where AZ are not available. More details on AZ and AVD in the companion article. For a comparison between AZ and AS you can read here: https://learn.microsoft.com/azure/virtual-machines/availability.", + "guid": "25ab225c-6f4e-4168-9fdd-dea8a4b7cdeb", + "id": "A01.04", + "link": "https://techcommunity.microsoft.com/t5/azure-virtual-desktop-blog/announcing-general-availability-of-support-for-azure/ba-p/3636262", "services": [ - "AzurePolicy", - "Cost" + "ACR", + "ASR", + "AVD" ], - "subcategory": "Automation", - "text": "plan and enforce a ON-DEMAND policy with auto-shutdown for non-production services, where possible" + "severity": "High", + "subcategory": "Compute", + "text": "Plan the best resiliency option for AVD Host Pool deployment", + "waf": "Reliability" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "ccbd9792-a6bc-4ca2-a4fe-a1dbf3dd95d4", - "id": "E02.01", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#send-logs-to-microsoft-sentinel", + "category": "Business Continuity and Disaster Recovery", + "checklist": "Azure Virtual Desktop Review", + "description": "Azure Backup can be used to protect Host Pool VMs. For Pooled Pools, this is not necessary since should be stateless. Instead, this option can be considered for Personal Host Pools.", + "guid": "4c61fc3f-c14e-4ea6-b69e-8d9a3eec218e", + "id": "A01.05", + "link": "https://docs.microsoft.com/azure/virtual-desktop/disaster-recovery", "services": [ "VM", - "Cost" + "AVD", + "ASR", + "Backup" ], - "subcategory": "Autoscale", - "text": "consider using a VMSS to match demand rather than flat sizing" + "severity": "Medium", + "subcategory": "Compute", + "text": "Assess the requirement to backup AVD Session Host VMs", + "waf": "Reliability" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "c1b1cd52-1e54-4a29-a9de-39ac0e7c28dc", - "id": "E02.02", - "link": "https://learn.microsoft.com/azure/reliability/cross-region-replication-azure", + "category": "Business Continuity and Disaster Recovery", + "checklist": "Azure Virtual Desktop Review", + "description": "Even for Personal Pools, usage of Availability Zones, when available, is recommended. Three possible in-region DR strategies are possible, it is recommended to select the best one based on cost, RTO/RPO, and if it is really necessary to save the entire VM OS disk: (1) create each session host in a specific zone (AZ) and then use Azure Site Recovery (ASR) to replicate to a different zone. (2) Use Azure Backup to backup and restore the specific session host in a different AZ. (3) Create a new session host in a different AZ and rely on FSLogix and/or OneDrive to make data and settings available on the new machine. All options require administrator intervention for DR and direct user assignment at Host Pool level, then must be planned and configured in advance.", + "guid": "5da58639-ca3a-4961-890b-29663c5e10d", + "id": "A01.06", + "link": "https://learn.microsoft.com/azure/site-recovery/azure-to-azure-how-to-enable-zone-to-zone-disaster-recovery", "services": [ - "AKS", - "Cost" + "VM", + "AVD", + "Cost", + "ASR", + "Backup" ], - "subcategory": "Autoscale", - "text": "use AKS autoscaler to match your clusters usage (make sure the pods requirements match the scaler)" + "severity": "Medium", + "subcategory": "Compute", + "text": "Prepare a local DR strategy for Personal Host Pool Session Hosts", + "waf": "Reliability" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "93665720-2bff-4456-9b0d-934a359c363e", - "id": "E02.03", - "link": "https://learn.microsoft.com/azure/storage/common/storage-redundancy", + "category": "Business Continuity and Disaster Recovery", + "checklist": "Azure Virtual Desktop Review", + "description": "If custom images are used to deploy AVD Host Pool VMs, it is important to ensure those artifacts are available in all regions where AVD is deployed. Azure Compute Gallery service can be used to replicate images across all regions where a Host Pool is deployed, with redundant storage and in multiple copies. Please be aware that the Azure Compute Gallery service isn't a global resource. For disaster recovery scenarios, the best practice is to have at least two galleries, in different regions.", + "guid": "dd2e0d5d-771d-441e-9610-cc57b4a4a141", + "id": "A02.01", + "link": "https://learn.microsoft.com/azure/virtual-machines/azure-compute-gallery", "services": [ - "Cost" + "VM", + "AVD", + "Storage", + "ACR", + "ASR" ], - "subcategory": "Autoscale", - "text": "right-size PaaS service according to average use and accomodate spikes with auto or manual scaling" + "severity": "Low", + "subcategory": "Dependencies", + "text": "Plan for Golden Image cross-region availability", + "waf": "Reliability" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "7dd61623-a364-4a90-9eba-e38ead53cc7d", - "id": "E02.04", - "link": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", + "category": "Business Continuity and Disaster Recovery", + "checklist": "Azure Virtual Desktop Review", + "description": "If users of the AVD infrastructure need on-premises resource access, high availability of network infrastructure required to connect is also critical and should be considered. Resiliency of authentication infrastructure needs to be assessed and evaluated. BCDR aspects for dependent applications and other resources need to be considered to ensure availability in the secondary DR location.", + "guid": "fd339489-8c12-488b-9c6a-57cfb644451e", + "id": "A02.02", + "link": "https://docs.microsoft.com/azure/virtual-desktop/disaster-recovery", "services": [ - "Cost" + "ASR", + "AVD" ], - "subcategory": "Autoscale", - "text": "plan for demand shaping where applicable" + "severity": "Medium", + "subcategory": "Dependencies", + "text": "Assess Infrastructure & Application dependencies ", + "waf": "Reliability" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "e2e8aaab-3571-4549-ab91-53d89f89dc7b", - "id": "E02.05", + "category": "Business Continuity and Disaster Recovery", + "checklist": "Azure Virtual Desktop Review", + "description": "Not all data inside FSLogix user profiles may deserve protection from disaster. Additionally, if external storage is used, for example OneDrive or File Servers/Shares, what is remaining in the FSLogix profile is minimal and could be lost in some extreme circumstances. In other cases, data inside the profile can be rebuilt from other storages (for example Outlook Inbox in cached mode).", + "guid": "687ab077-adb5-49e5-a960-3334fdf8cc23", + "id": "A03.01", + "link": "https://docs.microsoft.com/fslogix/manage-profile-content-cncpt", "services": [ - "Cost" + "ASR", + "AVD", + "Storage" ], - "subcategory": "Autoscale", - "text": "consider implementing a service re-scaling logic within the application", - "training": "https://learn.microsoft.com/azure/cost-management-billing/savings-plan/" + "severity": "Medium", + "subcategory": "Storage", + "text": "Assess which data need to be protected in the Profile and Office Containers", + "waf": "Reliability" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "44be3b1a-27f8-4b9e-a1be-1f38df03a822", - "id": "E03.01", - "link": "https://learn.microsoft.com/azure/azure-monitor/logs/data-retention-archive?tabs=portal-1%2Cportal-2#how-retention-and-archiving-work", + "category": "Business Continuity and Disaster Recovery", + "checklist": "Azure Virtual Desktop Review", + "description": "Preventing data loss for critical user data is important, first step is to assess which data need to be saved and protected. If using OneDrive or other external storage, saving user Profile and/or Office Containers data maybe not necessary. Appropriate mechanism must be considered to provide protection for critical user data. Azure Backup service can be used to protect Profile and Office Containers data when stored on Azure Files Standard and Premium tiers. Azure NetApp Files Snapshots and Policies can be used for Azure NetApp Files (all tiers).", + "guid": "fc4972cc-3cd2-45bf-a707-6e9eab4bed32", + "id": "A03.02", + "link": "https://docs.microsoft.com/azure/virtual-desktop/disaster-recovery", "services": [ - "Backup", - "Cost" + "AVD", + "AzurePolicy", + "Storage", + "ASR", + "Backup" ], - "subcategory": "Backup", - "text": "Move recovery points to vault-archive where applicable (Validate)", - "training": "https://azure.microsoft.com/pricing/reservations/" + "severity": "Medium", + "subcategory": "Storage", + "text": "Build a backup protection strategy for Profile and Office Containers", + "waf": "Reliability" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "cd463cbb-bc8a-4c29-aebc-91a43da1dae2", - "id": "E04.01", - "link": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", + "category": "Business Continuity and Disaster Recovery", + "checklist": "Azure Virtual Desktop Review", + "description": "In AVD, multiple replication mechanisms and strategies can be used for user data residing in FSLogix containers: [Profile Pattern #1]: Native Azure storage replication mechanisms, for example Azure Files Standard GRS replication, Azure NetApp Files Cross Region Replication. Use Zone Replicated Storage (ZRS) or Geo replicated storage (GRS) for Azure Files is recommended. LRS with local-only resiliency can be used if no zone/region protection is required. NOTE: Azure Files Share Standard is LRS/ZRS/GRS, but with 100TB large support enabled only LRS/ZRS are supported. [Profile Pattern #2]: FSLogix Cloud Cache is built in automatic mechanism to replicate containers between different (up to 4) storage accounts. Cloud Cache should be used only when:(1) User Profile or Office containers data availability required high-availability SLA is critical and need to be resilient to region failure. (2) Selected storage option is not able to satisfy BCDR requirements. For example, with Azure File Share Premium tier, or Azure File Share Standard with Large File Support enabled, GRS is not available. (3) When replication between disparate storage is required. [Profile Pattern #3]: Only set up geo disaster recovery for application data and not for user data/profile containers: store important application data in separate storages, like OneDrive or other external storage with its own built-in DR mechanism.", + "guid": "9f7547c1-746d-4c56-868a-714435bd09dd", + "id": "A03.03", + "link": "https://docs.microsoft.com/azure/virtual-desktop/disaster-recovery", "services": [ - "VM", - "LoadBalancer", - "Cost" + "ASR", + "AVD", + "Storage" ], - "subcategory": "databricks", - "text": "consider using Spot VMs with fallback where possibleconsider autotermination of clusters https://learn.microsoft.com/azure/databricks/clusters/cluster-config-best-practices#automatic-termination ", - "training": "https://andrewmatveychuk.com/how-to-audit-azure-hybrid-benefit-usage-with-azure-workbooks/" + "severity": "Medium", + "subcategory": "Storage", + "text": "Assess Profile Container storage replication requirements and resiliency for BCDR purpose", + "waf": "Reliability" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "cc881470-607c-41cc-a0e6-14658dd458e9", - "id": "E05.01", - "link": "https://learn.microsoft.com/azure/governance/policy/how-to/guest-configuration-create", + "category": "Business Continuity and Disaster Recovery", + "checklist": "Azure Virtual Desktop Review", + "description": "For local disaster recovery, Azure Backup for Azure Files can be used. For cross-region geo disaster recovery: GRS for Azure Files is only available with standard SKU and no large share support, then not suitable in most customer scenarios. If geo-replication is required with Azure File Share Premium, replication with FSLogix Cloud Cache can be evaluated, or 'in-region' Availability Zone (AZ) only resiliency should be considered.", + "guid": "3d4f3537-c134-46dc-9602-7a71efe1bd05", + "id": "A03.04", + "link": "https://docs.microsoft.com/azure/backup/backup-afs", "services": [ - "Cost" - ], - "subcategory": "Functions", - "text": "Functions - Reuse connections", - "training": "https://learn.microsoft.com/azure/cost-management-billing/reservations/reservation-apis?toc=%2Fazure%2Fcost-management-billing%2Ftoc.json" + "ASR", + "AVD", + "Storage", + "Backup" + ], + "severity": "Medium", + "subcategory": "Storage", + "text": "Review Azure Files disaster recovery strategy", + "waf": "Reliability" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "27139b82-1102-4dbd-9eaf-11e6f843e52f", - "id": "E05.02", - "link": "https://learn.microsoft.com/azure/automation/update-management/overview", + "category": "Business Continuity and Disaster Recovery", + "checklist": "Azure Virtual Desktop Review", + "description": "Zone Redundant Storage will maximize in-region resiliency for the user profile data. ZRS is supported for premium file shares through the 'FileStorage' storage account kind. ZRS is supported in standard general-purpose v2 storage accounts. Usage of zone redundant storage must be paired with zone redundant deployment of Session Hosts in each Host Pool. ", + "guid": "10d4e875-d502-4142-a795-f2b6eff34f88", + "id": "A03.05", + "link": "https://learn.microsoft.com/azure/storage/files/files-redundancy#zone-redundant-storage", "services": [ - "Cost" + "ASR", + "AVD", + "Storage" ], - "subcategory": "Functions", - "text": "functions -Cache data locally", - "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-compute-resources/" + "severity": "High", + "subcategory": "Storage", + "text": "Use Zone Redundant Storage (ZRS) for Azure Files to maximize resiliency", + "waf": "Reliability" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "4722d928-c1b1-4cd5-81e5-4a29b9de39ac", - "id": "E05.03", - "link": "https://learn.microsoft.com/azure/network-watcher/network-watcher-monitoring-overview", + "category": "Business Continuity and Disaster Recovery", + "checklist": "Azure Virtual Desktop Review", + "description": "For local disaster recovery, Azure NetApp Files (ANF) native backup is available. ANF is essentially locally redundant, then for cross-region geo disaster recovery it is necessary to use an additional mechanism that is Cross-Region Replication (CRR) https://learn.microsoft.com/azure/azure-netapp-files/cross-region-replication-create-peering. Currently, ANF does not provide replication nor redundancy across different Availability Zones (AZ), only the possibility to select in which single AZ to place the ANF volume: https://learn.microsoft.com/azure/azure-netapp-files/manage-availability-zone-volume-placement.", + "guid": "23429db7-2281-4376-85cc-57b4a4b18142", + "id": "A03.06", + "link": "https://learn.microsoft.com/azure/azure-netapp-files/cross-region-replication-create-peering", "services": [ + "AVD", "Storage", - "Cost" + "ACR", + "ASR", + "Backup" ], - "subcategory": "Functions", - "text": "functions - Cold starts-Use the 'Run from package' functionality. This way, the code is downloaded as a single zip file. This can, for example, result in significant improvements with Javascript functions, which have a lot of node modules.Use language specific tools to reduce the package size, for example, tree shaking Javascript applications.", - "training": "https://learn.microsoft.com/learn/modules/configure-network-watcher/" + "severity": "Medium", + "subcategory": "Storage", + "text": "Review Azure NetApp Files disaster recovery strategy", + "waf": "Reliability" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "0e7c28dc-9366-4572-82bf-f4564b0d934a", - "id": "E05.04", - "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/lock-resources?tabs=json", + "category": "Compute", + "checklist": "Azure Virtual Desktop Review", + "description": "Applications can be preinstalled in the golden image/s, can be attached using MSIX & AppAttach feature or distributed to the session hosts after host pool deployment using traditional software distribution methods.", + "guid": "86ba2802-1459-4014-95d3-8e5309ccbd97", + "id": "B01.01", + "link": "https://learn.microsoft.com/azure/virtual-desktop/set-up-golden-image", "services": [ - "Cost" + "AVD" ], - "subcategory": "Functions", - "text": "Functions -Keep your functions warm", - "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/" + "severity": "High", + "subcategory": "Golden Images", + "text": "Determine how applications will be deployed in AVD Host Pools", + "waf": "Operations" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "359c363e-7dd6-4162-9a36-4a907ebae38e", - "id": "E05.05", - "link": "https://learn.microsoft.com/azure/governance/policy/overview", + "category": "Compute", + "checklist": "Azure Virtual Desktop Review", + "description": "Multiple golden images can be required to support different OS versions and/or settings, different groups of applications that must be separated and cannot be included in a single image.", + "guid": "9266bcca-274f-4aa1-abf3-9d95d44c7c89", + "id": "B01.02", + "link": "https://learn.microsoft.com/azure/virtual-desktop/set-up-golden-image", "services": [ - "Cost" + "AVD" ], - "subcategory": "Functions", - "text": "when using autoscale with different functions, there might be one driving all the autoscale for all the resources - consider moving it to a separate consumption plan (and consider higher plan for CPU)" + "severity": "Medium", + "subcategory": "Golden Images", + "text": "Estimate the number of golden images that will be required", + "waf": "Operations" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "ad53cc7d-e2e8-4aaa-a357-1549ab9153d8", - "id": "E05.06", - "link": "https://learn.microsoft.com/azure/service-health/alerts-activity-log-service-notifications-portal", + "category": "Compute", + "checklist": "Azure Virtual Desktop Review", + "description": "Determine which Guest OS will be used to deploy each Host Pool: Windows 10 vs. Windows Server, Marketplace vs. Custom images", + "guid": "19ca1f6d-5315-4ae5-84ba-34d4585e2213", + "id": "B01.03", + "link": "https://learn.microsoft.com/azure/virtual-desktop/prerequisites?tabs=portal#operating-systems-and-licenses", "services": [ - "Cost" + "AVD" ], - "subcategory": "Functions", - "text": "Function apps in a given plan are all scaled together, so any issues with scaling can affect all apps in the plan." + "severity": "Medium", + "subcategory": "Golden Images", + "text": "Determine which OS image/s you will use for Host Pool deployment", + "waf": "Reliability" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "9f89dc7b-44be-43b1-a27f-8b9e91be1f38", - "id": "E05.07", - "link": "https://learn.microsoft.com/azure/azure-monitor/alerts/action-groups", + "category": "Compute", + "checklist": "Azure Virtual Desktop Review", + "description": "Azure VM custom images can be created and stored in different ways: in an Azure Compute Gallery, as a managed image object or as a managed disk in the storage. The recommended way is to use Azure Compute Gallery.", + "guid": "5a2adb2c-3e23-426b-b225-ca44e1696fdd", + "id": "B01.04", + "link": "https://learn.microsoft.com/azure/virtual-machines/shared-image-galleries", "services": [ - "Cost" + "VM", + "AVD", + "Storage" ], - "subcategory": "Functions", - "text": "Am I billed for 'await time' ?This question is typically asked in the context of a C# function that does an async operation and waits for the result, e.g. await Task.Delay(1000) or await client.GetAsync('http://google.com'). The answer is yes - the GB second calculation is based on the start and end time of the function and the memory usage over that period. What actually happens over that time in terms of CPU activity is not factored into the calculation.One exception to this rule is if you are using durable functions. You are not billed for time spent at awaits in orchestrator functions.apply demand shaping techinques where possible (dev environments?) https://github.com/Azure-Samples/functions-csharp-premium-scaler" + "severity": "Low", + "subcategory": "Golden Images", + "text": "Select the proper store for custom images", + "waf": "Reliability" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "df03a822-cd46-43cb-abc8-ac299ebc91a4", - "id": "E06.01", - "link": "https://learn.microsoft.com/azure/sentinel/quickstart-onboard", + "category": "Compute", + "checklist": "Azure Virtual Desktop Review", + "description": "If custom images will be used, plan for an automated build process. If no pre-existing software factory exists, consider using Custom Image Templates and/or Azure Image Builder to automate the build process.", + "guid": "9bd7bb01-2f7b-495e-86e1-54e2aa359282", + "id": "B01.05", + "link": "https://learn.microsoft.com/azure/virtual-desktop/create-custom-image-templates", "services": [ - "Cost" + "AVD" ], - "subcategory": "Networking", - "text": "evaluate your network topology against networking costs and where applicable reduce the egress and peering data" + "severity": "Low", + "subcategory": "Golden Images", + "text": "Design your build process for custom images", + "waf": "Operations" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "3da1dae2-cc88-4147-8607-c1cca0e61465", - "id": "E06.02", - "link": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", + "category": "Compute", + "checklist": "Azure Virtual Desktop Review", + "description": "There are some known best practices and recommendations for the golden image customization, be sure to check the referenced article.", + "guid": "deace4cb-1dec-44c6-90c3-fc14eebb36a3", + "id": "B01.06", + "link": "https://learn.microsoft.com/azure/virtual-desktop/set-up-golden-image", "services": [ - "FrontDoor", - "EventHubs", - "Cost" + "AVD" ], - "subcategory": "Networking", - "text": "Frontdoor - Turn off the default homepageIn the application settings of your App, set AzureWebJobsDisableHomepage to true. This will return a 204 (No Content) to the PoP so only header data is returned." + "severity": "Medium", + "subcategory": "Golden Images", + "text": "If custom image will be used, check recommended best practices for AVD on how to build custom image", + "waf": "Operations" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "8dd458e9-2713-49b8-8110-2dbd6eaf11e6", - "id": "E06.03", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-setup-guide/monitoring-reporting?tabs=AzureMonitor", + "category": "Compute", + "checklist": "Azure Virtual Desktop Review", + "description": "FSLogix stack installed in AVD session hosts does not provide auto-update capability. For this reason, it is recommended to download the latest version of FSLogix and include in the golden image update process.", + "guid": "ed5c9027-dd1a-4343-86ca-52b199223186", + "id": "B01.07", + "link": "https://learn.microsoft.com/fslogix/how-to-install-fslogix", "services": [ - "FrontDoor", - "AppSvc", - "Cost" + "AVD" ], - "subcategory": "Networking", - "text": "Frontdoor -Route to something that returns nothingEither set up a Function, Function Proxy, or add a route in your WebApp that returns 200 (OK) and sends no or minimal content. The advantage of this is you will be able to log out when it is called." + "severity": "High", + "subcategory": "Golden Images", + "text": "Include the latest version of FSLogix in the golden image update process", + "waf": "Reliability" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "f843e52f-4722-4d92-ac1b-1cd521e54a29", - "id": "E07.01", - "link": "https://learn.microsoft.com/azure/azure-monitor/agents/diagnostics-extension-overview", + "category": "Compute", + "checklist": "Azure Virtual Desktop Review", + "description": "This tool-set has been created to automatically apply setting referenced in white paper 'Optimizing Windows 10, version 2004 for a Virtual Desktop Infrastructure (VDI) role': https://docs.microsoft.com/windows-server/remote/remote-desktop-services/rds-vdi-recommendations-2004. Usage of the tool and/or optimizations mentioned in the white-paper should be considered. ", + "guid": "829e3fec-2183-4687-a017-7a2b5945bda4", + "id": "B01.08", + "link": "https://github.com/The-Virtual-Desktop-Team/Virtual-Desktop-Optimization-Tool", "services": [ - "Cost" + "RBAC", + "AVD" ], - "subcategory": "PaaS", - "text": "consider using free tiers where applicable for all non-production environments" + "severity": "Low", + "subcategory": "Golden Images", + "text": "Evaluate the usage of Virtual-Desktop-Optimization-Tool", + "waf": "Performance" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "b9de39ac-0e7c-428d-a936-657202bff456", - "id": "E08.01", - "link": "https://learn.microsoft.com/azure/azure-monitor/alerts/alerts-overview", + "category": "Compute", + "checklist": "Azure Virtual Desktop Review", + "description": "If OneDrive is used and included in a golden image, be sure to follow the configuration procedure reported in the companion article in the 'More Info' section. Not in scope in this AVD checklist, but OneDrive optimizations like 'Known Folder Redirection' and 'Files On-Demand' should be evaluated used to reduce the space used in FSLogix profiles and provide a better user experience. OneDrive today is not supported for Remote Apps.", + "guid": "e3d3e084-4276-4d4b-bc01-5bcf219e4a1e", + "id": "B01.09", + "link": "https://learn.microsoft.com/azure/virtual-desktop/install-office-on-wvd-master-image#install-onedrive-in-per-machine-mode", "services": [ - "Cost" + "AVD", + "Storage" ], - "subcategory": "serverless", - "text": "using serverless patterns for spikes can help keeping costs down" + "severity": "Low", + "subcategory": "Golden Images", + "text": "Determine if Microsoft OneDrive will be part of AVD deployment", + "waf": "Operations" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "7e31c67d-68cf-46a6-8a11-94956d697dc3", - "id": "E09.01", - "link": "https://learn.microsoft.com/azure/architecture/best-practices/monitoring", + "category": "Compute", + "checklist": "Azure Virtual Desktop Review", + "description": "Be sure to review the requirements and configuration procedure contained in the companion article in the 'More Info' column. Since Teams automatic updates will be disabled, it is recommended to check and include Teams latest version in the golden image update process.", + "guid": "b5887953-5d22-4788-9d30-b66c67be5951", + "id": "B01.10", + "link": "https://learn.microsoft.com/azure/virtual-desktop/teams-on-AVD", "services": [ - "Storage", - "Cost" + "AVD" ], - "subcategory": "Storage", - "text": "consider archiving tiers for less used data" - }, - { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "a2ed27b2-d186-4f1a-8252-bddde68a487c", - "id": "E09.02", - "link": "https://learn.microsoft.com/azure/automation/how-to/region-mappings", + "severity": "Low", + "subcategory": "Golden Images", + "text": "Determine if Microsoft Teams will be part of AVD deployment", + "waf": "Performance" + }, + { + "category": "Compute", + "checklist": "Azure Virtual Desktop Review", + "description": "AVD can support users with different language and localization requirements in the same host pool. This can be done customizing golden images to ensure users can select whichever language they need. The procedure to configure additional language packs in Windows 11 is documented in the reference article.", + "guid": "7c336f3b-822a-498e-8cd1-667d1150df4a", + "id": "B01.11", + "link": "https://learn.microsoft.com/azure/virtual-desktop/windows-11-language-packs", "services": [ - "Storage", - "Cost" + "AVD" ], - "subcategory": "Storage", - "text": "check disk sizes where the size does not match the tier (i.e. A 513 GiB disk will pay a P30 (1TiB) and consider resizing" + "severity": "Low", + "subcategory": "Golden Images", + "text": "Assess the requirement to support multiple languages", + "waf": "Reliability" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "dec4861b-c3bc-410a-b77e-26e4d5a3bec2", - "id": "E09.03", - "link": "https://learn.microsoft.com/azure/governance/policy/concepts/guest-configuration", + "category": "Compute", + "checklist": "Azure Virtual Desktop Review", + "description": "It is highly recommended to use separate storage accounts/shares to store MSIX packages. If necessary, storage can scale out independently and not being impacted by profile I/O activities. Azure offers multiple storage options that can be used for MISX app attach. We recommend using Azure Files or Azure NetApp Files as those options offer the best value between cost and management overhead. ", + "guid": "90083845-c587-4cb3-a1ec-16a1d076ef9f", + "id": "B02.01", + "link": "https://docs.microsoft.com/azure/virtual-desktop/app-attach-file-share", "services": [ - "Storage", - "Cost" + "Cost", + "AVD", + "Storage" ], - "subcategory": "Storage", - "text": "consider using standard SSD rather than Premium or Ultra where possible" + "severity": "Medium", + "subcategory": "MSIX & AppAttach", + "text": "Do not use the same storage account/share as FSLogix profiles", + "waf": "Performance" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "c4e2436b-1336-4db5-9f17-960eee0bdf5c", - "id": "E09.04", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/management-operational-compliance#monitoring-for-configuration-drift", + "category": "Compute", + "checklist": "Azure Virtual Desktop Review", + "description": "In the referenced article, we reported few but important performance considerations for MSIX usage in AVD context, be sure to carefully review.", + "guid": "241addce-5793-477b-adb3-751ab2ac1fad", + "id": "B02.02", + "link": "https://docs.microsoft.com/azure/virtual-desktop/app-attach-file-share", "services": [ - "Storage", - "Cost" + "AVD" ], - "subcategory": "Storage", - "text": "For storage accounts, make sure that the chosen tier is not adding up transaction charges (it might be cheaper to move to the next tier)" + "severity": "Medium", + "subcategory": "MSIX & AppAttach", + "text": "Review performance considerations for MSIX", + "waf": "Performance" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "c2efc5d7-61d4-41d2-900b-b47a393a040f", - "id": "E09.05", - "link": "https://learn.microsoft.com/azure/site-recovery/site-recovery-overview", + "category": "Compute", + "checklist": "Azure Virtual Desktop Review", + "description": "MSIX app attach requires read-only permissions to access the file share. If you're storing your MSIX applications in Azure Files, then for your session hosts, you'll need to assign all session host VMs both storage account role-based access control (RBAC) and file share New Technology File System (NTFS) permissions on the share.", + "guid": "66e15d4d-5a2a-4db2-a3e2-326bf225ca41", + "id": "B02.03", + "link": "https://docs.microsoft.com/azure/virtual-desktop/app-attach-file-share", "services": [ - "ASR", - "Storage", - "Cost" + "RBAC", + "VM", + "AVD", + "Storage" ], - "subcategory": "Storage", - "text": "for ASR, consider using Standard SSD disks if the RPO/RTO and replication throughput allow it" + "severity": "Medium", + "subcategory": "MSIX & AppAttach", + "text": "Check proper session host permissions for MSIX share", + "waf": "Security" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "d3294798-b118-48b2-a5a4-6ceb544451e1", - "id": "E10.01", - "link": "https://learn.microsoft.com/azure/architecture/framework/resiliency/backup-and-recovery", + "category": "Compute", + "checklist": "Azure Virtual Desktop Review", + "description": "3rd-party software vendor must provide a MSIX package, it is not recommended for customer to attempt the conversion procedure without proper support from the application owner.", + "guid": "bd362caa-ab79-4b19-adab-81932c9fc9d1", + "id": "B02.04", + "link": "https://docs.microsoft.com/azure/virtual-desktop/app-attach-faq", "services": [ - "Storage", - "Cost" + "AVD" ], - "subcategory": "storage", - "text": "storage accounts: check hot tier and/or GRS necessary" + "severity": "Low", + "subcategory": "MSIX & AppAttach", + "text": "MSIX packages for 3rd-party applications", + "waf": "Cost" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "92d34429-3c76-4286-97a5-51c5b04e4f18", - "id": "E10.02", - "link": "https://learn.microsoft.com/azure/backup/backup-center-overview", + "category": "Compute", + "checklist": "Azure Virtual Desktop Review", + "description": "MSIX app attach doesn't support auto-update for MSIX applications, so they should be disabled.", + "guid": "bb88037f-5e6b-4fbb-aed5-03547cc447e8", + "id": "B02.05", + "link": "https://docs.microsoft.com/azure/virtual-desktop/app-attach-faq", "services": [ - "Storage", - "Cost" + "AVD" ], - "subcategory": "storage", - "text": "Disks -validate use of Premium SSD disks everywhere: for example, non-prod could swap to Standard SSD or On demand Premium SSD " + "severity": "Low", + "subcategory": "MSIX & AppAttach", + "text": "Disable auto-update for MSIX packages", + "waf": "Operations" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "54387e5c-ed12-46cd-832a-f5b2fc6998a5", - "id": "E11.01", - "link": "https://learn.microsoft.com/azure/reliability/availability-zones-overview", + "category": "Compute", + "checklist": "Azure Virtual Desktop Review", + "description": "In order to leverage MSIX & App Attach, guest OS image for AVD Host pool must be Windows 10/11 Enterprise or Windows 10/11 Enterprise Multi-session, version 2004 or later.", + "guid": "26128a71-f0f1-4cac-9d9e-f1d5e832e42e", + "id": "B02.06", + "link": "https://docs.microsoft.com/azure/virtual-desktop/app-attach-faq", "services": [ - "Monitor", - "EventHubs", - "Cost" + "AVD" ], - "subcategory": "Synapse", - "text": "Create budgets to manage costs and create alerts that automatically notify stakeholders of spending anomalies and overspending risks." + "severity": "Medium", + "subcategory": "MSIX & AppAttach", + "text": "Review operating systems support", + "waf": "Reliability" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "35e33789-7e31-4c67-b68c-f6a62a119495", - "id": "E11.02", - "link": "https://learn.microsoft.com/azure/virtual-machines/availability", + "category": "Compute", + "checklist": "Azure Virtual Desktop Review", + "description": "Once selected the VM SKU that will be used for Host Pool deployment, it is recommended to use Gen2 type of the SKU for higher security and improved capabilities.", + "guid": "e4633254-3185-40a1-b120-bd563a1c8e9d", + "id": "B03.01", + "link": "https://docs.microsoft.com/azure/virtual-machines/generation-2", "services": [ - "Storage", - "Cost" + "VM", + "AVD" ], - "subcategory": "Synapse", - "text": "Export cost data to a storage account for additional data analysis." + "severity": "Medium", + "subcategory": "Session Host", + "text": "Evaluate the usage of Gen2 VM for Host Pool deployment", + "waf": "Performance" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "6d697dc3-a2ed-427b-8d18-6f1a1252bddd", - "id": "E11.03", - "link": "https://learn.microsoft.com/azure/load-balancer/load-balancer-overview", + "category": "Compute", + "checklist": "Azure Virtual Desktop Review", + "description": "MMR redirects the media content from Session Host to your local machine for faster processing and rendering. It only works when you play media content on Microsoft Edge or Google Chrome. See linked URL for more details.", + "guid": "adecb27f-dc40-40f5-aca2-0090f633b1c9", + "id": "B03.02", + "link": "https://learn.microsoft.com/azure/virtual-desktop/multimedia-redirection", "services": [ - "SQL", - "Cost" + "AVD" ], - "subcategory": "Synapse", - "text": "Control costs for a dedicated SQL pool by pausing the resource when it is not in use." + "severity": "Low", + "subcategory": "Session Host", + "text": "Consider using MMR (MultiMedia Redirection) to get better video performance on browser", + "waf": "Performance" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "e68a487c-dec4-4861-ac3b-c10ae77e26e4", - "id": "E11.04", - "link": "https://learn.microsoft.com/azure/virtual-machine-scale-sets/overview", + "category": "Foundation", + "checklist": "Azure Virtual Desktop Review", + "description": "A host pool is a collection of Azure virtual machines that register to Azure Virtual Desktop as session hosts. A host pool can be one of two types: Personal and Pooled. Which type to use, and how many, is a key design decision that must be documented and validated. See companion article in 'More Info' column for more details.", + "guid": "8468c55a-775c-46ee-a5b8-6ad8844ce3b2", + "id": "C01.01", + "link": "https://learn.microsoft.com/azure/virtual-desktop/terminology#host-pools", "services": [ - "Cost" + "VM", + "AVD" ], - "subcategory": "Synapse", - "text": "Enable the serverless Apache Spark automatic pause feature and set your timeout value accordingly." + "severity": "High", + "subcategory": "Capacity Planning", + "text": "Determine the Host Pool type to use", + "waf": "Cost" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "d5a3bec2-c4e2-4436-a133-6db55f17960e", - "id": "E11.05", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-latest-version-for-customer-managed-certificates", + "category": "Foundation", + "checklist": "Azure Virtual Desktop Review", + "description": "Use your design criteria to determine the number of Host Pools to deploy. This will be based on factors such as different OS images, multi-region support, guest VM hardware differences (such as GPU support or no), different user expectations and uptime requirements (examples might be 'Executives', 'Office Workers', 'Developers', etc.), and Host Pool RDP settings (such as drive redirection support). These will determine the number of host pools as well as how many hosts will be in each pool.", + "guid": "4e98495f-d3c0-4af2-aa59-a793395a32a7", + "id": "C01.02", + "link": "https://learn.microsoft.com/azure/virtual-desktop/terminology?WT.mc_id=Portal-fx#host-pools", "services": [ - "Cost" + "VM", + "AVD" ], - "subcategory": "Synapse", - "text": "Create multiple Apache Spark pool definitions of various sizes." + "severity": "High", + "subcategory": "Capacity Planning", + "text": "Estimate the number of different Host Pools to deploy ", + "waf": "Performance" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "ee0bdf5c-c2ef-4c5d-961d-41d2500bb47a", - "id": "E11.06", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/resource-org-management-groups#management-groups-in-the-azure-landing-zone-accelerator", + "category": "Foundation", + "checklist": "Azure Virtual Desktop Review", + "description": "Confirm that the difference between automatic and direct assignment is well understood and the selected option is appropriate for the scenario in question. Automatic is the default setting.", + "guid": "b38b875b-a1cf-4204-a901-3a5d3ce474db", + "id": "C01.03", + "link": "https://docs.microsoft.com/azure/virtual-desktop/configure-host-pool-personal-desktop-assignment-type", "services": [ - "Cost" + "AVD" ], - "subcategory": "Synapse", - "text": "Purchase Azure Synapse commit units (SCU) for one year with a pre-purchase plan to save on your Azure Synapse Analytics costs.", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/" + "severity": "Low", + "subcategory": "Capacity Planning", + "text": "For Personal Host Pool type, select the proper assignment type", + "waf": "Operations" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "393a040f-d329-4479-ab11-88b2c5a46ceb", - "id": "E12.01", - "link": "https://learn.microsoft.com/azure/application-gateway/overview-v2", + "category": "Foundation", + "checklist": "Azure Virtual Desktop Review", + "description": "Check which one to use and available options, autoscale ignores existing load-balancing algorithms.", + "guid": "cbd8682a-6abc-4a2a-9fda-1dbf3dc95d48", + "id": "C01.04", + "link": "https://docs.microsoft.com/azure/virtual-desktop/host-pool-load-balancing", "services": [ - "VM", - "Cost" + "AVD" ], - "subcategory": "VM", - "text": "Use SPOT VMs for interruptible jobs: These are VMs that can be bid on and purchased at a discounted price, providing a cost-effective solution for non-critical workloads.", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/" + "severity": "Low", + "subcategory": "Capacity Planning", + "text": "For Pooled Host Pool type, select the best load balancing method", + "waf": "Performance" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "544451e1-92d3-4442-a3c7-628637a551c5", - "id": "E12.02", - "link": "https://learn.microsoft.com/azure/load-balancer/load-balancer-overview", + "category": "Foundation", + "checklist": "Azure Virtual Desktop Review", + "description": "The number of cores increase, the system's synchronization overhead also increases. Especially for multiple user's sign-in simultaneously. Make sure not to use a VM that is too large for the session host", + "guid": "b3724959-4943-4577-a3a9-e10ff6345f24", + "id": "C01.05", + "link": "https://learn.microsoft.com/windows-server/remote/remote-desktop-services/virtual-machine-recs", "services": [ "VM", - "Cost" + "AVD" ], - "subcategory": "VM", - "text": "right-sizing all VMs" + "severity": "Medium", + "subcategory": "Capacity Planning", + "text": "For Pooled Host Pool type, VMs shouldn't have more than 32 cores", + "waf": "Performance" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "b04e4f18-5438-47e5-aed1-26cd032af5b2", - "id": "E12.03", - "link": "https://learn.microsoft.com/azure/application-gateway/configuration-infrastructure#size-of-the-subnet", + "category": "Foundation", + "checklist": "Azure Virtual Desktop Review", + "description": "AVD does not support assigning both the RemoteApp and Desktop Application Group (DAG) in a single host pool to the same set of users. Doing so will cause a single user to have two user sessions in a single host pool. Users aren't supposed to have two active sessions at the same time in the same host pool using the same profile.", + "guid": "b384b7ed-1cdd-457e-a2cd-c8d4d55bc144", + "id": "C01.06", + "link": "https://learn.microsoft.com/azure/virtual-desktop/terminology?WT.mc_id=Portal-fx#application-groups", "services": [ - "VM", - "Cost" + "AVD", + "Storage" ], - "subcategory": "VM", - "text": "swap VM sized with normalized and most recent sizes", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/" + "severity": "High", + "subcategory": "Capacity Planning", + "text": "Do not use the same Host Pool to offer both full desktops (DAG) and Remote Apps to the same set of users", + "waf": "Security" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "fc6998a5-35e3-4378-a7e3-1c67d68cf6a6", - "id": "E12.04", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "category": "Foundation", + "checklist": "Azure Virtual Desktop Review", + "description": "There is a limit of 500 Application Groups that can be created in AVD for each Microsoft Entra ID (former Azure AD) tenant. The limit can be increased (see the companion link for details) but it is not recommended.", + "guid": "971cc4a4-b1f7-4c12-90e0-1ad96808f00c", + "id": "C01.07", + "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits#azure-virtual-desktop-service-limits", "services": [ - "VM", - "Monitor", - "Cost" + "ACR", + "AVD", + "Entra" ], - "subcategory": "VM", - "text": "right-sizing VMs - start with monitoring usage below 5% and then work up to 40%", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/" + "severity": "Medium", + "subcategory": "Capacity Planning", + "text": "Estimate the number of Application Groups required across all Host Pools in the Microsoft Entra ID tenant", + "waf": "Reliability" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "2a119495-6d69-47dc-9a2e-d27b2d186f1a", - "id": "E12.05", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "category": "Foundation", + "checklist": "Azure Virtual Desktop Review", + "description": "Applications are grouped under Application Groups as containers for publishing and assigning permissions: we recommend that you do not publish more than 50 applications per application group.", + "guid": "fa9f2895-473d-439b-ab8e-5a5cf92c7f32", + "id": "C01.08", + "link": "https://learn.microsoft.com/azure/architecture/example-scenario/wvd/windows-virtual-desktop#considerations", "services": [ - "VM", - "Cost" + "AVD" ], - "subcategory": "VM", - "text": "containerizing an application can improve VM density and save money on scaling it", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/" + "severity": "Low", + "subcategory": "Capacity Planning", + "text": "Estimate the number of Applications for each Application Group", + "waf": "Reliability" }, { - "category": "Business Continuity and Disaster Recovery", + "category": "Foundation", "checklist": "Azure Virtual Desktop Review", - "description": "AVD control plane does not offer a financially backed service level agreement. We strive to attain at least 99.9% availability for the Azure Virtual Desktop service URLs. The availability of the session host virtual machines in your subscription is covered by the Virtual Machines SLA. Dependent resources/services and infrastructure availability must be also considered to properly satisfy global high-availability requirements.", - "guid": "56c57ba5-9119-4bf8-b8f5-c586c7d9cdc1", - "id": "A01.01", - "link": "https://azure.microsoft.com/support/legal/sla/virtual-desktop/v1_0/", + "description": "FSLogix is not required for Personal Host Pools since each VM is statically assigned to a single user, then no immediate needs for a roaming profile solution. In some usage scenarios FSLogix can help. For example, a VM can be re-assigned, or user moved to another desktop, or roaming profile can be used to save user profile in a different location for DR purposes.", + "guid": "38b19ab6-0693-4992-9394-5590883916ec", + "id": "C01.09", + "link": "https://learn.microsoft.com/azure/virtual-desktop/configure-host-pool-personal-desktop-assignment-type?tabs=azure#reassign-a-personal-desktop", "services": [ - "ASR", "VM", "AVD", - "Subscriptions" + "Storage" ], - "severity": "High", - "subcategory": "Compute", - "text": "Determine the expected High Availability SLA for applications/desktops published through AVD", + "severity": "Low", + "subcategory": "Capacity Planning", + "text": "Evaluate the usage of FSLogix for Personal Host Pools", "waf": "Reliability" }, { - "category": "Business Continuity and Disaster Recovery", + "category": "Foundation", "checklist": "Azure Virtual Desktop Review", - "description": "'Active-Active' model can be achieved with multiple host pools in different regions. A single Host Pool with VMs from different regions is not recommended. If multiple pools for same users will be used, the problem of how to synchronize/replicate user profiles must be solved. FSLogix Cloud Cache could be used, but need to be carefully reviewed and planned, or customers can decide to do not synchronize/replicate at all. 'Active-Passive' can be achieved using Azure Site Recovery (ASR) or on-demand Pool deployment with automated mechanism. For a detailed discussion on multi-region BCDR, please read the companion article in the 'More Info' column and this FSLogix related page: https://learn.microsoft.com/fslogix/concepts-container-recovery-business-continuity.", - "guid": "6acc076e-f9b1-441a-a989-579e76b897e7", - "id": "A01.02", - "link": "https://learn.microsoft.com/azure/architecture/example-scenario/wvd/azure-virtual-desktop-multi-region-bcdr", + "description": "Use the link provided to set a starting point for SKU decision, then validate using a performance test. Ensure a minimum of four cores for Production is selected per Session Host (multi-session)", + "guid": "e1112dbd-7ba0-412e-9b94-ef6e047d2ea2", + "id": "C01.10", + "link": "https://docs.microsoft.com/windows-server/remote/remote-desktop-services/virtual-machine-recs", "services": [ - "ASR", "VM", - "Storage", "AVD" ], - "severity": "Medium", - "subcategory": "Compute", - "text": "Assess Geo Disaster Recovery requirements for AVD Host Pools", - "waf": "Reliability" + "severity": "High", + "subcategory": "Capacity Planning", + "text": "Run workload performance test to determine the best Azure VM SKU and size to use", + "waf": "Performance" }, { - "category": "Business Continuity and Disaster Recovery", + "category": "Foundation", "checklist": "Azure Virtual Desktop Review", - "description": "Before approaching Azure Virtual Desktop BCDR planning and design, it is important to initially consider which applications consumed through AVD are critical. You may want to separate them from non-critical apps and use a separate Host Pool with a different disaster recovery approach and capabilities.", - "guid": "10a7da7b-e996-46e1-9d3c-4ada97cc3d13", - "id": "A01.03", - "link": "https://docs.microsoft.com/azure/virtual-desktop/disaster-recovery", + "description": "It is critical to check AVD capacity and limits reported in the referenced article. Additional limits and thresholds apply for network, compute, storage and service management. ", + "guid": "992b1cd6-d2f5-44b2-a769-e3a691e8838a", + "id": "C01.11", + "link": "https://learn.microsoft.com/azure/architecture/example-scenario/wvd/windows-virtual-desktop#considerations", "services": [ - "ASR", - "AVD" + "AVD", + "Storage" ], - "severity": "Low", - "subcategory": "Compute", - "text": "Separate critical applications in different AVD Host Pools", + "severity": "High", + "subcategory": "Capacity Planning", + "text": "Verify AVD scalability limits for the environment", "waf": "Reliability" }, { - "category": "Business Continuity and Disaster Recovery", + "category": "Foundation", "checklist": "Azure Virtual Desktop Review", - "description": "Each Host Pool can be deployed using Availability Zones (AZ) or Availability Set (AS). To maximize resiliency, usage of AZ is recommended: at Host Pool creation time you can decide to spread Host Pool Session Hosts across all available AZ. Usage of AS will not protect from single datacenter failure, then should be used only in regions where AZ are not available. More details on AZ and AVD in the companion article. For a comparison between AZ and AS you can read here: https://learn.microsoft.com/azure/virtual-machines/availability.", - "guid": "25ab225c-6f4e-4168-9fdd-dea8a4b7cdeb", - "id": "A01.04", - "link": "https://techcommunity.microsoft.com/t5/azure-virtual-desktop-blog/announcing-general-availability-of-support-for-azure/ba-p/3636262", + "description": "Host Pools with GPU require special configuration, please be sure to review the referenced article.", + "guid": "c936667e-13c0-4056-94b1-e945a459837e", + "id": "C01.12", + "link": "https://docs.microsoft.com/azure/virtual-desktop/configure-vm-gpu", "services": [ - "ASR", - "ACR", "AVD" ], - "severity": "High", - "subcategory": "Compute", - "text": "Plan the best resiliency option for AVD Host Pool deployment", - "waf": "Reliability" + "severity": "Low", + "subcategory": "Capacity Planning", + "text": "Determine if Session Hosts will require GPU", + "waf": "Performance" }, { - "category": "Business Continuity and Disaster Recovery", + "category": "Foundation", "checklist": "Azure Virtual Desktop Review", - "description": "Azure Backup can be used to protect Host Pool VMs. For Pooled Pools, this is not necessary since should be stateless. Instead, this option can be considered for Personal Host Pools.", - "guid": "4c61fc3f-c14e-4ea6-b69e-8d9a3eec218e", - "id": "A01.05", - "link": "https://docs.microsoft.com/azure/virtual-desktop/disaster-recovery", + "description": "Whenever is possible, it is recommended to leverage VM SKUs with Accelerated Networking feature. This feature does require specific VM SKU/size and OS versions, please see the list and requirement in the companion article.", + "guid": "b47a393a-0803-4272-a479-8b1578b219a4", + "id": "C01.13", + "link": "https://learn.microsoft.com/azure/virtual-network/accelerated-networking-overview", "services": [ - "Backup", "VM", - "AVD", - "ASR" + "AVD" ], - "severity": "Medium", - "subcategory": "Compute", - "text": "Assess the requirement to backup AVD Session Host VMs", - "waf": "Reliability" + "severity": "Low", + "subcategory": "Capacity Planning", + "text": "Use Azure VM SKUs able to leverage Accelerated Networking", + "waf": "Performance" }, { - "category": "Business Continuity and Disaster Recovery", + "category": "Foundation", "checklist": "Azure Virtual Desktop Review", - "description": "Even for Personal Pools, usage of Availability Zones, when available, is recommended. Three possible in-region DR strategies are possible, it is recommended to select the best one based on cost, RTO/RPO, and if it is really necessary to save the entire VM OS disk: (1) create each session host in a specific zone (AZ) and then use Azure Site Recovery (ASR) to replicate to a different zone. (2) Use Azure Backup to backup and restore the specific session host in a different AZ. (3) Create a new session host in a different AZ and rely on FSLogix and/or OneDrive to make data and settings available on the new machine. All options require administrator intervention for DR and direct user assignment at Host Pool level, then must be planned and configured in advance.", - "guid": "5da58639-ca3a-4961-890b-29663c5e10d", - "id": "A01.06", - "link": "https://learn.microsoft.com/azure/site-recovery/azure-to-azure-how-to-enable-zone-to-zone-disaster-recovery", + "description": "For proper planning and deployment, it is important to assess the maximum number of concurrent and total users for each Host Pool. Additionally, users from different regions may require different Host Pools to ensure the best user experience.", + "guid": "bb91a33d-90ca-4e2c-a881-3706f7c0cb9f", + "id": "C02.01", + "link": "https://learn.microsoft.com/azure/virtual-desktop/overview", "services": [ - "Backup", - "Cost", - "VM", - "AVD", - "ASR" + "AVD" ], "severity": "Medium", - "subcategory": "Compute", - "text": "Prepare a local DR strategy for Personal Host Pool Session Hosts", - "waf": "Reliability" + "subcategory": "Clients & Users", + "text": "Assess how many users will connect to AVD and from which regions", + "waf": "Performance" }, { - "category": "Business Continuity and Disaster Recovery", + "category": "Foundation", "checklist": "Azure Virtual Desktop Review", - "description": "If custom images are used to deploy AVD Host Pool VMs, it is important to ensure those artifacts are available in all regions where AVD is deployed. Azure Compute Gallery service can be used to replicate images across all regions where a Host Pool is deployed, with redundant storage and in multiple copies. Please be aware that the Azure Compute Gallery service isn't a global resource. For disaster recovery scenarios, the best practice is to have at least two galleries, in different regions.", - "guid": "dd2e0d5d-771d-441e-9610-cc57b4a4a141", - "id": "A02.01", - "link": "https://learn.microsoft.com/azure/virtual-machines/azure-compute-gallery", + "description": "The dependencies on resources external to the AVD pool should be assessed and reviewed, for example Active Directory, external file shares or other storage, on-premises services and resources, network infrastructure components like VPN and or ExpressRoute, external services and 3rd-party components. For all these resources, latency from the AVD Host Pool needs to be evaluated and connectivity considered. Additionally, BCDR considerations need to be applied to these dependencies as well.", + "guid": "6abca2a4-fda1-4dbf-9dc9-5d48c7c791dc", + "id": "C02.02", + "link": "https://learn.microsoft.com/azure/architecture/example-scenario/wvd/windows-virtual-desktop?toc=%2Fazure%2Fvirtual-desktop%2Ftoc.json&bc=%2Fazure%2Fvirtual-desktop%2Fbreadcrumb%2Ftoc.json", "services": [ - "ACR", - "VM", + "ExpressRoute", "AVD", - "ASR", - "Storage" + "Storage", + "VPN" ], - "severity": "Low", - "subcategory": "Dependencies", - "text": "Plan for Golden Image cross-region availability", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "Clients & Users", + "text": "Assess external dependencies for each Host Pool", + "waf": "Performance" }, { - "category": "Business Continuity and Disaster Recovery", + "category": "Foundation", "checklist": "Azure Virtual Desktop Review", - "description": "If users of the AVD infrastructure need on-premises resource access, high availability of network infrastructure required to connect is also critical and should be considered. Resiliency of authentication infrastructure needs to be assessed and evaluated. BCDR aspects for dependent applications and other resources need to be considered to ensure availability in the secondary DR location.", - "guid": "fd339489-8c12-488b-9c6a-57cfb644451e", - "id": "A02.02", - "link": "https://docs.microsoft.com/azure/virtual-desktop/disaster-recovery", + "description": "AVD offers a variety of client types (fat, thin, web) to connect over different platforms (Windows, MacOS, iOS, Android). Review limitations of each client and compare multiple options when possible.", + "guid": "a1f6d565-99e5-458b-a37d-4985e1112dbd", + "id": "C02.03", + "link": "https://learn.microsoft.com/azure/virtual-desktop/users/connect-windows", "services": [ - "ASR", "AVD" ], - "severity": "Medium", - "subcategory": "Dependencies", - "text": "Assess Infrastructure & Application dependencies ", - "waf": "Reliability" + "severity": "Low", + "subcategory": "Clients & Users", + "text": "Review user client OS used and AVD client type", + "waf": "Performance" }, { - "category": "Business Continuity and Disaster Recovery", + "category": "Foundation", "checklist": "Azure Virtual Desktop Review", - "description": "Not all data inside FSLogix user profiles may deserve protection from disaster. Additionally, if external storage is used, for example OneDrive or File Servers/Shares, what is remaining in the FSLogix profile is minimal and could be lost in some extreme circumstances. In other cases, data inside the profile can be rebuilt from other storages (for example Outlook Inbox in cached mode).", - "guid": "687ab077-adb5-49e5-a960-3334fdf8cc23", - "id": "A03.01", - "link": "https://docs.microsoft.com/fslogix/manage-profile-content-cncpt", + "description": "Depending on the user locations, and AVD region deployment, users may have a non-optimal experience, hence is important to test as soon as possible in a small PoC environment. Run the 'Azure Virtual Desktop Experience Estimator' tool to select the best Azure region to deploy Host Pools. Beyond 150ms latency, user experience may be not optimal.", + "guid": "d2f54b29-769e-43a6-a1e8-838ac936667e", + "id": "C02.04", + "link": "https://azure.microsoft.com/services/virtual-desktop/assessment/", "services": [ - "ASR", - "Storage", "AVD" ], - "severity": "Medium", - "subcategory": "Storage", - "text": "Assess which data need to be protected in the Profile and Office Containers", - "waf": "Reliability" + "severity": "High", + "subcategory": "Clients & Users", + "text": "Run a PoC to validate end-to-end user experience and impact of network latency", + "waf": "Performance" }, { - "category": "Business Continuity and Disaster Recovery", + "category": "Foundation", "checklist": "Azure Virtual Desktop Review", - "description": "Preventing data loss for critical user data is important, first step is to assess which data need to be saved and protected. If using OneDrive or other external storage, saving user Profile and/or Office Containers data maybe not necessary. Appropriate mechanism must be considered to provide protection for critical user data. Azure Backup service can be used to protect Profile and Office Containers data when stored on Azure Files Standard and Premium tiers. Azure NetApp Files Snapshots and Policies can be used for Azure NetApp Files (all tiers).", - "guid": "fc4972cc-3cd2-45bf-a707-6e9eab4bed32", - "id": "A03.02", - "link": "https://docs.microsoft.com/azure/virtual-desktop/disaster-recovery", + "description": "RDP settings can currently only be configured at the host pool level, not per user/group. If different settings are required for different set of users, it is recommended to create multiple Host Pools.", + "guid": "3b365a5c-7acb-4e48-abe5-4cd79f2e8776", + "id": "C02.05", + "link": "https://docs.microsoft.com/azure/virtual-desktop/customize-rdp-properties", "services": [ - "ASR", - "AzurePolicy", - "AVD", - "Backup", - "Storage" + "AVD" ], - "severity": "Medium", - "subcategory": "Storage", - "text": "Build a backup protection strategy for Profile and Office Containers", - "waf": "Reliability" + "severity": "Low", + "subcategory": "Clients & Users", + "text": "Assess and document RDP settings for all user groups", + "waf": "Security" }, { - "category": "Business Continuity and Disaster Recovery", + "category": "Foundation", "checklist": "Azure Virtual Desktop Review", - "description": "In AVD, multiple replication mechanisms and strategies can be used for user data residing in FSLogix containers: [Profile Pattern #1]: Native Azure storage replication mechanisms, for example Azure Files Standard GRS replication, Azure NetApp Files Cross Region Replication. Use Zone Replicated Storage (ZRS) or Geo replicated storage (GRS) for Azure Files is recommended. LRS with local-only resiliency can be used if no zone/region protection is required. NOTE: Azure Files Share Standard is LRS/ZRS/GRS, but with 100TB large support enabled only LRS/ZRS are supported. [Profile Pattern #2]: FSLogix Cloud Cache is built in automatic mechanism to replicate containers between different (up to 4) storage accounts. Cloud Cache should be used only when:(1) User Profile or Office containers data availability required high-availability SLA is critical and need to be resilient to region failure. (2) Selected storage option is not able to satisfy BCDR requirements. For example, with Azure File Share Premium tier, or Azure File Share Standard with Large File Support enabled, GRS is not available. (3) When replication between disparate storage is required. [Profile Pattern #3]: Only set up geo disaster recovery for application data and not for user data/profile containers: store important application data in separate storages, like OneDrive or other external storage with its own built-in DR mechanism.", - "guid": "9f7547c1-746d-4c56-868a-714435bd09dd", - "id": "A03.03", - "link": "https://docs.microsoft.com/azure/virtual-desktop/disaster-recovery", + "description": "AVD is a non-regional service, Host Pools can be created in any region, automatic redirection from closest front-end will happen automatically.", + "guid": "42e52f47-21d9-428c-8b1b-d521e44a29a9", + "id": "C03.01", + "link": "https://azure.microsoft.com/global-infrastructure/services/?products=virtual-desktop", "services": [ - "ASR", - "Storage", "AVD" ], - "severity": "Medium", - "subcategory": "Storage", - "text": "Assess Profile Container storage replication requirements and resiliency for BCDR purpose", - "waf": "Reliability" + "severity": "High", + "subcategory": "General", + "text": "Determine in which Azure regions AVD Host Pools will be deployed.", + "waf": "Performance" }, { - "category": "Business Continuity and Disaster Recovery", + "category": "Foundation", "checklist": "Azure Virtual Desktop Review", - "description": "For local disaster recovery, Azure Backup for Azure Files can be used. For cross-region geo disaster recovery: GRS for Azure Files is only available with standard SKU and no large share support, then not suitable in most customer scenarios. If geo-replication is required with Azure File Share Premium, replication with FSLogix Cloud Cache can be evaluated, or 'in-region' Availability Zone (AZ) only resiliency should be considered.", - "guid": "3d4f3537-c134-46dc-9602-7a71efe1bd05", - "id": "A03.04", - "link": "https://docs.microsoft.com/azure/backup/backup-afs", + "description": "AVD must store metadata to support the service; this is stored in the specified geography. However, this is independent of the regions where Host Pools are located.", + "guid": "bad37ead-53cc-47ce-8d7a-aab3571449ab", + "id": "C03.02", + "link": "https://docs.microsoft.com/azure/virtual-desktop/data-locations", "services": [ - "ASR", - "Storage", - "AVD", - "Backup" + "AVD" ], "severity": "Medium", - "subcategory": "Storage", - "text": "Review Azure Files disaster recovery strategy", + "subcategory": "General", + "text": "Determine metadata location for AVD service", "waf": "Reliability" }, { - "category": "Business Continuity and Disaster Recovery", + "category": "Foundation", "checklist": "Azure Virtual Desktop Review", - "description": "Zone Redundant Storage will maximize in-region resiliency for the user profile data. ZRS is supported for premium file shares through the 'FileStorage' storage account kind. ZRS is supported in standard general-purpose v2 storage accounts. Usage of zone redundant storage must be paired with zone redundant deployment of Session Hosts in each Host Pool. ", - "guid": "10d4e875-d502-4142-a795-f2b6eff34f88", - "id": "A03.05", - "link": "https://learn.microsoft.com/azure/storage/files/files-redundancy#zone-redundant-storage", + "description": "Check for specific VM SKUs, especially if you need GPU or high-specs SKUs, and eventually Azure NetApp Files if used.", + "guid": "8053d89e-89dc-47b3-9be2-a1a27f7a9e91", + "id": "C03.03", + "link": "https://docs.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits", "services": [ - "ASR", - "Storage", - "AVD" + "VM", + "AVD", + "Storage" ], - "severity": "High", - "subcategory": "Storage", - "text": "Use Zone Redundant Storage (ZRS) for Azure Files to maximize resiliency", + "severity": "Low", + "subcategory": "General", + "text": "Check Azure quotas and availability for specific VM sizes and types in the selected regions", "waf": "Reliability" }, { - "category": "Business Continuity and Disaster Recovery", + "category": "Identity", "checklist": "Azure Virtual Desktop Review", - "description": "For local disaster recovery, Azure NetApp Files (ANF) native backup is available. ANF is essentially locally redundant, then for cross-region geo disaster recovery it is necessary to use an additional mechanism that is Cross-Region Replication (CRR) https://learn.microsoft.com/azure/azure-netapp-files/cross-region-replication-create-peering. Currently, ANF does not provide replication nor redundancy across different Availability Zones (AZ), only the possibility to select in which single AZ to place the ANF volume: https://learn.microsoft.com/azure/azure-netapp-files/manage-availability-zone-volume-placement.", - "guid": "23429db7-2281-4376-85cc-57b4a4b18142", - "id": "A03.06", - "link": "https://learn.microsoft.com/azure/azure-netapp-files/cross-region-replication-create-peering", + "description": "AD DCs in Azure are recommended (at least two in different AZ) to reduce latency for users logging into AVD session hosts, and eventually for Azure NetApp Files and AD integration. A DC need to be able to talk to DCs for ALL child domains. As alternative, on-premise connectivity must be used to reach AD DCs.", + "guid": "c14aea7e-65e8-4d9a-9aec-218e6436b073", + "id": "D01.01", + "link": "https://docs.microsoft.com/azure/architecture/reference-architectures/identity/adds-extend-domain", "services": [ - "Backup", - "ACR", + "VNet", "AVD", - "ASR", - "Storage" + "Storage", + "Entra" ], "severity": "Medium", - "subcategory": "Storage", - "text": "Review Azure NetApp Files disaster recovery strategy", + "subcategory": "Active Directory", + "text": "Create at least two Active Directory Domain Controllers (DCs) in Azure VNet environment close to AVD Host Pool", "waf": "Reliability" }, { - "category": "Compute", + "category": "Identity", "checklist": "Azure Virtual Desktop Review", - "description": "Applications can be preinstalled in the golden image/s, can be attached using MSIX & AppAttach feature or distributed to the session hosts after host pool deployment using traditional software distribution methods.", - "guid": "86ba2802-1459-4014-95d3-8e5309ccbd97", - "id": "B01.01", - "link": "https://learn.microsoft.com/azure/virtual-desktop/set-up-golden-image", + "description": "Recommended to create a separate OU per Host Pool under a separate OU hierarchy. These OUs will contain machine accounts of AVD Session Hosts. ", + "guid": "6db55f57-9603-4334-adf9-cc23418db612", + "id": "D01.02", + "link": "https://docs.microsoft.com/azure/virtual-desktop/create-host-pools-azure-marketplace", "services": [ - "AVD" + "AVD", + "Entra" ], - "severity": "High", - "subcategory": "Golden Images", - "text": "Determine how applications will be deployed in AVD Host Pools", + "severity": "Medium", + "subcategory": "Active Directory", + "text": "Create a specific OU in Active Directory for each Host Pool", "waf": "Operations" }, { - "category": "Compute", + "category": "Identity", "checklist": "Azure Virtual Desktop Review", - "description": "Multiple golden images can be required to support different OS versions and/or settings, different groups of applications that must be separated and cannot be included in a single image.", - "guid": "9266bcca-274f-4aa1-abf3-9d95d44c7c89", - "id": "B01.02", - "link": "https://learn.microsoft.com/azure/virtual-desktop/set-up-golden-image", + "description": "Carefully review, and potentially block/filter inheritance of GPOs to the OUs containing AVD Host Pools. ", + "guid": "7126504b-b47a-4393-a080-327294798b15", + "id": "D01.03", + "link": "https://docs.microsoft.com/previous-versions/windows/desktop/Policy/group-policy-hierarchy", "services": [ - "AVD" + "AVD", + "Entra" ], "severity": "Medium", - "subcategory": "Golden Images", - "text": "Estimate the number of golden images that will be required", + "subcategory": "Active Directory", + "text": "Review Domain GPOs that will be applied to OU and impacting Host Pool Session Hosts functionalities", "waf": "Operations" }, { - "category": "Compute", + "category": "Identity", "checklist": "Azure Virtual Desktop Review", - "description": "Determine which Guest OS will be used to deploy each Host Pool: Windows 10 vs. Windows Server, Marketplace vs. Custom images", - "guid": "19ca1f6d-5315-4ae5-84ba-34d4585e2213", - "id": "B01.03", - "link": "https://learn.microsoft.com/azure/virtual-desktop/prerequisites?tabs=portal#operating-systems-and-licenses", + "description": "If Active Directory Domain GPOs are used, it is recommended to configure FSLogix using the built-in provided GPO ADMX template referenced in the companion article in the 'More Info' column", + "guid": "2226a8e3-50a4-4ac3-8bd6-ee150553051f", + "id": "D01.04", + "link": "https://learn.microsoft.com/fslogix/how-to-use-group-policy-templates", "services": [ - "AVD" + "AVD", + "Entra" ], "severity": "Medium", - "subcategory": "Golden Images", - "text": "Determine which OS image/s you will use for Host Pool deployment", - "waf": "Reliability" + "subcategory": "Active Directory", + "text": "Configure FSLogix settings using the built-in provided GPO ADMX template", + "waf": "Operations" }, { - "category": "Compute", + "category": "Identity", "checklist": "Azure Virtual Desktop Review", - "description": "Azure VM custom images can be created and stored in different ways: in an Azure Compute Gallery, as a managed image object or as a managed disk in the storage. The recommended way is to use Azure Compute Gallery.", - "guid": "5a2adb2c-3e23-426b-b225-ca44e1696fdd", - "id": "B01.04", - "link": "https://learn.microsoft.com/azure/virtual-machines/shared-image-galleries", + "description": "It is recommended to have a specific dedicated account with minimal permissions, and without the default 10 joins limitation. Review the companion article for more details.", + "guid": "347dc560-28a7-41ff-b1cd-15dd2f0d5e77", + "id": "D01.05", + "link": "https://learn.microsoft.com/azure/virtual-desktop/prerequisites?tabs=portal#session-hosts", "services": [ "VM", - "Storage", - "AVD" - ], - "severity": "Low", - "subcategory": "Golden Images", - "text": "Select the proper store for custom images", - "waf": "Reliability" - }, - { - "category": "Compute", - "checklist": "Azure Virtual Desktop Review", - "description": "If custom images will be used, plan for an automated build process. If no pre-existing software factory exists, consider using Custom Image Templates and/or Azure Image Builder to automate the build process.", - "guid": "9bd7bb01-2f7b-495e-86e1-54e2aa359282", - "id": "B01.05", - "link": "https://learn.microsoft.com/azure/virtual-desktop/create-custom-image-templates", - "services": [ - "AVD" + "AVD", + "Entra" ], - "severity": "Low", - "subcategory": "Golden Images", - "text": "Design your build process for custom images", - "waf": "Operations" + "severity": "Medium", + "subcategory": "Active Directory", + "text": "Create a dedicated user account with only permissions to join VM to the domain", + "waf": "Security" }, { - "category": "Compute", + "category": "Identity", "checklist": "Azure Virtual Desktop Review", - "description": "There are some known best practices and recommendations for the golden image customization, be sure to check the referenced article.", - "guid": "deace4cb-1dec-44c6-90c3-fc14eebb36a3", - "id": "B01.06", - "link": "https://learn.microsoft.com/azure/virtual-desktop/set-up-golden-image", + "description": "Avoid granting access per user, instead use AD groups and replicate them using Active Directory Connector (ADC) in Microsoft Entra ID (former Azure AD). ", + "guid": "2d41e361-1cc5-47b4-a4b1-410d43958a8c", + "id": "D01.06", + "link": "https://docs.microsoft.com/azure/virtual-desktop/manage-app-groups", "services": [ - "AVD" + "AVD", + "Entra" ], "severity": "Medium", - "subcategory": "Golden Images", - "text": "If custom image will be used, check recommended best practices for AVD on how to build custom image", - "waf": "Operations" + "subcategory": "Active Directory", + "text": "Create a domain user group for each set of users that will be granted access to each Host Pool Application Group (DAG or RAG)", + "waf": "Security" }, { - "category": "Compute", + "category": "Identity", "checklist": "Azure Virtual Desktop Review", - "description": "FSLogix stack installed in AVD session hosts does not provide auto-update capability. For this reason, it is recommended to download the latest version of FSLogix and include in the golden image update process.", - "guid": "ed5c9027-dd1a-4343-86ca-52b199223186", - "id": "B01.07", - "link": "https://learn.microsoft.com/fslogix/how-to-install-fslogix", + "description": "If Azure Files Active Directory (AD) integration is used, as part of the configuration procedure, an AD account to represent the storage account (file share) will be created. You can choose to register as a computer account or service logon account, see FAQ for details. For computer accounts, there is a default password expiration age set in AD at 30 days. Similarly, the service logon account may have a default password expiration age set on the AD domain or Organizational Unit (OU). For both account types, we recommend you check the password expiration age configured in your AD environment and plan to update the password of your storage account identity of the AD account before the maximum password age. You can consider creating a new AD Organizational Unit (OU) in AD and disabling password expiration policy on computer accounts or service logon accounts accordingly.", + "guid": "2289b3d6-b57c-4fc6-9546-1e1a3e3453a3", + "id": "D01.07", + "link": "https://docs.microsoft.com/azure/storage/files/storage-files-identity-ad-ds-enable", "services": [ - "AVD" + "AVD", + "Storage", + "AzurePolicy", + "Entra" ], "severity": "High", - "subcategory": "Golden Images", - "text": "Include the latest version of FSLogix in the golden image update process", - "waf": "Reliability" + "subcategory": "Active Directory", + "text": "Review your organization password expiration policy for accounts used by Azure Files AD integration", + "waf": "Security" }, { - "category": "Compute", + "category": "Identity", "checklist": "Azure Virtual Desktop Review", - "description": "This tool-set has been created to automatically apply setting referenced in white paper 'Optimizing Windows 10, version 2004 for a Virtual Desktop Infrastructure (VDI) role': https://docs.microsoft.com/windows-server/remote/remote-desktop-services/rds-vdi-recommendations-2004. Usage of the tool and/or optimizations mentioned in the white-paper should be considered. ", - "guid": "829e3fec-2183-4687-a017-7a2b5945bda4", - "id": "B01.08", - "link": "https://github.com/The-Virtual-Desktop-Team/Virtual-Desktop-Optimization-Tool", + "description": "You can configure this using Active Directory Connect (ADC) or Azure AD Domain Services (for hybrid or cloud organizations). Microsoft Entra ID is the new name for Azure Active Directory (Azure AD).", + "guid": "5119bf8e-8f58-4542-a7d9-cec166cd072a", + "id": "D01.08", + "link": "https://learn.microsoft.com/azure/virtual-desktop/prerequisites?tabs=portal#identity", "services": [ - "RBAC", - "AVD" + "AVD", + "Entra" ], - "severity": "Low", - "subcategory": "Golden Images", - "text": "Evaluate the usage of Virtual-Desktop-Optimization-Tool", - "waf": "Performance" + "severity": "High", + "subcategory": "Active Directory", + "text": "A Windows Server Active Directory forest/domain must be in sync with Microsoft Entra ID", + "waf": "Reliability" }, { - "category": "Compute", + "category": "Identity", "checklist": "Azure Virtual Desktop Review", - "description": "If OneDrive is used and included in a golden image, be sure to follow the configuration procedure reported in the companion article in the 'More Info' section. Not in scope in this AVD checklist, but OneDrive optimizations like 'Known Folder Redirection' and 'Files On-Demand' should be evaluated used to reduce the space used in FSLogix profiles and provide a better user experience. OneDrive today is not supported for Remote Apps.", - "guid": "e3d3e084-4276-4d4b-bc01-5bcf219e4a1e", - "id": "B01.09", - "link": "https://learn.microsoft.com/azure/virtual-desktop/install-office-on-wvd-master-image#install-onedrive-in-per-machine-mode", + "description": "If Azure Files is used and pre-requisites can be satisfied, it is recommended to configure (Microsoft Entra ID) Kerberos authentication. This configuration will allow to store FSLogix profiles that can be accessed by hybrid user identities from Azure AD-joined session hosts without requiring network line-of-sight to domain controllers.", + "guid": "e777fd5e-c5f1-4d6e-8fa9-fc210b88e338", + "id": "D02.01", + "link": "https://learn.microsoft.com/azure/storage/files/storage-files-identity-auth-hybrid-identities-enable", "services": [ + "AVD", "Storage", - "AVD" + "Entra" ], - "severity": "Low", - "subcategory": "Golden Images", - "text": "Determine if Microsoft OneDrive will be part of AVD deployment", - "waf": "Operations" + "severity": "Medium", + "subcategory": "Microsoft Entra ID", + "text": "Configure Azure Files share for Microsoft Entra ID (former Azure AD) Kerberos authentication on Microsoft Entra ID Joined scenario", + "waf": "Security" }, { - "category": "Compute", + "category": "Identity", "checklist": "Azure Virtual Desktop Review", - "description": "Be sure to review the requirements and configuration procedure contained in the companion article in the 'More Info' column. Since Teams automatic updates will be disabled, it is recommended to check and include Teams latest version in the golden image update process.", - "guid": "b5887953-5d22-4788-9d30-b66c67be5951", - "id": "B01.10", - "link": "https://learn.microsoft.com/azure/virtual-desktop/teams-on-AVD", + "description": "An Azure subscription must be parented to the same Microsoft Entra ID (former Azure AD) tenant, that contains a virtual network that either contains or is connected to the Windows Server Active Directory Domain Services or Microsoft Entra ID Domain Services instance.", + "guid": "6ceb5443-5125-4922-9442-93bb628537a5", + "id": "D03.01", + "link": "https://learn.microsoft.com/azure/virtual-desktop/prerequisites?tabs=portal#identity", "services": [ - "AVD" + "VNet", + "AVD", + "Subscriptions", + "Entra" ], - "severity": "Low", - "subcategory": "Golden Images", - "text": "Determine if Microsoft Teams will be part of AVD deployment", - "waf": "Performance" + "severity": "High", + "subcategory": "Requirements", + "text": "A Microsoft Entra ID tenant must be available with at least one subscription linked", + "waf": "Reliability" }, { - "category": "Compute", + "category": "Identity", "checklist": "Azure Virtual Desktop Review", - "description": "AVD can support users with different language and localization requirements in the same host pool. This can be done customizing golden images to ensure users can select whichever language they need. The procedure to configure additional language packs in Windows 11 is documented in the reference article.", - "guid": "7c336f3b-822a-498e-8cd1-667d1150df4a", - "id": "B01.11", - "link": "https://learn.microsoft.com/azure/virtual-desktop/windows-11-language-packs", + "description": "Azure Virtual Desktop supports different types of identities depending on which configuration you choose. Please review the supported scenarios mentioned in the 'More Info' article and document the design decision accordingly in the 'Comment' column. Critically, external identities (B2B or B2C) are not supported. Be sure to review also the list of supported scenarios in https://learn.microsoft.com/azure/virtual-desktop/prerequisites?tabs=portal#supported-identity-scenarios.", + "guid": "b4ce4781-7557-4a1f-8043-332ae199d44c", + "id": "D03.02", + "link": "https://learn.microsoft.com/azure/virtual-desktop/authentication", "services": [ - "AVD" + "AVD", + "Entra" ], - "severity": "Low", - "subcategory": "Golden Images", - "text": "Assess the requirement to support multiple languages", - "waf": "Reliability" + "severity": "High", + "subcategory": "Requirements", + "text": "Review and document your identity scenario", + "waf": "Security" }, { - "category": "Compute", + "category": "Identity", "checklist": "Azure Virtual Desktop Review", - "description": "It is highly recommended to use separate storage accounts/shares to store MSIX packages. If necessary, storage can scale out independently and not being impacted by profile I/O activities. Azure offers multiple storage options that can be used for MISX app attach. We recommend using Azure Files or Azure NetApp Files as those options offer the best value between cost and management overhead. ", - "guid": "90083845-c587-4cb3-a1ec-16a1d076ef9f", - "id": "B02.01", - "link": "https://docs.microsoft.com/azure/virtual-desktop/app-attach-file-share", + "description": "Users need accounts that are in Microsoft Entra ID (former Azure AD). If you're also using AD DS or Azure AD Domain Services in your deployment of Azure Virtual Desktop, these accounts will need to be hybrid identities, which means the user accounts are synchronized. If you're using Microsoft Entra ID with AD DS, you'll need to configure Azure AD Connect to synchronize user identity data between AD DS and Microsoft Entra ID. If you're using Microsoft Entra ID with Azure AD Domain Services, user accounts are synchronized one way from Microsoft Entra ID to Azure AD Domain Services. This synchronization process is automatic. AVD also supports Microsoft Entra ID native accounts with some restrictions. External identities (B2B or B2C) are not supported.", + "guid": "f9b141a8-98a5-435e-9378-97e71ca7da7b", + "id": "D03.03", + "link": "https://learn.microsoft.com/azure/virtual-desktop/prerequisites?tabs=portal#supported-identity-scenarios", "services": [ - "Storage", "AVD", - "Cost" + "Entra" ], "severity": "Medium", - "subcategory": "MSIX & AppAttach", - "text": "Do not use the same storage account/share as FSLogix profiles", - "waf": "Performance" + "subcategory": "Requirements", + "text": "Assess User Account types and requirements", + "waf": "Security" }, { - "category": "Compute", + "category": "Identity", "checklist": "Azure Virtual Desktop Review", - "description": "In the referenced article, we reported few but important performance considerations for MSIX usage in AVD context, be sure to carefully review.", - "guid": "241addce-5793-477b-adb3-751ab2ac1fad", - "id": "B02.02", - "link": "https://docs.microsoft.com/azure/virtual-desktop/app-attach-file-share", + "description": "AVD supports SSO using either Active Directory Federation Services (AD FS) or Microsoft Entra ID (former Azure AD) authentication. The latter is recommended, please check the requirements and limitation in the 'More Info' article. Using AD FS could be a viable choice if already present in the customer environment, it is not recommended to deploy a brand new ADFS infrastructure just for AVD SSO implementation.", + "guid": "5f9f680a-ba07-4429-bbf7-93d7071561f4", + "id": "D03.04", + "link": "https://learn.microsoft.com/azure/virtual-desktop/authentication#single-sign-on-sso", "services": [ - "AVD" + "AVD", + "Entra" ], "severity": "Medium", - "subcategory": "MSIX & AppAttach", - "text": "Review performance considerations for MSIX", - "waf": "Performance" + "subcategory": "Requirements", + "text": "If Single-Sign On (SSO) is a requirement, review the supported scenarios and prerequisites", + "waf": "Reliability" }, { - "category": "Compute", + "category": "Identity", "checklist": "Azure Virtual Desktop Review", - "description": "MSIX app attach requires read-only permissions to access the file share. If you're storing your MSIX applications in Azure Files, then for your session hosts, you'll need to assign all session host VMs both storage account role-based access control (RBAC) and file share New Technology File System (NTFS) permissions on the share.", - "guid": "66e15d4d-5a2a-4db2-a3e2-326bf225ca41", - "id": "B02.03", - "link": "https://docs.microsoft.com/azure/virtual-desktop/app-attach-file-share", + "description": "VMs can be Windows Active Directory (AD) domain-joined, Hybrid AD-joined, Microsoft Entra ID (former Azure AD) Joined or Azure AD Domain Services joined. Be sure to review supported scenarios, limitations and requirements from the referenced article.", + "guid": "ea962a15-9394-46da-a7cc-3923266b2258", + "id": "D03.05", + "link": "https://learn.microsoft.com/azure/virtual-desktop/prerequisites?tabs=portal#supported-identity-scenarios", "services": [ "VM", - "Storage", - "RBAC", - "AVD" + "AVD", + "Entra" ], - "severity": "Medium", - "subcategory": "MSIX & AppAttach", - "text": "Check proper session host permissions for MSIX share", + "severity": "High", + "subcategory": "Requirements", + "text": "Select the proper AVD Session Host domain join type", "waf": "Security" }, { - "category": "Compute", + "category": "Identity", "checklist": "Azure Virtual Desktop Review", - "description": "3rd-party software vendor must provide a MSIX package, it is not recommended for customer to attempt the conversion procedure without proper support from the application owner.", - "guid": "bd362caa-ab79-4b19-adab-81932c9fc9d1", - "id": "B02.04", - "link": "https://docs.microsoft.com/azure/virtual-desktop/app-attach-faq", + "description": "Compare self-managed Windows Active Directory Domain Services, Microsoft Entra ID (former Azure AD), and managed Azure AD Domain Services (AAD-DS)", + "guid": "6f4a1651-bddd-4ea8-a487-cdeb4861bc3b", + "id": "D03.06", + "link": "https://docs.microsoft.com/azure/active-directory-domain-services/compare-identity-solutions", "services": [ - "AVD" + "AVD", + "Entra" ], "severity": "Low", - "subcategory": "MSIX & AppAttach", - "text": "MSIX packages for 3rd-party applications", - "waf": "Cost" + "subcategory": "Requirements", + "text": "Before using Azure AD Domain Services (AAD-DS) for AVD, be sure to review the limitations.", + "waf": "Reliability" }, { - "category": "Compute", + "category": "Monitoring and Management", "checklist": "Azure Virtual Desktop Review", - "description": "MSIX app attach doesn't support auto-update for MSIX applications, so they should be disabled.", - "guid": "bb88037f-5e6b-4fbb-aed5-03547cc447e8", - "id": "B02.05", - "link": "https://docs.microsoft.com/azure/virtual-desktop/app-attach-faq", + "description": "AVD provides administrative templates for Intune and Active Directory GPO. Using these templates it is possible to centrally control several AVD configuration settings: Graphics related data logging, Screen capture protection, RDP Shortpath for managed networks, Watermarking. See companion article in 'More Info' colum for details. NOTE: FSLogix has its own separate template.", + "guid": "5549524b-36c0-4f1a-892b-ab3ca78f5db2", + "id": "E01.01", + "link": "https://learn.microsoft.com/azure/virtual-desktop/administrative-template", "services": [ - "AVD" + "Monitor", + "AVD", + "Entra" ], "severity": "Low", - "subcategory": "MSIX & AppAttach", - "text": "Disable auto-update for MSIX packages", + "subcategory": "Management", + "text": "Use built-in provided administrative templates for AVD settings configuration", "waf": "Operations" }, { - "category": "Compute", - "checklist": "Azure Virtual Desktop Review", - "description": "In order to leverage MSIX & App Attach, guest OS image for AVD Host pool must be Windows 10/11 Enterprise or Windows 10/11 Enterprise Multi-session, version 2004 or later.", - "guid": "26128a71-f0f1-4cac-9d9e-f1d5e832e42e", - "id": "B02.06", - "link": "https://docs.microsoft.com/azure/virtual-desktop/app-attach-faq", - "services": [ - "AVD" - ], - "severity": "Medium", - "subcategory": "MSIX & AppAttach", - "text": "Review operating systems support", - "waf": "Reliability" - }, - { - "category": "Compute", + "category": "Monitoring and Management", "checklist": "Azure Virtual Desktop Review", - "description": "Once selected the VM SKU that will be used for Host Pool deployment, it is recommended to use Gen2 type of the SKU for higher security and improved capabilities.", - "guid": "e4633254-3185-40a1-b120-bd563a1c8e9d", - "id": "B03.01", - "link": "https://docs.microsoft.com/azure/virtual-machines/generation-2", + "description": "Determine if a configuration management tool is already in place to manage Host Pool VM configuration after initial deployment, For example SCCM/SCOM, Intune/ConfigurationManager, 3rd-party solutions.", + "guid": "3334fdf9-1c23-4418-8b65-285269440b4b", + "id": "E01.02", + "link": "https://learn.microsoft.com/azure/virtual-desktop/management", "services": [ + "Monitor", "VM", "AVD" ], - "severity": "Medium", - "subcategory": "Session Host", - "text": "Evaluate the usage of Gen2 VM for Host Pool deployment", - "waf": "Performance" + "severity": "Low", + "subcategory": "Management", + "text": "Plan AVD Session Hosts configuration management strategy", + "waf": "Operations" }, { - "category": "Compute", + "category": "Monitoring and Management", "checklist": "Azure Virtual Desktop Review", - "description": "MMR redirects the media content from Session Host to your local machine for faster processing and rendering. It only works when you play media content on Microsoft Edge or Google Chrome. See linked URL for more details.", - "guid": "adecb27f-dc40-40f5-aca2-0090f633b1c9", - "id": "B03.02", - "link": "https://learn.microsoft.com/azure/virtual-desktop/multimedia-redirection", + "description": "We recommend using Microsoft Intune, if requirements can be satisfied, to manage your Azure Virtual Desktop environment. Review supported scenarios and requirements to enable Intune for AVD Session Host management in the referenced article in the “More Info” column. Document your choice in the 'Comment' column. In that article, review the different requirements and capabilities for single-session https://learn.microsoft.com/mem/intune/fundamentals/windows-virtual-desktop and multi-session https://learn.microsoft.com/mem/intune/fundamentals/windows-virtual-desktop-multi-session AVD.", + "guid": "63a08be1-6004-4b4a-a79b-f3239faae113", + "id": "E01.03", + "link": "https://learn.microsoft.com/mem/intune/fundamentals/azure-virtual-desktop", "services": [ + "Monitor", "AVD" ], - "severity": "Low", - "subcategory": "Session Host", - "text": "Consider using MMR (MultiMedia Redirection) to get better video performance on browser", - "waf": "Performance" + "severity": "Medium", + "subcategory": "Management", + "text": "Evaluate Intune for AVD Session Hosts management", + "waf": "Operations" }, { - "category": "Foundation", + "category": "Monitoring and Management", "checklist": "Azure Virtual Desktop Review", - "description": "A host pool is a collection of Azure virtual machines that register to Azure Virtual Desktop as session hosts. A host pool can be one of two types: Personal and Pooled. Which type to use, and how many, is a key design decision that must be documented and validated. See companion article in 'More Info' column for more details.", - "guid": "8468c55a-775c-46ee-a5b8-6ad8844ce3b2", - "id": "C01.01", - "link": "https://learn.microsoft.com/azure/virtual-desktop/terminology#host-pools", + "description": "The scaling tool provides a low-cost automation option for customers who want to optimize their session host VM costs. You can use the scaling tool to schedule VMs to start and stop based on Peak and Off-Peak business hours, scale out VMs based on number of sessions per CPU core, scale in VMs during Off-Peak hours, leaving the minimum number of session host VMs running. Not available yet for Personal Host Pool type.", + "guid": "7138b820-102c-4e16-be30-1e6e872e52e3", + "id": "E01.04", + "link": "https://learn.microsoft.com/azure/virtual-desktop/autoscale-scenarios", "services": [ + "Monitor", "VM", + "Cost", "AVD" ], - "severity": "High", - "subcategory": "Capacity Planning", - "text": "Determine the Host Pool type to use", - "waf": "Cost" + "severity": "Medium", + "subcategory": "Management", + "text": "Assess the requirements for host pool auto-scaling capability", + "waf": "Reliability" }, { - "category": "Foundation", + "category": "Monitoring and Management", "checklist": "Azure Virtual Desktop Review", - "description": "Use your design criteria to determine the number of Host Pools to deploy. This will be based on factors such as different OS images, multi-region support, guest VM hardware differences (such as GPU support or no), different user expectations and uptime requirements (examples might be 'Executives', 'Office Workers', 'Developers', etc.), and Host Pool RDP settings (such as drive redirection support). These will determine the number of host pools as well as how many hosts will be in each pool.", - "guid": "4e98495f-d3c0-4af2-aa59-a793395a32a7", - "id": "C01.02", - "link": "https://learn.microsoft.com/azure/virtual-desktop/terminology?WT.mc_id=Portal-fx#host-pools", + "description": "Start VM On Connect lets you reduce costs by enabling end users to turn on their session host virtual machines (VMs) only when they need them. You can then turn off VMs when they're not needed. You can configure Start VM on Connect for personal or pooled host pools using the Azure portal or PowerShell. Start VM on Connect is a host pool wide setting.", + "guid": "55f612fe-f215-4f0d-a956-10e7dd96bcbc", + "id": "E01.05", + "link": "https://learn.microsoft.com/azure/virtual-desktop/start-virtual-machine-connect", "services": [ + "Monitor", "VM", + "Cost", "AVD" ], - "severity": "High", - "subcategory": "Capacity Planning", - "text": "Estimate the number of different Host Pools to deploy ", - "waf": "Performance" + "severity": "Low", + "subcategory": "Management", + "text": "Consider the usage of Start VM on Connect for Personal Host Pools", + "waf": "Cost" }, { - "category": "Foundation", + "category": "Monitoring and Management", "checklist": "Azure Virtual Desktop Review", - "description": "Confirm that the difference between automatic and direct assignment is well understood and the selected option is appropriate for the scenario in question. Automatic is the default setting.", - "guid": "b38b875b-a1cf-4204-a901-3a5d3ce474db", - "id": "C01.03", - "link": "https://docs.microsoft.com/azure/virtual-desktop/configure-host-pool-personal-desktop-assignment-type", + "description": "'Start VM On Connect' provides a smart way to automatically start previously stopped Session Hosts but does not provide a mechanism to shut down when not in used. Administrators are encouraged to configure additional policies to sign users out of their sessions and run Azure automation scripts to de-allocate VMs. Users should be not allowed to shut down their Personal Hosts since will not be able to de-allocate Azure VMs, then billing will still be active with no cost reduction.", + "guid": "79a686ea-d971-4ea0-a9a8-1aea074c94cb", + "id": "E01.06", + "link": "https://learn.microsoft.com/azure/virtual-desktop/start-virtual-machine-connect-faq#are-vms-automatically-deallocated-when-a-user-stops-using-them", "services": [ - "AVD" + "VM", + "AVD", + "AzurePolicy", + "Monitor", + "Cost" ], "severity": "Low", - "subcategory": "Capacity Planning", - "text": "For Personal Host Pool type, select the proper assignment type", - "waf": "Operations" + "subcategory": "Management", + "text": "Evaluate the implementation of an ad-hoc mechanism to shut down Personal AVD Session Hosts", + "waf": "Cost" }, { - "category": "Foundation", + "category": "Monitoring and Management", "checklist": "Azure Virtual Desktop Review", - "description": "Check which one to use and available options, autoscale ignores existing load-balancing algorithms.", - "guid": "cbd8682a-6abc-4a2a-9fda-1dbf3dc95d48", - "id": "C01.04", - "link": "https://docs.microsoft.com/azure/virtual-desktop/host-pool-load-balancing", + "description": "Azure Virtual Desktop billing is mainly based on cost associated to compute, networking and storage resources consumed by Host Pools. In addition to this, costs can be generated by dependent resources, for example VPN or ExpressRoute or vWAN, Active Directory Domain Controllers, DNS, etc. There is no direct cost associated to AVD objects like workspaces, host pools or application groups. To make AVD associated costs more evident and grouped by Host Pool, it is recommended to use 'cm-resource-parent' tag. ", + "guid": "51bcafca-476a-48fa-9b91-9645a7679f20", + "id": "E01.07", + "link": "https://learn.microsoft.com/azure/virtual-desktop/tag-virtual-desktop-resources", "services": [ - "AVD" + "AVD", + "Monitor", + "Cost", + "VWAN", + "ExpressRoute", + "Storage", + "DNS", + "VPN" ], "severity": "Low", - "subcategory": "Capacity Planning", - "text": "For Pooled Host Pool type, select the best load balancing method", - "waf": "Performance" + "subcategory": "Management", + "text": "Review and adopt suggested Azure Tags for Azure Virtual Desktop", + "waf": "Cost" }, { - "category": "Foundation", + "category": "Monitoring and Management", "checklist": "Azure Virtual Desktop Review", - "description": "The number of cores increase, the system's synchronization overhead also increases. Especially for multiple user's sign-in simultaneously. Make sure not to use a VM that is too large for the session host", - "guid": "b3724959-4943-4577-a3a9-e10ff6345f24", - "id": "C01.05", - "link": "https://learn.microsoft.com/windows-server/remote/remote-desktop-services/virtual-machine-recs", + "description": "Azure Advisor analyzes your configurations and telemetry to offer personalized recommendations to solve common problems. With these recommendations, you can optimize your Azure resources for reliability, security, operational excellence, performance, and cost.", + "guid": "611dd68c-5a4b-4252-8e44-a59a9c2399c4", + "id": "E01.08", + "link": "https://learn.microsoft.com/azure/virtual-desktop/azure-advisor-recommendations", "services": [ - "VM", - "AVD" + "Monitor", + "Cost", + "AVD", + "Entra" ], - "severity": "Medium", - "subcategory": "Capacity Planning", - "text": "For Pooled Host Pool type, VMs shouldn't have more than 32 cores", - "waf": "Performance" + "severity": "Low", + "subcategory": "Management", + "text": "Periodically check Azure Advisor recommendations for AVD", + "waf": "Operations" }, { - "category": "Foundation", + "category": "Monitoring and Management", "checklist": "Azure Virtual Desktop Review", - "description": "AVD does not support assigning both the RemoteApp and Desktop Application Group (DAG) in a single host pool to the same set of users. Doing so will cause a single user to have two user sessions in a single host pool. Users aren't supposed to have two active sessions at the same time in the same host pool using the same profile.", - "guid": "b384b7ed-1cdd-457e-a2cd-c8d4d55bc144", - "id": "C01.06", - "link": "https://learn.microsoft.com/azure/virtual-desktop/terminology?WT.mc_id=Portal-fx#application-groups", + "description": "Customers have several options: Microsoft Configuration Manager, this article explains how to automatically apply updates to a Azure Virtual Desktop session hosts running Windows 10/11: https://learn.microsoft.com/azure/virtual-desktop/configure-automatic-updates, Microsoft Intune: https://docs.microsoft.com/mem/intune/fundamentals/windows-virtual-desktop-multi-session, Azure Update Management and WSUS for Windows Server OS only (client OS not supported: https://learn.microsoft.com/azure/automation/update-management/operating-system-requirements), 3rd Party tools. Outside an emergency security patching situation, it is recommended to move away from an 'in-place' update strategy patching strategy and adopt a re-imaging approach.", + "guid": "04722da2-9c2b-41cd-922f-54b29bade3aa", + "id": "E01.09", + "link": "https://learn.microsoft.com/mem/intune/fundamentals/azure-virtual-desktop-multi-session", "services": [ - "Storage", + "Monitor", "AVD" ], - "severity": "High", - "subcategory": "Capacity Planning", - "text": "Do not use the same Host Pool to offer both full desktops (DAG) and Remote Apps to the same set of users", - "waf": "Security" + "severity": "Medium", + "subcategory": "Management", + "text": "Plan for a Session Host emergency patching and update strategy", + "waf": "Operations" }, { - "category": "Foundation", + "category": "Monitoring and Management", "checklist": "Azure Virtual Desktop Review", - "description": "There is a limit of 500 Application Groups that can be created in AVD for each Microsoft Entra ID (former Azure AD) tenant. The limit can be increased (see the companion link for details) but it is not recommended.", - "guid": "971cc4a4-b1f7-4c12-90e0-1ad96808f00c", - "id": "C01.07", - "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits#azure-virtual-desktop-service-limits", + "description": "The Scheduled Agent Updates feature lets you create up to two maintenance windows per Host Pool to update AVD components at a convenient time. It is recommended to specify maintenance windows then upgrading Session Hosts will not happen during peak business hours. Scheduled Agent Updates is disabled by default. This means that, unless you enable this setting, the agent can get updated at any time by the agent update flighting service.", + "guid": "c067939b-e5ca-4698-b9ce-3bd91843e73f", + "id": "E01.10", + "link": "https://learn.microsoft.com/azure/virtual-desktop/scheduled-agent-updates", "services": [ - "ACR", - "AVD", - "Entra" + "Monitor", + "AVD" ], - "severity": "Medium", - "subcategory": "Capacity Planning", - "text": "Estimate the number of Application Groups required across all Host Pools in the Microsoft Entra ID tenant", + "severity": "Low", + "subcategory": "Management", + "text": "Configure the Scheduled Agent Updates feature", "waf": "Reliability" }, { - "category": "Foundation", + "category": "Monitoring and Management", "checklist": "Azure Virtual Desktop Review", - "description": "Applications are grouped under Application Groups as containers for publishing and assigning permissions: we recommend that you do not publish more than 50 applications per application group.", - "guid": "fa9f2895-473d-439b-ab8e-5a5cf92c7f32", - "id": "C01.08", - "link": "https://learn.microsoft.com/azure/architecture/example-scenario/wvd/windows-virtual-desktop#considerations", + "description": "Host pools are a collection of one or more identical virtual machines within Azure Virtual Desktop environment. We highly recommend you create a validation host pool where service updates are applied first. This allows you to monitor service updates before the service applies them to your standard or non-validation environment.", + "guid": "d1e8c38e-c936-4667-913c-005674b1e944", + "id": "E01.11", + "link": "https://docs.microsoft.com/azure/virtual-desktop/create-validation-host-pool", "services": [ + "Monitor", + "VM", "AVD" ], - "severity": "Low", - "subcategory": "Capacity Planning", - "text": "Estimate the number of Applications for each Application Group", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "Management", + "text": "Create a validation (canary) Host Pool", + "waf": "Operations" }, { - "category": "Foundation", + "category": "Monitoring and Management", "checklist": "Azure Virtual Desktop Review", - "description": "FSLogix is not required for Personal Host Pools since each VM is statically assigned to a single user, then no immediate needs for a roaming profile solution. In some usage scenarios FSLogix can help. For example, a VM can be re-assigned, or user moved to another desktop, or roaming profile can be used to save user profile in a different location for DR purposes.", - "guid": "38b19ab6-0693-4992-9394-5590883916ec", - "id": "C01.09", - "link": "https://learn.microsoft.com/azure/virtual-desktop/configure-host-pool-personal-desktop-assignment-type?tabs=azure#reassign-a-personal-desktop", + "description": "An AVD Host Pool can be deployed in several ways: Azure Portal, ARM templates, Azure CLI tool, Powershell, manual VM creation with registration token, Terraform, 3rd-party tools. It is important to adopt proper method/s to support automatic deployment through automation and CI/CD tools.", + "guid": "a459c373-e7ed-4616-83b3-65a917ecbe48", + "id": "E01.12", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/wvd/eslz-platform-automation-and-devops", "services": [ + "Monitor", "VM", - "Storage", "AVD" ], - "severity": "Low", - "subcategory": "Capacity Planning", - "text": "Evaluate the usage of FSLogix for Personal Host Pools", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "Management", + "text": "Determine Host Pool deployment strategy", + "waf": "Operations" }, { - "category": "Foundation", + "category": "Monitoring and Management", "checklist": "Azure Virtual Desktop Review", - "description": "Use the link provided to set a starting point for SKU decision, then validate using a performance test. Ensure a minimum of four cores for Production is selected per Session Host (multi-session)", - "guid": "e1112dbd-7ba0-412e-9b94-ef6e047d2ea2", - "id": "C01.10", - "link": "https://docs.microsoft.com/windows-server/remote/remote-desktop-services/virtual-machine-recs", + "description": "After you register a VM to a host pool within the Azure Virtual Desktop service, the agent regularly refreshes the VM's token whenever the VM is active. The certificate for the registration token is valid for 90 days. Because of this 90-day limit, we recommend VMs to be online for 20 minutes every 90 days so that the machine can refresh its tokens and update the agent and side-by-side stack components.", + "guid": "ebe54cd7-df2e-48bb-ac35-81559bb9153e", + "id": "E01.13", + "link": "https://docs.microsoft.com/azure/virtual-desktop/faq", "services": [ + "Monitor", "VM", "AVD" ], - "severity": "High", - "subcategory": "Capacity Planning", - "text": "Run workload performance test to determine the best Azure VM SKU and size to use", - "waf": "Performance" + "severity": "Medium", + "subcategory": "Management", + "text": "Turn on Session Host VMs at least every 90 days for token refresh", + "waf": "Operations" }, { - "category": "Foundation", + "category": "Monitoring and Management", "checklist": "Azure Virtual Desktop Review", - "description": "It is critical to check AVD capacity and limits reported in the referenced article. Additional limits and thresholds apply for network, compute, storage and service management. ", - "guid": "992b1cd6-d2f5-44b2-a769-e3a691e8838a", - "id": "C01.11", - "link": "https://learn.microsoft.com/azure/architecture/example-scenario/wvd/windows-virtual-desktop#considerations", + "description": "Azure Virtual Desktop Insights is a dashboard built on Azure Monitor Workbooks that helps IT professionals understand their Azure Virtual Desktop environments. Read the referenced article to learn how to set up Azure Monitor for Azure Virtual Desktop to monitor your AVD environments.", + "guid": "63cfff1c-ac59-49ef-8d5a-83dd4de36c1c", + "id": "E02.01", + "link": "https://learn.microsoft.com/azure/virtual-desktop/insights", "services": [ - "Storage", + "Monitor", "AVD" ], "severity": "High", - "subcategory": "Capacity Planning", - "text": "Verify AVD scalability limits for the environment", + "subcategory": "Monitoring", + "text": "Enable monitoring for AVD", "waf": "Reliability" }, { - "category": "Foundation", + "category": "Monitoring and Management", "checklist": "Azure Virtual Desktop Review", - "description": "Host Pools with GPU require special configuration, please be sure to review the referenced article.", - "guid": "c936667e-13c0-4056-94b1-e945a459837e", - "id": "C01.12", - "link": "https://docs.microsoft.com/azure/virtual-desktop/configure-vm-gpu", + "description": "Azure Virtual Desktop uses Azure Monitor and Log Analytics for monitoring and alerts like many other Azure services. This lets admins identify issues through a single interface. The service creates activity logs for both user and administrative actions. Each activity log falls under the following categories: Management, Feed, Connections, Host Registration, Errors, Checkpoints. ", + "guid": "81770afb-c4c0-4e43-a186-58d2857ed671", + "id": "E02.02", + "link": "https://docs.microsoft.com/azure/virtual-desktop/diagnostics-log-analytics", "services": [ + "Monitor", + "VM", "AVD" ], - "severity": "Low", - "subcategory": "Capacity Planning", - "text": "Determine if Session Hosts will require GPU", - "waf": "Performance" + "severity": "Medium", + "subcategory": "Monitoring", + "text": "Enable diagnostic settings for Workspaces, Host Pools, Application Groups and Host VMs to Log Analytics workspace", + "waf": "Reliability" }, { - "category": "Foundation", + "category": "Monitoring and Management", "checklist": "Azure Virtual Desktop Review", - "description": "Whenever is possible, it is recommended to leverage VM SKUs with Accelerated Networking feature. This feature does require specific VM SKU/size and OS versions, please see the list and requirement in the companion article.", - "guid": "b47a393a-0803-4272-a479-8b1578b219a4", - "id": "C01.13", - "link": "https://learn.microsoft.com/azure/virtual-network/accelerated-networking-overview", + "description": "See the referenced article and this additional one to setup proper monitoring and alerting for storage: https://docs.microsoft.com/azure/storage/files/storage-troubleshooting-files-performance. ", + "guid": "2463cffe-179c-4599-be0d-5973dd4ce32c", + "id": "E02.03", + "link": "https://docs.microsoft.com/azure/storage/files/storage-files-monitoring?tabs=azure-portal", "services": [ - "VM", - "AVD" + "Monitor", + "AVD", + "Storage" ], - "severity": "Low", - "subcategory": "Capacity Planning", - "text": "Use Azure VM SKUs able to leverage Accelerated Networking", - "waf": "Performance" + "severity": "Medium", + "subcategory": "Monitoring", + "text": "Create alerts on the profile storage to be alerted in case of high usage and throttling", + "waf": "Reliability" }, { - "category": "Foundation", + "category": "Monitoring and Management", "checklist": "Azure Virtual Desktop Review", - "description": "For proper planning and deployment, it is important to assess the maximum number of concurrent and total users for each Host Pool. Additionally, users from different regions may require different Host Pools to ensure the best user experience.", - "guid": "bb91a33d-90ca-4e2c-a881-3706f7c0cb9f", - "id": "C02.01", - "link": "https://learn.microsoft.com/azure/virtual-desktop/overview", + "description": "You can use Azure Service Health to monitor service issues and health advisories for Azure Virtual Desktop. Azure Service Health can notify you with different types of alerts (for example, email or SMS), help you understand the effect of an issue, and keep you updated as the issue resolves.", + "guid": "18813706-f7c4-4c0d-9e51-4548d2457ed6", + "id": "E02.04", + "link": "https://docs.microsoft.com/azure/virtual-desktop/set-up-service-alerts", "services": [ + "Monitor", "AVD" ], "severity": "Medium", - "subcategory": "Clients & Users", - "text": "Assess how many users will connect to AVD and from which regions", - "waf": "Performance" + "subcategory": "Monitoring", + "text": "Configure Azure Service Health for AVD alerts ", + "waf": "Reliability" }, { - "category": "Foundation", + "category": "Networking", "checklist": "Azure Virtual Desktop Review", - "description": "The dependencies on resources external to the AVD pool should be assessed and reviewed, for example Active Directory, external file shares or other storage, on-premises services and resources, network infrastructure components like VPN and or ExpressRoute, external services and 3rd-party components. For all these resources, latency from the AVD Host Pool needs to be evaluated and connectivity considered. Additionally, BCDR considerations need to be applied to these dependencies as well.", - "guid": "6abca2a4-fda1-4dbf-9dc9-5d48c7c791dc", - "id": "C02.02", - "link": "https://learn.microsoft.com/azure/architecture/example-scenario/wvd/windows-virtual-desktop?toc=%2Fazure%2Fvirtual-desktop%2Ftoc.json&bc=%2Fazure%2Fvirtual-desktop%2Fbreadcrumb%2Ftoc.json", + "description": "If required to connect to on-premises environment, assess the current connectivity option or plan for the required connectivity (ExpressRoute, Azure S2S or 3rd-party NVA VPN). ", + "guid": "dd399cfd-7b28-4dc8-9555-6202bfe4563b", + "id": "F01.01", + "link": "https://docs.microsoft.com/azure/architecture/reference-architectures/hybrid-networking/", "services": [ - "Storage", "ExpressRoute", "AVD", + "NVA", "VPN" ], "severity": "Medium", - "subcategory": "Clients & Users", - "text": "Assess external dependencies for each Host Pool", - "waf": "Performance" + "subcategory": "Networking", + "text": "Determine if hybrid connectivity is required to connect to on-premises environment", + "waf": "Reliability" }, { - "category": "Foundation", + "category": "Networking", "checklist": "Azure Virtual Desktop Review", - "description": "AVD offers a variety of client types (fat, thin, web) to connect over different platforms (Windows, MacOS, iOS, Android). Review limitations of each client and compare multiple options when possible.", - "guid": "a1f6d565-99e5-458b-a37d-4985e1112dbd", - "id": "C02.03", - "link": "https://learn.microsoft.com/azure/virtual-desktop/users/connect-windows", + "description": "AVD Host Pools can be deployed in either Azure Virtual WAN or traditional 'Hub & Spoke' network topologies. It is recommended to deploy each Host Pool in a separate 'spoke' VNet, using 'hub' is not recommended.", + "guid": "c8639648-a652-4d6c-85e5-02965388e5de", + "id": "F01.02", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/wvd/eslz-network-topology-and-connectivity", "services": [ + "VWAN", + "VNet", "AVD" ], - "severity": "Low", - "subcategory": "Clients & Users", - "text": "Review user client OS used and AVD client type", + "severity": "Medium", + "subcategory": "Networking", + "text": "Determine Azure Virtual Network (VNet) placement for each AVD Host Pool", "waf": "Performance" }, { - "category": "Foundation", + "category": "Networking", "checklist": "Azure Virtual Desktop Review", - "description": "Depending on the user locations, and AVD region deployment, users may have a non-optimal experience, hence is important to test as soon as possible in a small PoC environment. Run the 'Azure Virtual Desktop Experience Estimator' tool to select the best Azure region to deploy Host Pools. Beyond 150ms latency, user experience may be not optimal.", - "guid": "d2f54b29-769e-43a6-a1e8-838ac936667e", - "id": "C02.04", - "link": "https://azure.microsoft.com/services/virtual-desktop/assessment/", + "description": "Evaluate the bandwidth requirements, ensure VPN/ER bandwidth will be enough, ensure proper routing and firewall rules are in place, test end-to-end latency. ", + "guid": "d227dd14-2b06-4c21-a799-9a646f4389a7", + "id": "F01.03", + "link": "https://docs.microsoft.com/azure/architecture/reference-architectures/hybrid-networking/", "services": [ - "AVD" + "AVD", + "VPN" ], - "severity": "High", - "subcategory": "Clients & Users", - "text": "Run a PoC to validate end-to-end user experience and impact of network latency", - "waf": "Performance" + "severity": "Medium", + "subcategory": "Networking", + "text": "Assess which on-premises resources are required from AVD Host Pools", + "waf": "Reliability" }, { - "category": "Foundation", + "category": "Networking", "checklist": "Azure Virtual Desktop Review", - "description": "RDP settings can currently only be configured at the host pool level, not per user/group. If different settings are required for different set of users, it is recommended to create multiple Host Pools.", - "guid": "3b365a5c-7acb-4e48-abe5-4cd79f2e8776", - "id": "C02.05", - "link": "https://docs.microsoft.com/azure/virtual-desktop/customize-rdp-properties", + "description": "Several options are available. You can use Azure Firewall or equivalent 3rd-party NVA, Network Security Group (NSG) and/or Proxy servers. NSG is not able to enable/disable by URL, only ports and protocols. Proxy should be used only as explicit setting in user browser. Details on using Azure Firewall Premium with AVD are reported in the companion article in the 'More Info' column. Be sure to allow proper access to required AVD URLs. Forced Tunneling to on-premises is not recommended.", + "guid": "fc4972cd-3cd2-41bf-9703-6e5e6b4bed3d", + "id": "F01.04", + "link": "https://docs.microsoft.com/azure/firewall/protect-windows-virtual-desktop", "services": [ - "AVD" + "NVA", + "VNet", + "AVD", + "Firewall" ], - "severity": "Low", - "subcategory": "Clients & Users", - "text": "Assess and document RDP settings for all user groups", + "severity": "Medium", + "subcategory": "Networking", + "text": "Need to control/restrict Internet outbound traffic for AVD hosts?", "waf": "Security" }, { - "category": "Foundation", + "category": "Networking", "checklist": "Azure Virtual Desktop Review", - "description": "AVD is a non-regional service, Host Pools can be created in any region, automatic redirection from closest front-end will happen automatically.", - "guid": "42e52f47-21d9-428c-8b1b-d521e44a29a9", - "id": "C03.01", - "link": "https://azure.microsoft.com/global-infrastructure/services/?products=virtual-desktop", + "description": "Required URLs for AVD control plane access by session hosts are documented here: https://docs.microsoft.com/azure/virtual-desktop/safe-url-list. A check tool is available to verify connectivity from the session hosts: https://docs.microsoft.com/azure/virtual-desktop/safe-url-list#required-url-check-tool. Forced Tunneling to on-premises is not recommended.", + "guid": "65c7acbe-45bb-4e60-ad89-f2e87778424d", + "id": "F01.05", + "link": "https://docs.microsoft.com/azure/virtual-desktop/safe-url-list", "services": [ "AVD" ], "severity": "High", - "subcategory": "General", - "text": "Determine in which Azure regions AVD Host Pools will be deployed.", - "waf": "Performance" - }, - { - "category": "Foundation", - "checklist": "Azure Virtual Desktop Review", - "description": "AVD must store metadata to support the service; this is stored in the specified geography. However, this is independent of the regions where Host Pools are located.", - "guid": "bad37ead-53cc-47ce-8d7a-aab3571449ab", - "id": "C03.02", - "link": "https://docs.microsoft.com/azure/virtual-desktop/data-locations", - "services": [ - "AVD" - ], - "severity": "Medium", - "subcategory": "General", - "text": "Determine metadata location for AVD service", + "subcategory": "Networking", + "text": "Ensure AVD control plane endpoints are accessible", "waf": "Reliability" }, { - "category": "Foundation", + "category": "Networking", "checklist": "Azure Virtual Desktop Review", - "description": "Check for specific VM SKUs, especially if you need GPU or high-specs SKUs, and eventually Azure NetApp Files if used.", - "guid": "8053d89e-89dc-47b3-9be2-a1a27f7a9e91", - "id": "C03.03", - "link": "https://docs.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits", + "description": "Consider the usage of Azure Defender Endpoint or similar 3rd-party agents to control user web navigation, see the Security section for more details.", + "guid": "73676ae4-6691-4e88-95ad-a42223e13810", + "id": "F01.06", + "link": "https://learn.microsoft.com/microsoft-365/security/defender-endpoint/onboard-windows-multi-session-device?view=o365-worldwide", "services": [ - "VM", - "Storage", - "AVD" + "AVD", + "Defender" ], - "severity": "Low", - "subcategory": "General", - "text": "Check Azure quotas and availability for specific VM sizes and types in the selected regions", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "Networking", + "text": "Need to control/restrict Internet outbound traffic only for users on AVD hosts? ", + "waf": "Security" }, { - "category": "Identity", + "category": "Networking", "checklist": "Azure Virtual Desktop Review", - "description": "AD DCs in Azure are recommended (at least two in different AZ) to reduce latency for users logging into AVD session hosts, and eventually for Azure NetApp Files and AD integration. A DC need to be able to talk to DCs for ALL child domains. As alternative, on-premise connectivity must be used to reach AD DCs.", - "guid": "c14aea7e-65e8-4d9a-9aec-218e6436b073", - "id": "D01.01", - "link": "https://docs.microsoft.com/azure/architecture/reference-architectures/identity/adds-extend-domain", + "description": "Custom UDR and NSG can be applied to AVD Host Pool subnets, for example to redirect to Azure Firewall or NVA, or to filter/block network traffic. In this case is recommended to carefully review to ensure optimal path for outbound traffic to AVD control plane is used. Service Tags can now be used with UDR and NSG, then AVD management plane traffic can be easily allowed: https://learn.microsoft.com/azure/virtual-desktop/safe-url-list.", + "guid": "523181a9-4174-4158-93ff-7ae7c6d37431", + "id": "F01.07", + "link": "https://docs.microsoft.com/azure/firewall/protect-windows-virtual-desktop", "services": [ - "Storage", + "NVA", "VNet", "AVD", - "Entra" + "Firewall" ], - "severity": "Medium", - "subcategory": "Active Directory", - "text": "Create at least two Active Directory Domain Controllers (DCs) in Azure VNet environment close to AVD Host Pool", - "waf": "Reliability" + "severity": "Low", + "subcategory": "Networking", + "text": "Review custom UDR and NSG for AVD Host Pool subnets", + "waf": "Security" }, { - "category": "Identity", + "category": "Networking", "checklist": "Azure Virtual Desktop Review", - "description": "Recommended to create a separate OU per Host Pool under a separate OU hierarchy. These OUs will contain machine accounts of AVD Session Hosts. ", - "guid": "6db55f57-9603-4334-adf9-cc23418db612", - "id": "D01.02", - "link": "https://docs.microsoft.com/azure/virtual-desktop/create-host-pools-azure-marketplace", + "description": "Network traffic from AVD Session Host VMs to AVD control plane should be as direct as possible. Redirecting this traffic through a Proxy or Firewall with deep packet inspection and/or SSL termination could cause serious issues and bad customer experience. It is recommended to bypass Proxy and Firewall just for the AVD control plane. User generated traffic surfing the web instead, should be filtered by Firewall and/or redirected to a Proxy. For details and guidelines, please see the companion article in the 'More Info' column.", + "guid": "cc6edca0-aeca-4566-9e92-cf246f1465af", + "id": "F01.08", + "link": "https://learn.microsoft.com/azure/virtual-desktop/proxy-server-support", "services": [ - "AVD", - "Entra" + "VM", + "AVD" ], - "severity": "Medium", - "subcategory": "Active Directory", - "text": "Create a specific OU in Active Directory for each Host Pool", - "waf": "Operations" + "severity": "High", + "subcategory": "Networking", + "text": "Do not use Proxy servers, SSL termination and Deep Packet Inspection for AVD control plane traffic", + "waf": "Reliability" }, { - "category": "Identity", + "category": "Networking", "checklist": "Azure Virtual Desktop Review", - "description": "Carefully review, and potentially block/filter inheritance of GPOs to the OUs containing AVD Host Pools. ", - "guid": "7126504b-b47a-4393-a080-327294798b15", - "id": "D01.03", - "link": "https://docs.microsoft.com/previous-versions/windows/desktop/Policy/group-policy-hierarchy", + "description": "It is recommended to assess and review networking bandwidth requirements for users, based on the specific workload type. The referenced article provide general estimations and recommendations, but specific measure are required for proper sizing. ", + "guid": "516785c6-fa96-4c96-ad88-408f372734c8", + "id": "F01.09", + "link": "https://learn.microsoft.com/azure/virtual-desktop/rdp-bandwidth", "services": [ - "AVD", - "Entra" + "VM", + "AVD" ], - "severity": "Medium", - "subcategory": "Active Directory", - "text": "Review Domain GPOs that will be applied to OU and impacting Host Pool Session Hosts functionalities", - "waf": "Operations" + "severity": "Low", + "subcategory": "Networking", + "text": "Check the network bandwidth required for each user and in total for the VM SKU", + "waf": "Performance" }, { - "category": "Identity", + "category": "Networking", "checklist": "Azure Virtual Desktop Review", - "description": "If Active Directory Domain GPOs are used, it is recommended to configure FSLogix using the built-in provided GPO ADMX template referenced in the companion article in the 'More Info' column", - "guid": "2226a8e3-50a4-4ac3-8bd6-ee150553051f", - "id": "D01.04", - "link": "https://learn.microsoft.com/fslogix/how-to-use-group-policy-templates", + "description": "If Azure Files SMB share will be used to store user profiles via FSLogix, the usage of Private Endpoint (PE) for private access to the storage is recommended. AVD Session Hosts will access the storage using a private IP in the same VNet, a separate subnet is recommended. This feature has an additional cost that must be evaluated. If PE will not be used, at least Service Endpoint is recommended (no cost associated).", + "guid": "ec27d589-9178-426d-8df2-ff60020f30a6", + "id": "F01.10", + "link": "https://learn.microsoft.com/azure/storage/files/storage-files-networking-endpoints", "services": [ "AVD", - "Entra" + "Cost", + "PrivateLink", + "Storage", + "VNet" ], "severity": "Medium", - "subcategory": "Active Directory", - "text": "Configure FSLogix settings using the built-in provided GPO ADMX template", - "waf": "Operations" + "subcategory": "Networking", + "text": "Evaluate usage Private Endpoint for Azure Files share", + "waf": "Security" }, { - "category": "Identity", + "category": "Networking", "checklist": "Azure Virtual Desktop Review", - "description": "It is recommended to have a specific dedicated account with minimal permissions, and without the default 10 joins limitation. Review the companion article for more details.", - "guid": "347dc560-28a7-41ff-b1cd-15dd2f0d5e77", - "id": "D01.05", - "link": "https://learn.microsoft.com/azure/virtual-desktop/prerequisites?tabs=portal#session-hosts", + "description": "Connections to Azure Virtual Desktop can use TCP or UDP. RDP Shortpath is a feature of AVD that establishes a direct UDP-based transport between a supported Windows Remote Desktop client and session host. if clients have line of sight to AVD session hosts from internal network (VPN usage is not recommended), this feature can provide lower latency and best performances as explained in https://learn.microsoft.com/azure/virtual-desktop/rdp-shortpath?tabs=managed-networks#key-benefits.", + "guid": "b2074747-d01a-4f61-b1aa-92ad793d9ff4", + "id": "F01.11", + "link": "https://docs.microsoft.com/azure/virtual-desktop/shortpath", "services": [ - "VM", "AVD", - "Entra" - ], - "severity": "Medium", - "subcategory": "Active Directory", - "text": "Create a dedicated user account with only permissions to join VM to the domain", - "waf": "Security" + "VPN" + ], + "severity": "Medium", + "subcategory": "Networking", + "text": "Evaluate usage of RDP ShortPath for clients connecting from managed internal networks", + "waf": "Performance" }, { - "category": "Identity", + "category": "Security", "checklist": "Azure Virtual Desktop Review", - "description": "Avoid granting access per user, instead use AD groups and replicate them using Active Directory Connector (ADC) in Microsoft Entra ID (former Azure AD). ", - "guid": "2d41e361-1cc5-47b4-a4b1-410d43958a8c", - "id": "D01.06", - "link": "https://docs.microsoft.com/azure/virtual-desktop/manage-app-groups", + "description": "Security mechanisms provided by GPO should be used, if available. For example, it is possible to impose desktop screen lock and idle session disconnection time. Existing GPOs applied to on-premises environment should be reviewed and eventually applied also to secure also AVD Hosts when joined to the domain.", + "guid": "a135e337-897e-431c-97d6-8cb6a22ac19f", + "id": "G01.01", + "link": "https://learn.microsoft.com/azure/virtual-desktop/security-guide#establish-maximum-inactive-time-and-disconnection-policies", "services": [ - "AVD", - "Entra" + "AVD" ], "severity": "Medium", "subcategory": "Active Directory", - "text": "Create a domain user group for each set of users that will be granted access to each Host Pool Application Group (DAG or RAG)", + "text": "Review Active Directory GPO to secure RDP sessions", "waf": "Security" }, { - "category": "Identity", + "category": "Security", "checklist": "Azure Virtual Desktop Review", - "description": "If Azure Files Active Directory (AD) integration is used, as part of the configuration procedure, an AD account to represent the storage account (file share) will be created. You can choose to register as a computer account or service logon account, see FAQ for details. For computer accounts, there is a default password expiration age set in AD at 30 days. Similarly, the service logon account may have a default password expiration age set on the AD domain or Organizational Unit (OU). For both account types, we recommend you check the password expiration age configured in your AD environment and plan to update the password of your storage account identity of the AD account before the maximum password age. You can consider creating a new AD Organizational Unit (OU) in AD and disabling password expiration policy on computer accounts or service logon accounts accordingly.", - "guid": "2289b3d6-b57c-4fc6-9546-1e1a3e3453a3", - "id": "D01.07", - "link": "https://docs.microsoft.com/azure/storage/files/storage-files-identity-ad-ds-enable", + "description": "Microsoft Defender for Endpoint supports Azure Virtual Desktop for Windows 10/11 Enterprise multi-session. Check article for onboarding non-persistent virtual desktop infrastructure (VDI) devices: https://docs.microsoft.com/windows/security/threat-protection/microsoft-defender-atp/configure-endpoints-vdi", + "guid": "b1172576-9ef6-4691-a483-5ac932223ece", + "id": "G02.01", + "link": "https://learn.microsoft.com/microsoft-365/security/defender-endpoint/deployment-vdi-microsoft-defender-antivirus", "services": [ - "AzurePolicy", - "Storage", "AVD", - "Entra" + "Defender" ], "severity": "High", - "subcategory": "Active Directory", - "text": "Review your organization password expiration policy for accounts used by Azure Files AD integration", + "subcategory": "Host Configuration", + "text": "Ensure anti-virus and anti-malware solutions are used", "waf": "Security" }, { - "category": "Identity", + "category": "Security", "checklist": "Azure Virtual Desktop Review", - "description": "You can configure this using Active Directory Connect (ADC) or Azure AD Domain Services (for hybrid or cloud organizations). Microsoft Entra ID is the new name for Azure Active Directory (Azure AD).", - "guid": "5119bf8e-8f58-4542-a7d9-cec166cd072a", - "id": "D01.08", - "link": "https://learn.microsoft.com/azure/virtual-desktop/prerequisites?tabs=portal#identity", + "description": "Disks in Azure are already encrypted at rest by default with Microsoft managed keys. Host VM OS disk encryption is possible and supported using Azure Disk Encryption (ADE - BitLocker) and Disk Encryption Set (DES - Server Side Encryption), the latter is recommended. Encryption of FSLogix storage using Azure Files can be done using SSE on Azure Storage. For OneDrive encryption, see this article: https://docs.microsoft.com/compliance/assurance/assurance-encryption-for-microsoft-365-services.", + "guid": "0fd32907-98bc-4178-adc5-a06ca7144351", + "id": "G02.02", + "link": "https://learn.microsoft.com/azure/virtual-machines/disk-encryption-overview", "services": [ + "VM", "AVD", - "Entra" + "Storage", + "AKV" ], - "severity": "High", - "subcategory": "Active Directory", - "text": "A Windows Server Active Directory forest/domain must be in sync with Microsoft Entra ID", - "waf": "Reliability" + "severity": "Low", + "subcategory": "Host Configuration", + "text": "Assess disk encryption requirements for AVD Session Hosts", + "waf": "Security" }, { - "category": "Identity", + "category": "Security", "checklist": "Azure Virtual Desktop Review", - "description": "If Azure Files is used and pre-requisites can be satisfied, it is recommended to configure (Microsoft Entra ID) Kerberos authentication. This configuration will allow to store FSLogix profiles that can be accessed by hybrid user identities from Azure AD-joined session hosts without requiring network line-of-sight to domain controllers.", - "guid": "e777fd5e-c5f1-4d6e-8fa9-fc210b88e338", - "id": "D02.01", - "link": "https://learn.microsoft.com/azure/storage/files/storage-files-identity-auth-hybrid-identities-enable", + "description": "Trusted launch are Gen2 Azure VMs with enhanced security features aimed to protect against “bottom of the stack” threats through attack vectors such as rootkits, boot kits, and kernel-level malware. Recommended to enable and leverage Secure Boot, Virtual TPM (vTPM) and Integrity Monitoring.", + "guid": "36a5a67f-bb9e-4d5b-9547-8c4479816b28", + "id": "G02.03", + "link": "https://learn.microsoft.com/azure/virtual-desktop/security-guide#azure-virtual-desktop-support-for-trusted-launch", "services": [ - "Storage", - "AVD", - "Entra" + "Monitor", + "VM", + "AVD" ], "severity": "Medium", - "subcategory": "Microsoft Entra ID", - "text": "Configure Azure Files share for Microsoft Entra ID (former Azure AD) Kerberos authentication on Microsoft Entra ID Joined scenario", + "subcategory": "Host Configuration", + "text": "Enable Trusted launch in Azure Gen2 VM Session Hosts", "waf": "Security" }, { - "category": "Identity", + "category": "Security", "checklist": "Azure Virtual Desktop Review", - "description": "An Azure subscription must be parented to the same Microsoft Entra ID (former Azure AD) tenant, that contains a virtual network that either contains or is connected to the Windows Server Active Directory Domain Services or Microsoft Entra ID Domain Services instance.", - "guid": "6ceb5443-5125-4922-9442-93bb628537a5", - "id": "D03.01", - "link": "https://learn.microsoft.com/azure/virtual-desktop/prerequisites?tabs=portal#identity", + "description": "Trusted Launch and Gen2 VM are not only security and performance enhancing features but also system requirements for Windows 11. When building an AVD environment based on Windows 11, it is essential to enable these features.", + "guid": "135d3899-4b31-44d3-bc8f-028871a359d8", + "id": "G02.04", + "link": "https://learn.microsoft.com/windows/whats-new/windows-11-requirements", "services": [ - "Entra", - "VNet", - "AVD", - "Subscriptions" + "VM", + "AVD" ], "severity": "High", - "subcategory": "Requirements", - "text": "A Microsoft Entra ID tenant must be available with at least one subscription linked", - "waf": "Reliability" + "subcategory": "Host Configuration", + "text": "Enable Trusted Launch and use Gen2 image are system requirements for Windows 11", + "waf": "Security" }, { - "category": "Identity", + "category": "Security", "checklist": "Azure Virtual Desktop Review", - "description": "Azure Virtual Desktop supports different types of identities depending on which configuration you choose. Please review the supported scenarios mentioned in the 'More Info' article and document the design decision accordingly in the 'Comment' column. Critically, external identities (B2B or B2C) are not supported. Be sure to review also the list of supported scenarios in https://learn.microsoft.com/azure/virtual-desktop/prerequisites?tabs=portal#supported-identity-scenarios.", - "guid": "b4ce4781-7557-4a1f-8043-332ae199d44c", - "id": "D03.02", - "link": "https://learn.microsoft.com/azure/virtual-desktop/authentication", + "description": "Displayed content will be automatically blocked or hidden in screenshots. Keep in mind screen sharing will also be blocked when using Teams or other collaboration software which use screen sharing.", + "guid": "a49dc137-7896-4343-b2bc-1a31bf1d30b6", + "id": "G02.05", + "link": "https://learn.microsoft.com/azure/virtual-desktop/screen-capture-protection", "services": [ - "AVD", - "Entra" + "AVD" ], - "severity": "High", - "subcategory": "Requirements", - "text": "Review and document your identity scenario", + "severity": "Low", + "subcategory": "Host Configuration", + "text": "Consider enabling screen capture protection to prevent sensitive information from being captured", "waf": "Security" }, { - "category": "Identity", + "category": "Security", "checklist": "Azure Virtual Desktop Review", - "description": "Users need accounts that are in Microsoft Entra ID (former Azure AD). If you're also using AD DS or Azure AD Domain Services in your deployment of Azure Virtual Desktop, these accounts will need to be hybrid identities, which means the user accounts are synchronized. If you're using Microsoft Entra ID with AD DS, you'll need to configure Azure AD Connect to synchronize user identity data between AD DS and Microsoft Entra ID. If you're using Microsoft Entra ID with Azure AD Domain Services, user accounts are synchronized one way from Microsoft Entra ID to Azure AD Domain Services. This synchronization process is automatic. AVD also supports Microsoft Entra ID native accounts with some restrictions. External identities (B2B or B2C) are not supported.", - "guid": "f9b141a8-98a5-435e-9378-97e71ca7da7b", - "id": "D03.03", - "link": "https://learn.microsoft.com/azure/virtual-desktop/prerequisites?tabs=portal#supported-identity-scenarios", + "description": "If not absolutely required, redirecting drives, printers, and USB devices to a user's local device in a remote desktop session should be disabled or highly restricted. Restrict Windows Explorer access by hiding local and remote drive mappings is also a secure measure to adopt preventing users from discovering unwanted information about system configuration and users.", + "guid": "7ce2cd20-85b4-4f82-828e-6558736ede6a", + "id": "G02.06", + "link": "https://learn.microsoft.com/azure/virtual-desktop/security-guide#other-security-tips-for-session-hosts", "services": [ - "AVD", - "Entra" + "AVD" ], "severity": "Medium", - "subcategory": "Requirements", - "text": "Assess User Account types and requirements", + "subcategory": "Host Configuration", + "text": "Restrict device redirection and drive mapping", "waf": "Security" }, { - "category": "Identity", + "category": "Security", "checklist": "Azure Virtual Desktop Review", - "description": "AVD supports SSO using either Active Directory Federation Services (AD FS) or Microsoft Entra ID (former Azure AD) authentication. The latter is recommended, please check the requirements and limitation in the 'More Info' article. Using AD FS could be a viable choice if already present in the customer environment, it is not recommended to deploy a brand new ADFS infrastructure just for AVD SSO implementation.", - "guid": "5f9f680a-ba07-4429-bbf7-93d7071561f4", - "id": "D03.04", - "link": "https://learn.microsoft.com/azure/virtual-desktop/authentication#single-sign-on-sso", + "description": "When choosing a deployment model, you can either provide remote users access to entire virtual desktops or only select applications. Remote applications, or RemoteApps, provide a seamless experience as the user works with apps on their virtual desktop. RemoteApps reduce risk by only letting the user work with a subset of the remote machine exposed by the application.", + "guid": "4e25d70e-3924-44f4-b66f-d6cdd4f4a973", + "id": "G03.01", + "link": "https://learn.microsoft.com/microsoft-365/security/defender-endpoint/web-protection-overview", "services": [ - "AVD", - "Entra" + "AVD" ], "severity": "Medium", - "subcategory": "Requirements", - "text": "If Single-Sign On (SSO) is a requirement, review the supported scenarios and prerequisites", - "waf": "Reliability" + "subcategory": "Management", + "text": "When possible, prefer Remote Apps over Full Desktops (DAG)", + "waf": "Security" }, { - "category": "Identity", + "category": "Security", "checklist": "Azure Virtual Desktop Review", - "description": "VMs can be Windows Active Directory (AD) domain-joined, Hybrid AD-joined, Microsoft Entra ID (former Azure AD) Joined or Azure AD Domain Services joined. Be sure to review supported scenarios, limitations and requirements from the referenced article.", - "guid": "ea962a15-9394-46da-a7cc-3923266b2258", - "id": "D03.05", - "link": "https://learn.microsoft.com/azure/virtual-desktop/prerequisites?tabs=portal#supported-identity-scenarios", + "description": "Web content filtering feature provided by Web Protection capability in Microsoft Defender for Endpoint, can be used to to control user web navigation. If this tool is used, configuration of web filtering for user Internet browsing is recommended. Access by the Guest OS system to required AVD control plane URLs must be guaranteed.", + "guid": "e19dd344-29eb-4722-a237-a151c5bb4e4f", + "id": "G03.02", + "link": "https://learn.microsoft.com/microsoft-365/security/defender-endpoint/web-protection-overview", "services": [ - "VM", "AVD", - "Entra" + "Defender" ], - "severity": "High", - "subcategory": "Requirements", - "text": "Select the proper AVD Session Host domain join type", + "severity": "Medium", + "subcategory": "Management", + "text": "Need to control/restrict user Internet navigation from AVD session hosts?", "waf": "Security" }, { - "category": "Identity", + "category": "Security", "checklist": "Azure Virtual Desktop Review", - "description": "Compare self-managed Windows Active Directory Domain Services, Microsoft Entra ID (former Azure AD), and managed Azure AD Domain Services (AAD-DS)", - "guid": "6f4a1651-bddd-4ea8-a487-cdeb4861bc3b", - "id": "D03.06", - "link": "https://docs.microsoft.com/azure/active-directory-domain-services/compare-identity-solutions", + "description": "We recommend you don't grant your users admin access to virtual desktops. If you need software packages, we recommend you make them available through configuration management utilities.", + "guid": "a0cdb3b5-4eb2-4eb0-9dda-a3592718e2ed", + "id": "G03.03", + "link": "https://docs.microsoft.com/azure/virtual-desktop/security-guide", "services": [ - "AVD", - "Entra" + "AVD" ], - "severity": "Low", - "subcategory": "Requirements", - "text": "Before using Azure AD Domain Services (AAD-DS) for AVD, be sure to review the limitations.", - "waf": "Reliability" + "severity": "High", + "subcategory": "Management", + "text": "Ensure AVD users will not have local administrator privileges on AVD Hosts", + "waf": "Security" }, { - "category": "Monitoring and Management", + "category": "Security", "checklist": "Azure Virtual Desktop Review", - "description": "AVD provides administrative templates for Intune and Active Directory GPO. Using these templates it is possible to centrally control several AVD configuration settings: Graphics related data logging, Screen capture protection, RDP Shortpath for managed networks, Watermarking. See companion article in 'More Info' colum for details. NOTE: FSLogix has its own separate template.", - "guid": "5549524b-36c0-4f1a-892b-ab3ca78f5db2", - "id": "E01.01", - "link": "https://learn.microsoft.com/azure/virtual-desktop/administrative-template", + "description": "We recommend you enable Defender for Cloud for the subscriptions, virtual machines, key vaults, and storage accounts used by AVD. With this tool is possible to assess and manage vulnerabilities, assess compliance with common frameworks like PCI, strengthen the overall security of your AVD environment and measure it over time using 'Secure Score': https://learn.microsoft.com/azure/virtual-desktop/security-guide#improve-your-secure-score.", + "guid": "1814387e-5ca9-4c26-a9b3-2ab5bdfc6998", + "id": "G03.04", + "link": "https://learn.microsoft.com/azure/virtual-desktop/security-guide#enable-microsoft-defender-for-cloud", "services": [ - "Monitor", + "VM", "AVD", - "Entra" + "AKV", + "Defender", + "Storage", + "Subscriptions" ], - "severity": "Low", + "severity": "Medium", "subcategory": "Management", - "text": "Use built-in provided administrative templates for AVD settings configuration", - "waf": "Operations" + "text": "Enable Microsoft Defender for Cloud to manage AVD Session Hosts security posture", + "waf": "Security" }, { - "category": "Monitoring and Management", + "category": "Security", "checklist": "Azure Virtual Desktop Review", - "description": "Determine if a configuration management tool is already in place to manage Host Pool VM configuration after initial deployment, For example SCCM/SCOM, Intune/ConfigurationManager, 3rd-party solutions.", - "guid": "3334fdf9-1c23-4418-8b65-285269440b4b", - "id": "E01.02", - "link": "https://learn.microsoft.com/azure/virtual-desktop/management", + "description": "Enabling audit log collection lets you view user and admin activity related to Azure Virtual Desktop and store in a central repository like Log Analytics workspace. ", + "guid": "a0916a76-4980-4ad0-b278-ee293c1bc352", + "id": "G03.05", + "link": "https://learn.microsoft.com/azure/virtual-desktop/security-guide#collect-audit-logs", "services": [ - "VM", "Monitor", - "AVD" + "AVD", + "Entra" ], - "severity": "Low", + "severity": "Medium", "subcategory": "Management", - "text": "Plan AVD Session Hosts configuration management strategy", - "waf": "Operations" + "text": "Enable diagnostic and audit logging", + "waf": "Security" }, { - "category": "Monitoring and Management", + "category": "Security", "checklist": "Azure Virtual Desktop Review", - "description": "We recommend using Microsoft Intune, if requirements can be satisfied, to manage your Azure Virtual Desktop environment. Review supported scenarios and requirements to enable Intune for AVD Session Host management in the referenced article in the “More Info” column. Document your choice in the 'Comment' column. In that article, review the different requirements and capabilities for single-session https://learn.microsoft.com/mem/intune/fundamentals/windows-virtual-desktop and multi-session https://learn.microsoft.com/mem/intune/fundamentals/windows-virtual-desktop-multi-session AVD.", - "guid": "63a08be1-6004-4b4a-a79b-f3239faae113", - "id": "E01.03", - "link": "https://learn.microsoft.com/mem/intune/fundamentals/azure-virtual-desktop", + "description": "Assign the least privilege required by defining administrative, operations, and engineering roles to Azure RBAC roles. To limit access to high privilege roles within your Azure Virtual Desktop landing zone, consider integration with Azure Privileged Identity Management (PIM). Maintaining knowledge of which team is responsible for each particular administrative area helps you determine Azure role-based access control (RBAC) roles and configuration.", + "guid": "baaab757-1849-4ab8-893d-c9fc9d1bb73b", + "id": "G03.06", + "link": "https://docs.microsoft.com/azure/virtual-desktop/rbac", "services": [ - "Monitor", - "AVD" + "RBAC", + "AVD", + "Entra" ], - "severity": "Medium", + "severity": "Low", "subcategory": "Management", - "text": "Evaluate Intune for AVD Session Hosts management", - "waf": "Operations" + "text": "Assess the requirement to use custom RBAC roles for AVD management", + "waf": "Security" }, { - "category": "Monitoring and Management", + "category": "Security", "checklist": "Azure Virtual Desktop Review", - "description": "The scaling tool provides a low-cost automation option for customers who want to optimize their session host VM costs. You can use the scaling tool to schedule VMs to start and stop based on Peak and Off-Peak business hours, scale out VMs based on number of sessions per CPU core, scale in VMs during Off-Peak hours, leaving the minimum number of session host VMs running. Not available yet for Personal Host Pool type.", - "guid": "7138b820-102c-4e16-be30-1e6e872e52e3", - "id": "E01.04", - "link": "https://learn.microsoft.com/azure/virtual-desktop/autoscale-scenarios", + "description": "AVD users should not have permission to install application. If required, Windows Defender Application Control (WDAC) can be used to control which drivers and applications are allowed to run on their Windows clients. ", + "guid": "b9ea80c8-0628-49fc-ae63-125aa4c0a284", + "id": "G03.07", + "link": "https://learn.microsoft.com/azure/virtual-desktop/security-guide#windows-defender-application-control", "services": [ - "VM", - "Monitor", "AVD", - "Cost" + "Defender" ], "severity": "Medium", "subcategory": "Management", - "text": "Assess the requirements for host pool auto-scaling capability", - "waf": "Reliability" + "text": "Restrict users from installing un-authorized applications", + "waf": "Security" }, { - "category": "Monitoring and Management", + "category": "Security", "checklist": "Azure Virtual Desktop Review", - "description": "Start VM On Connect lets you reduce costs by enabling end users to turn on their session host virtual machines (VMs) only when they need them. You can then turn off VMs when they're not needed. You can configure Start VM on Connect for personal or pooled host pools using the Azure portal or PowerShell. Start VM on Connect is a host pool wide setting.", - "guid": "55f612fe-f215-4f0d-a956-10e7dd96bcbc", - "id": "E01.05", - "link": "https://learn.microsoft.com/azure/virtual-desktop/start-virtual-machine-connect", + "description": "Enabling MFA and CA lets you manage risks before you grant users access to your AVD environment. When deciding which users to grant access to, we recommend you also consider who the user is, how they sign in, and which device they're using. Additional details and configuration procedures are provided in the companion article. Microsoft Entra ID is the new name for Azure Active Directory (Azure AD).", + "guid": "916d697d-8ead-4ed2-9bdd-186f1ac252b9", + "id": "G04.01", + "link": "https://learn.microsoft.com/azure/virtual-desktop/set-up-mfa", "services": [ - "VM", - "Monitor", "AVD", - "Cost" + "Entra" ], - "severity": "Low", - "subcategory": "Management", - "text": "Consider the usage of Start VM on Connect for Personal Host Pools", - "waf": "Cost" + "severity": "Medium", + "subcategory": "Microsoft Entra ID", + "text": "Evaluate the usage of Multi-Factor Authentication (MFA) and Conditional Access (CA) for AVD users", + "waf": "Security" }, { - "category": "Monitoring and Management", + "category": "Security", "checklist": "Azure Virtual Desktop Review", - "description": "'Start VM On Connect' provides a smart way to automatically start previously stopped Session Hosts but does not provide a mechanism to shut down when not in used. Administrators are encouraged to configure additional policies to sign users out of their sessions and run Azure automation scripts to de-allocate VMs. Users should be not allowed to shut down their Personal Hosts since will not be able to de-allocate Azure VMs, then billing will still be active with no cost reduction.", - "guid": "79a686ea-d971-4ea0-a9a8-1aea074c94cb", - "id": "E01.06", - "link": "https://learn.microsoft.com/azure/virtual-desktop/start-virtual-machine-connect-faq#are-vms-automatically-deallocated-when-a-user-stops-using-them", + "description": "If Zero Trust is a requirement, review the companion article in the 'More Info' column. It provides steps to apply the principles of Zero Trust to an Azure Virtual Desktop deployment.", + "guid": "221102d0-90af-49fc-b2b7-8d3fe397e43", + "id": "G05.01", + "link": "https://learn.microsoft.com/security/zero-trust/azure-infrastructure-avd", "services": [ - "Cost", - "VM", - "AzurePolicy", - "Monitor", "AVD" ], - "severity": "Low", - "subcategory": "Management", - "text": "Evaluate the implementation of an ad-hoc mechanism to shut down Personal AVD Session Hosts", - "waf": "Cost" + "severity": "Medium", + "subcategory": "Zero Trust", + "text": "Review and Apply Zero Trust principles and guidance", + "waf": "Security" }, { - "category": "Monitoring and Management", + "category": "Storage", "checklist": "Azure Virtual Desktop Review", - "description": "Azure Virtual Desktop billing is mainly based on cost associated to compute, networking and storage resources consumed by Host Pools. In addition to this, costs can be generated by dependent resources, for example VPN or ExpressRoute or vWAN, Active Directory Domain Controllers, DNS, etc. There is no direct cost associated to AVD objects like workspaces, host pools or application groups. To make AVD associated costs more evident and grouped by Host Pool, it is recommended to use 'cm-resource-parent' tag. ", - "guid": "51bcafca-476a-48fa-9b91-9645a7679f20", - "id": "E01.07", - "link": "https://learn.microsoft.com/azure/virtual-desktop/tag-virtual-desktop-resources", + "description": "If used, make sure to check the list of best practices and recommendations described in the referenced article.", + "guid": "9164e990-9ae2-48c8-9c33-b6b7808bafe6", + "id": "H01.01", + "link": "https://learn.microsoft.com/azure/virtual-desktop/fslogix-containers-azure-files#best-practices-for-azure-virtual-desktop", "services": [ - "VPN", - "Cost", - "DNS", - "ExpressRoute", - "Monitor", "AVD", - "VWAN", "Storage" ], - "severity": "Low", - "subcategory": "Management", - "text": "Review and adopt suggested Azure Tags for Azure Virtual Desktop", - "waf": "Cost" + "severity": "Medium", + "subcategory": "Azure Files", + "text": "Check best-practices for Azure Files", + "waf": "Performance" }, { - "category": "Monitoring and Management", + "category": "Storage", "checklist": "Azure Virtual Desktop Review", - "description": "Azure Advisor analyzes your configurations and telemetry to offer personalized recommendations to solve common problems. With these recommendations, you can optimize your Azure resources for reliability, security, operational excellence, performance, and cost.", - "guid": "611dd68c-5a4b-4252-8e44-a59a9c2399c4", - "id": "E01.08", - "link": "https://learn.microsoft.com/azure/virtual-desktop/azure-advisor-recommendations", + "description": "SMB Multichannel enables clients to use multiple network connections that provide increased performance while lowering the cost of ownership. Increased performance is achieved through bandwidth aggregation over multiple NICs and utilizing Receive Side Scaling (RSS) support for NICs to distribute the IO load across multiple CPUs.", + "guid": "5784b6ca-5e9e-4bcf-8b54-c95459ea7369", + "id": "H01.02", + "link": "https://learn.microsoft.com/azure/storage/files/storage-files-smb-multichannel-performance", "services": [ + "ACR", "Cost", - "Monitor", "AVD", - "Entra" + "Storage" ], "severity": "Low", - "subcategory": "Management", - "text": "Periodically check Azure Advisor recommendations for AVD", - "waf": "Operations" + "subcategory": "Azure Files", + "text": "Enable SMB multichannel when using a premium file share to host FSLogix profile containers.", + "waf": "Performance" }, { - "category": "Monitoring and Management", + "category": "Storage", "checklist": "Azure Virtual Desktop Review", - "description": "Customers have several options: Microsoft Configuration Manager, this article explains how to automatically apply updates to a Azure Virtual Desktop session hosts running Windows 10/11: https://learn.microsoft.com/azure/virtual-desktop/configure-automatic-updates, Microsoft Intune: https://docs.microsoft.com/mem/intune/fundamentals/windows-virtual-desktop-multi-session, Azure Update Management and WSUS for Windows Server OS only (client OS not supported: https://learn.microsoft.com/azure/automation/update-management/operating-system-requirements), 3rd Party tools. Outside an emergency security patching situation, it is recommended to move away from an 'in-place' update strategy patching strategy and adopt a re-imaging approach.", - "guid": "04722da2-9c2b-41cd-922f-54b29bade3aa", - "id": "E01.09", - "link": "https://learn.microsoft.com/mem/intune/fundamentals/azure-virtual-desktop-multi-session", + "description": "If a second region is required for DR purposes verify NetApp availability in there as well.", + "guid": "4a359836-ee79-4d6c-9d3a-364a5b7abae3", + "id": "H02.01", + "link": "https://azure.microsoft.com/global-infrastructure/services/", "services": [ - "Monitor", - "AVD" + "AVD", + "Storage" ], "severity": "Medium", - "subcategory": "Management", - "text": "Plan for a Session Host emergency patching and update strategy", - "waf": "Operations" + "subcategory": "Azure NetApp Files", + "text": "If NetApp Files storage is required, check storage service availability in your specific region.", + "waf": "Reliability" }, { - "category": "Monitoring and Management", + "category": "Storage", "checklist": "Azure Virtual Desktop Review", - "description": "The Scheduled Agent Updates feature lets you create up to two maintenance windows per Host Pool to update AVD components at a convenient time. It is recommended to specify maintenance windows then upgrading Session Hosts will not happen during peak business hours. Scheduled Agent Updates is disabled by default. This means that, unless you enable this setting, the agent can get updated at any time by the agent update flighting service.", - "guid": "c067939b-e5ca-4698-b9ce-3bd91843e73f", - "id": "E01.10", - "link": "https://learn.microsoft.com/azure/virtual-desktop/scheduled-agent-updates", + "description": "CA option is a recommended setting in the FSLogix scenario, as it enables a more resilient SMB session between the Session Host and NetApp Files.", + "guid": "a2661898-866a-4c8d-9d1f-8cfc86e88024", + "id": "H02.02", + "link": "https://learn.microsoft.com/azure/virtual-desktop/create-fslogix-profile-container", "services": [ - "Monitor", - "AVD" + "AVD", + "Storage" ], - "severity": "Low", - "subcategory": "Management", - "text": "Configure the Scheduled Agent Updates feature", + "severity": "Medium", + "subcategory": "Azure NetApp Files", + "text": "If NetApp Files storage is used enable CA (Continuous Availability) option to increase resiliency", "waf": "Reliability" }, { - "category": "Monitoring and Management", + "category": "Storage", "checklist": "Azure Virtual Desktop Review", - "description": "Host pools are a collection of one or more identical virtual machines within Azure Virtual Desktop environment. We highly recommend you create a validation host pool where service updates are applied first. This allows you to monitor service updates before the service applies them to your standard or non-validation environment.", - "guid": "d1e8c38e-c936-4667-913c-005674b1e944", - "id": "E01.11", - "link": "https://docs.microsoft.com/azure/virtual-desktop/create-validation-host-pool", + "description": "An Active Directory Site should be created for the Azure virtual network environment where Azure NetApp Files (ANF) subnet will be created, and that site name should be specified in the ANF connection property when executing the join procedure as explained in the reference article.", + "guid": "6647e977-db49-48a8-bc35-743f17499d42", + "id": "H02.03", + "link": "https://docs.microsoft.com/azure/azure-netapp-files/create-active-directory-connections", "services": [ - "VM", - "Monitor", - "AVD" + "VNet", + "AVD", + "Storage" ], - "severity": "Medium", - "subcategory": "Management", - "text": "Create a validation (canary) Host Pool", - "waf": "Operations" + "severity": "High", + "subcategory": "Azure NetApp Files", + "text": "If Azure NetApp Files storage is used, check Active Directory Site name setting in the Active Directory Connection configuration", + "waf": "Reliability" }, { - "category": "Monitoring and Management", + "category": "Storage", "checklist": "Azure Virtual Desktop Review", - "description": "An AVD Host Pool can be deployed in several ways: Azure Portal, ARM templates, Azure CLI tool, Powershell, manual VM creation with registration token, Terraform, 3rd-party tools. It is important to adopt proper method/s to support automatic deployment through automation and CI/CD tools.", - "guid": "a459c373-e7ed-4616-83b3-65a917ecbe48", - "id": "E01.12", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/wvd/eslz-platform-automation-and-devops", + "description": "Possible options: Standard HDD, Standard SSD, or Premium SSD. Ephemeral disks are not supported, Ultra-Disks not recommended. Recommended to evaluate Premium for OS disk if user density is not low, and if Cloud Cache will be used. ", + "guid": "3611c818-b0a0-4bc5-80e4-3a18a9cd289c", + "id": "H03.01", + "link": "https://docs.microsoft.com/azure/virtual-machines/disks-types", "services": [ - "VM", - "Monitor", - "AVD" + "AVD", + "Storage" ], "severity": "Medium", - "subcategory": "Management", - "text": "Determine Host Pool deployment strategy", - "waf": "Operations" + "subcategory": "Capacity Planning", + "text": "Determine which type of managed disk will be used for the Session Hosts", + "waf": "Performance" }, { - "category": "Monitoring and Management", + "category": "Storage", "checklist": "Azure Virtual Desktop Review", - "description": "After you register a VM to a host pool within the Azure Virtual Desktop service, the agent regularly refreshes the VM's token whenever the VM is active. The certificate for the registration token is valid for 90 days. Because of this 90-day limit, we recommend VMs to be online for 20 minutes every 90 days so that the machine can refresh its tokens and update the agent and side-by-side stack components.", - "guid": "ebe54cd7-df2e-48bb-ac35-81559bb9153e", - "id": "E01.13", - "link": "https://docs.microsoft.com/azure/virtual-desktop/faq", + "description": "Possible options are: Azure NetApp Files, Azure Files, VM based File Server. File-server it is not recommended. Azure Files Premium typically a good starting point. NetApp usually required for large scale / high-performant environment. For a detailed comparison see the article in the 'More Info' column.", + "guid": "ed6b17db-8255-4462-b2ae-e4553afc8339", + "id": "H03.02", + "link": "https://docs.microsoft.com/azure/virtual-desktop/store-fslogix-profile", "services": [ "VM", - "Monitor", - "AVD" + "AVD", + "Storage" ], - "severity": "Medium", - "subcategory": "Management", - "text": "Turn on Session Host VMs at least every 90 days for token refresh", - "waf": "Operations" + "severity": "High", + "subcategory": "Capacity Planning", + "text": "Determine which storage backend solution will be used for FSLogix Profiles", + "waf": "Performance" }, { - "category": "Monitoring and Management", + "category": "Storage", "checklist": "Azure Virtual Desktop Review", - "description": "Azure Virtual Desktop Insights is a dashboard built on Azure Monitor Workbooks that helps IT professionals understand their Azure Virtual Desktop environments. Read the referenced article to learn how to set up Azure Monitor for Azure Virtual Desktop to monitor your AVD environments.", - "guid": "63cfff1c-ac59-49ef-8d5a-83dd4de36c1c", - "id": "E02.01", - "link": "https://learn.microsoft.com/azure/virtual-desktop/insights", + "description": "Every Host Pool should use a separate set of storage accounts/volumes (at least one) and shares. Users should have a different profile for each Host Pool since settings and configurations are specific to each Host Pool. Additionally, accessing different Host Pools at the same time can cause errors on the shared user profile VHD/X. Usage of different storage accounts/volumes for multiple shares is also recommended to scale independently.", + "guid": "2fad62bd-5004-453c-ace4-64d862e7f5a4", + "id": "H03.03", + "link": "https://learn.microsoft.com/azure/virtual-desktop/store-fslogix-profile", "services": [ - "Monitor", - "AVD" + "AVD", + "Storage" ], "severity": "High", - "subcategory": "Monitoring", - "text": "Enable monitoring for AVD", - "waf": "Reliability" + "subcategory": "Capacity Planning", + "text": "Do not share storage and profiles between different Host Pools", + "waf": "Performance" }, { - "category": "Monitoring and Management", + "category": "Storage", "checklist": "Azure Virtual Desktop Review", - "description": "Azure Virtual Desktop uses Azure Monitor and Log Analytics for monitoring and alerts like many other Azure services. This lets admins identify issues through a single interface. The service creates activity logs for both user and administrative actions. Each activity log falls under the following categories: Management, Feed, Connections, Host Registration, Errors, Checkpoints. ", - "guid": "81770afb-c4c0-4e43-a186-58d2857ed671", - "id": "E02.02", - "link": "https://docs.microsoft.com/azure/virtual-desktop/diagnostics-log-analytics", + "description": "As a starting point for estimating profile container storage performance requirements we recommend to assume 10 IOPS per user in the steady state and 50 IOPS per user during sign-in/sign-out. Space requirements is simply obtained based on the maximum profiles size in FSLogix per the total number of users for each Host Pool. Multiple storage accounts can be used for the same Host Pool if required.", + "guid": "680e7828-9c93-4665-9d02-bff4564b0d93", + "id": "H03.04", + "link": "https://learn.microsoft.com/azure/virtual-desktop/faq#what-s-the-largest-profile-size-fslogix-can-handle-", "services": [ - "VM", - "Monitor", - "AVD" + "AVD", + "Storage" ], - "severity": "Medium", - "subcategory": "Monitoring", - "text": "Enable diagnostic settings for Workspaces, Host Pools, Application Groups and Host VMs to Log Analytics workspace", + "severity": "High", + "subcategory": "Capacity Planning", + "text": "Verify storage scalability limits and Host Pool requirements", "waf": "Reliability" }, { - "category": "Monitoring and Management", + "category": "Storage", "checklist": "Azure Virtual Desktop Review", - "description": "See the referenced article and this additional one to setup proper monitoring and alerting for storage: https://docs.microsoft.com/azure/storage/files/storage-troubleshooting-files-performance. ", - "guid": "2463cffe-179c-4599-be0d-5973dd4ce32c", - "id": "E02.03", - "link": "https://docs.microsoft.com/azure/storage/files/storage-files-monitoring?tabs=azure-portal", + "description": "Avoid introducing additional latency and costs associated with cross-region network traffic where possible.", + "guid": "8aad53cc-79e2-4e86-9673-57c549675c5e", + "id": "H03.05", + "link": "https://docs.microsoft.com/azure/virtual-desktop/fslogix-containers-azure-files", "services": [ - "Storage", - "Monitor", - "AVD" + "Cost", + "AVD", + "Storage" ], - "severity": "Medium", - "subcategory": "Monitoring", - "text": "Create alerts on the profile storage to be alerted in case of high usage and throttling", - "waf": "Reliability" + "severity": "High", + "subcategory": "Capacity Planning", + "text": "For optimal performance, the storage solution and the FSLogix profile container should be in the same Azure region.", + "waf": "Performance" }, { - "category": "Monitoring and Management", + "category": "Storage", "checklist": "Azure Virtual Desktop Review", - "description": "You can use Azure Service Health to monitor service issues and health advisories for Azure Virtual Desktop. Azure Service Health can notify you with different types of alerts (for example, email or SMS), help you understand the effect of an issue, and keep you updated as the issue resolves.", - "guid": "18813706-f7c4-4c0d-9e51-4548d2457ed6", - "id": "E02.04", - "link": "https://docs.microsoft.com/azure/virtual-desktop/set-up-service-alerts", + "description": "The recommendation in Azure Virtual Desktop is to use Profile Container without Office Container (ODFC) split unless you are planning for specific Business Continuity and Disaster Recovery (BCDR) scenarios as described in the Disaster Recovery section below. https://docs.microsoft.com/fslogix/profile-container-office-container-cncpt ", + "guid": "df47d2d9-2881-4b1c-b5d1-e54a29759e39", + "id": "H04.01", + "link": "https://learn.microsoft.com/fslogix/concepts-container-types#when-to-use-profile-and-odfc-containers", "services": [ - "Monitor", - "AVD" + "ASR", + "AVD", + "Storage" ], - "severity": "Medium", - "subcategory": "Monitoring", - "text": "Configure Azure Service Health for AVD alerts ", + "severity": "High", + "subcategory": "FSLogix", + "text": "Do not use Office Containers (ODFC) if not strictly required and justified", "waf": "Reliability" }, { - "category": "Networking", + "category": "Storage", "checklist": "Azure Virtual Desktop Review", - "description": "If required to connect to on-premises environment, assess the current connectivity option or plan for the required connectivity (ExpressRoute, Azure S2S or 3rd-party NVA VPN). ", - "guid": "dd399cfd-7b28-4dc8-9555-6202bfe4563b", - "id": "F01.01", - "link": "https://docs.microsoft.com/azure/architecture/reference-architectures/hybrid-networking/", + "description": "Make sure to configure the following antivirus exclusions for FSLogix Profile Container virtual hard drives, as documented in the referenced article in the 'More Info' column.", + "guid": "83f63047-22ee-479d-9b5c-3632054b69ba", + "id": "H04.02", + "link": "https://learn.microsoft.com/fslogix/overview-prerequisites#configure-antivirus-file-and-folder-exclusions", "services": [ - "ExpressRoute", - "NVA", "AVD", - "VPN" + "Storage" ], "severity": "Medium", - "subcategory": "Networking", - "text": "Determine if hybrid connectivity is required to connect to on-premises environment", - "waf": "Reliability" + "subcategory": "FSLogix", + "text": "Configure the recommended antivirus exclusions for FSLogix (includes not scanning VHD(x) files on connect).", + "waf": "Security" }, { - "category": "Networking", + "category": "Storage", "checklist": "Azure Virtual Desktop Review", - "description": "AVD Host Pools can be deployed in either Azure Virtual WAN or traditional 'Hub & Spoke' network topologies. It is recommended to deploy each Host Pool in a separate 'spoke' VNet, using 'hub' is not recommended.", - "guid": "c8639648-a652-4d6c-85e5-02965388e5de", - "id": "F01.02", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/wvd/eslz-network-topology-and-connectivity", + "description": "Profile containers have a default max size of 30GB. If large Profile Containers are anticipated, and customers wants to try to keep them small, consider using OneDrive to host Office 365 files outside the FSLogix profile.", + "guid": "01e6a84d-e5df-443d-8992-481718d5d1e5", + "id": "H04.03", + "link": "https://docs.microsoft.com/fslogix/profile-container-configuration-reference", "services": [ - "VNet", "AVD", - "VWAN" + "Storage" ], - "severity": "Medium", - "subcategory": "Networking", - "text": "Determine Azure Virtual Network (VNet) placement for each AVD Host Pool", - "waf": "Performance" + "severity": "High", + "subcategory": "FSLogix", + "text": "Review and confirm configured maximum profile size in FSLogix", + "waf": "Cost" }, { - "category": "Networking", + "category": "Storage", "checklist": "Azure Virtual Desktop Review", - "description": "Evaluate the bandwidth requirements, ensure VPN/ER bandwidth will be enough, ensure proper routing and firewall rules are in place, test end-to-end latency. ", - "guid": "d227dd14-2b06-4c21-a799-9a646f4389a7", - "id": "F01.03", - "link": "https://docs.microsoft.com/azure/architecture/reference-architectures/hybrid-networking/", + "description": "Defaults and recommended settings are reported in the companion article in the 'More Info' column. If not recommended keys and/or values must be used, be sure to review with a Microsoft AVD expert and clearly document your choices.", + "guid": "d34aad5e-8c78-4e1d-9666-7313c405674c", + "id": "H04.04", + "link": "https://learn.microsoft.com/fslogix/concepts-configuration-examples", "services": [ + "ACR", "AVD", - "VPN" + "Storage", + "AKV" ], - "severity": "Medium", - "subcategory": "Networking", - "text": "Assess which on-premises resources are required from AVD Host Pools", + "severity": "High", + "subcategory": "FSLogix", + "text": "Review FSLogix registry keys and determine which ones to apply", "waf": "Reliability" }, { - "category": "Networking", + "category": "Storage", "checklist": "Azure Virtual Desktop Review", - "description": "Several options are available. You can use Azure Firewall or equivalent 3rd-party NVA, Network Security Group (NSG) and/or Proxy servers. NSG is not able to enable/disable by URL, only ports and protocols. Proxy should be used only as explicit setting in user browser. Details on using Azure Firewall Premium with AVD are reported in the companion article in the 'More Info' column. Be sure to allow proper access to required AVD URLs. Forced Tunneling to on-premises is not recommended.", - "guid": "fc4972cd-3cd2-41bf-9703-6e5e6b4bed3d", - "id": "F01.04", - "link": "https://docs.microsoft.com/azure/firewall/protect-windows-virtual-desktop", + "description": "Concurrent or multiple connections are not recommended in Azure Virtual Desktop. Concurrent connections are also not supported by Session Hosts running in an Azure Virtual Desktop Host Pool. OneDrive, if used, doesn't support concurrent or multiple connections using the same container, under any circumstance. For multiple connections, usage of the same profile disk is not recommended.", + "guid": "5e985b85-9c77-43e7-b261-623b775a917e", + "id": "H04.05", + "link": "https://learn.microsoft.com/fslogix/concepts-multi-concurrent-connections", "services": [ - "Firewall", - "VNet", - "NVA", - "AVD" + "AVD", + "Storage" ], - "severity": "Medium", - "subcategory": "Networking", - "text": "Need to control/restrict Internet outbound traffic for AVD hosts?", - "waf": "Security" + "severity": "High", + "subcategory": "FSLogix", + "text": "Avoid usage of concurrent or multiple connections", + "waf": "Reliability" }, { - "category": "Networking", + "category": "Storage", "checklist": "Azure Virtual Desktop Review", - "description": "Required URLs for AVD control plane access by session hosts are documented here: https://docs.microsoft.com/azure/virtual-desktop/safe-url-list. A check tool is available to verify connectivity from the session hosts: https://docs.microsoft.com/azure/virtual-desktop/safe-url-list#required-url-check-tool. Forced Tunneling to on-premises is not recommended.", - "guid": "65c7acbe-45bb-4e60-ad89-f2e87778424d", - "id": "F01.05", - "link": "https://docs.microsoft.com/azure/virtual-desktop/safe-url-list", + "description": "Cloud Cache uses OS drive as local cache storage and may generate lot of pressure on the VM disk. Depending on the VM SKU and size used, the VM temporary drive can be a viable and performant solution where to relocate Cloud Cache cached content. Before adopting this solution, tests should be executed to confirm performance and stability. More details on Cloud Cache can be found here: https://learn.microsoft.com/fslogix/concepts-fslogix-cloud-cache. ", + "guid": "b2d1215a-e114-4ba3-9df5-85ecdcd9bd3b", + "id": "H04.06", + "link": "https://docs.microsoft.com/fslogix/cloud-cache-configuration-reference", "services": [ - "AVD" + "VM", + "AVD", + "Storage" ], - "severity": "High", - "subcategory": "Networking", - "text": "Ensure AVD control plane endpoints are accessible", - "waf": "Reliability" + "severity": "Low", + "subcategory": "FSLogix", + "text": "If FSLogix Cloud Cache is used, consider moving the cache directory to the VM temporary drive.", + "waf": "Performance" }, { - "category": "Networking", + "category": "Storage", "checklist": "Azure Virtual Desktop Review", - "description": "Consider the usage of Azure Defender Endpoint or similar 3rd-party agents to control user web navigation, see the Security section for more details.", - "guid": "73676ae4-6691-4e88-95ad-a42223e13810", - "id": "F01.06", - "link": "https://learn.microsoft.com/microsoft-365/security/defender-endpoint/onboard-windows-multi-session-device?view=o365-worldwide", + "description": "REDIRECTION.XML file is used to control what folders are redirected out of the profile container to the 'C:' drive. Exclusions should be the exception and should never be used unless the specific exclusion is completely understood by the person configuring the exclusion. Exclusions should always be fully tested in the environment where they are intended to be implemented. Configuring exclusions may impact functionality, stability and performance.", + "guid": "0b50ca97-b1d2-473c-b4d9-6e98b0f912de", + "id": "H04.07", + "link": "https://docs.microsoft.com/fslogix/manage-profile-content-cncpt#redirectionsxml", "services": [ - "Defender", - "AVD" + "AVD", + "Storage" ], "severity": "Medium", - "subcategory": "Networking", - "text": "Need to control/restrict Internet outbound traffic only for users on AVD hosts? ", - "waf": "Security" + "subcategory": "FSLogix", + "text": "Review the usage of FSLogix redirection.", + "waf": "Cost" }, { - "category": "Networking", - "checklist": "Azure Virtual Desktop Review", - "description": "Custom UDR and NSG can be applied to AVD Host Pool subnets, for example to redirect to Azure Firewall or NVA, or to filter/block network traffic. In this case is recommended to carefully review to ensure optimal path for outbound traffic to AVD control plane is used. Service Tags can now be used with UDR and NSG, then AVD management plane traffic can be easily allowed: https://learn.microsoft.com/azure/virtual-desktop/safe-url-list.", - "guid": "523181a9-4174-4158-93ff-7ae7c6d37431", - "id": "F01.07", - "link": "https://docs.microsoft.com/azure/firewall/protect-windows-virtual-desktop", + "category": "Azure Billing and Microsoft Entra ID Tenants", + "checklist": "Azure Landing Zone Review", + "guid": "70c15989-c726-42c7-b0d3-24b7375b9201", + "id": "A01.01", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/multi-tenant/considerations-recommendations", "services": [ - "Firewall", - "VNet", - "NVA", - "AVD" + "Entra" ], - "severity": "Low", - "subcategory": "Networking", - "text": "Review custom UDR and NSG for AVD Host Pool subnets", - "waf": "Security" + "severity": "Medium", + "subcategory": "Microsoft Entra ID Tenants", + "text": "Use one Entra tenant for managing your Azure resources, unless you have a clear regulatory or business requirement for multi-tenants.", + "waf": "Operations" }, { - "category": "Networking", - "checklist": "Azure Virtual Desktop Review", - "description": "Network traffic from AVD Session Host VMs to AVD control plane should be as direct as possible. Redirecting this traffic through a Proxy or Firewall with deep packet inspection and/or SSL termination could cause serious issues and bad customer experience. It is recommended to bypass Proxy and Firewall just for the AVD control plane. User generated traffic surfing the web instead, should be filtered by Firewall and/or redirected to a Proxy. For details and guidelines, please see the companion article in the 'More Info' column.", - "guid": "cc6edca0-aeca-4566-9e92-cf246f1465af", - "id": "F01.08", - "link": "https://learn.microsoft.com/azure/virtual-desktop/proxy-server-support", + "category": "Azure Billing and Microsoft Entra ID Tenants", + "checklist": "Azure Landing Zone Review", + "guid": "6309957b-821a-43d1-b9d9-7fcf1802b747", + "id": "A01.02", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/multi-tenant/automation", "services": [ - "VM", - "AVD" + "Entra" ], - "severity": "High", - "subcategory": "Networking", - "text": "Do not use Proxy servers, SSL termination and Deep Packet Inspection for AVD control plane traffic", - "waf": "Reliability" + "severity": "Low", + "subcategory": "Microsoft Entra ID Tenants", + "text": "Ensure you have a Multi-Tenant Automation approach to managing your Microsoft Entra ID Tenants", + "waf": "Operations" }, { - "category": "Networking", - "checklist": "Azure Virtual Desktop Review", - "description": "It is recommended to assess and review networking bandwidth requirements for users, based on the specific workload type. The referenced article provide general estimations and recommendations, but specific measure are required for proper sizing. ", - "guid": "516785c6-fa96-4c96-ad88-408f372734c8", - "id": "F01.09", - "link": "https://learn.microsoft.com/azure/virtual-desktop/rdp-bandwidth", + "category": "Azure Billing and Microsoft Entra ID Tenants", + "checklist": "Azure Landing Zone Review", + "guid": "78e11934-499a-45ed-8ef7-aae5578f0ecf", + "id": "A01.03", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/multi-tenant/lighthouse", "services": [ - "VM", - "AVD" + "Entra" ], "severity": "Low", - "subcategory": "Networking", - "text": "Check the network bandwidth required for each user and in total for the VM SKU", - "waf": "Performance" + "subcategory": "Microsoft Entra ID Tenants", + "text": "Leverage Azure Lighthouse for Multi-Tenant Management", + "waf": "Operations" }, { - "category": "Networking", - "checklist": "Azure Virtual Desktop Review", - "description": "If Azure Files SMB share will be used to store user profiles via FSLogix, the usage of Private Endpoint (PE) for private access to the storage is recommended. AVD Session Hosts will access the storage using a private IP in the same VNet, a separate subnet is recommended. This feature has an additional cost that must be evaluated. If PE will not be used, at least Service Endpoint is recommended (no cost associated).", - "guid": "ec27d589-9178-426d-8df2-ff60020f30a6", - "id": "F01.10", - "link": "https://learn.microsoft.com/azure/storage/files/storage-files-networking-endpoints", - "services": [ - "Cost", - "Storage", - "AVD", - "VNet", - "PrivateLink" + "category": "Azure Billing and Microsoft Entra ID Tenants", + "checklist": "Azure Landing Zone Review", + "guid": "5d82e6df-6f61-42f2-82e2-3132d293be3d", + "id": "A02.01", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", + "services": [ + "Entra" ], "severity": "Medium", - "subcategory": "Networking", - "text": "Evaluate usage Private Endpoint for Azure Files share", - "waf": "Security" + "subcategory": "Cloud Solution Provider", + "text": "Ensure that Azure Lighthouse is used for administering the tenant by partner", + "waf": "Cost" }, { - "category": "Networking", - "checklist": "Azure Virtual Desktop Review", - "description": "Connections to Azure Virtual Desktop can use TCP or UDP. RDP Shortpath is a feature of AVD that establishes a direct UDP-based transport between a supported Windows Remote Desktop client and session host. if clients have line of sight to AVD session hosts from internal network (VPN usage is not recommended), this feature can provide lower latency and best performances as explained in https://learn.microsoft.com/azure/virtual-desktop/rdp-shortpath?tabs=managed-networks#key-benefits.", - "guid": "b2074747-d01a-4f61-b1aa-92ad793d9ff4", - "id": "F01.11", - "link": "https://docs.microsoft.com/azure/virtual-desktop/shortpath", + "category": "Azure Billing and Microsoft Entra ID Tenants", + "checklist": "Azure Landing Zone Review", + "guid": "a24d0de3-d4b9-4dfb-8ddd-bbfaf123fa01", + "id": "A02.02", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", "services": [ - "AVD", - "VPN" + "Entra" ], - "severity": "Medium", - "subcategory": "Networking", - "text": "Evaluate usage of RDP ShortPath for clients connecting from managed internal networks", - "waf": "Performance" + "severity": "Low", + "subcategory": "Cloud Solution Provider", + "text": "Discuss support request and escalation process with CSP partner", + "waf": "Cost" }, { - "category": "Security", - "checklist": "Azure Virtual Desktop Review", - "description": "Security mechanisms provided by GPO should be used, if available. For example, it is possible to impose desktop screen lock and idle session disconnection time. Existing GPOs applied to on-premises environment should be reviewed and eventually applied also to secure also AVD Hosts when joined to the domain.", - "guid": "a135e337-897e-431c-97d6-8cb6a22ac19f", - "id": "G01.01", - "link": "https://learn.microsoft.com/azure/virtual-desktop/security-guide#establish-maximum-inactive-time-and-disconnection-policies", + "category": "Azure Billing and Microsoft Entra ID Tenants", + "checklist": "Azure Landing Zone Review", + "guid": "32952499-58c8-4e6f-ada5-972e67893d55", + "id": "A02.03", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", "services": [ - "AVD" + "Cost", + "Entra" ], "severity": "Medium", - "subcategory": "Active Directory", - "text": "Review Active Directory GPO to secure RDP sessions", - "waf": "Security" + "subcategory": "Cloud Solution Provider", + "text": "Setup Cost Reporting and Views with Azure Cost Management", + "waf": "Cost" }, { - "category": "Security", - "checklist": "Azure Virtual Desktop Review", - "description": "Microsoft Defender for Endpoint supports Azure Virtual Desktop for Windows 10/11 Enterprise multi-session. Check article for onboarding non-persistent virtual desktop infrastructure (VDI) devices: https://docs.microsoft.com/windows/security/threat-protection/microsoft-defender-atp/configure-endpoints-vdi", - "guid": "b1172576-9ef6-4691-a483-5ac932223ece", - "id": "G02.01", - "link": "https://learn.microsoft.com/microsoft-365/security/defender-endpoint/deployment-vdi-microsoft-defender-antivirus", + "category": "Azure Billing and Microsoft Entra ID Tenants", + "checklist": "Azure Landing Zone Review", + "guid": "685cb4f2-ac9c-4b19-9167-993ed0b32415", + "id": "A03.01", + "link": "https://learn.microsoft.com/azure/cost-management-billing/manage/direct-ea-administration#manage-notification-contacts", "services": [ - "Defender", - "AVD" + "LoadBalancer", + "Entra" ], - "severity": "High", - "subcategory": "Host Configuration", - "text": "Ensure anti-virus and anti-malware solutions are used", - "waf": "Security" + "severity": "Medium", + "subcategory": "Enterprise Agreement", + "text": "Configure Notification Contacts to a group mailbox", + "waf": "Cost" }, { - "category": "Security", - "checklist": "Azure Virtual Desktop Review", - "description": "Disks in Azure are already encrypted at rest by default with Microsoft managed keys. Host VM OS disk encryption is possible and supported using Azure Disk Encryption (ADE - BitLocker) and Disk Encryption Set (DES - Server Side Encryption), the latter is recommended. Encryption of FSLogix storage using Azure Files can be done using SSE on Azure Storage. For OneDrive encryption, see this article: https://docs.microsoft.com/compliance/assurance/assurance-encryption-for-microsoft-365-services.", - "guid": "0fd32907-98bc-4178-adc5-a06ca7144351", - "id": "G02.02", - "link": "https://learn.microsoft.com/azure/virtual-machines/disk-encryption-overview", + "category": "Azure Billing and Microsoft Entra ID Tenants", + "checklist": "Azure Landing Zone Review", + "guid": "12cd499f-96e2-4e41-a243-231fb3245a1c", + "id": "A03.02", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-enterprise-agreement#design-considerations", "services": [ - "VM", - "Storage", - "AKV", - "AVD" + "TrafficManager", + "Entra" ], "severity": "Low", - "subcategory": "Host Configuration", - "text": "Assess disk encryption requirements for AVD Session Hosts", - "waf": "Security" + "subcategory": "Enterprise Agreement", + "text": "Use departments and accounts to map your organization's structure to your enrollment hierarchy which can help with separating billing.", + "waf": "Cost" }, { - "category": "Security", - "checklist": "Azure Virtual Desktop Review", - "description": "Trusted launch are Gen2 Azure VMs with enhanced security features aimed to protect against “bottom of the stack” threats through attack vectors such as rootkits, boot kits, and kernel-level malware. Recommended to enable and leverage Secure Boot, Virtual TPM (vTPM) and Integrity Monitoring.", - "guid": "36a5a67f-bb9e-4d5b-9547-8c4479816b28", - "id": "G02.03", - "link": "https://learn.microsoft.com/azure/virtual-desktop/security-guide#azure-virtual-desktop-support-for-trusted-launch", + "ammp": true, + "category": "Azure Billing and Microsoft Entra ID Tenants", + "checklist": "Azure Landing Zone Review", + "guid": "29213165-f066-46c4-81fc-4214cc19f3d0", + "id": "A03.03", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-enterprise-agreement#design-considerations", "services": [ - "VM", - "Monitor", - "AVD" + "Entra" ], - "severity": "Medium", - "subcategory": "Host Configuration", - "text": "Enable Trusted launch in Azure Gen2 VM Session Hosts", + "severity": "High", + "subcategory": "Enterprise Agreement", + "text": "Ensure that Accounts are configured to be of the type 'Work or School Account", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure Virtual Desktop Review", - "description": "Trusted Launch and Gen2 VM are not only security and performance enhancing features but also system requirements for Windows 11. When building an AVD environment based on Windows 11, it is essential to enable these features.", - "guid": "135d3899-4b31-44d3-bc8f-028871a359d8", - "id": "G02.04", - "link": "https://learn.microsoft.com/windows/whats-new/windows-11-requirements", + "category": "Azure Billing and Microsoft Entra ID Tenants", + "checklist": "Azure Landing Zone Review", + "guid": "ca0fe401-12ad-46fc-8a7e-86293866a9f6", + "id": "A03.04", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-enterprise-agreement#design-considerations", "services": [ - "VM", - "AVD" + "Cost", + "Entra" ], - "severity": "High", - "subcategory": "Host Configuration", - "text": "Enable Trusted Launch and use Gen2 image are system requirements for Windows 11", + "severity": "Medium", + "subcategory": "Enterprise Agreement", + "text": "Enable both DA View Charges and AO View Charges on your EA Enrollments to allow users with the correct perms review Cost and Billing Data.", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure Virtual Desktop Review", - "description": "Displayed content will be automatically blocked or hidden in screenshots. Keep in mind screen sharing will also be blocked when using Teams or other collaboration software which use screen sharing.", - "guid": "a49dc137-7896-4343-b2bc-1a31bf1d30b6", - "id": "G02.05", - "link": "https://learn.microsoft.com/azure/virtual-desktop/screen-capture-protection", + "category": "Azure Billing and Microsoft Entra ID Tenants", + "checklist": "Azure Landing Zone Review", + "guid": "5cf9f485-2784-49b3-9824-75d9b8bdb57b", + "id": "A03.05", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-enterprise-agreement#design-considerations", "services": [ - "AVD" + "Cost", + "Subscriptions", + "Entra" ], "severity": "Low", - "subcategory": "Host Configuration", - "text": "Consider enabling screen capture protection to prevent sensitive information from being captured", - "waf": "Security" + "subcategory": "Enterprise Agreement", + "text": "Make use of Enterprise Dev/Test Subscriptions to reduce costs for non-production workloads", + "waf": "Cost" }, { - "category": "Security", - "checklist": "Azure Virtual Desktop Review", - "description": "If not absolutely required, redirecting drives, printers, and USB devices to a user's local device in a remote desktop session should be disabled or highly restricted. Restrict Windows Explorer access by hiding local and remote drive mappings is also a secure measure to adopt preventing users from discovering unwanted information about system configuration and users.", - "guid": "7ce2cd20-85b4-4f82-828e-6558736ede6a", - "id": "G02.06", - "link": "https://learn.microsoft.com/azure/virtual-desktop/security-guide#other-security-tips-for-session-hosts", + "category": "Azure Billing and Microsoft Entra ID Tenants", + "checklist": "Azure Landing Zone Review", + "guid": "2cf08656-13ea-4f7e-a53a-e2c956b1ff6c", + "id": "A03.06", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-enterprise-agreement#design-considerations", "services": [ - "AVD" + "RBAC", + "Entra" ], "severity": "Medium", - "subcategory": "Host Configuration", - "text": "Restrict device redirection and drive mapping", - "waf": "Security" + "subcategory": "Enterprise Agreement", + "text": "Periodically audit the role assignments to review who has access to your Enterprise Agreement Enrollment", + "waf": "Cost" }, { - "category": "Security", - "checklist": "Azure Virtual Desktop Review", - "description": "When choosing a deployment model, you can either provide remote users access to entire virtual desktops or only select applications. Remote applications, or RemoteApps, provide a seamless experience as the user works with apps on their virtual desktop. RemoteApps reduce risk by only letting the user work with a subset of the remote machine exposed by the application.", - "guid": "4e25d70e-3924-44f4-b66f-d6cdd4f4a973", - "id": "G03.01", - "link": "https://learn.microsoft.com/microsoft-365/security/defender-endpoint/web-protection-overview", + "category": "Azure Billing and Microsoft Entra ID Tenants", + "checklist": "Azure Landing Zone Review", + "guid": "6ad5c3dd-e5ea-4ff1-81a4-7886ff87845c", + "id": "A04.01", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", "services": [ - "AVD" + "Entra" ], - "severity": "Medium", - "subcategory": "Management", - "text": "When possible, prefer Remote Apps over Full Desktops (DAG)", - "waf": "Security" + "severity": "Low", + "subcategory": "Microsoft Customer Agreement", + "text": "Configure Agreement billing account notification contact email", + "waf": "Cost" }, { - "category": "Security", - "checklist": "Azure Virtual Desktop Review", - "description": "Web content filtering feature provided by Web Protection capability in Microsoft Defender for Endpoint, can be used to to control user web navigation. If this tool is used, configuration of web filtering for user Internet browsing is recommended. Access by the Guest OS system to required AVD control plane URLs must be guaranteed.", - "guid": "e19dd344-29eb-4722-a237-a151c5bb4e4f", - "id": "G03.02", - "link": "https://learn.microsoft.com/microsoft-365/security/defender-endpoint/web-protection-overview", + "category": "Azure Billing and Microsoft Entra ID Tenants", + "checklist": "Azure Landing Zone Review", + "guid": "90e87802-602f-4dfb-acea-67c60689f1d7", + "id": "A04.02", + "link": "https://learn.microsoft.com/azure/cost-management-billing/manage/mca-section-invoice", "services": [ - "Defender", - "AVD" + "Cost", + "Storage", + "Entra" ], - "severity": "Medium", - "subcategory": "Management", - "text": "Need to control/restrict user Internet navigation from AVD session hosts?", - "waf": "Security" + "severity": "Low", + "subcategory": "Microsoft Customer Agreement", + "text": "Use Billing Profiles and Invoice sections to structure your agreements billing for effective cost management", + "waf": "Cost" }, { - "category": "Security", - "checklist": "Azure Virtual Desktop Review", - "description": "We recommend you don't grant your users admin access to virtual desktops. If you need software packages, we recommend you make them available through configuration management utilities.", - "guid": "a0cdb3b5-4eb2-4eb0-9dda-a3592718e2ed", - "id": "G03.03", - "link": "https://docs.microsoft.com/azure/virtual-desktop/security-guide", + "category": "Azure Billing and Microsoft Entra ID Tenants", + "checklist": "Azure Landing Zone Review", + "guid": "e81a73f0-84c4-4641-b406-14db3b4d1f50", + "id": "A04.03", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", "services": [ - "AVD" + "Cost", + "Entra" ], - "severity": "High", - "subcategory": "Management", - "text": "Ensure AVD users will not have local administrator privileges on AVD Hosts", - "waf": "Security" + "severity": "Low", + "subcategory": "Microsoft Customer Agreement", + "text": "Make use of Azure Plan to reduce costs for non-production workloads", + "waf": "Cost" }, { - "category": "Security", - "checklist": "Azure Virtual Desktop Review", - "description": "We recommend you enable Defender for Cloud for the subscriptions, virtual machines, key vaults, and storage accounts used by AVD. With this tool is possible to assess and manage vulnerabilities, assess compliance with common frameworks like PCI, strengthen the overall security of your AVD environment and measure it over time using 'Secure Score': https://learn.microsoft.com/azure/virtual-desktop/security-guide#improve-your-secure-score.", - "guid": "1814387e-5ca9-4c26-a9b3-2ab5bdfc6998", - "id": "G03.04", - "link": "https://learn.microsoft.com/azure/virtual-desktop/security-guide#enable-microsoft-defender-for-cloud", + "category": "Azure Billing and Microsoft Entra ID Tenants", + "checklist": "Azure Landing Zone Review", + "guid": "ae757485-92a4-482a-8bc9-eefe6f5b5ec3", + "id": "A04.04", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", "services": [ - "AKV", - "VM", - "Defender", - "AVD", - "Storage", - "Subscriptions" + "RBAC", + "Entra" ], "severity": "Medium", - "subcategory": "Management", - "text": "Enable Microsoft Defender for Cloud to manage AVD Session Hosts security posture", - "waf": "Security" + "subcategory": "Microsoft Customer Agreement", + "text": "Periodically audit the agreement billing RBAC role assignments to review who has access to your MCA billing account", + "waf": "Cost" }, { - "category": "Security", - "checklist": "Azure Virtual Desktop Review", - "description": "Enabling audit log collection lets you view user and admin activity related to Azure Virtual Desktop and store in a central repository like Log Analytics workspace. ", - "guid": "a0916a76-4980-4ad0-b278-ee293c1bc352", - "id": "G03.05", - "link": "https://learn.microsoft.com/azure/virtual-desktop/security-guide#collect-audit-logs", + "ammp": true, + "category": "Identity and Access Management", + "checklist": "Azure Landing Zone Review", + "guid": "4348bf81-7573-4512-8f46-9061cc198fea", + "id": "B01.01", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/identity-access-landing-zones#identity-and-access-management-in-the-azure-landing-zone-accelerator", "services": [ - "Monitor", - "AVD", "Entra" ], - "severity": "Medium", - "subcategory": "Management", - "text": "Enable diagnostic and audit logging", + "severity": "High", + "subcategory": "Microsoft Entra ID and Hybrid Identity", + "text": "Use managed identities instead of service principals for authentication to Azure services", + "training": "https://learn.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure Virtual Desktop Review", - "description": "Assign the least privilege required by defining administrative, operations, and engineering roles to Azure RBAC roles. To limit access to high privilege roles within your Azure Virtual Desktop landing zone, consider integration with Azure Privileged Identity Management (PIM). Maintaining knowledge of which team is responsible for each particular administrative area helps you determine Azure role-based access control (RBAC) roles and configuration.", - "guid": "baaab757-1849-4ab8-893d-c9fc9d1bb73b", - "id": "G03.06", - "link": "https://docs.microsoft.com/azure/virtual-desktop/rbac", + "category": "Identity and Access Management", + "checklist": "Azure Landing Zone Review", + "guid": "cd163e39-84a5-4b39-97b7-6973abd70d94", + "id": "B02.01", + "link": "https://learn.microsoft.com/azure/active-directory/hybrid/how-to-connect-sync-staging-server", "services": [ - "RBAC", - "AVD", + "ASR", "Entra" ], - "severity": "Low", - "subcategory": "Management", - "text": "Assess the requirement to use custom RBAC roles for AVD management", - "waf": "Security" + "severity": "Medium", + "subcategory": "Microsoft Entra ID", + "text": "When deploying an AD Connect VM, consider having a staging sever for high availability / Disaster recovery", + "waf": "Reliability" }, { - "category": "Security", - "checklist": "Azure Virtual Desktop Review", - "description": "AVD users should not have permission to install application. If required, Windows Defender Application Control (WDAC) can be used to control which drivers and applications are allowed to run on their Windows clients. ", - "guid": "b9ea80c8-0628-49fc-ae63-125aa4c0a284", - "id": "G03.07", - "link": "https://learn.microsoft.com/azure/virtual-desktop/security-guide#windows-defender-application-control", + "ammp": true, + "category": "Identity and Access Management", + "checklist": "Azure Landing Zone Review", + "guid": "984a859c-773e-47d2-9162-3a765a917e1f", + "id": "B03.01", + "link": "https://learn.microsoft.com/azure/active-directory/roles/security-emergency-access", "services": [ - "Defender", - "AVD" + "Entra" ], - "severity": "Medium", - "subcategory": "Management", - "text": "Restrict users from installing un-authorized applications", + "severity": "High", + "subcategory": "Identity", + "text": "Implement an emergency access or break-glass accounts to prevent tenant-wide account lockout", + "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure Virtual Desktop Review", - "description": "Enabling MFA and CA lets you manage risks before you grant users access to your AVD environment. When deciding which users to grant access to, we recommend you also consider who the user is, how they sign in, and which device they're using. Additional details and configuration procedures are provided in the companion article. Microsoft Entra ID is the new name for Azure Active Directory (Azure AD).", - "guid": "916d697d-8ead-4ed2-9bdd-186f1ac252b9", - "id": "G04.01", - "link": "https://learn.microsoft.com/azure/virtual-desktop/set-up-mfa", + "category": "Identity and Access Management", + "checklist": "Azure Landing Zone Review", + "guid": "1cf0b8da-70bd-44d0-94af-8d99cfc89ae1", + "id": "B03.02", + "link": "https://learn.microsoft.com/azure/active-directory/reports-monitoring/concept-activity-logs-azure-monitor", "services": [ - "AVD", + "Monitor", "Entra" ], "severity": "Medium", - "subcategory": "Microsoft Entra ID", - "text": "Evaluate the usage of Multi-Factor Authentication (MFA) and Conditional Access (CA) for AVD users", + "subcategory": "Identity", + "text": "Integrate Microsoft Entra ID logs with the platform-central Azure Monitor. Azure Monitor allows for a single source of truth around log and monitoring data in Azure, giving organizations a cloud native options to meet requirements around log collection and retention.", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure Virtual Desktop Review", - "description": "If Zero Trust is a requirement, review the companion article in the 'More Info' column. It provides steps to apply the principles of Zero Trust to an Azure Virtual Desktop deployment.", - "guid": "221102d0-90af-49fc-b2b7-8d3fe397e43", - "id": "G05.01", - "link": "https://learn.microsoft.com/security/zero-trust/azure-infrastructure-avd", + "ammp": true, + "category": "Identity and Access Management", + "checklist": "Azure Landing Zone Review", + "guid": "348ef254-c27d-442e-abba-c7571559ab91", + "id": "B03.03", + "link": "https://learn.microsoft.com/azure/role-based-access-control/overview", "services": [ - "AVD" + "ACR", + "RBAC", + "Subscriptions", + "Entra" ], - "severity": "Medium", - "subcategory": "Zero Trust", - "text": "Review and Apply Zero Trust principles and guidance", + "severity": "High", + "subcategory": "Identity", + "text": "Enforce a RBAC model that aligns to your cloud operating model. Scope and Assign across Management Groups and Subscriptions.", + "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", "waf": "Security" }, { - "category": "Storage", - "checklist": "Azure Virtual Desktop Review", - "description": "If used, make sure to check the list of best practices and recommendations described in the referenced article.", - "guid": "9164e990-9ae2-48c8-9c33-b6b7808bafe6", - "id": "H01.01", - "link": "https://learn.microsoft.com/azure/virtual-desktop/fslogix-containers-azure-files#best-practices-for-azure-virtual-desktop", + "category": "Identity and Access Management", + "checklist": "Azure Landing Zone Review", + "guid": "53e8908a-e28c-484c-93b6-b7808b9fe5c4", + "id": "B03.04", + "link": "https://learn.microsoft.com/azure/active-directory/conditional-access/overview", "services": [ - "Storage", - "AVD" + "AzurePolicy", + "Entra" ], - "severity": "Medium", - "subcategory": "Azure Files", - "text": "Check best-practices for Azure Files", - "waf": "Performance" + "severity": "Low", + "subcategory": "Identity", + "text": "Enforce Microsoft Entra ID conditional-access policies for any user with rights to Azure environments", + "training": "https://learn.microsoft.com/learn/modules/plan-implement-administer-conditional-access/", + "waf": "Security" }, { - "category": "Storage", - "checklist": "Azure Virtual Desktop Review", - "description": "SMB Multichannel enables clients to use multiple network connections that provide increased performance while lowering the cost of ownership. Increased performance is achieved through bandwidth aggregation over multiple NICs and utilizing Receive Side Scaling (RSS) support for NICs to distribute the IO load across multiple CPUs.", - "guid": "5784b6ca-5e9e-4bcf-8b54-c95459ea7369", - "id": "H01.02", - "link": "https://learn.microsoft.com/azure/storage/files/storage-files-smb-multichannel-performance", + "ammp": true, + "category": "Identity and Access Management", + "checklist": "Azure Landing Zone Review", + "guid": "1049d403-a923-4c34-94d0-0018ac6a9e01", + "id": "B03.05", + "link": "https://learn.microsoft.com/azure/active-directory/authentication/concept-mfa-howitworks", "services": [ - "ACR", - "Storage", - "AVD", - "Cost" + "Entra" ], - "severity": "Low", - "subcategory": "Azure Files", - "text": "Enable SMB multichannel when using a premium file share to host FSLogix profile containers.", - "waf": "Performance" + "severity": "High", + "subcategory": "Identity", + "text": "Enforce multi-factor authentication for any user with rights to the Azure environments", + "training": "https://learn.microsoft.com/learn/modules/secure-aad-users-with-mfa/", + "waf": "Security" }, { - "category": "Storage", - "checklist": "Azure Virtual Desktop Review", - "description": "If a second region is required for DR purposes verify NetApp availability in there as well.", - "guid": "4a359836-ee79-4d6c-9d3a-364a5b7abae3", - "id": "H02.01", - "link": "https://azure.microsoft.com/global-infrastructure/services/", + "category": "Identity and Access Management", + "checklist": "Azure Landing Zone Review", + "guid": "e6a83de5-de32-4c19-a248-1607d5d1e4e6", + "id": "B03.06", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/manage/centralize-operations", "services": [ - "Storage", - "AVD" + "RBAC", + "Entra" ], "severity": "Medium", - "subcategory": "Azure NetApp Files", - "text": "If NetApp Files storage is required, check storage service availability in your specific region.", - "waf": "Reliability" + "subcategory": "Identity", + "text": "Enforce centralized and delegated responsibilities to manage resources deployed inside the landing zone, based on role and security requirements", + "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-identities-governance/", + "waf": "Security" }, { - "category": "Storage", - "checklist": "Azure Virtual Desktop Review", - "description": "CA option is a recommended setting in the FSLogix scenario, as it enables a more resilient SMB session between the Session Host and NetApp Files.", - "guid": "a2661898-866a-4c8d-9d1f-8cfc86e88024", - "id": "H02.02", - "link": "https://learn.microsoft.com/azure/virtual-desktop/create-fslogix-profile-container", + "category": "Identity and Access Management", + "checklist": "Azure Landing Zone Review", + "guid": "14658d35-58fd-4772-99b8-21112df27ee4", + "id": "B03.07", + "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-configure", "services": [ - "Storage", - "AVD" + "Entra" ], "severity": "Medium", - "subcategory": "Azure NetApp Files", - "text": "If NetApp Files storage is used enable CA (Continuous Availability) option to increase resiliency", - "waf": "Reliability" + "subcategory": "Identity", + "text": "Enforce Microsoft Entra ID Privileged Identity Management (PIM) to establish zero standing access and least privilege", + "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/", + "waf": "Security" }, { - "category": "Storage", - "checklist": "Azure Virtual Desktop Review", - "description": "An Active Directory Site should be created for the Azure virtual network environment where Azure NetApp Files (ANF) subnet will be created, and that site name should be specified in the ANF connection property when executing the join procedure as explained in the reference article.", - "guid": "6647e977-db49-48a8-bc35-743f17499d42", - "id": "H02.03", - "link": "https://docs.microsoft.com/azure/azure-netapp-files/create-active-directory-connections", + "ammp": true, + "category": "Identity and Access Management", + "checklist": "Azure Landing Zone Review", + "guid": "12e7f983-f630-4472-8dd6-9c5b5c2622f5", + "id": "B03.08", + "link": "https://learn.microsoft.com/azure/active-directory/roles/security-planning#identify-microsoft-accounts-in-administrative-roles-that-need-to-be-switched-to-work-or-school-accounts", "services": [ - "Storage", - "AVD", - "VNet" + "Entra" ], "severity": "High", - "subcategory": "Azure NetApp Files", - "text": "If Azure NetApp Files storage is used, check Active Directory Site name setting in the Active Directory Connection configuration", - "waf": "Reliability" + "subcategory": "Identity", + "text": "Only use the authentication type Work or school account for all account types. Avoid using the Microsoft account", + "training": "https://learn.microsoft.com/learn/modules/explore-basic-services-identity-types/", + "waf": "Security" }, { - "category": "Storage", - "checklist": "Azure Virtual Desktop Review", - "description": "Possible options: Standard HDD, Standard SSD, or Premium SSD. Ephemeral disks are not supported, Ultra-Disks not recommended. Recommended to evaluate Premium for OS disk if user density is not low, and if Cloud Cache will be used. ", - "guid": "3611c818-b0a0-4bc5-80e4-3a18a9cd289c", - "id": "H03.01", - "link": "https://docs.microsoft.com/azure/virtual-machines/disks-types", + "category": "Identity and Access Management", + "checklist": "Azure Landing Zone Review", + "guid": "4b69bad3-3aad-45e8-a68e-1d76667313b4", + "id": "B03.09", + "link": "https://learn.microsoft.com/azure/active-directory/fundamentals/active-directory-groups-create-azure-portal", + "services": [ + "Entra" + ], + "severity": "Medium", + "subcategory": "Identity", + "text": "Only use groups to assign permissions. Add on-premises groups to the Azure-AD-only group if a group management system is already in place.", + "training": "https://learn.microsoft.com/learn/paths/manage-identity-and-access/", + "waf": "Security" + }, + { + "category": "Identity and Access Management", + "checklist": "Azure Landing Zone Review", + "guid": "f5664b5e-984a-4859-a773-e7d261623a76", + "id": "B03.10", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/identity-access#prerequisites-for-a-landing-zone---design-recommendations", "services": [ - "Storage", - "AVD" + "RBAC", + "Subscriptions", + "Entra" ], "severity": "Medium", - "subcategory": "Capacity Planning", - "text": "Determine which type of managed disk will be used for the Session Hosts", - "waf": "Performance" + "subcategory": "Identity", + "text": "Consider using Azure custom roles for the following key roles: Azure platform owner, network management, security operations, subscription owner, application owner", + "training": "https://learn.microsoft.com/learn/modules/create-custom-azure-roles-with-rbac/", + "waf": "Security" }, { - "category": "Storage", - "checklist": "Azure Virtual Desktop Review", - "description": "Possible options are: Azure NetApp Files, Azure Files, VM based File Server. File-server it is not recommended. Azure Files Premium typically a good starting point. NetApp usually required for large scale / high-performant environment. For a detailed comparison see the article in the 'More Info' column.", - "guid": "ed6b17db-8255-4462-b2ae-e4553afc8339", - "id": "H03.02", - "link": "https://docs.microsoft.com/azure/virtual-desktop/store-fslogix-profile", + "category": "Identity and Access Management", + "checklist": "Azure Landing Zone Review", + "guid": "1559ab91-53e8-4908-ae28-c84c33b6b780", + "id": "B03.11", + "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/identity/adds-extend-domain#vm-recommendations", "services": [ + "ACR", "VM", - "Storage", - "AVD" + "Entra" ], - "severity": "High", - "subcategory": "Capacity Planning", - "text": "Determine which storage backend solution will be used for FSLogix Profiles", - "waf": "Performance" + "severity": "Medium", + "subcategory": "Identity", + "text": "When deploying Active Directory on Windows Server, use a location with Availability Zones and deploy at least two VMs across these zones. If not available, deploy in an Availability Set", + "training": "https://learn.microsoft.com/learn/modules/azure-active-directory/", + "waf": "Reliability" }, { - "category": "Storage", - "checklist": "Azure Virtual Desktop Review", - "description": "Every Host Pool should use a separate set of storage accounts/volumes (at least one) and shares. Users should have a different profile for each Host Pool since settings and configurations are specific to each Host Pool. Additionally, accessing different Host Pools at the same time can cause errors on the shared user profile VHD/X. Usage of different storage accounts/volumes for multiple shares is also recommended to scale independently.", - "guid": "2fad62bd-5004-453c-ace4-64d862e7f5a4", - "id": "H03.03", - "link": "https://learn.microsoft.com/azure/virtual-desktop/store-fslogix-profile", + "category": "Identity and Access Management", + "checklist": "Azure Landing Zone Review", + "guid": "8b9fe5c4-1049-4d40-9a92-3c3474d00018", + "id": "B03.12", + "link": "https://learn.microsoft.com/azure/active-directory-domain-services/overview", "services": [ - "Storage", - "AVD" + "Entra" ], - "severity": "High", - "subcategory": "Capacity Planning", - "text": "Do not share storage and profiles between different Host Pools", - "waf": "Performance" + "severity": "Medium", + "subcategory": "Identity", + "text": "If AADDS in use, evaluate the compatibility of all workloads", + "training": "https://learn.microsoft.com/learn/modules/implement-hybrid-identity-windows-server/", + "waf": "Security" }, { - "category": "Storage", - "checklist": "Azure Virtual Desktop Review", - "description": "As a starting point for estimating profile container storage performance requirements we recommend to assume 10 IOPS per user in the steady state and 50 IOPS per user during sign-in/sign-out. Space requirements is simply obtained based on the maximum profiles size in FSLogix per the total number of users for each Host Pool. Multiple storage accounts can be used for the same Host Pool if required.", - "guid": "680e7828-9c93-4665-9d02-bff4564b0d93", - "id": "H03.04", - "link": "https://learn.microsoft.com/azure/virtual-desktop/faq#what-s-the-largest-profile-size-fslogix-can-handle-", + "category": "Identity and Access Management", + "checklist": "Azure Landing Zone Review", + "guid": "ac6a9e01-e6a8-43de-9de3-2c1992481607", + "id": "B03.13", + "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/identity/adds-extend-domain", "services": [ - "Storage", - "AVD" + "Entra" ], - "severity": "High", - "subcategory": "Capacity Planning", - "text": "Verify storage scalability limits and Host Pool requirements", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "Identity", + "text": "If domain controllers are being used, ensure that resources are set to use the correct domain controller.", + "training": "https://learn.microsoft.com/learn/paths/implement-windows-server-iaas-virtual-machine-identity/", + "waf": "Security" }, { - "category": "Storage", - "checklist": "Azure Virtual Desktop Review", - "description": "Avoid introducing additional latency and costs associated with cross-region network traffic where possible.", - "guid": "8aad53cc-79e2-4e86-9673-57c549675c5e", - "id": "H03.05", - "link": "https://docs.microsoft.com/azure/virtual-desktop/fslogix-containers-azure-files", + "category": "Identity and Access Management", + "checklist": "Azure Landing Zone Review", + "guid": "d5d1e4e6-1465-48d3-958f-d77249b82111", + "id": "B03.14", + "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy", "services": [ - "Storage", - "AVD", - "Cost" + "VPN", + "Entra" ], - "severity": "High", - "subcategory": "Capacity Planning", - "text": "For optimal performance, the storage solution and the FSLogix profile container should be in the same Azure region.", - "waf": "Performance" + "severity": "Medium", + "subcategory": "Identity", + "text": "Consider using Microsoft Entra ID Application Proxy as a VPN or reverse proxy replacement to give remote users secure and authenticated access to internal applications (hosted in the cloud or on-premises).", + "training": "https://learn.microsoft.com/learn/paths/implement-applications-external-access-azure-ad/", + "waf": "Security" }, { - "category": "Storage", - "checklist": "Azure Virtual Desktop Review", - "description": "The recommendation in Azure Virtual Desktop is to use Profile Container without Office Container (ODFC) split unless you are planning for specific Business Continuity and Disaster Recovery (BCDR) scenarios as described in the Disaster Recovery section below. https://docs.microsoft.com/fslogix/profile-container-office-container-cncpt ", - "guid": "df47d2d9-2881-4b1c-b5d1-e54a29759e39", - "id": "H04.01", - "link": "https://learn.microsoft.com/fslogix/concepts-container-types#when-to-use-profile-and-odfc-containers", + "category": "Identity and Access Management", + "checklist": "Azure Landing Zone Review", + "guid": "35037e68-9349-4c15-b371-228514f4cdff", + "id": "B03.15", + "link": "https://learn.microsoft.com/azure/active-directory/roles/best-practices", "services": [ - "ASR", - "Storage", - "AVD" + "RBAC", + "Entra" ], - "severity": "High", - "subcategory": "FSLogix", - "text": "Do not use Office Containers (ODFC) if not strictly required and justified", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "Identity", + "text": "Avoid using on-premises synced accounts for Microsoft Entra ID role assignments.", + "training": "https://learn.microsoft.com/learn/modules/design-identity-security-strategy/", + "waf": "Security" }, { - "category": "Storage", - "checklist": "Azure Virtual Desktop Review", - "description": "Make sure to configure the following antivirus exclusions for FSLogix Profile Container virtual hard drives, as documented in the referenced article in the 'More Info' column.", - "guid": "83f63047-22ee-479d-9b5c-3632054b69ba", - "id": "H04.02", - "link": "https://learn.microsoft.com/fslogix/overview-prerequisites#configure-antivirus-file-and-folder-exclusions", + "category": "Identity and Access Management", + "checklist": "Azure Landing Zone Review", + "guid": "9cf5418b-1520-4b7b-add7-88eb28f833e8", + "id": "B04.01", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/identity-access-landing-zones#managed-identities", "services": [ - "Storage", - "AVD" + "VNet", + "Entra" ], "severity": "Medium", - "subcategory": "FSLogix", - "text": "Configure the recommended antivirus exclusions for FSLogix (includes not scanning VHD(x) files on connect).", + "subcategory": "Landing zones", + "text": "Configure Identity network segmentation through the use of a virtual Network and peer back to the hub. Providing authentication inside application landing zone (legacy).", + "training": "https://learn.microsoft.com/azure/architecture/example-scenario/identity/adds-extend-domain", "waf": "Security" }, { - "category": "Storage", - "checklist": "Azure Virtual Desktop Review", - "description": "Profile containers have a default max size of 30GB. If large Profile Containers are anticipated, and customers wants to try to keep them small, consider using OneDrive to host Office 365 files outside the FSLogix profile.", - "guid": "01e6a84d-e5df-443d-8992-481718d5d1e5", - "id": "H04.03", - "link": "https://docs.microsoft.com/fslogix/profile-container-configuration-reference", + "category": "Identity and Access Management", + "checklist": "Azure Landing Zone Review", + "guid": "d4d1ad54-1abc-4919-b267-3f342d3b49e4", + "id": "B04.02", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/identity-access-landing-zones#rbac-recommendations", "services": [ + "AKV", + "RBAC", "Storage", - "AVD" + "ACR", + "Entra" ], - "severity": "High", - "subcategory": "FSLogix", - "text": "Review and confirm configured maximum profile size in FSLogix", - "waf": "Cost" + "severity": "Medium", + "subcategory": "Landing zones", + "text": "Use Azure RBAC to manage data plane access to resources, if possible. E.G - Data Operations across Key Vault, Storage Account and Database Services. ", + "training": "https://learn.microsoft.com/azure/role-based-access-control/overview", + "waf": "Security" }, { - "category": "Storage", - "checklist": "Azure Virtual Desktop Review", - "description": "Defaults and recommended settings are reported in the companion article in the 'More Info' column. If not recommended keys and/or values must be used, be sure to review with a Microsoft AVD expert and clearly document your choices.", - "guid": "d34aad5e-8c78-4e1d-9666-7313c405674c", - "id": "H04.04", - "link": "https://learn.microsoft.com/fslogix/concepts-configuration-examples", + "category": "Identity and Access Management", + "checklist": "Azure Landing Zone Review", + "guid": "d505ebcb-79b1-4274-9c0d-a27c8bea489c", + "id": "B04.03", + "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-create-roles-and-resource-roles-review", "services": [ - "ACR", - "Storage", - "AKV", - "AVD" + "Entra" ], + "severity": "Medium", + "subcategory": "Landing zones", + "text": "Use Microsoft Entra ID PIM access reviews to periodically validate resource entitlements.", + "waf": "Security" + }, + { + "ammp": true, + "category": "Resource Organization", + "checklist": "Azure Landing Zone Review", + "guid": "cacf55bc-e4e4-46be-96bc-57a5f23a269a", + "id": "C01.01", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/resource-naming", + "services": [], "severity": "High", - "subcategory": "FSLogix", - "text": "Review FSLogix registry keys and determine which ones to apply", - "waf": "Reliability" + "subcategory": "Naming and tagging", + "text": "It is recommended to follow Microsoft Best Practice Naming Standards", + "waf": "Security" }, { - "category": "Storage", - "checklist": "Azure Virtual Desktop Review", - "description": "Concurrent or multiple connections are not recommended in Azure Virtual Desktop. Concurrent connections are also not supported by Session Hosts running in an Azure Virtual Desktop Host Pool. OneDrive, if used, doesn't support concurrent or multiple connections using the same container, under any circumstance. For multiple connections, usage of the same profile disk is not recommended.", - "guid": "5e985b85-9c77-43e7-b261-623b775a917e", - "id": "H04.05", - "link": "https://learn.microsoft.com/fslogix/concepts-multi-concurrent-connections", + "category": "Resource Organization", + "checklist": "Azure Landing Zone Review", + "graph": "resourcecontainers| where type == 'microsoft.resources/subscriptions'| extend ManagementGroup = tostring(tags),mgmtChain = properties.managementGroupAncestorsChain| extend compliant =( array_length(mgmtChain) <= 4 and array_length(mgmtChain) > 1)", + "guid": "2df27ee4-12e7-4f98-9f63-04722dd69c5b", + "id": "C02.01", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/resource-org-management-groups", "services": [ - "Storage", - "AVD" + "Subscriptions" ], - "severity": "High", - "subcategory": "FSLogix", - "text": "Avoid usage of concurrent or multiple connections", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "Subscriptions", + "text": "Enforce reasonably flat management group hierarchy with no more than four levels.", + "training": "https://learn.microsoft.com/learn/modules/azure-architecture-fundamentals/", + "waf": "Security" }, { - "category": "Storage", - "checklist": "Azure Virtual Desktop Review", - "description": "Cloud Cache uses OS drive as local cache storage and may generate lot of pressure on the VM disk. Depending on the VM SKU and size used, the VM temporary drive can be a viable and performant solution where to relocate Cloud Cache cached content. Before adopting this solution, tests should be executed to confirm performance and stability. More details on Cloud Cache can be found here: https://learn.microsoft.com/fslogix/concepts-fslogix-cloud-cache. ", - "guid": "b2d1215a-e114-4ba3-9df5-85ecdcd9bd3b", - "id": "H04.06", - "link": "https://docs.microsoft.com/fslogix/cloud-cache-configuration-reference", + "category": "Resource Organization", + "checklist": "Azure Landing Zone Review", + "guid": "667313b4-f566-44b5-b984-a859c773e7d2", + "id": "C02.02", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/resource-org-management-groups#management-group-recommendations", "services": [ - "VM", - "Storage", - "AVD" + "Subscriptions" ], - "severity": "Low", - "subcategory": "FSLogix", - "text": "If FSLogix Cloud Cache is used, consider moving the cache directory to the VM temporary drive.", - "waf": "Performance" + "severity": "Medium", + "subcategory": "Subscriptions", + "text": "Enforce a sandbox management group to allow users to immediately experiment with Azure", + "training": "https://learn.microsoft.com/learn/paths/enterprise-scale-architecture/", + "waf": "Security" }, { - "category": "Storage", - "checklist": "Azure Virtual Desktop Review", - "description": "REDIRECTION.XML file is used to control what folders are redirected out of the profile container to the 'C:' drive. Exclusions should be the exception and should never be used unless the specific exclusion is completely understood by the person configuring the exclusion. Exclusions should always be fully tested in the environment where they are intended to be implemented. Configuring exclusions may impact functionality, stability and performance.", - "guid": "0b50ca97-b1d2-473c-b4d9-6e98b0f912de", - "id": "H04.07", - "link": "https://docs.microsoft.com/fslogix/manage-profile-content-cncpt#redirectionsxml", + "category": "Resource Organization", + "checklist": "Azure Landing Zone Review", + "guid": "61623a76-5a91-47e1-b348-ef254c27d42e", + "id": "C02.03", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/resource-org-management-groups#management-group-recommendations", "services": [ - "Storage", - "AVD" + "RBAC", + "Subscriptions", + "AzurePolicy" ], "severity": "Medium", - "subcategory": "FSLogix", - "text": "Review the usage of FSLogix redirection.", - "waf": "Cost" + "subcategory": "Subscriptions", + "text": "Enforce a platform management group under the root management group to support common platform policy and Azure role assignment", + "training": "https://learn.microsoft.com/learn/paths/enterprise-scale-architecture/", + "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "f00a69de-7076-4734-a734-6e4552cad9e1", - "id": "A01.01", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-latest-version-for-customer-managed-certificates", + "category": "Resource Organization", + "checklist": "Azure Landing Zone Review", + "guid": "8bbac757-1559-4ab9-853e-8908ae28c84c", + "id": "C02.04", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/resource-org-management-groups#management-group-recommendations", "services": [ - "FrontDoor", - "AKV" + "ExpressRoute", + "VWAN", + "Subscriptions", + "DNS" ], "severity": "Medium", - "subcategory": "App delivery - Front Door", - "text": "If you use customer-managed TLS certificates with Azure Front Door, use the 'Latest' certificate version. Reduce the risk of outages caused by manual certificate renewal.", - "waf": "Operations" + "subcategory": "Subscriptions", + "text": "Enforce a dedicated connectivity subscription in the Connectivity management group to host an Azure Virtual WAN hub, private Domain Name System (DNS), ExpressRoute circuit, and other networking resources.", + "training": "https://learn.microsoft.com/learn/paths/enterprise-scale-architecture/", + "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "6138a720-0f1c-4e16-bd30-1d6e872e52e3", - "id": "A01.02", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/resource-org-management-groups#management-groups-in-the-azure-landing-zone-accelerator", - "services": [], + "category": "Resource Organization", + "checklist": "Azure Landing Zone Review", + "graph": "resourcecontainers| where type == 'microsoft.resources/subscriptions'| extend ManagementGroup = tostring(tags),mgmtChain = properties.managementGroupAncestorsChain| extend compliant = (array_length(mgmtChain) > 1)", + "guid": "33b6b780-8b9f-4e5c-9104-9d403a923c34", + "id": "C02.05", + "link": "https://learn.microsoft.com/azure/governance/management-groups/how-to/protect-resource-hierarchy#setting---default-management-group", + "services": [ + "Subscriptions" + ], "severity": "Medium", - "subcategory": "App delivery", - "text": "Perform app delivery within landing zones for both internal-facing (corp) and external-facing apps (online).", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "subcategory": "Subscriptions", + "text": "Enforce no subscriptions are placed under the root management group", "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "graph": "resources | where type == 'microsoft.network/applicationgateways' | project id, compliant = properties.sku.name in ('Standard_v2', 'WAF_v2') | project id,compliant", - "guid": "553585a6-abe0-11ed-afa1-0242ac120002", - "id": "A01.03", - "link": "https://learn.microsoft.com/azure/application-gateway/overview-v2", + "category": "Resource Organization", + "checklist": "Azure Landing Zone Review", + "guid": "74d00018-ac6a-49e0-8e6a-83de5de32c19", + "id": "C02.06", + "link": "https://learn.microsoft.com/azure/governance/management-groups/how-to/protect-resource-hierarchy#setting---require-authorization", "services": [ - "AppGW" + "RBAC", + "Subscriptions" ], "severity": "Medium", - "subcategory": "App delivery - App Gateway", - "text": "Ensure you are using Application Gateway v2 SKU", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "subcategory": "Subscriptions", + "text": "Enforce that only privileged users can operate management groups in the tenant by enabling Azure RBAC authorization in the management group hierarchy settings", "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "graph": "resources | where type == 'microsoft.network/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard')", - "guid": "4e35fbf5-0ae2-48b2-97ce-753353edbd1a", - "id": "A01.04", - "link": "https://learn.microsoft.com/azure/load-balancer/load-balancer-overview", + "category": "Resource Organization", + "checklist": "Azure Landing Zone Review", + "guid": "92481607-d5d1-4e4e-9146-58d3558fd772", + "id": "C02.07", + "link": "https://learn.microsoft.com/azure/governance/management-groups/overview", "services": [ - "LoadBalancer" + "Subscriptions" ], "severity": "Medium", - "subcategory": "App delivery - Load Balancer", - "text": "Ensure you are using the Standard SKU for your Azure Load Balancers", + "subcategory": "Subscriptions", + "text": "Enforce management groups under the root-level management group to represent the types of workloads, based on their security, compliance, connectivity, and feature needs.", "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "graph": "resources | where type=='microsoft.network/applicationgateways' | extend subnetId = tostring(properties.gatewayIPConfigurations[0].properties.subnet.id) | project id, subnetId | join (resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | mv-expand subnets.properties.addressPrefixes | project id, subnetId = tostring(subnets.id), prefix1 = subnets.properties.addressPrefix, prefix2 = subnets.properties.addressPrefixes | mv-expand prefix2 | extend prefix = iff(isnotnull(prefix1), prefix1, prefix2) | extend subnetPrefixLength = split(prefix, '/')[1])on subnetId | extend compliant = (subnetPrefixLength <= 24 or subnetPrefixLength == 64) | distinct id,compliant", - "guid": "dfc50f87-3800-424c-937b-ed5f186e7c15", - "id": "A01.05", - "link": "https://learn.microsoft.com/azure/application-gateway/configuration-infrastructure#size-of-the-subnet", + "ammp": true, + "category": "Resource Organization", + "checklist": "Azure Landing Zone Review", + "guid": "49b82111-2df2-47ee-912e-7f983f630472", + "id": "C02.08", + "link": "https://learn.microsoft.com/azure/governance/management-groups/overview", "services": [ - "VNet", - "AppGW" + "RBAC", + "Cost", + "Subscriptions", + "AzurePolicy" ], - "severity": "Medium", - "subcategory": "App delivery - App Gateway", - "text": "Your Application Gateways v2 should be deployed in subnets with IP prefixes equal or larger than /24", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "severity": "High", + "subcategory": "Subscriptions", + "text": "Enforce a process to make resource owners aware of their roles and responsibilities, access review, budget review, policy compliance and remediate when necessary.", "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "description": "Administration of reverse proxies in general and WAF in particular is closer to the application than to networking, so they belong in the same subscription as the app. Centralizing the Application Gateway and WAF in the connectivity subscription might be OK if it is managed by one single team.", - "guid": "48b662d6-d15f-4512-a654-98f6dfe237de", - "id": "A01.06", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "category": "Resource Organization", + "checklist": "Azure Landing Zone Review", + "guid": "2dd69c5b-5c26-422f-94b6-9bad33aad5e8", + "id": "C02.09", + "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits", "services": [ - "Entra", - "WAF", - "VNet", - "NVA", - "AppGW", "Subscriptions" ], "severity": "Medium", - "subcategory": "App delivery - App Gateway", - "text": "Deploy Azure Application Gateway v2 or partner NVAs used for proxying inbound HTTP(S) connections within the landing-zone virtual network and with the apps that they're securing.", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "subcategory": "Subscriptions", + "text": "Ensure that all subscription owners and IT core team are aware of subscription quotas and the impact they have on provision resources for a given subscription.", "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "143b16c3-1d7a-4a9b-9470-4489a8042d88", - "id": "A01.07", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "ammp": true, + "category": "Resource Organization", + "checklist": "Azure Landing Zone Review", + "guid": "c68e1d76-6673-413b-9f56-64b5e984a859", + "id": "C02.10", + "link": "https://learn.microsoft.com/azure/cost-management-billing/reservations/save-compute-costs-reservations", "services": [ - "DDoS" + "VM", + "Cost", + "Subscriptions", + "AzurePolicy" ], - "severity": "Medium", - "subcategory": "App delivery - App Gateway", - "text": "Use a DDoS Network or IP protection plans for all Public IP addresses in application landing zones.", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "severity": "High", + "subcategory": "Subscriptions", + "text": "Use Reserved Instances where appropriate to optimize cost and ensure available capacity in target regions. Enforce the use of purchased Reserved Instance VM SKUs via Azure Policy.", + "training": "https://learn.microsoft.com/learn/paths/improve-reliability-modern-operations/", "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "graph": "resources | where type =~ 'microsoft.network/applicationGateways' | extend compliant = (isnotnull(properties.autoscaleConfiguration) and properties.autoscaleConfiguration.minCapacity >= 2) | distinct id,compliant", - "guid": "135bf4ac-f9db-461f-b76b-2ee9e30b12c0", - "id": "A01.08", - "link": "https://learn.microsoft.com/azure/application-gateway/application-gateway-autoscaling-zone-redundant", - "services": [], - "severity": "Medium", - "subcategory": "App delivery - App Gateway", - "text": "Configure autoscaling with a minimum amount of instances of two.", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", - "waf": "Reliability" + "ammp": true, + "category": "Resource Organization", + "checklist": "Azure Landing Zone Review", + "guid": "c773e7d2-6162-43a7-95a9-17e1f348ef25", + "id": "C02.11", + "link": "https://learn.microsoft.com/azure/architecture/framework/scalability/design-capacity", + "services": [ + "Monitor", + "Subscriptions" + ], + "severity": "High", + "subcategory": "Subscriptions", + "text": "Enforce a dashboard, workbook, or manual process to monitor used capacity levels", + "training": "https://learn.microsoft.com/learn/paths/monitor-usage-performance-availability-resources-azure-monitor/", + "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "graph": "resources | where type =~ 'microsoft.network/applicationGateways' | extend compliant = (isnotnull(zones) and array_length(zones) > 1) | distinct id,compliant", - "guid": "060c6964-52b5-48db-af8b-83e4b2d85349", - "id": "A01.09", - "link": "https://learn.microsoft.com/azure/reliability/migrate-app-gateway-v2", + "ammp": true, + "category": "Resource Organization", + "checklist": "Azure Landing Zone Review", + "guid": "ae28c84c-33b6-4b78-88b9-fe5c41049d40", + "id": "C02.12", + "link": "https://learn.microsoft.com/azure/cost-management-billing/cost-management-billing-overview", "services": [ - "ACR", - "AppGW" + "Cost", + "Subscriptions" ], - "severity": "Medium", - "subcategory": "App delivery - App Gateway", - "text": "Deploy Application Gateway across Availability Zones", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", - "waf": "Reliability" + "severity": "High", + "subcategory": "Subscriptions", + "text": "Enforce a process for cost management", + "training": "https://learn.microsoft.com/learn/paths/control-spending-manage-bills/", + "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "e79d17b7-3b22-4a5a-97e7-a8ed4b30e38c", - "id": "A01.10", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "category": "Resource Organization", + "checklist": "Azure Landing Zone Review", + "guid": "3a923c34-74d0-4001-aac6-a9e01e6a83de", + "id": "C02.13", + "link": "https://learn.microsoft.com/azure/governance/management-groups/overview", + "services": [ + "Subscriptions", + "Entra" + ], + "severity": "Medium", + "subcategory": "Subscriptions", + "text": "If servers will be used for Identity services, like domain controllers, establish a dedicated identity subscription in the identity management group, to host these services", + "training": "https://learn.microsoft.com/learn/paths/enterprise-scale-architecture/", + "waf": "Security" + }, + { + "category": "Resource Organization", + "checklist": "Azure Landing Zone Review", + "graph": "resources | extend compliant = isnotnull(['tags']) | project name, id, subscriptionId, resourceGroup, tags, compliant", + "guid": "5de32c19-9248-4160-9d5d-1e4e614658d3", + "id": "C02.14", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/track-costs", "services": [ - "AzurePolicy", - "FrontDoor", - "WAF" + "Cost", + "Subscriptions" ], "severity": "Medium", - "subcategory": "App delivery - Front Door", - "text": "Use Azure Front Door with WAF policies to deliver and help protect global HTTP/S apps that span multiple Azure regions.", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "subcategory": "Subscriptions", + "text": "Ensure tags are used for billing and cost management", + "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "3f29812b-2363-4cef-b179-b599de0d5973", - "id": "A01.11", - "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", + "category": "Resource Organization", + "checklist": "Azure Landing Zone Review", + "guid": "6cc0ea22-42bb-441e-a345-804ab0a09666", + "id": "C02.15", + "link": "https://github.com/Azure/sovereign-landing-zone/blob/main/docs/02-Architecture.md", "services": [ - "AzurePolicy", - "FrontDoor", - "AppGW", - "WAF" + "Subscriptions" ], "severity": "Medium", - "subcategory": "App delivery", - "text": "When using Front Door and Application Gateway to help protect HTTP/S apps, use WAF policies in Front Door. Lock down Application Gateway to receive traffic only from Front Door.", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "subcategory": "Subscriptions", + "text": "For Sovereign Landing Zone, have a 'confidential corp' and 'confidential online' management group directly under the 'landing zones' MG.", "waf": "Security" }, { - "ammp": true, - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "cd4cd21b-0881-437f-9e6c-4cfd3e504547", - "id": "A01.12", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "category": "Resource Organization", + "checklist": "Azure Landing Zone Review", + "guid": "250d81ce-8bbe-4f85-9051-6a18a8221e50", + "id": "C03.01", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-setup-guide/regions", "services": [ - "TrafficManager" + "Cost" ], "severity": "High", - "subcategory": "App delivery - Traffic Manager", - "text": "Use Traffic Manager to deliver global apps that span protocols other than HTTP/S.", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "subcategory": "Regions", + "text": "Select the right Azure region/s for your deployment. Azure is a global-scale cloud platform that provide global coverage through many regions and geographies. Different Azure regions have different characteristics, access and availability models, costs, capacity, and services offered, then it is important to consider all criteria and requirements", + "training": "https://learn.microsoft.com/learn/modules/azure-architecture-fundamentals/", "waf": "Reliability" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "3b4b3e88-a459-4ed5-a22f-644dfbc58204", - "id": "A01.13", - "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy#how-application-proxy-works", + "category": "Resource Organization", + "checklist": "Azure Landing Zone Review", + "guid": "19ca3f89-397d-44b1-b5b6-5e18661372ac", + "id": "C03.02", + "link": "https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/azure-setup-guide/regions#operate-in-multiple-geographic-regions", "services": [ - "AVD", - "Entra" + "ASR" ], - "severity": "Low", - "subcategory": "App delivery", - "text": "If users only need access to internal applications, has Microsoft Entra ID Application Proxy been considered as an alternative to Azure Virtual Desktop (AVD)?", - "training": "https://learn.microsoft.com/learn/modules/configure-azure-ad-application-proxy/", - "waf": "Security" + "severity": "Medium", + "subcategory": "Regions", + "text": "Consider a multi-region deployment. Depending on customer size, locations, and users presence, operating in multiple regions can be a common choice to deliver services and run applications closer to them. Using a multi-region deployment is also important to provide geo disaster recovery capabilities, to eliminate the dependency from a single region capacity and diminish the risk of a temporary and localized resource capacity constraint", + "training": "https://learn.microsoft.com/learn/modules/azure-architecture-fundamentals/", + "waf": "Reliability" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "01ca7cf1-5754-442d-babb-8ba6772e5c30", - "id": "A01.14", - "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy#how-application-proxy-works", - "services": [ - "Entra" - ], + "category": "Resource Organization", + "checklist": "Azure Landing Zone Review", + "guid": "4c27d42e-8bba-4c75-9155-9ab9153e8908", + "id": "C03.03", + "link": "https://azure.microsoft.com/explore/global-infrastructure/products-by-region/", + "services": [], "severity": "Medium", - "subcategory": "App delivery", - "text": "To reduce the number of firewall ports open for incoming connections in your network, consider using Microsoft Entra ID Application Proxy to give remote users secure and authenticated access to internal applications.", - "training": "https://learn.microsoft.com/learn/paths/implement-applications-external-access-azure-ad/", - "waf": "Security" + "subcategory": "Regions", + "text": "Ensure required services and features are available within the chosen deployment regions", + "training": "https://learn.microsoft.com/learn/modules/azure-architecture-fundamentals/", + "waf": "Reliability" }, { - "ammp": true, "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "graph": "resources | where type == 'microsoft.network/frontdoorwebapplicationfirewallpolicies' | project policyName=name, policyId=id,policySku=sku.name, links=properties.securityPolicyLinks, enabledState=properties.policySettings.enabledState, mode=properties.policySettings.mode | mvexpand links | extend securityPolicy=links.id | extend securityPolicyParts=split(securityPolicy, '/') | extend profileId=strcat_array(array_slice(securityPolicyParts, 0, -3), '/') | project id=profileId, compliant=((enabledState=='Enabled') and (mode=='Prevention')), enabledState, mode", - "guid": "ae248989-b306-4591-9186-de482e3f0f0e", - "id": "A01.15", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-policy-settings", + "checklist": "Azure Landing Zone Review", + "guid": "373f482f-3e39-4d39-8aa4-7e566f6082b6", + "id": "D01.01", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-app-delivery", "services": [ "FrontDoor", - "Storage", - "WAF" + "AppGW" ], - "severity": "High", - "subcategory": "App delivery - Front Door", - "text": "Deploy your WAF profiles for Front Door in 'Prevention' mode.", - "waf": "Security" + "severity": "Medium", + "subcategory": "App delivery", + "text": "Develop a plan for securing the delivery application content from your Workload spokes using Application Gateway and Azure Front door. You can use the Application Delivery checklist to for recommendations.", + "waf": "Operations" }, { - "ammp": true, "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "062d5839-4d36-402f-bfa4-02811eb936e9", - "id": "A01.16", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#avoid-combining-traffic-manager-and-front-door", - "services": [ - "TrafficManager", - "FrontDoor" - ], - "severity": "High", - "subcategory": "App delivery - Front Door", - "text": "Avoid combining Azure Traffic Manager and Azure Front Door.", + "checklist": "Azure Landing Zone Review", + "guid": "6138a720-0f1c-4e16-bd30-1d6e872e52e3", + "id": "D01.02", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/resource-org-management-groups#management-groups-in-the-azure-landing-zone-accelerator", + "services": [], + "severity": "Medium", + "subcategory": "App delivery", + "text": "Perform app delivery within landing zones for both internal-facing (corp) and external-facing apps (online).", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", "waf": "Security" }, { - "ammp": true, "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "5efeb96a-003f-4b18-8fcd-b4d84459c2b2", - "id": "A01.17", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-the-same-domain-name-on-front-door-and-your-origin", + "checklist": "Azure Landing Zone Review", + "guid": "143b16c3-1d7a-4a9b-9470-4489a8042d88", + "id": "D01.03", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", "services": [ - "FrontDoor" + "DDoS" ], - "severity": "High", - "subcategory": "App delivery - Front Door", - "text": "Use the same domain name on Azure Front Door and your origin. Mismatched host names can cause subtle bugs.", + "severity": "Medium", + "subcategory": "App delivery", + "text": "Use a DDoS Network or IP protection plans for all Public IP addresses in application landing zones.", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", "waf": "Security" }, { "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "0b5a380c-4bfb-47bc-b1d7-dcfef363a61b", - "id": "A01.18", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#disable-health-probes-when-theres-only-one-origin-in-an-origin-group", - "services": [ - "FrontDoor" - ], - "severity": "Low", - "subcategory": "App delivery - Front Door", - "text": "Disable health probes when there is only one origin in an Azure Front Door origin group.", - "waf": "Performance" - }, - { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "5567048e-e5d7-4206-9c55-b5ed45d2cc0c", - "id": "A01.19", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#select-good-health-probe-endpoints", + "checklist": "Azure Landing Zone Review", + "guid": "de0d5973-cd4c-4d21-a088-137f5e6c4cfd", + "id": "D02.01", + "link": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", "services": [ - "FrontDoor" + "ExpressRoute" ], "severity": "Medium", - "subcategory": "App delivery - Front Door", - "text": "Select good health probe endpoints for Azure Front Door. Consider building health endpoints that check all of your application's dependencies.", - "waf": "Reliability" + "subcategory": "Encryption", + "text": "When you're using ExpressRoute Direct, configure MACsec in order to encrypt traffic at the layer-two level between the organization's routers and MSEE. The diagram shows this encryption in flow.", + "waf": "Security" }, { "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "a13f72f3-8f5c-4864-95e5-75bf37fbbeb1", - "id": "A01.20", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-head-health-probes", + "checklist": "Azure Landing Zone Review", + "guid": "ed301d6e-872e-452e-9611-cc58b5a4b151", + "id": "D02.02", + "link": "https://learn.microsoft.com/azure/expressroute/expressroute-erdirect-about", "services": [ - "FrontDoor" + "ExpressRoute", + "VPN" ], "severity": "Low", - "subcategory": "App delivery - Front Door", - "text": "Use HEAD health probes with Azure Front Door, to reduce the traffic that Front Door sends to your application.", - "waf": "Performance" + "subcategory": "Encryption", + "text": "For scenarios where MACsec isn't an option (for example, not using ExpressRoute Direct), use a VPN gateway to establish IPsec tunnels over ExpressRoute private peering. ", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "Security" }, { - "ammp": true, "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "graph": "resources | where type=='microsoft.network/loadbalancers' | extend countOutRules=array_length(properties.outboundRules) | extend compliant = (countOutRules == 0) | distinct id,compliant", - "guid": "97a2fd46-64b0-1dfa-b72d-9c8869496d75", - "id": "A01.21", - "link": "https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "e8bbac75-7155-49ab-a153-e8908ae28c84", + "id": "D03.01", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/enterprise-scale/network-topology-and-connectivity", "services": [ - "LoadBalancer" + "VNet" ], - "severity": "High", - "subcategory": "App delivery - Load Balancer", - "text": "Use Azure NAT Gateway instead of Load Balancer outbound rules for better SNAT scalability", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "Hub and spoke", + "text": "Consider a network design based on the traditional hub-and-spoke network topology for network scenarios that require maximum flexibility.", + "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", + "waf": "Security" }, { "ammp": true, "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "af95c92d-d723-4f4a-98d7-8722324efd4d", - "id": "A01.22", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-managed-tls-certificates", + "checklist": "Azure Landing Zone Review", + "guid": "7dd61623-a364-4a90-9eca-e48ebd54cd7d", + "id": "D03.02", + "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/hybrid-networking/expressroute", "services": [ - "FrontDoor", - "AKV", - "Cost" + "ExpressRoute", + "Firewall", + "DNS", + "VPN", + "NVA", + "VNet", + "Entra" ], - "severity": "High", - "subcategory": "App delivery - Front Door", - "text": "Use managed TLS certificates with Azure Front Door. Reduce operational cost and risk of outages due to certificate renewals.", - "waf": "Operations" + "severity": "High", + "subcategory": "Hub and spoke", + "text": "Ensure that shared networking services, including ExpressRoute gateways, VPN gateways, and Azure Firewall or partner NVAs in the central-hub virtual network. If necessary, also deploy DNS servers.", + "waf": "Cost" }, { "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "189ea962-3969-4863-8f5a-5ad808c2cf4b", - "id": "A01.23", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#define-your-waf-configuration-as-code", + "checklist": "Azure Landing Zone Review", + "guid": "e2e8abac-3571-4559-ab91-53e89f89dc7b", + "id": "D03.03", + "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/dmz/nva-ha", "services": [ - "FrontDoor", - "WAF" + "NVA" ], "severity": "Medium", - "subcategory": "App delivery - Front Door", - "text": "Define your Azure Front Door WAF configuration as code. By using code, you can more easily adopt new ruleset versions and gain additional protection.", - "waf": "Operations" + "subcategory": "Hub and spoke", + "text": "When deploying partner networking technologies or NVAs, follow the partner vendor's guidance", + "waf": "Reliability" }, { - "ammp": true, "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "2e30abab-5478-417c-81bf-bf1ad4ed1ed4", - "id": "A01.24", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-end-to-end-tls", + "checklist": "Azure Landing Zone Review", + "guid": "ce463dbb-bc8a-4c2a-aebc-92a43da1dae2", + "id": "D03.04", + "link": "https://learn.microsoft.com/azure/expressroute/expressroute-howto-coexist-resource-manager#to-enable-transit-routing-between-expressroute-and-azure-vpn", "services": [ - "FrontDoor" + "ExpressRoute", + "ARS", + "VPN" ], - "severity": "High", - "subcategory": "App delivery - Front Door", - "text": "Use end-to-end TLS with Azure Front Door. Use TLS for connections from your clients to Front Door, and from Front Door to your origin.", + "severity": "Low", + "subcategory": "Hub and spoke", + "text": "If you need transit between ExpressRoute and VPN gateways in hub and spoke scenarios, use Azure Route Server.", "waf": "Security" }, { "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "10aa45af-166f-44c4-9f36-b6d592dac2ca", - "id": "A01.25", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-http-to-https-redirection", + "checklist": "Azure Landing Zone Review", + "graph": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant", + "guid": "91b9d7d5-91e1-4dcb-8f1f-fa7e465646cc", + "id": "D03.05", + "link": "https://learn.microsoft.com/azure/route-server/quickstart-configure-route-server-portal#create-a-route-server-1", "services": [ - "FrontDoor" + "VNet", + "ARS" ], - "severity": "Medium", - "subcategory": "App delivery - Front Door", - "text": "Use HTTP to HTTPS redirection with Azure Front Door. Support older clients by redirecting them to an HTTPS request automatically.", + "severity": "Low", + "subcategory": "Hub and spoke", + "text": "If using Route Server, use a /27 prefix for the Route Server subnet.", "waf": "Security" }, { - "ammp": true, "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "28b9ee82-b2c7-45aa-bc98-6de6f59a095d", - "id": "A01.26", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#enable-the-waf", + "checklist": "Azure Landing Zone Review", + "guid": "cc881471-607c-41cc-a0e6-14658dd558f9", + "id": "D03.06", + "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-faq#can-i-create-a-peering-connection-to-a-vnet-in-a-different-region", "services": [ - "FrontDoor", - "WAF" + "ACR", + "VNet" ], - "severity": "High", - "subcategory": "App delivery - Front Door", - "text": "Enable the Azure Front Door WAF. Protect your application from a range of attacks.", - "waf": "Security" + "severity": "Medium", + "subcategory": "Hub and spoke", + "text": "For network architectures with multiple hub-and-spoke topologies across Azure regions, use global virtual network peerings between the hub VNets to connect the regions to each other. ", + "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-virtual-networks/", + "waf": "Performance" }, { - "ammp": true, "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "2902d8cc-1b0c-4495-afad-624ab70f7bd6", - "id": "A01.27", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#tune-your-waf", + "checklist": "Azure Landing Zone Review", + "guid": "4722d929-c1b1-4cd6-81f5-4b29bade39ad", + "id": "D03.07", + "link": "https://learn.microsoft.com/azure/azure-monitor/insights/network-insights-overview", "services": [ - "FrontDoor", - "WAF" + "Monitor" ], - "severity": "High", - "subcategory": "App delivery - Front Door", - "text": "Tune the Azure Front Door WAF for your workload. Reduce false positive detections.", - "waf": "Security" + "severity": "Medium", + "subcategory": "Hub and spoke", + "text": "Use Azure Monitor for Networks to monitor the end-to-end state of the networks on Azure.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/", + "waf": "Operations" }, { - "ammp": true, "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "17ba124b-127d-42b6-9322-388d5b2bbcfc", - "id": "A01.28", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-prevention-mode", + "checklist": "Azure Landing Zone Review", + "graph": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant", + "guid": "0e7c28ec-9366-4572-83b0-f4664b1d944a", + "id": "D03.08", + "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits", "services": [ - "FrontDoor", - "WAF" + "ExpressRoute", + "VNet", + "Entra" ], - "severity": "High", - "subcategory": "App delivery - Front Door", - "text": "Use prevention mode with the Azure Front Door WAF. Prevention mode ensures that the WAF blocks malicious requests.", - "waf": "Security" + "severity": "Medium", + "subcategory": "Hub and spoke", + "text": "When connecting spoke virtual networks to the central hub virtual network, consider VNet peering limits (500), the maximum number of prefixes that can be advertised via ExpressRoute (1000)", + "waf": "Reliability" }, { - "ammp": true, "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "49a98f2b-ec22-4a87-9415-6a10b00d6555", - "id": "A01.29", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#enable-default-rule-sets", + "checklist": "Azure Landing Zone Review", + "graph": "resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant", + "guid": "3d457936-e9b7-41eb-bdff-314b26450b12", + "id": "D03.09", + "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits", "services": [ - "FrontDoor", - "WAF" + "Storage" ], - "severity": "High", - "subcategory": "App delivery - Front Door", - "text": "Enable the Azure Front Door WAF default rule sets. The default rule sets detect and block common attacks.", - "waf": "Security" + "severity": "Medium", + "subcategory": "Hub and spoke", + "text": "Consider the limit of routes per route table (400).", + "waf": "Reliability" }, { "ammp": true, "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "147a13d4-2a2f-4824-a524-f5855b52b946", - "id": "A01.30", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#enable-bot-management-rules", + "checklist": "Azure Landing Zone Review", + "graph": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True)", + "guid": "c76cb5a2-abe2-11ed-afa1-0242ac120002", + "id": "D03.10", + "link": "https://learn.microsoft.com/azure/virtual-network/virtual-network-manage-peering", "services": [ - "FrontDoor", - "WAF" + "VNet" ], "severity": "High", - "subcategory": "App delivery - Front Door", - "text": "Enable the Azure Front Door WAF bot management rules. The bot rules detect good and bad bots.", - "waf": "Security" + "subcategory": "Hub and spoke", + "text": "Use the setting 'Allow traffic to remote virtual network' when configuring VNet peerings", + "waf": "Reliability" }, { "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "d7dcdcb9-0d99-44b9-baab-ac7570ede79a", - "id": "A01.31", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-the-latest-ruleset-versions", + "checklist": "Azure Landing Zone Review", + "guid": "359c373e-7dd6-4162-9a36-4a907ecae48e", + "id": "D04.01", + "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/hybrid-networking/hub-spoke?tabs=cli", "services": [ - "FrontDoor", - "WAF" + "ExpressRoute" ], "severity": "Medium", - "subcategory": "App delivery - Front Door", - "text": "Use the latest Azure Front Door WAF ruleset versions. Ruleset updates are regularly updated to take account of the current threat landscape.", - "waf": "Security" + "subcategory": "Hybrid", + "text": "Ensure that you have investigated the possibility to use ExpressRoute as primary connection to Azure.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "Performance" }, { "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "b9620385-1cde-418f-914b-a84a06982ffc", - "id": "A01.32", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#add-rate-limiting", + "checklist": "Azure Landing Zone Review", + "description": "You can use AS-path prepending and connection weights to influence traffic from Azure to on-premises, and the full range of BGP attributes in your own routers to influence traffic from on-premises to Azure.", + "guid": "f29812b2-363c-4efe-879b-599de0d5973c", + "id": "D04.02", + "link": "https://learn.microsoft.com/azure/expressroute/expressroute-routing", "services": [ - "FrontDoor", - "WAF" + "ExpressRoute" ], "severity": "Medium", - "subcategory": "App delivery - Front Door", - "text": "Add rate limiting to the Azure Front Door WAF. Rate limiting blocks clients accidentally or intentionally sending large amounts of traffic in a short period of time.", - "waf": "Security" + "subcategory": "Hybrid", + "text": "When you use multiple ExpressRoute circuits, or multiple on-prem locations, make sure to optimize routing with BGP attributes, if certain paths are preferred.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "Reliability" }, { "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "6dc36c52-0124-4ffe-9eaf-23ec1282dedb", - "id": "A01.33", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-a-high-threshold-for-rate-limits", + "checklist": "Azure Landing Zone Review", + "graph": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant", + "guid": "d4cd21b0-8813-47f5-b6c4-cfd3e504547c", + "id": "D04.03", + "link": "https://learn.microsoft.com/azure/expressroute/expressroute-routing", "services": [ - "FrontDoor", - "WAF" + "ExpressRoute", + "VPN" ], "severity": "Medium", - "subcategory": "App delivery - Front Door", - "text": "Use a high threshold for Azure Front Door WAF rate limits. High rate limit thresholds avoid blocking legitimate traffic, while still providing protection against extremely high numbers of requests that might overwhelm your infrastructure. ", - "waf": "Security" + "subcategory": "Hybrid", + "text": "Ensure that you're using the right SKU for the ExpressRoute/VPN gateways based on bandwidth and performance requirements.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "Performance" }, { + "ammp": true, "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "388a3d0e-0a43-4367-90b2-3dd2aeece5ee", - "id": "A01.34", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#geo-filter-traffic", + "checklist": "Azure Landing Zone Review", + "graph": "resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant", + "guid": "7025b442-f6e9-4af6-b11f-c9574916016f", + "id": "D04.04", + "link": "https://learn.microsoft.com/azure/expressroute/plan-manage-cost", "services": [ - "FrontDoor", - "WAF" + "ExpressRoute", + "Cost" ], - "severity": "Low", - "subcategory": "App delivery - Front Door", - "text": "Geo-filter traffic by using the Azure Front Door WAF. Allow traffic only from expected regions, and block traffic from other regions.", - "waf": "Security" + "severity": "High", + "subcategory": "Hybrid", + "text": "Ensure that you're using unlimited-data ExpressRoute circuits only if you reach the bandwidth that justifies their cost.", + "waf": "Cost" + }, + { + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "graph": "resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id", + "guid": "f4e7926a-ec35-476e-a412-5dd17136bd62", + "id": "D04.05", + "link": "https://learn.microsoft.com/azure/expressroute/expressroute-faqs#expressroute-local", + "services": [ + "ExpressRoute", + "Cost" + ], + "severity": "High", + "subcategory": "Hybrid", + "text": "Leverage the Local SKU of ExpressRoute to reduce the cost of your circuits, if your circuits' peering location supports your Azure regions for the Local SKU.", + "waf": "Cost" }, { "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "00acd8a9-6975-414f-8491-2be6309893b8", - "id": "A01.35", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#specify-the-unknown-zz-location", + "checklist": "Azure Landing Zone Review", + "graph": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant", + "guid": "2447ec66-138a-4720-8f1c-e16ed301d6e8", + "id": "D04.06", + "link": "https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways", "services": [ - "FrontDoor", - "WAF" + "ExpressRoute" ], "severity": "Medium", - "subcategory": "App delivery - Front Door", - "text": "Specify the unknown (ZZ) location when geo-filtering traffic with the Azure Front Door WAF. Avoid accidentally blocking legitimate requests when IP addresses can't be geo-matched.", - "waf": "Security" + "subcategory": "Hybrid", + "text": "Deploy a zone-redundant ExpressRoute gateway in the supported Azure regions.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "Reliability" }, { - "category": "Security", - "checklist": "Azure Event Hub Review", - "description": "Azure Event Hub provides encryption of data at rest. If you use your own key, the data is still encrypted using the Microsoft-managed key, but in addition the Microsoft-managed key will be encrypted using the customer-managed key. ", - "guid": "7aaf12e7-b94e-4f6e-847d-2d92981b1cd6", - "link": "https://learn.microsoft.com/azure/event-hubs/configure-customer-managed-key", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "72e52e36-11cc-458b-9a4b-1511e43a58a9", + "id": "D04.07", + "link": "https://learn.microsoft.com/azure/networking/", "services": [ - "EventHubs" + "ExpressRoute" ], - "severity": "Low", - "subcategory": "Data Protection", - "text": "Use customer-managed key option in data at rest encryption when required", - "training": "https://learn.microsoft.com/learn/modules/plan-implement-administer-conditional-access/" + "severity": "Medium", + "subcategory": "Hybrid", + "text": "For scenarios that require bandwidth higher than 10 Gbps or dedicated 10/100-Gbps ports, use ExpressRoute Direct.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "Performance" }, { - "category": "Security", - "checklist": "Azure Event Hub Review", - "description": "Azure Event Hubs namespaces permit clients to send and receive data with TLS 1.0 and above. To enforce stricter security measures, you can configure your Event Hubs namespace to require that clients send and receive data with a newer version of TLS. If an Event Hubs namespace requires a minimum version of TLS, then any requests made with an older version will fail. ", - "guid": "d2f54b29-769e-43a6-a0e7-828ac936657e", - "link": "https://learn.microsoft.com/azure/event-hubs/transport-layer-security-configure-minimum-version", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "c2299c4d-7b57-4d0c-9555-62f2b3e4563a", + "id": "D04.08", + "link": "https://learn.microsoft.com/azure/expressroute/about-fastpath", "services": [ - "EventHubs" + "ExpressRoute" ], "severity": "Medium", - "subcategory": "Data Protection", - "text": "Enforce a minimum required version of Transport Layer Security (TLS) for requests ", - "training": "https://learn.microsoft.com/learn/modules/secure-aad-users-with-mfa/" + "subcategory": "Hybrid", + "text": "When low latency is required, or throughput from on-premises to Azure must be greater than 10 Gbps, enable FastPath to bypass the ExpressRoute gateway from the data path.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "Performance" }, { - "category": "Security", - "checklist": "Azure Event Hub Review", - "description": "When you create an Event Hubs namespace, a policy rule named RootManageSharedAccessKey is automatically created for the namespace. This policy has manage permissions for the entire namespace. It’s recommended that you treat this rule like an administrative root account and don’t use it in your application. Using AAD as an authentication provider with RBAC is recommended. ", - "guid": "13b0f566-4b1e-4944-a459-837ee79d6c6d", - "link": "https://learn.microsoft.com/azure/event-hubs/authorize-access-shared-access-signature#shared-access-authorization-policies", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "graph": "resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant", + "guid": "4d873974-8b66-42d6-b15f-512a65498f6d", + "id": "D04.09", + "link": "https://learn.microsoft.com/azure/vpn-gateway/create-zone-redundant-vnet-gateway", "services": [ - "EventHubs", - "RBAC", - "Entra", - "AzurePolicy", - "TrafficManager" + "VPN" ], "severity": "Medium", - "subcategory": "Identity and Access Management", - "text": "Avoid using root account when it is not necessary", - "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-identities-governance/" + "subcategory": "Hybrid", + "text": "Use VPN gateways to connect branches or remote locations to Azure. For higher resilience, deploy zone-redundant gateways (where available).", + "training": "https://learn.microsoft.com/training/modules/intro-to-azure-vpn-gateway/", + "waf": "Reliability" }, { - "category": "Security", - "checklist": "Azure Event Hub Review", - "description": "Managed identities for Azure resources can authorize access to Event Hubs resources using Azure AD credentials from applications running in Azure Virtual Machines (VMs), Function apps, Virtual Machine Scale Sets, and other services. By using managed identities for Azure resources together with Azure AD authentication, you can avoid storing credentials with your applications that run in the cloud. ", - "guid": "3a365a5c-7acb-4e48-abd5-4cd79f2e8776", - "link": "https://learn.microsoft.com/azure/event-hubs/authenticate-managed-identity?tabs=latest", + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "718cb437-b060-2589-8856-2e93a5c6633b", + "id": "D04.10", + "link": "https://learn.microsoft.com/azure/expressroute/expressroute-erdirect-about", "services": [ - "EventHubs", - "AKV", - "Entra", - "VM", - "Storage" + "ExpressRoute", + "Cost" ], - "severity": "Medium", - "subcategory": "Identity and Access Management", - "text": "When possible, your application should be using a managed identity to authenticate to Azure Event Hub. If not, consider having the storage credential (SAS, service principal credential) in Azure Key Vault or an equivalent service", - "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/" + "severity": "High", + "subcategory": "Hybrid", + "text": "If using ExpressRoute Direct, consider using ExpressRoute Local circuits to the local Azure regions to save costs", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "Cost" }, { - "category": "Security", - "checklist": "Azure Event Hub Review", - "description": "When creating permissions, provide fine-grained control over a client's access to Azure Event Hub. Permissions in Azure Event Hub can and should be scoped to the individual resource level e.g. consumer group, event hub entity, event hub namespaces, etc.", - "guid": "8357c559-675c-45ee-a5b8-6ad8844ce3b2", - "link": "https://learn.microsoft.com/azure/event-hubs/authorize-access-azure-active-directory#azure-built-in-roles-for-azure-event-hubs", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "8042d88e-79d1-47b7-9b22-a5a67e7a8ed4", + "id": "D04.11", + "link": "https://learn.microsoft.com/azure/architecture/framework/services/networking/expressroute/reliability", "services": [ - "RBAC", - "EventHubs", - "Entra" + "ExpressRoute" ], - "severity": "High", - "subcategory": "Identity and Access Management", - "text": "Use least privilege data plane RBAC", - "training": "https://learn.microsoft.com/learn/modules/explore-basic-services-identity-types/" + "severity": "Medium", + "subcategory": "Hybrid", + "text": "When traffic isolation or dedicated bandwidth is required, such as for separating production and nonproduction environments, use different ExpressRoute circuits. It will help you ensure isolated routing domains and alleviate noisy-neighbor risks.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "Security" }, { - "category": "Security", - "checklist": "Azure Event Hub Review", - "description": "Azure Event Hub resource logs include operational logs, virtual network and Kafka logs. Runtime audit logs capture aggregated diagnostic information for all data plane access operations (such as send or receive events) in Event Hubs.", - "guid": "b38b875b-a1cf-4104-a900-3a4d3ce474db", - "link": "https://learn.microsoft.com/azure/event-hubs/monitor-event-hubs-reference", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "b30e38c3-f298-412b-8363-cefe179b599d", + "id": "D04.12", + "link": "https://learn.microsoft.com/azure/expressroute/expressroute-monitoring-metrics-alerts", "services": [ - "VNet", - "Monitor", - "EventHubs" + "ExpressRoute", + "Monitor" ], "severity": "Medium", - "subcategory": "Monitoring", - "text": "Enable logging for security investigation. Use Azure Monitor to captured metrics and logs such as resource logs, runtime audit logs and Kafka logs", - "training": "https://learn.microsoft.com/learn/paths/manage-identity-and-access/" + "subcategory": "Hybrid", + "text": "Monitor ExpressRoute availability and utilization using built-in Express Route Insights.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "Operations" }, { - "category": "Security", - "checklist": "Azure Event Hub Review", - "description": "Azure Event Hub by default has a public IP address and is Internet-reachable. Private endpoints allow traffic between your virtual network and Azure Event Hub traverses over the Microsoft backbone network. In addition to that, you should disable public endpoints if those are not used. ", - "guid": "5abca2a4-eda1-4dae-8cc9-5d48c6b791dc", - "link": "https://learn.microsoft.com/azure/event-hubs/private-link-service", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "5bf68dc9-325e-4873-bf88-f8214ef2e5d2", + "id": "D04.13", + "link": "https://learn.microsoft.com/azure/expressroute/how-to-configure-connection-monitor", "services": [ - "VNet", - "PrivateLink", - "EventHubs" + "ACR", + "Monitor", + "NetworkWatcher" ], "severity": "Medium", - "subcategory": "Networking", - "text": "Consider using private endpoints to access Azure Event Hub and disable public network access when applicable.", - "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/" + "subcategory": "Hybrid", + "text": "Use Connection Monitor for connectivity monitoring across the network, especially between on-premises and Azure.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "Operations" }, { - "category": "Security", - "checklist": "Azure Event Hub Review", - "description": "With IP firewall, you can restrict public endpoint further to only a set of IPv4 addresses or IPv4 address ranges in CIDR (Classless Inter-Domain Routing) notation. ", - "guid": "a0e6c465-89e5-458b-a37d-3974d1112dbd", - "link": "https://learn.microsoft.com/azure/event-hubs/event-hubs-ip-filtering", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "e0d5973c-d4cd-421b-8881-37f5e6c4cfd3", + "id": "D04.14", + "link": "https://learn.microsoft.com/azure/expressroute/designing-for-disaster-recovery-with-expressroute-privatepeering#challenges-of-using-multiple-expressroute-circuits", "services": [ - "EventHubs" + "ExpressRoute" ], "severity": "Medium", - "subcategory": "Networking", - "text": "Consider only allowing access to Azure Event Hub namespace from specific IP addresses or ranges", - "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/" + "subcategory": "Hybrid", + "text": "Use ExpressRoute circuits from different peering locations for redundancy.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "Reliability" }, { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "Disable image export to prevent data exfiltration. Note that this will prevent image import of images into another ACR instance.", - "guid": "ab91932c-9fc9-4d1b-a880-37f5e6bfcb9e", - "id": "A01.01", - "link": "https://learn.microsoft.com/azure/container-registry/data-loss-prevention", + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "graph": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation))", + "guid": "72105cc8-aaea-4ee1-8c7a-ad25977afcaf", + "id": "D04.16", + "link": "https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings#gwsub", "services": [ - "ACR" + "VNet", + "Storage" ], "severity": "High", - "subcategory": "Data Protection", - "text": "Disable Azure Container Registry image export", - "waf": "Security" + "subcategory": "Hybrid", + "text": "If you are using a route table in the GatewaySubnet, make sure that gateway routes are propagated.", + "waf": "Reliability" }, { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "Enable audit compliance visibility by enabling Azure Policy for Azure Container Registry", - "guid": "d503547c-d447-4e82-9128-a7100f1cac6d", - "id": "A01.02", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-azure-policy", + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "d581a947-69a2-4783-942e-9df3664324c8", + "id": "D04.17", + "link": "https://learn.microsoft.com/azure/expressroute/designing-for-high-availability-with-expressroute#active-active-connections", "services": [ - "ACR", - "AzurePolicy" + "ExpressRoute", + "ACR" ], "severity": "High", - "subcategory": "Data Protection", - "text": "Enable Azure Policies for Azure Container Registry", - "waf": "Security" + "subcategory": "Hybrid", + "text": "If using ExpressRoute, your on-premises routing should be dynamic: in the event of a connection failure it should converge to the remaining connection of the circuit. Load should be shared across both connections ideally as active/active, although active/passive is supported too.", + "waf": "Reliability" }, { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "The Azure Key Vault (AKV) is used to store a signing key that can be utilized by?notation?with the notation AKV plugin (azure-kv) to sign and verify container images and other artifacts. The Azure Container Registry (ACR) allows you to attach these signatures using the?az?or?oras?CLI commands.", - "guid": "d345293c-7639-4637-a551-c5c04e401955", - "id": "A01.03", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-tutorial-sign-build-push", + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "558fd772-49b8-4211-82df-27ee412e7f98", + "id": "D05.01", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing", "services": [ "ACR", - "AKV" + "VNet" ], "severity": "High", - "subcategory": "Data Protection", - "text": "Sign and Verify containers with notation (Notary v2)", + "subcategory": "IP plan", + "text": "Ensure no overlapping IP address spaces across Azure regions and on-premises locations are used", + "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "Azure Container Registry automatically encrypts images and other artifacts that you store. By default, Azure automatically encrypts the registry content at rest by using service-managed keys. By using a customer-managed key, you can supplement default encryption with an additional encryption layer.", - "guid": "0bd05dc2-efd5-4d76-8d41-d2500cc47b49", - "id": "A01.04", - "link": "https://learn.microsoft.com/azure/container-registry/tutorial-customer-managed-keys", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "graph": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\\\.|172\\\\.(1[6-9]|2[0-9]|3[01])\\\\.|192\\\\.168\\\\.)') | project id, compliant, cidr", + "guid": "3f630472-2dd6-49c5-a5c2-622f54b69bad", + "id": "D05.02", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing", "services": [ - "ACR", - "AKV" + "VNet" ], - "severity": "Medium", - "subcategory": "Data Protection", - "text": "Encrypt registry with a customer managed key", + "severity": "Low", + "subcategory": "IP plan", + "text": "Use IP addresses from the address allocation ranges for private internets (RFC 1918).", + "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "Use managed identities to secure ACRPull/Push RBAC access from client applications", - "guid": "8f42d78e-79dc-47b3-9bd2-a1a27e7a8e90", - "id": "A02.01", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "graph": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant", + "guid": "33aad5e8-c68e-41d7-9667-313b4f5664b5", + "id": "D05.03", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing", "services": [ - "ACR", - "RBAC", - "Entra" + "VNet" ], "severity": "High", - "subcategory": "Identity and Access Control", - "text": "Use Managed Identities to connect instead of Service Principals", - "waf": "Security" + "subcategory": "IP plan", + "text": "Ensure that IP address space isn't wasted, don't create unnecessarily large virtual networks (for example /16) ", + "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", + "waf": "Performance" }, { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "The local Administrator account is disabled by default and should not be enabled. Use either Token or RBAC-based access methods instead", - "guid": "be0e38ce-e297-411b-b363-caaab79b198d", - "id": "A02.02", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "f348ef25-4c27-4d42-b8bb-ac7571559ab9", + "id": "D05.04", + "link": "https://learn.microsoft.com/azure/site-recovery/concepts-on-premises-to-azure-networking#retain-ip-addresses", "services": [ - "ACR", - "RBAC", - "Entra" + "VNet" ], "severity": "High", - "subcategory": "Identity and Access Control", - "text": "Disable local authentication for management plane access", - "waf": "Security" + "subcategory": "IP plan", + "text": "Avoid using overlapping IP address ranges for production and DR sites.", + "training": "https://learn.microsoft.com/learn/paths/az-104-manage-virtual-networks/", + "waf": "Reliability" }, { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "Disable Administrator account and assign RBAC roles to principals for ACR Pull/Push operations", - "guid": "387e5ced-126c-4d13-8af5-b20c6998a646", - "id": "A02.03", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-roles?tabs=azure-cli", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "153e8908-ae28-4c84-a33b-6b7808b9fe5c", + "id": "D05.05", + "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-name-resolution-for-vms-and-role-instances", "services": [ - "ACR", - "RBAC", - "Entra" + "VNet", + "DNS" ], - "severity": "High", - "subcategory": "Identity and Access Control", - "text": "Assign AcrPull & AcrPush RBAC roles rather than granting Administrative access to identity principals", - "waf": "Security" + "severity": "Medium", + "subcategory": "IP plan", + "text": "For environments where name resolution in Azure is all that's required, use Azure Private DNS for resolution with a delegated zone for name resolution (such as 'azure.contoso.com').", + "training": "https://learn.microsoft.com/learn/paths/az-104-manage-virtual-networks/", + "waf": "Operations" }, { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "Disable anonymous pull/push access", - "guid": "e338997e-41c7-47d7-acf6-a62a1194956d", - "id": "A02.04", - "link": "https://learn.microsoft.com/azure/container-registry/anonymous-pull-access#configure-anonymous-pull-access", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "41049d40-3a92-43c3-974d-00018ac6a9e0", + "id": "D05.06", + "link": "https://learn.microsoft.com/azure/dns/dns-private-resolver-overview", "services": [ "ACR", - "Entra" + "VNet", + "DNS" ], "severity": "Medium", - "subcategory": "Identity and Access Control", - "text": "Disable Anonymous pull access", + "subcategory": "IP plan", + "text": "For environments where name resolution across Azure and on-premises is required, consider using Azure DNS Private Resolver.", + "training": "https://learn.microsoft.com/training/modules/intro-to-azure-dns-private-resolver/", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "Token authentication doesn't support assignment to an AAD principal. Any tokens provided are able to be used by anyone who can access the token", - "guid": "698dc3a2-fd27-4b2e-8870-1a1252beedf6", - "id": "A02.05", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication?tabs=azure-cli", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "1e6a83de-5de3-42c1-a924-81607d5d1e4e", + "id": "D05.07", + "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-name-resolution-for-vms-and-role-instances", "services": [ - "ACR", - "Entra" + "VNet", + "DNS" ], - "severity": "High", - "subcategory": "Identity and Access Control", - "text": "Disable repository-scoped access tokens", - "waf": "Security" + "severity": "Low", + "subcategory": "IP plan", + "text": "Special workloads that require and deploy their own DNS (such as Red Hat OpenShift) should use their preferred DNS solution.", + "waf": "Operations" }, { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "Deploy container images to an ACR behind a Private endpoint within a trusted network", - "guid": "b3bec3d4-f343-47c1-936d-b55f27a71eee", - "id": "A02.06", + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "614658d3-558f-4d77-849b-821112df27ee", + "id": "D05.08", + "link": "https://learn.microsoft.com/azure/dns/private-dns-autoregistration", "services": [ - "ACR", - "PrivateLink", - "EventHubs", - "Entra" + "VM", + "VNet", + "DNS" ], "severity": "High", - "subcategory": "Identity and Access Control", - "text": "Deploy images from a trusted environment", - "waf": "Security" + "subcategory": "IP plan", + "text": "Enable auto-registration for Azure DNS to automatically manage the lifecycle of the DNS records for the virtual machines deployed within a virtual network.", + "training": "https://learn.microsoft.com/learn/paths/az-104-manage-virtual-networks/", + "waf": "Operations" }, { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "Only tokens with an ACR audience can be used for authentication. Used when enabling Conditional access policies for ACR", - "guid": "3a041fd3-2947-498b-8288-b3c6a56ceb54", - "id": "A02.07", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-enable-conditional-access-policy", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "ee1ac551-c4d5-46cf-b035-d0a3c50d87ad", + "id": "D06.01", + "link": "https://learn.microsoft.com/azure/bastion/bastion-overview", "services": [ - "ACR", - "AzurePolicy", - "Entra" + "Bastion" ], "severity": "Medium", - "subcategory": "Identity and Access Control", - "text": "Disable Azure ARM audience tokens for authentication", + "subcategory": "Internet", + "text": "Consider using Azure Bastion to securely connect to your network.", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "Set up a diagnostic setting to send 'repositoryEvents' & 'LoginEvents' to Log Analytics as the central destination for logging and monitoring. This allows you to monitor control plane activity on the ACR resource itself.", - "guid": "8a488cde-c486-42bc-9bd2-1be77f26e5e6", - "id": "A03.01", - "link": "https://learn.microsoft.com/azure/container-registry/monitor-service", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "graph": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant", + "guid": "6eab9eb6-762b-485e-8ea8-15aa5dba0bd0", + "id": "D06.02", + "link": "https://learn.microsoft.com/azure/bastion/bastion-faq#subnet", "services": [ - "ACR", - "Monitor", - "Entra" + "Bastion", + "VNet" ], "severity": "Medium", - "subcategory": "Logging and Monitoring", - "text": "Enable diagnostics logging", + "subcategory": "Internet", + "text": "Use Azure Bastion in a subnet /26 or larger.", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "Service supports disabling public network access either through using service-level IP ACL filtering rule (not NSG or Azure Firewall) or using a 'Disable Public Network Access' toggle switch", - "guid": "21d41d25-00b7-407a-b9ea-b40fd3290798", - "id": "A04.01", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-private-link", + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "e6c4cfd3-e504-4547-a244-7ec66138a720", + "id": "D06.03", + "link": "https://learn.microsoft.com/azure/app-service/networking-features", + "services": [ + "Firewall" + ], + "severity": "High", + "subcategory": "Internet", + "text": "Use Azure Firewall to govern Azure outbound traffic to the internet, non-HTTP/S inbound connections, and East/West traffic filtering (if the organization requires it)", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "Security" + }, + { + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "5a4b1511-e43a-458a-ac22-99c4d7b57d0c", + "id": "D06.04", + "link": "https://learn.microsoft.com/azure/firewall/", "services": [ "ACR", + "RBAC", "Firewall", - "VNet", - "PrivateLink" + "AzurePolicy" ], "severity": "Medium", - "subcategory": "Network Security", - "text": "Control inbound network access with Private Link", + "subcategory": "Internet", + "text": "Create a global Azure Firewall policy to govern security posture across the global network environment and assign it to all Azure Firewall instances. Allow for granular policies to meet requirements of specific regions by delegating incremental firewall policies to local security teams via Azure role-based access control.", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "Disable public network access if inbound network access is secured using Private Link", - "guid": "cd289ced-6b17-4db8-8554-62f2aee4553a", - "id": "A04.02", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-access-selected-networks#disable-public-network-access", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "655562f2-b3e4-4563-a4d8-739748b662d6", + "id": "D06.05", + "link": "https://learn.microsoft.com/azure/firewall/", "services": [ - "ACR", - "PrivateLink" + "Firewall" ], - "severity": "Medium", - "subcategory": "Network Security", - "text": "Disable Public Network access", + "severity": "Low", + "subcategory": "Internet", + "text": "Configure supported partner SaaS security providers within Firewall Manager if the organization wants to use such solutions to help protect outbound connections.", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "Only the ACR Premium SKU supports Private Link access", - "guid": "fc833934-8b26-42d6-ac5f-512925498f6d", - "id": "A04.03", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-skus", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "1d7aa9b6-4704-4489-a804-2d88e79d17b7", + "id": "D06.06", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/afds-overview", "services": [ "ACR", - "PrivateLink" + "FrontDoor", + "AzurePolicy", + "WAF" ], "severity": "Medium", - "subcategory": "Network Security", - "text": "Use an Azure Container Registry SKU that supports Private Link (Premium SKU)", + "subcategory": "Internet", + "text": "Use Azure Front Door and WAF policies to provide global protection across Azure regions for inbound HTTP/S connections to a landing zone.", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "Azure Defender for containers or equivalent service should be used to scan container images for vulnerabilities", - "guid": "bad37dac-43bc-46ce-8d7a-a9b24604489a", - "id": "A04.04", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-introduction", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "3b22a5a6-7e7a-48ed-9b30-e38c3f29812b", + "id": "D06.07", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", "services": [ - "ACR", - "Defender" + "FrontDoor", + "AzurePolicy", + "WAF", + "AppGW" ], "severity": "Low", - "subcategory": "Network Security", - "text": "Enable Defender for Containers to scan Azure Container Registry for vulnerabilities", + "subcategory": "Internet", + "text": "When using Azure Front Door and Azure Application Gateway to help protect HTTP/S apps, use WAF policies in Azure Front Door. Lock down Azure Application Gateway to receive traffic only from Azure Front Door.", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "Deploy trusted code that was validated and scanned for vulnerabilities according to DevSecOps practices.", - "guid": "4451e1a2-d345-4293-a763-9637a551c5c0", - "id": "A05.01", + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "2363cefe-179b-4599-be0d-5973cd4cd21b", + "id": "D06.08", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", "services": [ - "ACR" + "VNet", + "WAF" ], - "severity": "Medium", - "subcategory": "Vulnerability Management", - "text": "Deploy validated container images", + "severity": "High", + "subcategory": "Internet", + "text": "Deploy WAFs and other reverse proxies are required for inbound HTTP/S connections, deploy them within a landing-zone virtual network and together with the apps that they're protecting and exposing to the internet.", + "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "Use the latest versions of supported platforms, programming languages, protocols, and frameworks.", - "guid": "4e401955-387e-45ce-b126-cd132af5b20c", - "id": "A05.02", + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "088137f5-e6c4-4cfd-9e50-4547c2447ec6", + "id": "D06.09", + "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-reference-architectures", "services": [ - "ACR" + "VNet", + "DDoS" ], "severity": "High", - "subcategory": "Vulnerability Management", - "text": "Use up-to-date platforms, languages, protocols and frameworks", + "subcategory": "Internet", + "text": "Use Azure DDoS Network or IP Protection plans to help protect Public IP Addresses endpoints within the virtual networks.", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", "waf": "Security" }, { - "category": "Foundation", - "checklist": "Azure Arc Review", - "description": "Define a resource group structure for placement of Azure Arc-enabled servers resources", - "guid": "585e1112-9bd7-4ba0-82f7-b94ef6e043d2", + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "graph": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant", + "guid": "14d99880-2f88-47e8-a134-62a7d85c94af", + "id": "D06.10", + "link": "https://learn.microsoft.com/azure/firewall/fqdn-filtering-network-rules", "services": [ - "Arc" + "Firewall", + "DNS" ], "severity": "High", - "subcategory": "Capacity Planning", - "text": "One or more resource groups is required for onboarding servers into Azure", - "waf": "Operations" + "subcategory": "Internet", + "text": "Use FQDN-based network rules and Azure Firewall with DNS proxy to filter egress traffic to the Internet over protocols not supported by application rules.", + "waf": "Security" }, { - "category": "Foundation", - "checklist": "Azure Arc Review", - "guid": "aa359271-8e6e-4205-8725-769e46691e88", - "link": "https://learn.microsoft.com/azure/azure-arc/servers/prerequisites#azure-subscription-and-service-limits", + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "graph": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant", + "guid": "c10d51ef-f999-455d-bba0-5c90ece07447", + "id": "D06.11", + "link": "https://learn.microsoft.com/azure/firewall/premium-features", "services": [ - "Arc", - "Entra" + "Firewall" ], - "severity": "Medium", - "subcategory": "Capacity Planning", - "text": "Take Azure Active Directory object limitations into account", - "waf": "Performance" + "severity": "High", + "subcategory": "Internet", + "text": "Use Azure Firewall Premium for additional security and protection.", + "waf": "Security" }, { - "category": "Foundation", - "checklist": "Azure Arc Review", - "description": "The following resource providers needs to be registered: Microsoft.HybridCompute, Microsoft.GuestConfiguration, Microsoft.HybridConnectivity", - "guid": "deace4bb-1deb-44c6-9fc3-fc14eeaa3692", - "link": "https://learn.microsoft.com/azure/azure-arc/servers/prerequisites#azure-resource-providers", + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "graph": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant", + "guid": "e9c8f584-6d5e-473b-8dc5-acc9fbaab4e3", + "id": "D06.12", + "link": "https://learn.microsoft.com/azure/firewall/premium-features", "services": [ - "Arc", - "Subscriptions" + "Firewall" ], "severity": "High", - "subcategory": "General", - "text": "Has the Resource providers required been registered in all subscriptions", - "waf": "Operations" + "subcategory": "Internet", + "text": "Configure Azure Firewall Threat Intelligence mode to Alert and Deny for additional protection.", + "waf": "Security" }, { - "category": "Foundation", - "checklist": "Azure Arc Review", - "description": "Aligning with an existing or creating an Azure tagging strategy is recommended. Resource tags allow you to quickly locate it, automate operational tasks amd more. ", - "guid": "c6d37331-65c7-4acb-b44b-be609d79f2e8", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/decision-guides/resource-tagging/", + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "graph": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant", + "guid": "b9d0dff5-bdd4-4cd8-88ed-5811610b2b2c", + "id": "D06.13", + "link": "https://learn.microsoft.com/azure/firewall/premium-features#idps", "services": [ - "Arc" + "Firewall" ], - "severity": "Low", - "subcategory": "General", - "text": "Has a tagging strategy for Azure Arc-enabled servers been defined", - "waf": "Cost" + "severity": "High", + "subcategory": "Internet", + "text": "Configure Azure Firewall IDPS mode to Deny for additional protection.", + "waf": "Security" }, { - "category": "Foundation", - "checklist": "Azure Arc Review", - "description": "Installation of the connected machine agent is supported on most newer Windows and Linux operative systems, review the link to se the latest list", - "guid": "7778424c-5167-475c-9fa9-5b96ad88408e", - "link": "https://learn.microsoft.com/azure/azure-arc/servers/prerequisites#supported-operating-systems", + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "graph": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant", + "guid": "a3784907-9836-4271-aafc-93535f8ec08b", + "id": "D06.14", + "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview", "services": [ - "Arc" + "VWAN", + "Firewall", + "Storage", + "NVA", + "VNet" ], "severity": "High", - "subcategory": "General", - "text": "What operating systems need to be Azure Arc-enabled", - "waf": "Operations" + "subcategory": "Internet", + "text": "For subnets in VNets not connected to Virtual WAN, attach a route table so that Internet traffic is redirected to Azure Firewall or a Network Virtual Appliance", + "waf": "Security" }, { - "category": "Foundation", - "checklist": "Azure Arc Review", - "description": "There are software requirements to the agent installation. Some might require a system reboot after installation, review to link", - "guid": "372734b8-76ba-428f-8145-901365d38e53", - "link": "https://learn.microsoft.com/azure/azure-arc/servers/prerequisites#software-requirements", - "services": [ - "Arc" - ], + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "b034c01e-110b-463a-b36e-e3346e57f225", + "id": "D06.15", + "link": "https://learn.microsoft.com/en-us/azure/virtual-network/ip-services/default-outbound-access", + "services": [], "severity": "High", - "subcategory": "General", - "text": "Are required software installed on Windows and Linux servers to support the installation", - "waf": "Operations" + "subcategory": "Internet", + "text": "Assess and review network outbound traffic configuration and strategy before the upcoming breaking change. On September 30, 2025, default outbound access for new deployments will be retired and only explicit access configurations will be allowed", + "waf": "Reliability" }, { - "category": "Foundation", - "checklist": "Azure Arc Review", - "guid": "d44c7c89-19ca-41f6-b521-5ae514ba34d4", - "link": "https://azure.microsoft.com/explore/global-infrastructure/products-by-region/?products=azure-arc®ions=all", + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "d301d6e8-72e5-42e3-911c-c58b5a4b1511", + "id": "D07.01", + "link": "https://learn.microsoft.com/azure/virtual-network/vnet-integration-for-azure-services", "services": [ - "Arc" + "VNet" ], "severity": "High", - "subcategory": "General", - "text": "Make sure to use a supported Azure region", - "waf": "Reliability" + "subcategory": "PaaS", + "text": "Ensure that control-plane communication for Azure PaaS services injected into a virtual network is not broken, for example with a 0.0.0.0/0 route or an NSG rule that blocks control plane traffic.", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "Security" }, { - "category": "Foundation", - "checklist": "Azure Arc Review", - "description": "The scope include organization into management groups, subscriptions, and resource groups.", - "guid": "f9ccbd86-8266-4abc-a264-f9a19bf39d95", - "link": "https://learn.microsoft.com/azure/azure-arc/servers/organize-inventory-servers#organize-resources-with-built-in-azure-hierarchies", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "e43a58a9-c229-49c4-b7b5-7d0c655562f2", + "id": "D07.02", + "link": "https://learn.microsoft.com/azure/app-service/networking-features", "services": [ - "Arc", - "Subscriptions" + "PrivateLink" ], - "severity": "Low", - "subcategory": "Organization", - "text": "Define the structure for Azure management of resources", - "waf": "Performance" + "severity": "Medium", + "subcategory": "PaaS", + "text": "Use Private Link, where available, for shared Azure PaaS services.", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "Security" }, { - "category": "Identity", - "checklist": "Azure Arc Review", - "description": "Define RBAC rules to the servers / resource groups as required for servers management, the 'Azure Connected Machine Resource Administrator' or 'Hybrid Server Resource Administrator' role would be sufficient for management of the Azure Arc-enabled servers resources in Azure", - "guid": "9bf39d95-d44c-47c8-a19c-a1f6d5215ae5", - "link": "https://learn.microsoft.com/azure/azure-arc/servers/security-overview#identity-and-access-control", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "b3e4563a-4d87-4397-98b6-62d6d15f512a", + "id": "D07.03", + "link": "https://learn.microsoft.com/azure/app-service/networking-features", "services": [ - "Arc", - "RBAC", - "Entra" + "ExpressRoute", + "PrivateLink" ], "severity": "Medium", - "subcategory": "Access", - "text": "Assign RBAC rights to Azure AD user/group access for managing Azure Arc-enabled servers", + "subcategory": "PaaS", + "text": "Access Azure PaaS services from on-premises via private endpoints and ExpressRoute private peering. This method avoids transiting over the public internet.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", "waf": "Security" }, { - "category": "Identity", - "checklist": "Azure Arc Review", - "guid": "14ba34d4-585e-4111-89bd-7ba012f7b94e", - "link": "https://learn.microsoft.com/azure/active-directory/managed-identities-azure-resources/tutorial-windows-vm-access-nonaad", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "graph": "resources | where type =~ 'microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets = properties.subnets | mv-expand subnets | project id = subnets.id, resourceGroup, VNet = name, serviceEndpoints = subnets.properties.serviceEndpoints, compliant = (isnull(subnets.properties.serviceEndpoints) or array_length(subnets.properties.serviceEndpoints) == 0) | order by compliant asc", + "guid": "4704489a-8042-4d88-b79d-17b73b22a5a6", + "id": "D07.04", + "link": "https://learn.microsoft.com/azure/app-service/networking-features", "services": [ - "Arc", - "AKV", - "Entra" + "VNet" ], - "severity": "Low", - "subcategory": "Access", - "text": "Consider using managed identities for applications to access Azure resources like Key Vault example in link", + "severity": "Medium", + "subcategory": "PaaS", + "text": "Don't enable virtual network service endpoints by default on all subnets.", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", "waf": "Security" }, { - "category": "Identity", - "checklist": "Azure Arc Review", - "description": "An Azure subscription must be parented to the same Azure AD tenant", - "guid": "35ac9322-23e1-4380-8523-081a94174158", - "link": "https://learn.microsoft.com/azure/azure-arc/servers/prerequisites#azure-subscription-and-service-limits", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "7e7a8ed4-b30e-438c-9f29-812b2363cefe", + "id": "D07.05", + "link": "https://learn.microsoft.com/azure/app-service/networking-features", "services": [ - "Entra", - "Arc", - "Subscriptions" + "NVA", + "PrivateLink", + "Firewall", + "DNS" ], - "severity": "High", - "subcategory": "Requirements", - "text": "An Azure Active Directory tenant must be available with at least one subscription", - "waf": "Operations" + "severity": "Medium", + "subcategory": "PaaS", + "text": "Filter egress traffic to Azure PaaS services using FQDNs instead of IP addresses in Azure Firewall or an NVA to prevent data exfiltration. If using Private Link you can block all FQDNs, otherwise allow only the required PaaS services.", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "Security" }, { - "category": "Identity", - "checklist": "Azure Arc Review", - "description": "Users (or SPs) need the 'Azure Connected Machine Onboarding' or 'Contributor' role to onboarding of servers", - "guid": "33ee7ad6-c6d3-4733-865c-7acbe44bbe60", - "link": "https://learn.microsoft.com/azure/azure-arc/servers/prerequisites#required-permissions", + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "graph": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant", + "guid": "22d6419e-b627-4d95-9e7d-019fa759387f", + "id": "D08.01", + "link": "https://learn.microsoft.com/azure/firewall/firewall-faq#why-does-azure-firewall-need-a--26-subnet-size", "services": [ - "Arc", - "RBAC", - "Entra" + "VNet", + "Firewall" ], - "severity": "Medium", - "subcategory": "Requirements", - "text": "Define which users (AAD user/groups) has access to onboard Azure Arc-enabled servers", + "severity": "High", + "subcategory": "Segmentation", + "text": "Use a /26 prefix for your Azure Firewall subnets.", "waf": "Security" }, { - "category": "Identity", - "checklist": "Azure Arc Review", - "description": "Ensure to only add the rights to users or groups that is required to perform their role", - "guid": "9d79f2e8-7778-4424-a516-775c6fa95b96", - "link": "https://learn.microsoft.com/azure/azure-arc/servers/onboard-service-principal#create-a-service-principal-for-onboarding-at-scale", + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "graph": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant", + "guid": "f2aad7e3-bb03-4adc-8606-4123d342a917", + "id": "D08.02", + "link": "https://learn.microsoft.com/azure/expressroute/expressroute-howto-add-gateway-resource-manager#add-a-gateway", "services": [ - "Arc", - "RBAC", - "Entra" + "ExpressRoute", + "VNet", + "VPN" ], - "severity": "Medium", - "subcategory": "Security", - "text": "Use the principle of least privileged", + "severity": "High", + "subcategory": "Segmentation", + "text": "Use at least a /27 prefix for your Gateway subnets", "waf": "Security" }, { - "category": "Identity", - "checklist": "Azure Arc Review", - "description": "A service principle with the 'Azure Connected Machine Onboarding' role is required for at-scale onboarding of servers, consider more SP's if onboarding is done by different teams/decentralized management", - "guid": "ad88408e-3727-434b-a76b-a28f21459013", - "link": "https://learn.microsoft.com/azure/azure-arc/servers/onboard-service-principal#create-a-service-principal-for-onboarding-at-scale", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "graph": "resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant)", + "guid": "11deb39d-8299-4e47-bbe0-0fb5a36318a8", + "id": "D08.03", + "link": "https://learn.microsoft.com/azure/virtual-network/service-tags-overview#available-service-tags", "services": [ - "Arc", - "RBAC", - "Entra" + "VNet" ], "severity": "Medium", - "subcategory": "Security", - "text": "How many Service Principals are needed for onboarding Arc-enabled servers into Azure", + "subcategory": "Segmentation", + "text": "Don't rely on the NSG inbound default rules using the VirtualNetwork service tag to limit connectivity.", "waf": "Security" }, { - "category": "Identity", - "checklist": "Azure Arc Review", - "description": "Consider assigning the rights for the 'Azure Connected Machine Onboarding' role at the resource group level, to control the resource creation", - "guid": "65d38e53-f9cc-4bd8-9826-6abca264f9a1", - "link": "https://learn.microsoft.com/azure/azure-arc/servers/prerequisites#required-permissions", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "c2447ec6-6138-4a72-80f1-ce16ed301d6e", + "id": "D08.04", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-landing-zone-network-segmentation", "services": [ - "Arc", - "RBAC", - "Entra" + "VNet" ], "severity": "Medium", - "subcategory": "Security", - "text": "Limit the rights to onboard Azure Arc-enabled servers to the desired resource groups", + "subcategory": "Segmentation", + "text": "Delegate subnet creation to the landing zone owner. ", + "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", "waf": "Security" }, { - "category": "Management and Monitoring", - "checklist": "Azure Arc Review", - "description": "Plan for agent deployments at scale", - "guid": "6ee79d6b-5c2a-4364-a4b6-9bad38aad53c", - "link": "https://learn.microsoft.com/azure/azure-arc/servers/plan-at-scale-deployment", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "872e52e3-611c-4c58-a5a4-b1511e43a58a", + "id": "D08.05", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", "services": [ - "Arc", - "Monitor" + "ACR", + "VNet" ], "severity": "Medium", - "subcategory": "Management", - "text": "Define a strategy for agent provisioning", - "waf": "Operations" + "subcategory": "Segmentation", + "text": "Use NSGs to help protect traffic across subnets, as well as east/west traffic across the platform (traffic between landing zones).", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "Security" }, { - "category": "Management and Monitoring", - "checklist": "Azure Arc Review", - "description": "Use Microsoft Update to ensure that the connected machine agent is always up-to-date", - "guid": "c78e1d76-6673-457c-9496-74c5ed85b859", - "link": "https://learn.microsoft.com/azure/azure-arc/servers/manage-agent#upgrade-the-agent", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "graph": "Resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetName=subnets.name,subnetNsg=subnets.properties.networkSecurityGroup | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend compliant = isnotnull(subnetNsg)", + "guid": "9c2299c4-d7b5-47d0-a655-562f2b3e4563", + "id": "D08.06", "services": [ - "Arc", - "Monitor" + "VM", + "VNet" ], - "severity": "High", - "subcategory": "Management", - "text": "Define a strategy for agent updates", - "waf": "Operations" + "severity": "Medium", + "subcategory": "Segmentation", + "text": "The application team should use application security groups at the subnet-level NSGs to help protect multi-tier VMs within the landing zone.", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "Security" }, { - "category": "Management and Monitoring", - "checklist": "Azure Arc Review", - "description": "Recommendation is to use Azure Policy, or another automation tool like Azure DevOps - important is to avoid configuration drift.", - "guid": "c7733be2-a1a2-47b7-95a9-1be1f388ff39", - "link": "https://learn.microsoft.com/azure/azure-arc/servers/manage-vm-extensions", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "a4d87397-48b6-462d-9d15-f512a65498f6", + "id": "D08.07", + "link": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", "services": [ - "Arc", - "Monitor", - "AzurePolicy" + "NVA", + "VNet", + "Entra" ], "severity": "Medium", - "subcategory": "Management", - "text": "Define a strategy for extension installation", - "waf": "Operations" + "subcategory": "Segmentation", + "text": "Use NSGs and application security groups to micro-segment traffic within the landing zone and avoid using a central NVA to filter traffic flows.", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "Security" }, { - "category": "Management and Monitoring", - "checklist": "Azure Arc Review", - "description": "Use automatic upgrades where available and define an update strategy for all extensions not supporting automatic upgrades.", - "guid": "4c2bd463-cbbb-4c86-a195-abb91a4ed90d", - "link": "https://learn.microsoft.com/azure/azure-arc/servers/manage-automatic-vm-extension-upgrade?tabs=azure-portal", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "dfe237de-143b-416c-91d7-aa9b64704489", + "id": "D08.08", + "link": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", "services": [ - "Arc", - "Monitor" + "VNet", + "NetworkWatcher" ], - "severity": "High", - "subcategory": "Management", - "text": "Define a strategy for extension updates", - "waf": "Operations" + "severity": "Medium", + "subcategory": "Segmentation", + "text": "Enable NSG flow logs and feed them into Traffic Analytics to gain insights into internal and external traffic flows.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/", + "waf": "Security" }, { - "category": "Management and Monitoring", - "checklist": "Azure Arc Review", - "description": "Azure Automanage help implement Microsoft best-practices for servers management in Azure", - "guid": "7a927c39-74d1-4102-aac6-aae01e6a84de", - "link": "https://learn.microsoft.com/azure/automanage/automanage-arc", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "412e7f98-3f63-4047-82dd-69c5b5c2622f", + "id": "D09.01", + "link": "https://learn.microsoft.com/azure/virtual-wan/scenario-any-to-any", "services": [ - "Arc", - "Monitor" + "VWAN" ], "severity": "Medium", - "subcategory": "Management", - "text": "Consider using Azure Automanage to control settings and avoid configuration drift on servers", + "subcategory": "Virtual WAN", + "text": "Consider Virtual WAN for simplified Azure networking management, and make sure your scenario is explicitly described in the list of Virtual WAN routing designs", + "training": "https://learn.microsoft.com/learn/modules/introduction-azure-virtual-wan/", "waf": "Operations" }, { - "category": "Management and Monitoring", - "checklist": "Azure Arc Review", - "guid": "37b6b780-cbaf-4e6c-9658-9d457a927c39", - "link": "https://learn.microsoft.com/azure/azure-arc/servers/plan-at-scale-deployment#phase-3-manage-and-operate", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "54b69bad-33aa-4d5e-ac68-e1d76667313b", + "id": "D09.02", + "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-about", "services": [ - "Arc", - "Monitor" + "ACR", + "VWAN" ], - "severity": "High", - "subcategory": "Monitoring", - "text": "Monitor for unresponsive agents", - "waf": "Operations" + "severity": "Medium", + "subcategory": "Virtual WAN", + "text": "Use a Virtual WAN hub per Azure region to connect multiple landing zones together across Azure regions via a common global Azure Virtual WAN.", + "waf": "Performance" }, { - "category": "Management and Monitoring", - "checklist": "Azure Arc Review", - "guid": "74d1102c-ac6a-4ae0-8e6a-84de5df47d2d", - "link": "https://learn.microsoft.com/azure/azure-monitor/agents/log-analytics-agent#data-collected", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "8ac6a9e0-1e6a-483d-b5de-32c199248160", + "id": "D09.03", + "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-about", "services": [ - "Arc", - "Monitor" + "ACR", + "VWAN" ], - "severity": "Medium", - "subcategory": "Monitoring", - "text": "Design a monitoring strategy to send metrics and logs to an Log Analytics workspace", - "waf": "Operations" + "severity": "Low", + "subcategory": "Virtual WAN", + "text": "Follow the principle 'traffic in Azure stays in Azure' so that communication across resources in Azure occurs via the Microsoft backbone network", + "waf": "Performance" }, { - "category": "Management and Monitoring", - "checklist": "Azure Arc Review", - "guid": "92881b1c-d5d1-4e54-a296-59e3958fd782", - "link": "https://learn.microsoft.com/azure/service-health/resource-health-alert-monitor-guide", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "graph": "resources | where type=='microsoft.network/virtualhubs' | extend compliant = isnotnull(properties.azureFirewall.id) | project id, compliant", + "guid": "7d5d1e4e-6146-458d-9558-fd77249b8211", + "id": "D09.04", + "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-about", "services": [ - "Arc", - "Monitor" + "VWAN", + "Firewall" ], "severity": "Medium", - "subcategory": "Monitoring", - "text": "Use notification in Activity logs to receive notification on unexpected changes to the resources", - "waf": "Operations" + "subcategory": "Virtual WAN", + "text": "For outbound Internet traffic protection and filtering, deploy Azure Firewall in secured hubs", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "Security" }, { - "category": "Management and Monitoring", - "checklist": "Azure Arc Review", - "guid": "89c93555-6d02-4bfe-9564-b0d834a34872", - "link": "https://learn.microsoft.com/azure/azure-arc/servers/learn/tutorial-enable-vm-insights", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "6667313b-4f56-464b-9e98-4a859c773e7d", + "id": "D09.05", + "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits", "services": [ - "Arc", - "Monitor" + "VWAN" ], "severity": "Medium", - "subcategory": "Monitoring", - "text": "Use Azure Monitor for compliance and operational monitoring", - "waf": "Operations" + "subcategory": "Virtual WAN", + "text": "Ensure that the network architecture is within the Azure Virtual WAN limits.", + "waf": "Reliability" }, { - "category": "Management and Monitoring", - "checklist": "Azure Arc Review", - "guid": "5df47d2d-9288-41b1-ad5d-1e54a29659e3", - "link": "https://learn.microsoft.com/azure/azure-arc/servers/plan-at-scale-deployment#phase-3-manage-and-operate", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "261623a7-65a9-417e-8f34-8ef254c27d42", + "id": "D09.06", + "link": "https://learn.microsoft.com/azure/virtual-wan/azure-monitor-insights", "services": [ - "Arc", + "VWAN", "Monitor" ], "severity": "Medium", - "subcategory": "Monitoring", - "text": "Create an alert to identify Azure Arc-enabled servers that aren't using the latest version of the Azure connected machine agent", + "subcategory": "Virtual WAN", + "text": "Use Azure Monitor Insights for Virtual WAN to monitor the end-to-end topology of the Virtual WAN, status, and key metrics.", "waf": "Operations" }, { - "category": "Management and Monitoring", - "checklist": "Azure Arc Review", - "description": "Use Update Management in Azure Automation or the new Update Management Center (preview) functionality to ensure update management of servers", - "guid": "ae2cc84c-37b6-4b78-8cba-fe6c46589d45", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/manage/hybrid/server/best-practices/arc-update-management", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "727c77e1-b9aa-4a37-a024-129d042422c1", + "id": "D09.07", + "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-faq#is-branch-to-branch-connectivity-allowed-in-virtual-wan", "services": [ - "Arc", - "Monitor" + "VWAN" ], - "severity": "Low", - "subcategory": "Security", - "text": "Use Azure Arc-enabled servers to control software updates deployments to servers", - "waf": "Operations" + "severity": "Medium", + "subcategory": "Virtual WAN", + "text": "Make sure that your IaC deployments does not disable branch-to-branch traffic in Virtual WAN, unless these flows should be explicitly blocked.", + "waf": "Reliability" }, { - "category": "Networking", - "checklist": "Azure Arc Review", - "description": "The Connected Machine Agent will by default communicate with Azure services over public Internet connectivity using HTTPS (TCP port 443)", - "guid": "f6e043d2-aa35-4927-88e6-e2050725769e", - "link": "https://learn.microsoft.com/azure/azure-arc/servers/network-requirements?tabs=azure-cloud#details", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "d49ac006-6670-4bc9-9948-d3e0a3a94f4d", + "id": "D09.08", + "link": "https://learn.microsoft.com/azure/virtual-wan/about-virtual-hub-routing-preference", "services": [ - "Arc" + "ExpressRoute", + "VWAN", + "VPN" ], - "severity": "High", - "subcategory": "Networking", - "text": "Define a connectivity method from the server to Azure", - "waf": "Operations" + "severity": "Medium", + "subcategory": "Virtual WAN", + "text": "Use AS-Path as hub routing preference, since it is more flexible than ExpressRoute or VPN.", + "waf": "Reliability" }, { - "category": "Networking", - "checklist": "Azure Arc Review", - "description": "The Connected Machine Agent can be configured to use a proxy server, it is recommended to define the proxy server address using 'azcmagent config set proxy.url' command on the local system.", - "guid": "46691e88-35ac-4932-823e-13800523081a", - "link": "https://learn.microsoft.com/azure/azure-arc/servers/manage-agent#update-or-remove-proxy-settings", + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "2586b854-237e-47f1-84a1-d45d4cd2310d", + "id": "D09.09", + "link": "https://learn.microsoft.com/azure/virtual-wan/about-virtual-hub-routing#labels", "services": [ - "Arc" + "VWAN" ], "severity": "Medium", - "subcategory": "Networking", - "text": "Is a proxy server a required for communication over the Public Internet", - "waf": "Operations" + "subcategory": "Virtual WAN", + "text": "Make sure that your IaC deployments are configuring label-based propagation in Virtual WAN, otherwise connectivity between virtual hubs will be impaired.", + "waf": "Reliability" }, { - "category": "Networking", - "checklist": "Azure Arc Review", - "description": "The Connected Machine Agent can use a Private Link for communication with Azure Services over an existing ExpressRoute or VPN connection", - "guid": "94174158-33ee-47ad-9c6d-3733165c7acb", - "link": "https://learn.microsoft.com/azure/azure-arc/servers/private-link-security", + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "9c75dfef-573c-461c-a698-68598595581a", + "id": "D09.10", + "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-faq#what-is-the-recommended-hub-address-space-during-hub-creation", "services": [ - "Arc", - "ExpressRoute", - "PrivateLink", - "VPN" + "VWAN" ], - "severity": "Medium", - "subcategory": "Networking", - "text": "Is a private (not public Internet) connection required?", - "waf": "Operations" + "severity": "High", + "subcategory": "Virtual WAN", + "text": "Assign enough IP space to virtual hubs, ideally a /23 prefix.", + "waf": "Reliability" }, { - "category": "Networking", - "checklist": "Azure Arc Review", - "description": "Firewall configuration might be required for the agent to communicate with Azure, use the link to see ServiceTags and/or URL's required", - "guid": "e44bbe60-9d79-4f2e-a777-8424c516775c", - "link": "https://learn.microsoft.com/azure/azure-arc/servers/network-requirements?tabs=azure-cloud#service-tags", + "ammp": true, + "category": "Governance", + "checklist": "Azure Landing Zone Review", + "guid": "5c986cb2-9131-456a-8247-6e49f541acdc", + "id": "E01.01", + "link": "https://learn.microsoft.com/azure/governance/policy/overview", "services": [ - "Arc" + "AzurePolicy" ], "severity": "High", - "subcategory": "Networking", - "text": "Will Firewall configurations be needed in order to ensure communication with Azure Services?", + "subcategory": "Governance", + "text": "Leverage Azure Policy strategically, define controls for your environment, using Policy Initiatives to group related policies.", "waf": "Security" }, { - "category": "Networking", - "checklist": "Azure Arc Review", - "description": "Use available automation tool for the system in question to regularly update the Azure endpoints", - "guid": "6fa95b96-ad88-4408-b372-734b876ba28f", - "link": "https://www.microsoft.com/download/details.aspx?id=56519", + "category": "Governance", + "checklist": "Azure Landing Zone Review", + "guid": "e979377b-cdb3-4751-ab2a-b13ada6e55d7", + "id": "E01.02", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/naming-and-tagging", "services": [ - "Arc" + "AzurePolicy" ], - "severity": "Low", - "subcategory": "Networking", - "text": "Can the Firewall or Proxy rules be automated updated if Service Tags or IP addresses change", + "severity": "Medium", + "subcategory": "Governance", + "text": "Identify required Azure tags and use the 'append' policy mode to enforce usage via Azure Policy.", "waf": "Security" }, { - "category": "Networking", - "checklist": "Azure Arc Review", - "description": "Configure Servers to use Transport Layer Security (TLS) version 1.2", - "guid": "21459013-65d3-48e5-9f9c-cbd868266abc", - "link": "https://learn.microsoft.com/azure/azure-arc/servers/network-requirements?tabs=azure-cloud#transport-layer-security-12-protocol", + "category": "Governance", + "checklist": "Azure Landing Zone Review", + "guid": "d8a2adb1-17d6-4326-af62-5ca44e5695f2", + "id": "E01.03", + "link": "https://learn.microsoft.com/azure/governance/policy/overview", "services": [ - "Arc" + "RBAC", + "AzurePolicy" ], - "severity": "High", - "subcategory": "Networking", - "text": "Always use secure communication for Azure where possible", + "severity": "Medium", + "subcategory": "Governance", + "text": "Map regulatory and compliance requirements to Azure Policy definitions and Azure role assignments.", "waf": "Security" }, { - "category": "Networking", - "checklist": "Azure Arc Review", - "description": "All extensions (like log analytics etc.) have separate network requirements, be sure to include all in the network design.", - "guid": "a264f9a1-9bf3-49d9-9d44-c7c8919ca1f6", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/hybrid/arc-enabled-servers/eslz-arc-servers-connectivity#define-extensions-connectivity-method", + "category": "Governance", + "checklist": "Azure Landing Zone Review", + "guid": "223ace8c-b123-408c-a501-7f154e3ab369", + "id": "E01.04", + "link": "https://learn.microsoft.com/azure/governance/policy/overview", "services": [ - "Arc", - "PrivateLink", - "Monitor" + "Subscriptions", + "AzurePolicy" ], - "severity": "Low", - "subcategory": "Networking", - "text": "Include communication for Azure Arc-enabled Servers extensions in the design (firewall/proxy/private link)", + "severity": "Medium", + "subcategory": "Governance", + "text": "Establish Azure Policy definitions at the intermediate root management group so that they can be assigned at inherited scopes", "waf": "Security" }, { - "category": "Security, Governance and Compliance", - "checklist": "Azure Arc Review", - "guid": "ac6aae01-e6a8-44de-9df4-7d2d92881b1c", - "link": "https://learn.microsoft.com/azure/governance/policy/", + "category": "Governance", + "checklist": "Azure Landing Zone Review", + "guid": "3829e7e3-1618-4368-9a04-77a209945bda", + "id": "E01.05", + "link": "https://learn.microsoft.com/azure/governance/policy/overview", "services": [ - "Arc", "AzurePolicy" ], "severity": "Medium", - "subcategory": "Management", - "text": "Use Azure Policy to implement a governance model for hybrid connected servers", + "subcategory": "Governance", + "text": "Manage policy assignments at the highest appropriate level with exclusions at bottom levels, if required.", "waf": "Security" }, { - "category": "Security, Governance and Compliance", - "checklist": "Azure Arc Review", - "guid": "5c2a3649-4b69-4bad-98aa-d53cc78e1d76", - "link": "https://learn.microsoft.com/azure/governance/machine-configuration/overview", + "category": "Governance", + "checklist": "Azure Landing Zone Review", + "guid": "43334f24-9116-4341-a2ba-527526944008", + "id": "E01.06", + "link": "https://learn.microsoft.com/security/benchmark/azure/mcsb-asset-management#am-2-use-only-approved-services", "services": [ - "Arc" + "Subscriptions", + "AzurePolicy" ], - "severity": "Medium", - "subcategory": "Management", - "text": "Consider using Machine configurations for in guest OS configurations", - "waf": "Operations" + "severity": "Low", + "subcategory": "Governance", + "text": "Use Azure Policy to control which services users can provision at the subscription/management group level", + "waf": "Security" }, { - "category": "Security, Governance and Compliance", - "checklist": "Azure Arc Review", - "guid": "667357c4-4967-44c5-bd85-b859c7733be2", - "link": "https://learn.microsoft.com/azure/governance/machine-configuration/machine-configuration-create", + "category": "Governance", + "checklist": "Azure Landing Zone Review", + "guid": "be7d7e48-4327-46d8-adc0-55bcf619e8a1", + "id": "E01.07", + "link": "https://learn.microsoft.com/azure/governance/policy/overview", "services": [ - "Arc", "AzurePolicy" ], "severity": "Medium", - "subcategory": "Management", - "text": "Evaluate the need for custom Guest Configuration policies", - "waf": "Operations" + "subcategory": "Governance", + "text": "Use built-in policies where possible to minimize operational overhead.", + "waf": "Security" }, { - "category": "Security, Governance and Compliance", - "checklist": "Azure Arc Review", - "guid": "49674c5e-d85b-4859-a773-3be2a1a27b77", - "link": "https://learn.microsoft.com/azure/automation/change-tracking/overview", + "category": "Governance", + "checklist": "Azure Landing Zone Review", + "description": "Assigning the Resource Policy Contributor role to specific scopes allows you to delegate policy management to relevant teams. For instance, a central IT team may oversee management group-level policies, while application teams handle policies for their subscriptions, enabling distributed governance with adherence to organizational standards.", + "guid": "3f988795-25d6-4268-a6d7-0ba6c97be995", + "id": "E01.08", + "link": "https://learn.microsoft.com/azure/governance/policy/overview#azure-rbac-permissions-in-azure-policy", "services": [ - "Arc", - "Monitor" + "RBAC", + "Subscriptions", + "AzurePolicy", + "Entra" ], "severity": "Medium", - "subcategory": "Monitoring", - "text": "Consider using change tracking for tracking changes made on the servers", - "waf": "Operations" + "subcategory": "Governance", + "text": "Assign the built-in Resource Policy Contributor role at a particular scope to enable application-level governance.", + "waf": "Security" }, { - "category": "Security, Governance and Compliance", - "checklist": "Azure Arc Review", - "guid": "d5d1e54a-2965-49e3-a58f-d78289c93555", - "link": "https://learn.microsoft.com/azure/azure-arc/servers/data-residency", + "category": "Governance", + "checklist": "Azure Landing Zone Review", + "guid": "19048384-5c98-46cb-8913-156a12476e49", + "id": "E01.09", + "link": "https://learn.microsoft.com/azure/governance/policy/overview", "services": [ - "Arc" + "Subscriptions", + "AzurePolicy" ], "severity": "Medium", - "subcategory": "Requirements", - "text": "Make sure to use an Azure region for storing the metadata approved by the organization", + "subcategory": "Governance", + "text": "Limit the number of Azure Policy assignments made at the root management group scope to avoid managing through exclusions at inherited scopes.", "waf": "Security" }, { - "category": "Security, Governance and Compliance", - "checklist": "Azure Arc Review", - "guid": "195abb91-a4ed-490d-ae2c-c84c37b6b780", - "link": "https://learn.microsoft.com/azure/key-vault/general/basic-concepts", + "category": "Governance", + "checklist": "Azure Landing Zone Review", + "guid": "5a917e1f-348e-4f25-9c27-d42e8bbac757", + "id": "E01.10", + "link": "https://azure.microsoft.com/resources/achieving-compliant-data-residency-and-security-with-azure/", "services": [ - "Arc", - "AKV" + "AzurePolicy" ], "severity": "Medium", - "subcategory": "Secrets", - "text": "Use Azure Key Vault for certificate management on servers", + "subcategory": "Governance", + "text": "If any data sovereignty requirements exist, Azure Policies can be deployed to enforce them", + "training": "https://learn.microsoft.com/learn/paths/secure-your-cloud-data/", "waf": "Security" }, { - "category": "Security, Governance and Compliance", - "checklist": "Azure Arc Review", - "description": "Consider using a short-lived Azure AD service principal client secrets.", - "guid": "6d02bfe4-564b-40d8-94a3-48726ee79d6b", - "link": "https://learn.microsoft.com/azure/active-directory/develop/howto-create-service-principal-portal#option-2-create-a-new-application-secret", + "category": "Governance", + "checklist": "Azure Landing Zone Review", + "guid": "78b22132-b41c-460b-a4d3-df8f73a67dc2", + "id": "E01.11", + "link": "https://github.com/Azure/sovereign-landing-zone/blob/main/docs/scenarios/Sovereignty-Policy-Baseline.md", "services": [ - "Arc", - "Storage", - "AKV", - "Entra" + "AzurePolicy" ], - "severity": "High", - "subcategory": "Secrets", - "text": "What is the acceptable life time of the secret used by SP's", + "severity": "Medium", + "subcategory": "Governance", + "text": "For Sovereign Landing Zone, sovereignty policy baseline' policy initiative is deployed and and assigned at correct MG level.", "waf": "Security" }, { - "category": "Security, Governance and Compliance", - "checklist": "Azure Arc Review", - "description": "A private key is saved to the disk, ensure this is protected using disk encryption", - "guid": "a1a27b77-5a91-4be1-b388-ff394c2bd463", - "link": "https://learn.microsoft.com/azure/azure-arc/servers/security-overview#using-disk-encryption", + "category": "Governance", + "checklist": "Azure Landing Zone Review", + "guid": "caeea0e9-1024-41df-a52e-d99c3f22a6f4", + "id": "E01.12", + "link": "https://learn.microsoft.com/en-us/industry/sovereignty/policy-portfolio-baseline", "services": [ - "Arc", - "AKV" + "AzurePolicy" ], "severity": "Medium", - "subcategory": "Secrets", - "text": "Secure the public key for Azure Arc-enabled Servers", + "subcategory": "Governance", + "text": "For Sovereign Landing Zone, sovereign Control objectives to policy mapping' is documented.", "waf": "Security" }, { - "category": "Security, Governance and Compliance", - "checklist": "Azure Arc Review", - "description": "Local administrator is required to install the Connected Machine Agent on Windows and Linux systems", - "guid": "29659e39-58fd-4782-a9c9-35556d02bfe4", - "link": "https://learn.microsoft.com/azure/azure-arc/servers/onboard-portal#install-manually", + "category": "Governance", + "checklist": "Azure Landing Zone Review", + "guid": "9b461617-db7b-4399-8ac6-d4eb7153893a", + "id": "E01.13", "services": [ - "Arc" + "AzurePolicy" ], - "severity": "High", - "subcategory": "Security", - "text": "Ensure there is local administrator access for executing the agent installation", + "severity": "Medium", + "subcategory": "Governance", + "text": "For Sovereign Landing Zone, process is in place for CRUD of 'Sovereign Control objectives to policy mapping'.", "waf": "Security" }, { - "category": "Security, Governance and Compliance", - "checklist": "Azure Arc Review", - "description": "Members of the local administrator group on Windows and users with root privileges on Linux, have permissions to manage the agent via command line.", - "guid": "564b0d83-4a34-4872-9ee7-9d6b5c2a3649", - "link": "https://learn.microsoft.com/azure/azure-arc/servers/security-overview#agent-security-and-permissions", + "category": "Governance", + "checklist": "Azure Landing Zone Review", + "guid": "9b5e2a28-9823-4faf-ab7e-afa5f6c57221", + "id": "E02.01", + "link": "https://learn.microsoft.com/azure/automation/automation-solution-vm-management-config", "services": [ - "Arc" + "TrafficManager", + "VM", + "Cost" ], - "severity": "Medium", - "subcategory": "Security", - "text": "Limit the amount of users with local administrator rights to the servers", + "severity": "Low", + "subcategory": "Optimize your cloud investment", + "text": "Consider using automation tags to start/stop VM's in your environment to save on cost.", "waf": "Security" }, { - "category": "Security, Governance and Compliance", - "checklist": "Azure Arc Review", - "guid": "4b69bad3-8aad-453c-a78e-1d76667357c4", - "link": "https://learn.microsoft.com/azure/azure-arc/servers/managed-identity-authentication", + "category": "Management ", + "checklist": "Azure Landing Zone Review", + "guid": "ecdc7506-6f37-4ea9-be87-fc5d3df08a64", + "id": "E02.01", + "link": "https://learn.microsoft.com/azure/virtual-machine-scale-sets/overview", "services": [ - "Arc", - "Entra" + "VM" ], "severity": "Medium", - "subcategory": "Security", - "text": "Consider using and restricting access to managed identities for applications.", - "waf": "Security" + "subcategory": "Scalability", + "text": "Leverage Azure Virtual Machine Scale sets to scale in and out based on the load.", + "waf": "Reliability" }, { - "category": "Security, Governance and Compliance", - "checklist": "Azure Arc Review", - "description": "Use Defender for Endpoint or another AV and EDR solution to protect endpoints", - "guid": "5a91be1f-388f-4f39-9c2b-d463cbbbc868", - "link": "https://learn.microsoft.com/azure/security-center/security-center-get-started", + "category": "Governance", + "checklist": "Azure Landing Zone Review", + "guid": "29fd366b-a180-452b-9bd7-954b7700c667", + "id": "E02.02", + "link": "https://learn.microsoft.com/azure/cost-management-billing/costs/tutorial-acm-create-budgets?bc=%2Fazure%2Fcloud-adoption-framework%2F_bread%2Ftoc.json&toc=%2Fazure%2Fcloud-adoption-framework%2Ftoc.json", "services": [ - "Arc", - "Defender" + "Monitor", + "Cost", + "TrafficManager" ], "severity": "Medium", - "subcategory": "Security", - "text": "Enable Defender for Servers for all servers to secure hybrid workloads from threats", - "waf": "Security" + "subcategory": "Optimize your cloud investment", + "text": "Configure 'Actual' and 'Forecasted' Budget Alerts.", + "waf": "Cost" }, { - "category": "Security, Governance and Compliance", - "checklist": "Azure Arc Review", - "guid": "cbafe6c4-6589-4d45-9a92-7c3974d1102c", + "ammp": true, + "category": "Management", + "checklist": "Azure Landing Zone Review", + "guid": "89cc5e11-aa4d-4c3b-893d-feb99215266a", + "id": "F01.01", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#add-diagnostic-settings-to-save-your-wafs-logs", "services": [ - "Arc" + "FrontDoor", + "WAF", + "AppGW" ], - "severity": "Medium", - "subcategory": "Security", - "text": "Define controls to detect security misconfigurations and track compliance", - "waf": "Security" + "severity": "High", + "subcategory": "App delivery", + "text": "Add diagnostic settings to save WAF logs from application delivery services like Azure Front Door and Azure Application Gateway. Regularly review the logs to check for attacks and for false positive detections.", + "waf": "Operations" }, { - "category": "Security, Governance and Compliance", - "checklist": "Azure Arc Review", - "guid": "cbbbc868-195a-4bb9-8a4e-d90dae2cc84c", - "link": "https://learn.microsoft.com/azure/azure-arc/servers/security-overview#extension-allowlists-and-blocklists", + "category": "Management", + "checklist": "Azure Landing Zone Review", + "guid": "7f408960-c626-44cb-a018-347c8d790cdf", + "id": "F01.02", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#send-logs-to-microsoft-sentinel", "services": [ - "Arc" + "FrontDoor", + "WAF", + "Sentinel", + "AppGW" ], "severity": "Medium", - "subcategory": "Security", - "text": "Use allow- or block-lists to control what extensions can be installed on the Azure Arc-enabled servers", - "waf": "Security" + "subcategory": "App delivery", + "text": "Send WAF logs from your application delivery services like Azure Front Door and Azure Application Gateway to Microsoft Sentinel. Detect attacks and integrate WAF telemetry into your overall Azure environment.", + "waf": "Operations" }, { - "category": "BCDR", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Ensure data repositories for the backup solution are stored outside of vSAN storage. Either in Azure native or on a disk pool-backed datastore", - "guid": "976f32a7-30d1-6caa-c2a0-207fdc26571b", - "id": "A01.01", - "link": "https://learn.microsoft.com/azure/azure-vmware/set-up-backup-server-for-azure-vmware-solution", - "services": [ - "AVS", - "Storage", - "Backup" - ], + "category": "Management", + "checklist": "Azure Landing Zone Review", + "guid": "7ea02e1c-7166-45a3-bdf5-098891367fcb", + "id": "F02.01", + "link": "https://learn.microsoft.com/azure/reliability/cross-region-replication-azure", + "services": [], "severity": "Medium", - "subcategory": "Backup", - "text": "Ensure backups are not stored on vSAN as vSAN is a finite resource", + "subcategory": "Data Protection", + "text": "Consider cross-region replication in Azure for BCDR with paired regions", "waf": "Reliability" }, { - "category": "BCDR", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Microsoft backup service", - "guid": "fc8af7a1-c724-e255-c18d-4ca22a6f27f0", - "id": "A02.01", - "link": "https://docs.microsoft.com/azure/azure-vmware/set-up-backup-server-for-azure-vmware-solution", + "category": "Management", + "checklist": "Azure Landing Zone Review", + "guid": "eba8cf22-45c6-4dc1-9b57-2cceb3b97ce5", + "id": "F02.02", + "link": "https://learn.microsoft.com/azure/storage/common/storage-redundancy", "services": [ - "AVS", "Backup" ], "severity": "Medium", - "subcategory": "Business Continuity", - "text": "Use MABS as your backup solution", + "subcategory": "Data Protection", + "text": "When using Azure Backup, consider the different backup types (GRS, ZRS & LRS) as the default setting is GRS", "waf": "Reliability" }, { - "category": "BCDR", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Best practice - this is Backup, not disaster recovery", - "guid": "be28860f-3d29-a79a-1a0e-36f1b23b36ae", - "id": "A02.02", - "link": "Best practice to deploy backup in the same region as your AVS deployment", + "category": "Management", + "checklist": "Azure Landing Zone Review", + "guid": "67e7a8ed-4b30-4e38-a3f2-9812b2363cef", + "id": "F03.01", + "link": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", "services": [ - "AVS", - "ASR", - "Backup" + "Monitor", + "RBAC", + "AzurePolicy", + "Entra" ], "severity": "Medium", - "subcategory": "Business Continuity", - "text": "Deploy your backup solution in the same region as your Azure VMware Solution private cloud", - "waf": "Reliability" + "subcategory": "Monitoring", + "text": "Use a single monitor logs workspace to manage platforms centrally except where Azure role-based access control (Azure RBAC), data sovereignty requirements, or data retention policies mandate separate workspaces.", + "training": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", + "waf": "Operations" }, { - "category": "BCDR", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Best practice - in case AVS is unavailable", - "guid": "4d2f79a5-4ccf-0dfc-557c-49619b99a540", - "id": "A02.03", - "link": "https://docs.microsoft.com/azure/azure-vmware/set-up-backup-server-for-azure-vmware-solution", + "category": "Management", + "checklist": "Azure Landing Zone Review", + "guid": "e179b599-de0d-4597-9cd4-cd21b088137f", + "id": "F03.02", "services": [ - "AVS" + "Monitor" ], "severity": "Medium", - "subcategory": "Business Continuity", - "text": "Preferably deploy MABS outside of the SDDC as native Azure IaaS", - "waf": "Reliability" + "subcategory": "Monitoring", + "text": "Is the landing zone documented?", + "waf": "Operations" }, { - "category": "BCDR", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Is a process in place to request a restore of the VMware components managed by the Azure Platform?", - "guid": "ff431c40-962c-5182-d536-0c2f0c4ce9e0", - "id": "A02.04", - "link": "Will Disaster Recovery Site Recovery, HCX Disaster Recovery, SRM or back tools be used?", + "category": "Management", + "checklist": "Azure Landing Zone Review", + "guid": "5e6c4cfd-3e50-4454-9c24-47ec66138a72", + "id": "F03.03", + "link": "https://learn.microsoft.com/azure/azure-monitor/logs/data-retention-archive?tabs=portal-1%2Cportal-2#how-retention-and-archiving-work", "services": [ - "AVS" + "Monitor", + "ARS" ], "severity": "Medium", - "subcategory": "Business Continuity", - "text": "Escalation process with Microsoft in the event of a regional DR", - "waf": "Reliability" + "subcategory": "Monitoring", + "text": "Use Azure Monitor Logs when log retention requirements exceed two years. You can currently keep data in archived state for up to 7 years.", + "training": "https://learn.microsoft.com/learn/paths/architect-infrastructure-operations/", + "waf": "Operations" }, { - "category": "BCDR", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Compare SRM with HCX", - "guid": "f379436d-3051-daa0-01fb-dc4e0e04d677", - "id": "A03.01", - "link": "https://docs.microsoft.com/azure/azure-vmware/disaster-recovery-using-vmware-site-recovery-manager", + "category": "Management", + "checklist": "Azure Landing Zone Review", + "guid": "00f1ce16-ed30-41d6-b872-e52e3611cc58", + "id": "F03.04", + "link": "https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/govern/policy-compliance/regulatory-compliance", "services": [ - "AVS", - "ASR" + "Monitor", + "AzurePolicy" ], "severity": "Medium", - "subcategory": "Disaster Recovery", - "text": "Use VMware Site Recovery Manager when both sites are Azure VMware Solution", - "waf": "Reliability" + "subcategory": "Monitoring", + "text": "Use Azure Policy for access control and compliance reporting. Azure Policy provides the ability to enforce organization-wide settings to ensure consistent policy adherence and fast violation detection. ", + "training": "https://learn.microsoft.com/en-us/azure/governance/policy/concepts/effects", + "waf": "Operations" }, { - "category": "BCDR", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Recovery into Azure instead of Vmware solution", - "guid": "367f71d8-3cf6-51a0-91a5-3db3d570cc19", - "id": "A03.02", - "link": "https://docs.microsoft.com/azure/site-recovery/avs-tutorial-prepare-azure", + "category": "Management", + "checklist": "Azure Landing Zone Review", + "guid": "e7d7e484-3276-4d8b-bc05-5bcf619e8a13", + "id": "F03.05", + "link": "https://learn.microsoft.com/azure/governance/policy/how-to/guest-configuration-create", "services": [ - "AVS", - "ASR" + "Monitor", + "VM", + "AzurePolicy" ], "severity": "Medium", - "subcategory": "Disaster Recovery", - "text": "Use Azure Site Recovery when the Disaster Recovery technology is native Azure IaaS", - "waf": "Reliability" + "subcategory": "Monitoring", + "text": "Monitor in-guest virtual machine (VM) configuration drift using Azure Policy. Enabling guest configuration audit capabilities through policy helps application team workloads to immediately consume feature capabilities with little effort.", + "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", + "waf": "Operations" }, { - "category": "BCDR", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Avoid manual tasks as much as possible", - "guid": "ee02ada0-1887-bb3a-b84c-423f45a09ef9", - "id": "A03.03", - "link": "https://docs.microsoft.com/azure/site-recovery/avs-tutorial-prepare-azure", + "category": "Management", + "checklist": "Azure Landing Zone Review", + "guid": "f9887952-5d62-4688-9d70-ba6c97be9951", + "id": "F03.06", + "link": "https://learn.microsoft.com/azure/automation/update-management/overview", "services": [ - "AVS", - "ASR" + "Monitor", + "VM" ], "severity": "Medium", - "subcategory": "Disaster Recovery", - "text": "Use Automated recovery plans with either of the Disaster solutions,", - "waf": "Reliability" + "subcategory": "Monitoring", + "text": "Use Update Management in Azure Automation as a long-term patching mechanism for both Windows and Linux VMs. ", + "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-compute-resources/", + "waf": "Operations" }, { - "category": "BCDR", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Any other datacenter in the same region", - "guid": "0c2b74e5-9c28-780d-1df3-12d3de4aaa76", - "id": "A03.04", - "link": "https://docs.microsoft.com/azure/azure-vmware/connect-multiple-private-clouds-same-region", + "category": "Management", + "checklist": "Azure Landing Zone Review", + "guid": "90483845-c986-4cb2-a131-56a12476e49f", + "id": "F03.07", + "link": "https://learn.microsoft.com/azure/network-watcher/network-watcher-monitoring-overview", "services": [ - "AVS", - "ASR" + "Monitor", + "NetworkWatcher" ], "severity": "Medium", - "subcategory": "Disaster Recovery", - "text": "Configure a secondary disaster recovery environment", - "waf": "Reliability" + "subcategory": "Monitoring", + "text": "Use Network Watcher to proactively monitor traffic flows", + "training": "https://learn.microsoft.com/learn/modules/configure-network-watcher/", + "waf": "Operations" }, { - "category": "BCDR", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Use 2 different address spaces between the regions, for example: 10.0.0.0/16 and 192.168.0.0/16 for the different regions", - "guid": "c2a34ec4-2933-4e6c-dc36-e20e67abbe3f", - "id": "A03.05", - "link": "https://docs.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing", + "category": "Management", + "checklist": "Azure Landing Zone Review", + "guid": "541acdce-9793-477b-adb3-751ab2ab13ad", + "id": "F03.08", + "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/lock-resources?tabs=json", "services": [ - "AVS", - "ASR" + "Monitor" ], "severity": "Medium", - "subcategory": "Disaster Recovery", - "text": "Assign IP ranges unique to each region", - "waf": "Reliability" + "subcategory": "Monitoring", + "text": "Use resource locks to prevent accidental deletion of critical shared services.", + "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", + "waf": "Operations" }, { - "category": "BCDR", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "ExpressRoute Global Reach can be used for connectivity between the primary and secondary Azure VMware Solution Private Clouds or routing must be done through network virtual appliances?", - "guid": "b44fb6ec-bfc1-3a8e-dba2-ca97f0991d2c", - "id": "A03.06", - "link": "This depends if you have multiple AVS Private Clouds. If so and they are in the same region then use AVS Interconnect. If they are in separate regions then use ExpressRoute Global Reach.", + "category": "Management", + "checklist": "Azure Landing Zone Review", + "guid": "a6e55d7d-8a2a-4db1-87d6-326af625ca44", + "id": "F03.09", + "link": "https://learn.microsoft.com/azure/governance/policy/overview", "services": [ - "AVS", - "ASR", - "ExpressRoute", - "NVA" + "RBAC", + "Monitor", + "AzurePolicy" ], - "severity": "Medium", - "subcategory": "Disaster Recovery", - "text": "Use Global Reach between DR regions", - "waf": "Reliability" + "severity": "Low", + "subcategory": "Monitoring", + "text": "Use deny policies to supplement Azure role assignments. The combination of deny policies and Azure role assignments ensures the appropriate guardrails are in place to enforce who can deploy and configure resources and what resources they can deploy and configure.", + "waf": "Operations" }, { - "category": "Connectivity", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "An ExR Global Reach connection will be established to the ExR circuit, no other connections", - "guid": "a2c12df2-07fa-3edd-2cec-fda0b55fb952", - "id": "B01.01", - "link": "https://learn.microsoft.com/azure/azure-vmware/tutorial-expressroute-global-reach-private-cloud", + "category": "Management", + "checklist": "Azure Landing Zone Review", + "guid": "e5695f22-23ac-4e8c-a123-08ca5017f154", + "id": "F03.10", + "link": "https://learn.microsoft.com/azure/service-health/alerts-activity-log-service-notifications-portal", "services": [ - "AVS", - "VWAN" + "Monitor" ], "severity": "Medium", - "subcategory": "Direct (no vWAN, no H&S)", - "text": "Global Reach to ExR circuit - no Azure resources", - "waf": "Performance" + "subcategory": "Monitoring", + "text": "Include service and resource health events as part of the overall platform monitoring solution. Tracking service and resource health from the platform perspective is an important component of resource management in Azure.", + "waf": "Operations" }, { - "category": "Connectivity", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Use ExR to connect on-premises (other) location to Azure", - "guid": "f62ce162-ba5a-429d-674e-fafa1af5f706", - "id": "B02.01", - "link": "https://learn.microsoft.com/azure/azure-vmware/tutorial-expressroute-global-reach-private-cloud", + "category": "Management", + "checklist": "Azure Landing Zone Review", + "guid": "d5f345bf-97ab-41a7-819c-6104baa7d48c", + "id": "F03.11", + "link": "https://learn.microsoft.com/azure/azure-monitor/alerts/action-groups", "services": [ - "AVS", - "ExpressRoute" + "Monitor" ], "severity": "Medium", - "subcategory": "ExpressRoute", - "text": "Connect to Azure using ExR", - "waf": "Performance" + "subcategory": "Monitoring", + "text": "Include alerts and action groups as part of the Azure Service Health platform to ensure that alerts or issues can be actioned", + "waf": "Operations" }, { - "category": "Connectivity", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Use the migration assesment tool and timeline to determine bandwidth required", - "guid": "cf01c73b-1247-0a7a-740c-e1ea29bda340", - "id": "B02.02", - "link": "https://learn.microsoft.com/azure/expressroute/expressroute-introduction", + "category": "Management", + "checklist": "Azure Landing Zone Review", + "guid": "e3ab3693-829e-47e3-8618-3687a0477a20", + "id": "F03.12", + "link": "https://learn.microsoft.com/azure/sentinel/quickstart-onboard", "services": [ - "AVS", - "ExpressRoute" + "Monitor" ], "severity": "Medium", - "subcategory": "ExpressRoute", - "text": "Bandwidth sizing", - "waf": "Performance" + "subcategory": "Monitoring", + "text": "Don't send raw log entries back to on-premises monitoring systems. Instead, adopt a principle that data born in Azure stays in Azure. If on-premises SIEM integration is required, then send critical alerts instead of logs.", + "waf": "Operations" }, { - "category": "Connectivity", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "What traffic is routed through a firewall, what goes directly into Azure", - "guid": "aab216ee-8941-315e-eada-c7e1f2243bd1", - "id": "B02.03", - "link": "https://learn.microsoft.com/azure/architecture/solution-ideas/articles/azure-vmware-solution-foundation-networking", + "category": "Management", + "checklist": "Azure Landing Zone Review", + "guid": "9945bda4-3334-4f24-a116-34182ba52752", + "id": "F03.13", + "link": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", "services": [ - "AVS", - "ExpressRoute" + "Monitor", + "RBAC", + "Entra" ], "severity": "Medium", - "subcategory": "ExpressRoute", - "text": "Traffic routing ", - "waf": "Performance" + "subcategory": "Monitoring", + "text": "Use a centralized Azure Monitor Log Analytics workspace to collect logs and metrics from IaaS and PaaS application resources and control log access with Azure RBAC.", + "waf": "Operations" }, { - "category": "Connectivity", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "AVS to ExR circuit, no traffic inspection", - "guid": "1f956e45-f62d-5c95-3a95-3bab718907f8", - "id": "B02.04", - "link": "https://learn.microsoft.com/azure/architecture/solution-ideas/articles/azure-vmware-solution-foundation-networking", + "category": "Management", + "checklist": "Azure Landing Zone Review", + "guid": "6944008b-e7d7-4e48-9327-6d8bdc055bcf", + "id": "F03.14", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-setup-guide/monitoring-reporting?tabs=AzureMonitor", "services": [ - "AVS", - "ExpressRoute" + "Monitor" ], "severity": "Medium", - "subcategory": "ExpressRoute", - "text": "Global Reach ", - "waf": "Performance" + "subcategory": "Monitoring", + "text": "Use Azure Monitor Logs for insights and reporting.", + "waf": "Operations" }, { - "category": "Connectivity", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Name of the vNet and a unique address space /24 minimum", - "guid": "91f7a87b-21ac-d712-959c-8df2ba034253", - "id": "B03.01", - "link": "https://learn.microsoft.com/azure/virtual-network/quick-create-portal", + "category": "Management", + "checklist": "Azure Landing Zone Review", + "guid": "619e8a13-f988-4795-85d6-26886d70ba6c", + "id": "F03.15", + "link": "https://learn.microsoft.com/azure/azure-monitor/agents/diagnostics-extension-overview", "services": [ - "AVS", - "VNet" + "Monitor", + "Storage" ], "severity": "Medium", - "subcategory": "Hub & Spoke", - "text": "VNet name & address space", - "waf": "Performance" + "subcategory": "Monitoring", + "text": "When necessary, use shared storage accounts within the landing zone for Azure diagnostic extension log storage.", + "waf": "Operations" }, { - "category": "Connectivity", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Subnet must be called GatewaySubnet", - "guid": "58a027e2-f37f-b540-45d5-e44843aba26b", - "id": "B03.02", - "link": "https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings", + "category": "Management", + "checklist": "Azure Landing Zone Review", + "guid": "97be9951-9048-4384-9c98-6cb2913156a1", + "id": "F03.16", + "link": "https://learn.microsoft.com/azure/azure-monitor/alerts/alerts-overview", "services": [ - "AVS", - "VNet", - "ExpressRoute", - "VPN" + "Monitor" ], "severity": "Medium", - "subcategory": "Hub & Spoke", - "text": "Gateway subnet", - "waf": "Performance" + "subcategory": "Monitoring", + "text": "Use Azure Monitor alerts for the generation of operational alerts.", + "waf": "Operations" }, { - "category": "Connectivity", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Create a VPN gateway on the hub Gateway subnet", - "guid": "d4806549-0913-3e79-b580-ac2d3706e65a", - "id": "B03.03", - "link": "https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings", + "category": "Management", + "checklist": "Azure Landing Zone Review", + "guid": "859c3900-4514-41eb-b010-475d695abd74", + "id": "F03.17", + "link": "https://learn.microsoft.com/azure/architecture/best-practices/monitoring", "services": [ - "AVS", - "VNet", - "ExpressRoute", - "VPN" + "Monitor" ], "severity": "Medium", - "subcategory": "Hub & Spoke", - "text": "VPN Gateway", - "waf": "Performance" + "subcategory": "Monitoring", + "text": "Ensure that monitoring requirements have been assessed and that appropriate data collection and alerting configurations are applied", + "waf": "Operations" }, { - "category": "Connectivity", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Create an ExR Gateway in the hub Gateway subnet.", - "guid": "864d7a8b-7016-c769-a717-61af6bfb73d2", - "id": "B03.04", - "link": "https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings", + "category": "Management", + "checklist": "Azure Landing Zone Review", + "guid": "fed3c55f-a67e-4875-aadd-3aba3f9fde31", + "id": "F03.18", + "link": "https://learn.microsoft.com/azure/automation/how-to/region-mappings", "services": [ - "AVS", - "VNet", - "ExpressRoute", - "VPN" + "Monitor" ], "severity": "Medium", - "subcategory": "Hub & Spoke", - "text": "ExR Gateway", - "waf": "Performance" + "subcategory": "Monitoring", + "text": "Consider supported regions for linked Log Analytics workspace and automation accounts", + "waf": "Operations" }, { - "category": "Connectivity", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "How will Internet traffic be routes, Az Firewall, NVA, Secure Hub, On-Premises firewall?", - "guid": "cc2e11b9-7911-7da1-458c-d7fcef794aad", - "id": "B04.01", - "link": "https://learn.microsoft.com/azure/azure-vmware/enable-public-internet-access", + "category": "Management", + "checklist": "Azure Landing Zone Review", + "guid": "f541acdc-e979-4377-acdb-3751ab2ab13a", + "id": "F04.01", + "link": "https://learn.microsoft.com/azure/governance/policy/concepts/guest-configuration", "services": [ - "AVS", - "NVA" + "VM", + "AzurePolicy" ], "severity": "Medium", - "subcategory": "Internet", - "text": "Egress point", - "waf": "Performance" + "subcategory": "Operational compliance", + "text": "Use Azure policies to automatically deploy software configurations through VM extensions and enforce a compliant baseline VM configuration.", + "waf": "Security" }, { - "category": "Connectivity", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Allow remote connectivity to AVS via the portal, specifically to vCenter, NSX-T and HCX", - "guid": "71e68ce3-982e-5e56-0191-01100ad0e66f", - "id": "B05.01", - "link": "https://learn.microsoft.com/answers/questions/171195/how-to-create-jump-server-in-azure-not-bastion-paa.html", + "category": "Management", + "checklist": "Azure Landing Zone Review", + "description": "Azure Policy's guest configuration features can audit and remediate machine settings (e.g., OS, application, environment) to ensure resources align with expected configurations, and Update Management can enforce patch management for VMs.", + "guid": "da6e55d7-d8a2-4adb-817d-6326af625ca4", + "id": "F04.02", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/management-operational-compliance#monitoring-for-configuration-drift", "services": [ - "AVS", - "Bastion" + "Monitor", + "VM", + "AzurePolicy" ], "severity": "Medium", - "subcategory": "Jumpbox & Bastion", - "text": "Remote connectivity to AVS", - "waf": "Performance" + "subcategory": "Operational compliance", + "text": "Monitor VM security configuration drift via Azure Policy.", + "waf": "Security" }, { - "category": "Connectivity", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Name the jumpbox and identify the subnet where it will be hosted", - "guid": "6f8e93a2-44b1-bb1d-28a1-4d5b3c2ea857", - "id": "B05.02", - "link": "https://learn.microsoft.com/azure/bastion/tutorial-create-host-portal", + "category": "Management", + "checklist": "Azure Landing Zone Review", + "guid": "2476e49f-541a-4cdc-b979-377bcdb3751a", + "id": "F05.01", + "link": "https://learn.microsoft.com/azure/site-recovery/site-recovery-overview", "services": [ - "AVS", - "VNet", - "Bastion" + "ACR", + "VM", + "ASR" ], "severity": "Medium", - "subcategory": "Jumpbox & Bastion", - "text": "Configure a jumbox and Azure Bastion", - "waf": "Performance" + "subcategory": "Protect and Recover", + "text": "Use Azure Site Recovery for Azure-to-Azure Virtual Machines disaster recovery scenarios. This enables you to replicate workloads across regions.", + "waf": "Operations" }, { - "category": "Connectivity", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Provides secure / seamless RDP/SSH connectivity to your vm's directly through the portal.", - "guid": "ba430d58-4541-085c-3641-068c00be9bc5", - "id": "B05.03", - "link": "https://learn.microsoft.com/azure/virtual-network/network-security-groups-overview", + "category": "Management", + "checklist": "Azure Landing Zone Review", + "guid": "b2ab13ad-a6e5-45d7-b8a2-adb117d6326a", + "id": "F05.02", + "link": "https://learn.microsoft.com/azure/architecture/framework/resiliency/backup-and-recovery", "services": [ - "AVS", - "VM", - "Bastion" + "ASR" ], "severity": "Medium", - "subcategory": "Jumpbox & Bastion", - "text": "Security measure allowing RDP access via the portal", - "waf": "Performance" + "subcategory": "Protect and Recover", + "text": "Ensure to use and test native PaaS service disaster recovery capabilities.", + "waf": "Operations" }, { - "category": "Connectivity", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Using a VPN to connect to Azure to enable VMware communications (HCX) (not recommended)", - "guid": "9988598f-2a9f-6b12-9b46-488415ceb325", - "id": "B06.01", - "link": "https://learn.microsoft.com/azure/azure-vmware/configure-site-to-site-vpn-gateway", + "category": "Management", + "checklist": "Azure Landing Zone Review", + "guid": "f625ca44-e569-45f2-823a-ce8cb12308ca", + "id": "F05.03", + "link": "https://learn.microsoft.com/azure/backup/backup-center-overview", "services": [ - "AVS", - "VPN" + "Backup" ], "severity": "Medium", - "subcategory": "VPN", - "text": "Connect to Azure using a VPN", - "waf": "Performance" + "subcategory": "Protect and Recover", + "text": "Use Azure-native backup capabilities, or an Azure-compatible, 3rd-party backup solution.", + "waf": "Operations" }, { - "category": "Connectivity", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Use the migration assesment tool and timeline to determine bandwidth required (eg 3rd party tool in link)", - "guid": "956ce5e9-a862-fe2b-a50d-a22923569357", - "id": "B06.02", - "link": "https://www.omnicalculator.com/other/data-transfer#:~:text=To%20calculate%20the%20data%20transfer%20speed%3A%201%20Download,measured%20time%20to%20find%20the%20data%20transfer%20speed.", + "ammp": true, + "category": "Management ", + "checklist": "Azure Landing Zone Review", + "guid": "826c5c45-bb79-4951-a812-e3bfbfd7326b", + "id": "F06.01", + "link": "https://learn.microsoft.com/azure/reliability/availability-zones-overview", "services": [ - "AVS", - "VPN" + "VM" ], - "severity": "Medium", - "subcategory": "VPN", - "text": "Bandwidth sizing", - "waf": "Performance" + "severity": "High", + "subcategory": "Fault Tolerance", + "text": "Leverage Availability Zones for your VMs in regions where they are supported.", + "waf": "Reliability" }, { - "category": "Connectivity", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "What traffic is routed through a firewall, what goes directly into Azure", - "guid": "e095116f-0bdc-4b51-4d71-b9e469d56f59", - "id": "B06.03", - "link": "https://learn.microsoft.com/azure/architecture/solution-ideas/articles/azure-vmware-solution-foundation-networking", + "ammp": true, + "category": "Management ", + "checklist": "Azure Landing Zone Review", + "guid": "7ccb7c06-5511-42df-8177-d97f08d0337d", + "id": "F06.02", + "link": "https://learn.microsoft.com/azure/virtual-machines/availability", "services": [ - "AVS", - "VPN" + "VM" ], - "severity": "Medium", - "subcategory": "VPN", - "text": "Traffic routing ", - "waf": "Performance" + "severity": "High", + "subcategory": "Fault Tolerance", + "text": "Avoid running a production workload on a single VM.", + "waf": "Reliability" }, { - "category": "Connectivity", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Name and unique address space for the vWAN, name for the vWAN hub", - "guid": "4dc480ac-cecd-39c4-fdc6-680b300716ab", - "id": "B07.01", - "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-site-to-site-portal#openvwan", + "category": "Management ", + "checklist": "Azure Landing Zone Review", + "guid": "84101f59-1941-4195-a270-e28034290e3a", + "id": "F06.03", + "link": "https://learn.microsoft.com/azure/load-balancer/load-balancer-overview", "services": [ - "AVS", - "VWAN" + "ACR", + "LoadBalancer", + "AppGW" ], "severity": "Medium", - "subcategory": "vWAN hub", - "text": "vWAN name, hub name and address space", - "waf": "Performance" + "subcategory": "Fault Tolerance", + "text": "Azure Load Balancer and Application Gateway distribute incoming network traffic across multiple resources.", + "waf": "Reliability" }, { - "category": "Connectivity", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Select either boh or the appropriate connection type.", - "guid": "51d6affd-8e02-6aea-d3d4-0baf618b3076", - "id": "B07.02", - "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-point-to-site-portal", - "services": [ - "AVS", - "VPN", - "VWAN" - ], + "category": "Security", + "checklist": "Azure Landing Zone Review", + "guid": "b86ad884-08e3-4727-94b8-75ba18f20459", + "id": "G01.01", + "link": "https://learn.microsoft.com/security/benchmark/azure/security-control-incident-response", + "services": [], "severity": "Medium", - "subcategory": "vWAN hub", - "text": "ExR and/or VPN gateway provisioned", - "waf": "Performance" + "subcategory": "Access control", + "text": "Determine the incident response plan for Azure services before allowing it into production.", + "waf": "Security" }, { - "category": "Connectivity", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Add Azure firewall to vWAN (recommended)", - "guid": "e32a4c67-3dc0-c134-1c12-52d46dcbab5b", - "id": "B07.03", - "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-expressroute-portal", - "services": [ - "AVS", - "Firewall", - "VWAN" - ], + "category": "Security", + "checklist": "Azure Landing Zone Review", + "guid": "01365d38-e43f-49cc-ad86-8266abca264f", + "id": "G01.02", + "link": "https://www.microsoft.com/security/business/zero-trust", + "services": [], "severity": "Medium", - "subcategory": "vWAN hub", - "text": "Secure vWAN", + "subcategory": "Access control", + "text": "Implement a zero-trust approach for access to the Azure platform, where appropriate.", "waf": "Security" }, { - "category": "Identity", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Active directory or other identity provider servers", - "guid": "fbc47fbf-bc96-fa93-ed5d-8c9be63cd5c3", - "id": "C01.01", - "link": "https://learn.microsoft.com/azure/azure-vmware/configure-identity-source-vcenter", + "ammp": true, + "category": "Security", + "checklist": "Azure Landing Zone Review", + "guid": "5017f154-e3ab-4369-9829-e7e316183687", + "id": "G02.01", + "link": "https://learn.microsoft.com/azure/key-vault/general/overview", "services": [ - "AVS", - "Entra" + "AKV" ], - "severity": "Medium", - "subcategory": "Access", - "text": "External Identity (user accounts)", + "severity": "High", + "subcategory": "Encryption and keys", + "text": "Use Azure Key Vault to store your secrets and credentials", "waf": "Security" }, { - "category": "Identity", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Not required for LDAPS, required for Kerberos", - "guid": "b5db7975-f6bb-8ba3-ee5f-e3e805887997", - "id": "C01.02", - "link": "https://learn.microsoft.com/windows-server/identity/ad-ds/plan/understanding-active-directory-site-topology", + "category": "Security", + "checklist": "Azure Landing Zone Review", + "graph": "ResourceContainers | where type=='microsoft.resources/subscriptions'| parse id with '/subscriptions/' SubscriptionID| project subscriptionId, SubscriptionName = name| join kind=leftouter (Resources| where type == 'microsoft.keyvault/vaults'| project id, name, subscriptionId) on subscriptionId| join kind= leftouter (Resources| where type == 'microsoft.keyvault/vaults'| summarize ResourceCount = count() by subscriptionId) on subscriptionId| extend RCount = iff(isnull(ResourceCount), 0, ResourceCount)| project-away ResourceCount| extend compliant = (RCount <> 1)", + "guid": "a0477a20-9945-4bda-9333-4f2491163418", + "id": "G02.02", + "link": "https://learn.microsoft.com/azure/key-vault/general/overview-throttling", "services": [ - "AVS", - "Entra" + "AKV" ], "severity": "Medium", - "subcategory": "Access", - "text": "If using AD domain, ensure Sites & Services has been configured", + "subcategory": "Encryption and keys", + "text": "Use different Azure Key Vaults for different applications and regions to avoid transaction scale limits and restrict access to secrets.", "waf": "Security" }, { - "category": "Identity", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Authentication for users, must be secure.", - "guid": "c30749c4-e2af-558c-2eb9-0b6ae84881d1", - "id": "C01.03", - "link": "https://learn.microsoft.com/azure/azure-vmware/configure-identity-source-vcenter", + "category": "Security", + "checklist": "Azure Landing Zone Review", + "guid": "2ba52752-6944-4008-ae7d-7e4843276d8b", + "id": "G02.03", + "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "services": [ - "AVS", - "Entra" + "AzurePolicy", + "AKV" ], "severity": "Medium", - "subcategory": "Access", - "text": "Use LDAPS not ldap ( vCenter)", + "subcategory": "Encryption and keys", + "text": "Provision Azure Key Vault with the soft delete and purge policies enabled to allow retention protection for deleted objects.", "waf": "Security" }, { - "category": "Identity", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Authentication for users, must be secure.", - "guid": "64cb9b5c-9edd-787e-1dd8-2b2338e51635", - "id": "C01.04", - "link": "https://learn.microsoft.com/azure/azure-vmware/configure-external-identity-source-nsx-t", + "category": "Security", + "checklist": "Azure Landing Zone Review", + "guid": "dc055bcf-619e-48a1-9f98-879525d62688", + "id": "G02.04", + "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "services": [ - "AVS", + "RBAC", + "AKV", "Entra" ], "severity": "Medium", - "subcategory": "Access", - "text": "Use LDAPS not ldap (NSX-T)", + "subcategory": "Encryption and keys", + "text": "Follow a least privilege model by limiting authorization to permanently delete keys, secrets, and certificates to specialized custom Microsoft Entra ID roles.", "waf": "Security" }, { - "category": "Identity", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "CN or SAN names, no wildcards, contains private key - CER or PFX", - "guid": "bec285ab-037e-d629-81d1-f61dac23cd4c", - "id": "C02.01", - "link": "https://youtu.be/4jvfbsrhnEs", + "category": "Security", + "checklist": "Azure Landing Zone Review", + "guid": "6d70ba6c-97be-4995-8904-83845c986cb2", + "id": "G02.05", + "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "services": [ - "AVS", - "Entra" + "AKV" ], "severity": "Medium", - "subcategory": "Security", - "text": "Security certificate installed on LDAPS servers ", + "subcategory": "Encryption and keys", + "text": "Automate the certificate management and renewal process with public certificate authorities to ease administration.", "waf": "Security" }, { - "category": "Identity", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Standard Azure Roles Based Access Controls", - "guid": "4ba394a2-3c33-104c-8e34-2dadaba9cc73", - "id": "C02.02", - "link": "https://learn.microsoft.com/azure/azure-vmware/concepts-identity", + "category": "Security", + "checklist": "Azure Landing Zone Review", + "guid": "913156a1-2476-4e49-b541-acdce979377b", + "id": "G02.06", + "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "services": [ - "AVS", - "RBAC", - "Entra" + "AKV" ], "severity": "Medium", - "subcategory": "Security", - "text": "RBAC applied to Azure roles", + "subcategory": "Encryption and keys", + "text": "Establish an automated process for key and certificate rotation.", "waf": "Security" }, { - "category": "Identity", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Create roles in vCenter required to meet minimum viable access guidelines", - "guid": "b04ca129-83a9-3494-7512-347dd2d766db", - "id": "C02.03", - "link": "https://learn.microsoft.com/azure/azure-vmware/concepts-identity#view-the-vcenter-server-privileges", + "category": "Security", + "checklist": "Azure Landing Zone Review", + "guid": "cdb3751a-b2ab-413a-ba6e-55d7d8a2adb1", + "id": "G02.07", + "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "services": [ - "AVS", - "RBAC", - "Entra" + "VNet", + "PrivateLink", + "AKV" ], "severity": "Medium", - "subcategory": "Security", - "text": "RBAC model in vCenter", + "subcategory": "Encryption and keys", + "text": "Enable firewall and virtual network service endpoint or private endpoint on the vault to control access to the key vault.", "waf": "Security" }, { - "category": "Identity", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "CloudAdmin account in vCenter IdP is used only as an emergency account (break-glass)", - "guid": "8e477d2f-8004-3dd0-93d6-0aece9e1b2fb", - "id": "C02.04", - "link": "Best practice", + "category": "Security", + "checklist": "Azure Landing Zone Review", + "guid": "17d6326a-f625-4ca4-9e56-95f2223ace8c", + "id": "G02.08", + "link": "https://learn.microsoft.com/azure/key-vault/general/monitor-key-vault", "services": [ - "AVS", - "RBAC", + "Monitor", + "AKV", "Entra" ], "severity": "Medium", - "subcategory": "Security", - "text": "CloudAdmin role usage", + "subcategory": "Encryption and keys", + "text": "Use the platform-central Azure Monitor Log Analytics workspace to audit key, certificate, and secret usage within each instance of Key Vault.", "waf": "Security" }, { - "category": "Identity", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "For roles managing the Azure VMware Solution resource in the Azure Portal (no standing permissions allowed)", - "guid": "00e0b729-f9be-f600-8c32-5ec0e8f2ed63", - "id": "C03.01", - "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-configure", + "category": "Security", + "checklist": "Azure Landing Zone Review", + "guid": "b12308ca-5017-4f15-9e3a-b3693829e7e3", + "id": "G02.09", + "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "services": [ - "AVS", - "RBAC", - "Entra" + "AzurePolicy", + "AKV" ], "severity": "Medium", - "subcategory": "Security ", - "text": "Is Privileged Identity Management implemented", + "subcategory": "Encryption and keys", + "text": "Delegate Key Vault instantiation and privileged access and use Azure Policy to enforce a consistent compliant configuration.", "waf": "Security" }, { - "category": "Identity", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "For the Azure VMware Solution PIM roles", - "guid": "0842d45f-41a8-8274-1155-2f6ed554d315", - "id": "C03.02", - "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-configure", + "category": "Security", + "checklist": "Azure Landing Zone Review", + "guid": "16183687-a047-47a2-8994-5bda43334f24", + "id": "G02.10", + "link": "https://learn.microsoft.com/azure/security/fundamentals/encryption-atrest", "services": [ - "AVS", - "RBAC", - "Entra" + "AKV" ], "severity": "Medium", - "subcategory": "Security ", - "text": "Is Privileged Identity Management audit reporting implemented", + "subcategory": "Encryption and keys", + "text": "Default to Microsoft-managed keys for principal encryption functionality and use customer-managed keys when required.", "waf": "Security" }, { - "category": "Identity", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Best practice, also see Monitoring/Alerts", - "guid": "915cbcd7-0640-eb7c-4162-9f33775de559", - "id": "C03.03", - "link": "Best practice", + "category": "Security", + "checklist": "Azure Landing Zone Review", + "guid": "91163418-2ba5-4275-8694-4008be7d7e48", + "id": "G02.11", + "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "services": [ - "AVS", - "Monitor", - "Entra" + "AKV" ], "severity": "Medium", - "subcategory": "Security ", - "text": "Limit use of CloudAdmin account to emergency access only", + "subcategory": "Encryption and keys", + "text": "Use an Azure Key Vault per application per environment per region.", "waf": "Security" }, { - "category": "Identity", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Operational procedure", - "guid": "7effa0c0-9172-e8e4-726a-67dbea8be40a", - "id": "C03.04", - "link": "https://learn.microsoft.com/azure/azure-vmware/rotate-cloudadmin-credentials?tabs=azure-portal", + "category": "Security", + "checklist": "Azure Landing Zone Review", + "guid": "25d62688-6d70-4ba6-a97b-e99519048384", + "id": "G02.12", + "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "services": [ - "AVS", - "Entra" + "ACR", + "ASR", + "AKV" ], "severity": "Medium", - "subcategory": "Security ", - "text": "Is a process defined to regularly rotate cloudadmin (vCenter) and admin (NSX) credentials", + "subcategory": "Encryption and keys", + "text": "If you want to bring your own keys, this might not be supported across all considered services. Implement relevant mitigation so that inconsistencies don't hinder desired outcomes. Choose appropriate region pairs and disaster recovery regions that minimize latency.", "waf": "Security" }, { - "category": "Management", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Use Azure ARC for Servers to properly govern workloads running on Azure VMware Solution using Azure native technologies (Azure ARC for Azure VMware Solution is not yet available)", - "guid": "8f426fd0-d73b-d398-1f6f-df0cbe262a82", - "id": "D01.01", - "link": "https://learn.microsoft.com/azure/azure-arc/vmware-vsphere/overview", + "category": "Security", + "checklist": "Azure Landing Zone Review", + "guid": "4ac6b67c-b3a4-4ff9-8e87-b07a7ce7bbdb", + "id": "G02.13", + "link": "https://learn.microsoft.com/en-us/industry/sovereignty/key-management", "services": [ - "AVS", - "VM", - "Arc" + "AKV" ], "severity": "Medium", - "subcategory": "Operations", - "text": "AVS VM Management (Azure Arc)", - "waf": "Operations" + "subcategory": "Encryption and keys", + "text": "For Sovereign Landing Zone, use Azure Key Vault managed HSM to store your secrets and credentials.", + "waf": "Security" }, { - "category": "Management", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Use Azure Policy to onboard Azure VMware Solution workloads in the Azure Management, Monitoring and Security solutions", - "guid": "11dbe773-e380-9191-1418-e886fa7a6fd0", - "id": "D01.02", - "link": "https://docs.microsoft.com/azure/governance/policy/overview", + "category": "Security", + "checklist": "Azure Landing Zone Review", + "guid": "4e5695f2-223a-4ce8-ab12-308ca5017f15", + "id": "G03.01", + "link": "https://learn.microsoft.com/azure/active-directory/reports-monitoring/overview-reports", "services": [ - "AVS", - "AzurePolicy", - "Monitor" + "Entra" ], "severity": "Medium", "subcategory": "Operations", - "text": "Azure policy", - "waf": "Operations" + "text": "Use Microsoft Entra ID reporting capabilities to generate access control audit reports.", + "waf": "Security" }, { - "category": "Management", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "For manual deployments, consider implementing resource locks to prevent accidental actions on your Azure VMware Solution Private Cloud", - "guid": "1e59c639-9b7e-a60b-5e93-3798c1aff5db", - "id": "D01.03", - "link": "https://docs.microsoft.com/azure/azure-resource-manager/management/lock-resources?tabs=json#configure-locks", + "category": "Security", + "checklist": "Azure Landing Zone Review", + "guid": "4e3ab369-3829-4e7e-9161-83687a0477a2", + "id": "G03.02", + "link": "https://learn.microsoft.com/azure/azure-monitor/logs/logs-data-export?tabs=portal", "services": [ - "AVS" + "Monitor", + "ARS", + "Storage" ], "severity": "Medium", "subcategory": "Operations", - "text": "Resource locks", - "waf": "Operations" + "text": "Export Azure activity logs to Azure Monitor Logs for long-term data retention. Export to Azure Storage for long-term storage beyond two years, if necessary.", + "waf": "Security" }, { - "category": "Management", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "For manual deployments, all configuration and deployments must be documented", - "guid": "8f2c46aa-ca1b-cad3-3ac9-213dfc0a265e", - "id": "D01.04", - "link": "Make sure to create your own runbook on the deployment of AVS.", + "ammp": true, + "category": "Security", + "checklist": "Azure Landing Zone Review", + "guid": "09945bda-4333-44f2-9911-634182ba5275", + "id": "G03.03", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/concept-cloud-security-posture-management", "services": [ - "AVS" + "Subscriptions", + "Defender" ], - "severity": "Medium", + "severity": "High", "subcategory": "Operations", - "text": "Run books", - "waf": "Operations" + "text": "Enable Defender Cloud Security Posture Management for all subscriptions.", + "waf": "Security" }, { - "category": "Management", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Implement human understandable names for ExR authorization keys to allow for easy identification of the keys purpose/use", - "guid": "86b314f9-1f1e-317a-4dfb-cf510ad4a030", - "id": "D01.05", - "link": "https://docs.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/resource-abbreviations", + "ammp": true, + "category": "Security", + "checklist": "Azure Landing Zone Review", + "guid": "36a72a48-fffe-4c40-9747-0ab5064355ba", + "id": "G03.04", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/plan-defender-for-servers-select-plan", "services": [ - "AVS", - "AKV" + "Subscriptions", + "Defender" ], - "severity": "Medium", + "severity": "High", "subcategory": "Operations", - "text": "Naming conventions for auth keys", - "waf": "Operations" + "text": "Enable a Defender Cloud Workload Protection Plan for Servers on all subscriptions.", + "waf": "Security" }, { - "category": "Monitoring", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "For automatic alerting on Azure VMware Solution performance (CPU >80%, Avg Memory >80%, vSAN >70%)", - "guid": "e22a2d99-eb71-7d7c-07af-6d4cdb1d4443", - "id": "E01.01", - "link": "https://docs.microsoft.com/azure/azure-vmware/configure-alerts-for-azure-vmware-solution", + "ammp": true, + "category": "Security", + "checklist": "Azure Landing Zone Review", + "guid": "77425f48-ecba-43a0-aeac-a3ac733ccc6a", + "id": "G03.05", + "link": "https://www.microsoft.com/en-gb/security/business/solutions/cloud-workload-protection", "services": [ - "AVS", - "Monitor" + "Subscriptions", + "Defender" ], - "severity": "Medium", - "subcategory": "Alerts", - "text": "Create warning alerts for critical thresholds ", - "waf": "Operations" + "severity": "High", + "subcategory": "Operations", + "text": "Enable Defender Cloud Workload Protection Plans for Azure Resources on all subscriptions.", + "waf": "Security" + }, + { + "ammp": true, + "category": "Security", + "checklist": "Azure Landing Zone Review", + "guid": "24d96b30-61ee-4436-a1cc-d6ef08bc574b", + "id": "G03.06", + "link": "https://learn.microsoft.com/mem/configmgr/protect/deploy-use/endpoint-protection", + "services": [], + "severity": "High", + "subcategory": "Operations", + "text": "Enable Endpoint Protection on IaaS Servers.", + "waf": "Security" }, { - "category": "Monitoring", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "for automatic alerting on Azure VMware Solution performance (CPU >80%, Avg Memory >80%, vSAN >70%)", - "guid": "6d02f159-627d-79bf-a931-fab6d947eda2", - "id": "E01.02", - "link": "https://docs.microsoft.com/azure/azure-vmware/configure-alerts-for-azure-vmware-solution", + "category": "Security", + "checklist": "Azure Landing Zone Review", + "guid": "15833ee7-ad6c-46d3-9331-65c7acbe44ab", + "id": "G03.07", + "link": "https://learn.microsoft.com/azure/security-center/", "services": [ - "AVS", - "Monitor" + "Monitor", + "Defender" ], "severity": "Medium", - "subcategory": "Alerts", - "text": "Create critical alert vSAN consumption", - "waf": "Operations" + "subcategory": "Operations", + "text": "Monitor base operating system patching drift via Azure Monitor Logs and Defender for Cloud.", + "waf": "Security" }, { - "category": "Monitoring", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Provides platform alerts (generated by Microsoft)", - "guid": "1cc97b39-2c7e-246f-6d73-789cfebfe951", - "id": "E01.03", - "link": "https://www.virtualworkloads.com/2021/04/azure-vmware-solution-azure-service-health/", + "category": "Security", + "checklist": "Azure Landing Zone Review", + "guid": "e5f8d79f-2e87-4768-924c-516775c6ea95", + "id": "G03.08", + "link": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", "services": [ - "AVS", - "Monitor" + "Monitor", + "Entra" ], "severity": "Medium", - "subcategory": "Alerts", - "text": "Configured for Azure Service Health alerts and notifications", - "waf": "Operations" + "subcategory": "Operations", + "text": "Connect default resource configurations to a centralized Azure Monitor Log Analytics workspace.", + "waf": "Security" }, { - "category": "Monitoring", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Ensure you have a documented and implemented backup policy and solution for Azure VMware Solution VM workloads", - "guid": "0962606c-e3b4-62a9-5661-e4ffd62a4509", - "id": "E02.01", - "link": "https://docs.microsoft.com/azure/azure-vmware/set-up-backup-server-for-azure-vmware-solution", + "category": "Security", + "checklist": "Azure Landing Zone Review", + "guid": "1761e147-f65e-4d09-bbc2-f464f23e2eba", + "id": "G03.09", + "link": "https://learn.microsoft.com/en-us/industry/sovereignty/transparency-logs", "services": [ - "Backup", - "AzurePolicy", - "VM", - "Monitor", - "AVS" + "Entra" ], "severity": "Medium", - "subcategory": "Backup", - "text": "Backup policy", - "waf": "Operations" + "subcategory": "Operations", + "text": "For Sovereign Landing Zone, transparancy logs is enabled on the Entra ID tenant.", + "waf": "Security" }, { - "category": "Monitoring", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Keep in mind the lead time for requesting new nodes", - "guid": "4ec7ccfb-795e-897e-4a84-fd31c04eadc6", - "id": "E03.01", - "link": "https://docs.microsoft.com/azure/azure-vmware/configure-alerts-for-azure-vmware-solution", + "category": "Security", + "checklist": "Azure Landing Zone Review", + "guid": "d21a922d-5ca7-427a-82a6-35f7b21f1bfc", + "id": "G03.10", + "link": "https://learn.microsoft.com/en-us/azure/security/fundamentals/customer-lockbox-overview", "services": [ - "AVS", - "AzurePolicy", - "Monitor" + "Entra" ], "severity": "Medium", - "subcategory": "Capacity", - "text": "Policy around ESXi host density and efficiency", - "waf": "Operations" + "subcategory": "Operations", + "text": "For Sovereign Landing Zone, customer Lockbox is enabled on the Entra ID tenant.", + "waf": "Security" }, { - "category": "Monitoring", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Azure Cost Management can be used - one option, put AVS in it's own Subscription. ", - "guid": "7f8f175d-13f4-5298-9e61-0bc7e9fcc279", - "id": "E04.01", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/azure-vmware/govern", + "ammp": true, + "category": "Security", + "checklist": "Azure Landing Zone Review", + "guid": "b03ed428-4617-4067-a787-85468b9ccf3f", + "id": "G04.01", + "link": "https://learn.microsoft.com/azure/storage/common/storage-require-secure-transfer", "services": [ - "AVS", - "Subscriptions", - "Monitor", - "Cost" + "Storage" ], - "severity": "Medium", - "subcategory": "Costs", - "text": "Ensure a good cost management process is in place for Azure VMware Solution - ", - "waf": "Operations" + "severity": "High", + "subcategory": "Overview", + "text": "Secure transfer to storage accounts should be enabled", + "waf": "Security" }, { - "category": "Monitoring", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Create dashboards to enable core Azure VMware Solution monitoring insights", - "guid": "01e689e0-7c6c-b58f-37bd-4d6b9b1b9c74", - "id": "E05.01", - "link": "https://docs.microsoft.com/azure/azure-portal/azure-portal-dashboards", + "ammp": true, + "category": "Security", + "checklist": "Azure Landing Zone Review", + "guid": "159aac9f-863f-4f48-82cf-00c28fa97a0e", + "id": "G04.02", + "link": "https://learn.microsoft.com/azure/storage/blobs/data-protection-overview#recommendations-for-basic-data-protection", "services": [ - "AVS", - "Monitor", - "NetworkWatcher" + "Storage" ], - "severity": "Medium", - "subcategory": "Dashboard", - "text": "Connection monitor dashboard", - "waf": "Operations" + "severity": "High", + "subcategory": "Overview", + "text": "Enable container soft delete for the storage account to recover a deleted container and its contents.", + "waf": "Security" }, { - "category": "Monitoring", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Send to an Azure Storage account or Azure EventHub for processing (direct to Log Analytics is pending)", - "guid": "f9afdcc9-649d-d840-9fb5-a3c0edcc697d", - "id": "E06.01", - "link": "https://docs.microsoft.com/azure/azure-vmware/configure-vmware-syslogs", + "ammp": true, + "category": "Security", + "checklist": "Azure Landing Zone Review", + "guid": "6f704104-85c1-441f-96d3-c9819911645e", + "id": "G05.01", + "link": "https://learn.microsoft.com/azure/active-directory/roles/security-planning", "services": [ - "AVS", - "Storage", - "Monitor" + "Entra" ], - "severity": "Medium", - "subcategory": "Logs & Metrics", - "text": "Configure Azure VMware Solution logging ", - "waf": "Operations" + "severity": "High", + "subcategory": "Secure privileged access", + "text": "Separate privileged admin accounts for Azure administrative tasks.", + "waf": "Security" }, { - "category": "Monitoring", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Must be on-premises, implement if available", - "guid": "7cbac8c3-4eda-d5d9-9bda-c6b5abba9fb6", - "id": "E06.02", - "link": "Is vROPS or vRealize Network Insight going to be used? ", - "services": [ - "AVS", - "Monitor" - ], + "category": "Security", + "checklist": "Azure Landing Zone Review", + "guid": "9a19bf39-c95d-444c-9c89-19ca1f6d5215", + "id": "G06.01", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/service-enablement-framework", + "services": [], "severity": "Medium", - "subcategory": "Logs & Metrics", - "text": "vRealize Operations", - "waf": "Operations" + "subcategory": "Service enablement framework", + "text": "Plan how new azure services will be implemented", + "waf": "Security" }, { - "category": "Monitoring", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Ensure workloads running on Azure VMware Solution are monitored using Azure Log Analytics and Azure Monitor", - "guid": "b243521a-644d-f865-7fb6-21f9019c0dd2", - "id": "E06.03", - "link": "https://docs.microsoft.com/azure/azure-vmware/configure-vmware-syslogs", - "services": [ - "AVS", - "VM", - "Monitor" - ], + "category": "Security", + "checklist": "Azure Landing Zone Review", + "guid": "ae514b93-3d45-485e-8112-9bd7ba012f7b", + "id": "G06.02", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/service-enablement-framework", + "services": [], "severity": "Medium", - "subcategory": "Logs & Metrics", - "text": "AVS VM logging", - "waf": "Operations" + "subcategory": "Service enablement framework", + "text": "Plan how service request will be fulfilled for Azure services", + "waf": "Security" }, { - "category": "Monitoring", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Between on-premises to Azure are monitored using 'connection monitor'", - "guid": "2ca97d91-dd36-7229-b668-01036ccc3cd3", - "id": "E07.01", - "link": "https://learn.microsoft.com/azure/network-watcher/connection-monitor-create-using-portal", - "services": [ - "VPN", - "ExpressRoute", - "NetworkWatcher", - "Monitor", - "AVS" - ], - "severity": "Medium", - "subcategory": "Network", - "text": "Monitor ExpressRoute and/or VPN connections ", + "ammp": true, + "category": "Platform Automation and DevOps", + "checklist": "Azure Landing Zone Review", + "guid": "e85f4226-bf06-4e35-8a8b-7aee4d2d633a", + "id": "H01.01", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/platform-automation-devops", + "services": [], + "severity": "High", + "subcategory": "DevOps Team Topologies", + "text": "Ensure you have a cross functional DevOps Platform Team to build, manage and maintain your Azure Landing Zone architecture.", "waf": "Operations" }, { - "category": "Monitoring", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "To monitor the Azure VMware Solution back-end ExpressRoute connection (Azure native to AVS)", - "guid": "99209143-60fe-19f0-5633-8b5671277ba5", - "id": "E07.02", - "link": "https://learn.microsoft.com/azure/network-watcher/connection-monitor-create-using-portal", - "services": [ - "AVS", - "ExpressRoute", - "Monitor" - ], - "severity": "Medium", - "subcategory": "Network", - "text": "Monitor from an Azure native resource to an Azure VMware Solution VM", + "category": "Platform Automation and DevOps", + "checklist": "Azure Landing Zone Review", + "guid": "634146bf-7085-4419-a7b5-f96d2726f6da", + "id": "H01.02", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/devops-teams-topologies#design-recommendations", + "services": [], + "severity": "Low", + "subcategory": "DevOps Team Topologies", + "text": "Aim to define functions for Azure Landing Zone Platform team.", "waf": "Operations" }, { - "category": "Monitoring", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "To monitor end-to-end, on-premises to AVS workloads", - "guid": "b9e5867c-57d3-036f-fb1b-3f0a71664efe", - "id": "E07.03", - "link": "https://learn.microsoft.com/azure/network-watcher/connection-monitor-create-using-portal", + "category": "Platform Automation and DevOps", + "checklist": "Azure Landing Zone Review", + "guid": "a9e65070-c59e-4112-8bf6-c11364d4a2a5", + "id": "H01.03", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/devops-teams-topologies#design-recommendations", "services": [ - "AVS", - "Monitor" + "RBAC" ], - "severity": "Medium", - "subcategory": "Network", - "text": "Monitor from an on-premises resource to an Azure VMware Solution VM", + "severity": "Low", + "subcategory": "DevOps Team Topologies", + "text": "Aim to define functions for application workload teams to be self-sufficient and not require DevOps Platform Team support. Achieve this through the use of custom RBAC role.", "waf": "Operations" }, { - "category": "Monitoring", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Track requests to Azure VMware Solution and Azure VMware Solution based workloads", - "guid": "4af7c5f7-e5e9-bedf-a8cf-314b81735962", - "id": "E08.01", - "link": "Firewall logging and alerting rules are configured (Azure Firewall or 3rd party)", - "services": [ - "AVS", - "Monitor" - ], - "severity": "Medium", - "subcategory": "Security", - "text": "Auditing and logging is implemented for inbound internet ", + "ammp": true, + "category": "Platform Automation and DevOps", + "checklist": "Azure Landing Zone Review", + "guid": "165eb5e9-b434-448a-9e24-178632186212", + "id": "H01.04", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/infrastructure-as-code", + "services": [], + "severity": "High", + "subcategory": "DevOps Team Topologies", + "text": "Use a CI/CD pipeline to deploy IaC artifacts and ensure the quality of your deployment and Azure environments.", "waf": "Operations" }, { - "category": "Monitoring", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Implemented for outbound internet connections from Azure VMware Solution or Azure VMware Solution based workloads to identify suspicious/malicious activity", - "guid": "74be60a3-cfac-f057-eda6-3ee087e805d5", - "id": "E08.02", - "link": "https://docs.microsoft.com/azure/cloud-adoption-framework/scenarios/azure-vmware/eslz-network-topology-connectivity", - "services": [ - "AVS", - "Monitor" - ], + "category": "Platform Automation and DevOps", + "checklist": "Azure Landing Zone Review", + "guid": "0cadb8c7-8fa5-4fbf-8f39-d1fadb3b0460", + "id": "H01.05", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/development-strategy-development-lifecycle#automated-builds", + "services": [], "severity": "Medium", - "subcategory": "Security", - "text": "Session monitoring ", + "subcategory": "DevOps Team Topologies", + "text": "Include unit tests for IaC and application code as part of your build process.", "waf": "Operations" }, { - "category": "Monitoring", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Enable Diagnostic and metric logging on Azure VMware Solution", - "guid": "a434b3b5-f258-0845-cd76-d7df6ef5890e", - "id": "E09.01", - "link": "https://docs.microsoft.com/azure/azure-vmware/configure-vmware-syslogs", + "ammp": true, + "category": "Platform Automation and DevOps", + "checklist": "Azure Landing Zone Review", + "guid": "108d5099-a11d-4445-bd8b-e12a5e95412e", + "id": "H01.06", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/development-strategy-development-lifecycle#automated-builds", "services": [ - "AVS", - "Monitor" + "VM", + "AKV" ], - "severity": "Medium", - "subcategory": "VMWare", - "text": "Logging and diagnostics", + "severity": "High", + "subcategory": "DevOps Team Topologies", + "text": "Use Key Vault secrets to avoid hard-coding sensitive information such as credentials (virtual machines user passwords), certificates or keys.", "waf": "Operations" }, { - "category": "Monitoring", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Monitor AVS workloads (each VM in AVS)", - "guid": "fb00b69a-83ec-ce72-446e-6c23a0cab09a", - "id": "E10.01", - "link": "https://docs.microsoft.com/azure/azure-monitor/agents/agent-windows?tabs=setup-wizard", + "category": "Platform Automation and DevOps", + "checklist": "Azure Landing Zone Review", + "guid": "a52e0c98-76b9-4a09-a1c9-6b2babf22ac4", + "id": "H01.07", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/subscription-vending", "services": [ - "AVS", - "VM", - "Monitor" + "Storage" ], - "severity": "Medium", - "subcategory": "VMware", - "text": "Log Analytics Agents deployed on Azure VMware Solution guest VM workloads", + "severity": "Low", + "subcategory": "DevOps Team Topologies", + "text": "Implement automation for File > New > Landing Zone for applications and workloads.", "waf": "Operations" }, { - "category": "Networking", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Decision on traffic flow", - "guid": "a1354b87-e18e-bf5c-c50b-8ddf0540e971", - "id": "F01.01", - "link": "https://learn.microsoft.com/azure/azure-vmware/concepts-hub-and-spoke", - "services": [ - "AVS" - ], - "severity": "Medium", - "subcategory": "Hub & Spoke", - "text": "North/South routing through Az Firewall or 3rd party ", - "waf": "Security" + "ammp": true, + "category": "Platform Automation and DevOps", + "checklist": "Azure Landing Zone Review", + "guid": "cfe363b5-f579-4284-bc56-a42153e4c10b", + "id": "H02.01", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/infrastructure-as-code", + "services": [], + "severity": "High", + "subcategory": "Development Lifecycle", + "text": "Ensure a version control system is used for source code of applications and IaC developed. Microsoft recommends Git.", + "waf": "Operations" }, { - "category": "Networking", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Decision to route Azure to Azure traffic through Firewall, not E/W between AVS workloads (internal to AVS)", - "guid": "29a8a499-ec31-f336-3266-0895f035e379", - "id": "F01.02", - "link": "https://learn.microsoft.com/azure/azure-vmware/concepts-hub-and-spoke", - "services": [ - "AVS" - ], - "severity": "Medium", - "subcategory": "Hub & Spoke", - "text": "East West (Internal to Azure)", - "waf": "Security" + "category": "Platform Automation and DevOps", + "checklist": "Azure Landing Zone Review", + "guid": "c7245dd4-af8a-403a-8bb7-890c1a7cfa9d", + "id": "H02.02", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/development-strategy-development-lifecycle", + "services": [], + "severity": "Low", + "subcategory": "Development Lifecycle", + "text": "Follow a branching strategy to allow teams to collaborate better and efficiently manage version control of IaC and application Code. Review options such as Github Flow.", + "waf": "Operations" }, { - "category": "Networking", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Requires a 3rd party NVA with Azure Route server - Scenario 2 (see link)", - "guid": "ebd3cc3c-ac3d-4293-950d-cecd8445a523", - "id": "F01.03", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/azure-vmware/eslz-network-topology-connectivity", - "services": [ - "AVS", - "NVA", - "ARS" - ], + "category": "Platform Automation and DevOps", + "checklist": "Azure Landing Zone Review", + "guid": "12aeea20-9165-4b3e-bdf2-6795fcd3cdbe", + "id": "H02.03", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/development-strategy-development-lifecycle", + "services": [], "severity": "Medium", - "subcategory": "Hub & Spoke", - "text": "ExR without Global Reach", + "subcategory": "Development Lifecycle", + "text": "Adopt a pull request strategy to help keep control of code changes merged into branches.", "waf": "Operations" }, { - "category": "Networking", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "When route server is used, ensure no more then 200 routes are propagated from route server to ExR gateway to on-premises (ARS limit). Important when using MoN", - "guid": "ffb5c5ca-bd89-ff1b-8b73-8a54d503d506", - "id": "F01.04", - "link": "https://learn.microsoft.com/azure/route-server/route-server-faq", - "services": [ - "AVS", - "ARS" - ], - "severity": "Medium", - "subcategory": "Hub & Spoke", - "text": "Route server ", + "ammp": true, + "category": "Platform Automation and DevOps", + "checklist": "Azure Landing Zone Review", + "guid": "2cdc9d99-dbcc-4ad4-97f5-e7d358bdfa73", + "id": "H03.01", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/infrastructure-as-code", + "services": [], + "severity": "High", + "subcategory": "Development Strategy", + "text": "Leverage Declarative Infrastructure as Code Tools such as Azure Bicep, ARM Templates or Terraform to build and maintain your Azure Landing Zone architecture. Both from a Platform and Application workload perspective.", "waf": "Operations" }, { - "category": "Networking", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Via on-premises, Az Firewall, 3rd Party, NSX-T pubic IP", - "guid": "a4070dad-3def-818d-e9f7-be440d10e7de", - "id": "F02.01", - "link": "https://learn.microsoft.com/azure/azure-vmware/concepts-design-public-internet-access", - "services": [ - "AVS" - ], - "severity": "Medium", - "subcategory": "Internet", - "text": "Egress point(s)", - "waf": "Security" + "ammp": true, + "category": "Platform Automation and DevOps", + "checklist": "Azure Landing Zone Review", + "guid": "cc87a3bc-c572-4ad2-92ed-8cabab66160f", + "id": "H04.01", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/landing-zone-security#secure", + "services": [], + "severity": "High", + "subcategory": "Security", + "text": "Integrate security into the already combined process of development and operations in DevOps to mitigate risks in the innovation process.", + "waf": "Operations" }, { - "category": "Networking", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Az Firewall, 3rd party NVA, Application Gateway, Azure Frontdoor ", - "guid": "e942c03d-beaa-3d9f-0526-9b26cd5e9937", - "id": "F02.02", - "link": "Research and choose optimal solution for each application", + "category": "Business", + "checklist": "Multitenant architecture", + "guid": "41177955-fe8f-430b-ae72-20dc5b6880da", + "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/overview", "services": [ - "AVS", - "FrontDoor", - "NVA", - "AppGW" + "Entra" ], - "severity": "Medium", - "subcategory": "Internet", - "text": "Internet facing applications", - "waf": "Security" + "severity": "High", + "subcategory": "Business", + "text": "Understand what kind of solution you're creating, such as business-to-business (B2B), business-to-consumer (B2C), or your enterprise software, and how tenants are different from users." + }, + { + "category": "Business", + "checklist": "Multitenant architecture", + "guid": "2d33d1b7-697c-49f9-b944-afbeac0b2c8f", + "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/considerations/tenancy-models", + "services": [], + "severity": "High", + "subcategory": "Business", + "text": "Define your tenants. Understand how many tenants you will support initially, and your growth plans." + }, + { + "category": "Business", + "checklist": "Multitenant architecture", + "guid": "a2111b8b-cc66-4aa2-9da6-c09fa23851b6", + "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/considerations/pricing-models", + "services": [], + "severity": "High", + "subcategory": "Business", + "text": "Define your pricing model and ensure it aligns with your tenants' consumption of Azure resources." }, { - "category": "Networking", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Ensure no more then 200 routes are propagated from route server to ExR gateway to on-premises (ARS limit). Important when using MoN", - "guid": "e778a2ec-b4d7-1d27-574c-14476b167d37", - "id": "F03.01", - "link": "https://docs.microsoft.com/azure/route-server/route-server-faq#route-server-limits", - "services": [ - "AVS", - "ARS" - ], + "category": "Business", + "checklist": "Multitenant architecture", + "guid": "331e84a6-2d65-4359-92ff-a1870b062995", + "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/considerations/pricing-models", + "services": [], "severity": "Medium", - "subcategory": "Routing", - "text": "When route server Route limit understood? ", - "waf": "Security" + "subcategory": "Business", + "text": "Understand whether you need to separate your tenants into different tiers. Tiers might have different pricing, features, performance promises, geographic locations, and so forth." }, { - "category": "Networking", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "(VPN Gateway, AppGW, FrontDoor, Load balancer, VMs (etc) (Remove: enabled on ExR/VPN Gateway subnet in Azure)", - "guid": "66c97b30-81b9-139a-cc76-dd1d94aef42a", - "id": "F04.01", - "link": "https://docs.microsoft.com/azure/ddos-protection/manage-ddos-protection", - "services": [ - "FrontDoor", - "VPN", - "DDoS", - "ExpressRoute", - "LoadBalancer", - "VM", - "AVS", - "VNet", - "AppGW" - ], + "category": "Business", + "checklist": "Multitenant architecture", + "guid": "90516b37-aab1-46ca-95bb-cc14a6a1608b", + "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/considerations/tenancy-models", + "services": [], "severity": "Medium", - "subcategory": "Security", - "text": "Is DDoS standard protection of public facing IP addresses? ", - "waf": "Security" + "subcategory": "Business", + "text": "Based on your customers' requirements, decide on the tenancy models that are appropriate for various parts of your solution." }, { - "category": "Networking", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "To manage Azure VMware Solution, vCenter, NSX manager and HCX manager", - "guid": "d43da920-4ecc-a4e9-dd45-a2986ce81d32", - "id": "F04.02", - "link": "Best practice: Bastion or 3rd party tool", + "category": "Business", + "checklist": "Multitenant architecture", + "guid": "f5d76ae1-7048-4ff5-abba-f1ca799578b9", + "link": "https://learn.microsoft.com/azure/marketplace/plan-saas-offer", "services": [ - "AVS" + "Entra" ], "severity": "Medium", - "subcategory": "Security", - "text": "Use a dedicated privileged access workstation (PAW)", - "waf": "Security" + "subcategory": "Business", + "text": "When you're ready, sell your B2B multitenant solution using the Microsoft Commercial Marketplace." }, { - "category": "Networking", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Use NSX-T for inter-vmware-traffic inspection", - "guid": "a2dac74f-5380-6e39-25e6-f13b99ece51f", - "id": "F05.01", - "link": "https://docs.vmware.com/en/VMware-NSX-T-Data-Center/3.2/administration/GUID-F6685367-7AA1-4771-927E-ED77727CFDA3.html", - "services": [ - "AVS" - ], - "severity": "Medium", - "subcategory": "Traffic Inspection", - "text": "East West (Internal to AVS)", - "waf": "Security" + "category": "Reliability", + "checklist": "Multitenant architecture", + "guid": "9e7cedd9-1e05-4aeb-a7b3-01fe695a394c", + "link": "https://learn.microsoft.com/azure/architecture/framework/resiliency/design-checklist", + "services": [], + "severity": "High", + "subcategory": "Reliability", + "text": "Review the Azure Well-Architected Reliability checklist, which is applicable to all workloads." }, { - "category": "Networking", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Decision on whether or not to use Secure hub for E/W and Internet traffic - requires Global Reach", - "guid": "3f621543-dfac-c471-54a6-7b2849b6909a", - "id": "F06.01", - "link": "https://learn.microsoft.com/azure/architecture/networking/hub-spoke-vwan-architecture", - "services": [ - "AVS", - "Firewall", - "VWAN" - ], - "severity": "Medium", - "subcategory": "Virtual WAN", - "text": "Use Secure Hub (Azure Firewall or 3rd party)", - "waf": "Security" + "category": "Reliability", + "checklist": "Multitenant architecture", + "guid": "e9521a55-2a7c-425c-8f3e-c38fd0c4df75", + "link": "https://learn.microsoft.com/azure/architecture/antipatterns/noisy-neighbor/noisy-neighbor", + "services": [], + "severity": "High", + "subcategory": "Reliability", + "text": "Understand the Noisy Neighbor antipattern. Prevent individual tenants from impacting the system's availability for other tenants." }, { - "category": "Networking", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Decision to route Azure to Azure traffic through Firewall, not E/W between AVS workloads (internal to AVS)", - "guid": "d7af5670-1b39-d95d-6da2-8d660dfbe16b", - "id": "F06.02", - "link": "https://learn.microsoft.com/azure/firewall-manager/secure-cloud-network", - "services": [ - "AVS", - "VWAN" - ], + "category": "Reliability", + "checklist": "Multitenant architecture", + "guid": "2b99cb00-9abb-49b6-b11c-f2af9692f09e", + "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/approaches/overview", + "services": [], "severity": "Medium", - "subcategory": "Virtual WAN", - "text": "East West (Internal to Azure)", - "waf": "Security" + "subcategory": "Reliability", + "text": "Design your multitenant solution for the level of growth that you expect. But don't overengineer for unrealistic growth." }, { - "category": "Other Services/Operations", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "When intending to use automated scale-out, be sure to apply for sufficient Azure VMware Solution quota for the subscriptions running Azure VMware Solution", - "guid": "7d049005-eb35-4a93-50a5-3b31a9f61161", - "id": "G01.01", - "link": "https://docs.microsoft.com/azure/azure-vmware/configure-nsx-network-components-azure-portal", - "services": [ - "AVS", - "Subscriptions" - ], + "category": "Reliability", + "checklist": "Multitenant architecture", + "guid": "7a634a0e-1c9d-42b1-aac2-5a5378f103f1", + "link": "https://learn.microsoft.com/azure/architecture/framework/resiliency/business-metrics", + "services": [], "severity": "Medium", - "subcategory": "Automated Scale", - "text": "Scale out operations planning", - "waf": "Performance" + "subcategory": "Reliability", + "text": "Define service-level objectives (SLOs) and optionally service-level agreements (SLAs) for your solution. SLAs and SLOs should be based on the requirements of your tenants, as well as the composite SLA of the Azure resources in your architecture." }, { - "category": "Other Services/Operations", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "When intending to use automated scale-in, be sure to take storage policy requirements into account before performing such action", - "guid": "7242c1de-da37-27f3-1ddd-565ccccb8ece", - "id": "G01.02", - "link": "https://docs.microsoft.com/azure/cloud-adoption-framework/scenarios/azure-vmware/eslz-platform-automation-and-devops#automated-scale", - "services": [ - "AVS", - "AzurePolicy", - "Storage" - ], - "severity": "Medium", - "subcategory": "Automated Scale", - "text": "Scale in operations planning", - "waf": "Performance" + "category": "Reliability", + "checklist": "Multitenant architecture", + "guid": "45beeeaf-fc59-4079-8fca-65d5724abaa7", + "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/approaches/compute", + "services": [], + "severity": "High", + "subcategory": "Reliability", + "text": "Test the scale of your solution. Ensure that it performs well under all levels of load, and that it scales correctly as the number of tenants increases." }, { - "category": "Other Services/Operations", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Scaling operations always need to be serialized within a single SDDC as only one scale operation can be performed at a time (even when multiple clusters are used)", - "guid": "3233e49e-62ce-97f3-8737-8230e771b694", - "id": "G01.03", - "link": "https://docs.microsoft.com/azure/cloud-adoption-framework/scenarios/azure-vmware/eslz-platform-automation-and-devops#automated-scale", - "services": [ - "AVS" - ], + "category": "Reliability", + "checklist": "Multitenant architecture", + "guid": "2ff55551-984b-4606-95eb-bfb9c8b36761", + "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/approaches/compute", + "services": [], "severity": "Medium", - "subcategory": "Automated Scale", - "text": "Scale serialized operations planning", - "waf": "Performance" + "subcategory": "Reliability", + "text": "Apply chaos engineering principles to test the reliability of your solution." }, { - "category": "Other Services/Operations", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Consider and validate scaling operations on 3rd party solutions used in the architecture (supported or not)", - "guid": "68161d66-5707-319b-e77d-9217da892593", - "id": "G01.04", - "link": "Best practice (testing)", - "services": [ - "AVS" - ], - "severity": "Medium", - "subcategory": "Automated Scale", - "text": "Scale rd operations planning", - "waf": "Performance" + "category": "Security", + "checklist": "Multitenant architecture", + "guid": "8238c038-8eb2-4a02-8bd5-4908c9442c1c", + "link": "https://learn.microsoft.com/security/zero-trust", + "services": [], + "severity": "High", + "subcategory": "Security", + "text": "Apply the Zero Trust and least privilege principles in all layers of your solution." }, { - "category": "Other Services/Operations", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Define and enforce scale in/out maximum limits for your environment in the automations", - "guid": "c32cb953-e860-f204-957a-c79d61202669", - "id": "G01.05", - "link": "Operational planning - understand workload requirements", + "category": "Security", + "checklist": "Multitenant architecture", + "guid": "92160e00-6894-4102-97e0-615d4ed93c01", + "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/considerations/map-requests", "services": [ - "AVS" + "Entra" ], - "severity": "Medium", - "subcategory": "Automated Scale", - "text": "Scale maximum operations planning", - "waf": "Performance" + "severity": "High", + "subcategory": "Security", + "text": "Ensure that you can correctly map user requests to tenants. Consider including the tenant context as part of the identity system, or by using another means, like application-level tenant authorization." }, { - "category": "Other Services/Operations", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Implement monitoring rules to monitor automated scaling operations and monitor success and failure to enable appropriate (automated) responses", - "guid": "7bd65a5e-7b5d-652d-dbea-fc6f73a42857", - "id": "G01.06", - "link": "https://docs.microsoft.com/azure/cloud-adoption-framework/scenarios/azure-vmware/eslz-management-and-monitoring", - "services": [ - "AVS", - "Monitor" - ], + "category": "Security", + "checklist": "Multitenant architecture", + "guid": "3c1538b4-5676-4b85-b451-432befb37b4f", + "link": "https://learn.microsoft.com/azure/security/fundamentals/pen-testing", + "services": [], "severity": "Medium", - "subcategory": "Automated Scale", - "text": "Monitor scaling operations ", - "waf": "Performance" + "subcategory": "Security", + "text": "Perform ongoing penetration testing and security code reviews." }, { - "category": "Other Services/Operations", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Consider the use of Azure Private-Link when using other Azure Native Services", - "guid": "95e374af-8a2a-2672-7ab7-b4a1be43ada7", - "id": "G02.01", - "link": "https://learn.microsoft.com/azure/private-link/private-link-overview", - "services": [ - "AVS", - "PrivateLink" - ], - "severity": "Medium", - "subcategory": "Networking", - "text": "Private link", - "waf": "Performance" + "category": "Security", + "checklist": "Multitenant architecture", + "guid": "5fca45ce-cf2d-42c0-a62c-aac92ba31498", + "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/approaches/governance-compliance", + "services": [], + "severity": "High", + "subcategory": "Security", + "text": "Understand your tenants' compliance requirements, including data residency and any compliance or regulatory standards that they require you to meet." }, { - "category": "Other Services/Operations", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "When performing automated configuration of NSX-T segments with a single Tier-1 gateway, use Azure Portal APIs instead of NSX-Manager APIs", - "guid": "71eff90d-5ad7-ac60-6244-2a6f7d3c51f2", - "id": "G02.02", - "link": "Best practice", + "category": "Security", + "checklist": "Multitenant architecture", + "guid": "30adb90d-83d4-4a2e-986e-327ffe04e7a5", + "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/considerations/domain-names", "services": [ - "AVS" + "DNS" ], - "severity": "Medium", - "subcategory": "Networking", - "text": "Provisioning Vmware VLANs", - "waf": "Performance" + "severity": "High", + "subcategory": "Security", + "text": "Correctly manage domain names and avoid vulnerabilities like dangling DNS and subdomain takeover attacks." }, { - "category": "Planning", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "In which region will AVS be deployed", - "guid": "04e3a2f9-83b7-968a-1044-2811811a924b", - "id": "H01.01", - "link": "https://learn.microsoft.com/windows-server/identity/ad-ds/plan/understanding-active-directory-site-topology", - "services": [ - "AVS" - ], + "category": "Security", + "checklist": "Multitenant architecture", + "guid": "72ded36d-c633-4e0d-bd41-799a29da3481", + "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/service/overview", + "services": [], "severity": "Medium", - "subcategory": "Pre-deployment", - "text": "Region selected", - "waf": "Reliability" + "subcategory": "Security", + "text": "Follow service-specific guidance for multitenancy." }, { - "category": "Planning", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Are there regulatory or compliance policies in play", - "guid": "e52d1615-9cc6-565c-deb6-743ed7e90f4b", - "id": "H01.02", - "link": "Internal policy or regulatory compliance", + "category": "Cost Optimization", + "checklist": "Multitenant architecture", + "guid": "db30a9fc-9b1d-40f3-ab90-01f6a3e87fc8", + "link": "https://learn.microsoft.com/azure/architecture/framework/cost/design-checklist", "services": [ - "AVS", - "AzurePolicy" + "Cost" ], "severity": "Medium", - "subcategory": "Pre-deployment", - "text": "Data residency compliant with selected regions", - "waf": "Reliability" + "subcategory": "Cost Optimization", + "text": "Review the Azure Well-Architected Operational Excellence checklist, which is applicable to all workloads." }, { - "category": "Planning", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Request through the support blade", - "guid": "92bd5ad6-441f-a983-7aa9-05dd669d760b", - "id": "H01.03", - "link": "https://learn.microsoft.com/azure/migrate/concepts-azure-vmware-solution-assessment-calculation", + "category": "Cost Optimization", + "checklist": "Multitenant architecture", + "guid": "8533af39-52f6-45b6-a9c3-81b2a54a31e0", + "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/considerations/measure-consumption", "services": [ - "AVS" + "Cost" ], - "severity": "Medium", - "subcategory": "Pre-deployment", - "text": "Request for number of AVS hosts submitted ", - "waf": "Reliability" + "severity": "High", + "subcategory": "Cost Optimization", + "text": "Ensure you can adequately measure per-tenant consumption and correlate it with your infrastructure costs." }, { - "category": "Planning", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "PG approval for deployment", - "guid": "28370f63-1cb8-2e35-907f-c5516b6954fa", - "id": "H01.04", - "link": "Support request through portal or get help from Account Team", + "category": "Cost Optimization", + "checklist": "Multitenant architecture", + "guid": "c851fd44-7cf1-459c-95a4-f6455d75a981", + "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/approaches/cost-management-allocation", "services": [ - "AVS" + "Monitor", + "Cost" ], "severity": "Medium", - "subcategory": "Pre-deployment", - "text": "Region and number of AVS nodes approved", - "waf": "Reliability" + "subcategory": "Cost Optimization", + "text": "Avoid antipatterns. Antipatterns include failing to track costs, tracking costs with unnecessary precision, real-time measurement, and using monitoring tools for billing." }, { - "category": "Planning", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Portal/subscription/resource providers/ Microsoft.AVS", - "guid": "96c76997-30a6-bb92-024d-f4f93f5f57fa", - "id": "H01.05", - "link": "Done through the subscription/resource providers/ AVS register in the portal", - "services": [ - "AVS", - "Subscriptions" - ], - "severity": "Medium", - "subcategory": "Pre-deployment", - "text": "Resource provider for AVS registered", - "waf": "Reliability" + "category": "Operational Excellence", + "checklist": "Multitenant architecture", + "guid": "0d475a5a-2c0f-47ab-b1e1-701da68d3407", + "link": "https://learn.microsoft.com/azure/architecture/checklist/data-ops", + "services": [], + "severity": "High", + "subcategory": "Operational Excellence", + "text": "Review the Azure Well-Architected Operational Excellence checklist, which is applicable to all workloads." }, { - "category": "Planning", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Connectivity, subscription & governanace model", - "guid": "5898e3ff-5e6b-bee1-6f85-22fee261ce63", - "id": "H01.06", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/azure-vmware/enterprise-scale-landing-zone", - "services": [ - "AVS", - "Subscriptions" - ], + "category": "Operational Excellence", + "checklist": "Multitenant architecture", + "guid": "9f7fa7a9-47fc-4f04-81f6-9f9e87571ed3", + "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/considerations/tenant-lifecycle", + "services": [], "severity": "Medium", - "subcategory": "Pre-deployment", - "text": "Landing zone architecture", - "waf": "Reliability" + "subcategory": "Operational Excellence", + "text": "Use automation to manage the tenant lifecycle, such as onboarding, deployment, provisioning, and configuration." }, { - "category": "Planning", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "The name of the RG where AVS will exist", - "guid": "d0181fb8-9cb8-bf4b-f5e5-b5f9bf7ae4ea", - "id": "H01.07", - "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/manage-resource-groups-portal", - "services": [ - "AVS" - ], + "category": "Operational Excellence", + "checklist": "Multitenant architecture", + "guid": "e0bfceed-4f4e-492d-b9f5-898815faa363", + "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/considerations/updates", + "services": [], "severity": "Medium", - "subcategory": "Pre-deployment", - "text": "Resource group name selected", - "waf": "Reliability" + "subcategory": "Operational Excellence", + "text": "Find the right balance for deploying service updates. Consider both your tenants' requirements and your own operational requirements." }, { - "category": "Planning", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Each resource created as part of the deployment will also utilize this prefix in the name", - "guid": "0f0d20c2-5a19-726c-de20-0984e070d9d6", - "id": "H01.08", - "link": "Best practice - naming standards", + "category": "Operational Excellence", + "checklist": "Multitenant architecture", + "guid": "a3f80518-d428-4c02-b2cc-dfaef47db7e2", "services": [ - "AVS" + "Monitor" ], - "severity": "Medium", - "subcategory": "Pre-deployment", - "text": "Deployment prefix selected", - "waf": "Reliability" + "severity": "High", + "subcategory": "Operational Excellence", + "text": "Monitor the health of the overall system, as well as each tenant." }, { - "category": "Planning", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "/22 unique non-overlapping IPv4 address space", - "guid": "7fbf2ab7-a36c-5957-c27a-67038557af2a", - "id": "H01.09", - "link": "https://learn.microsoft.com/azure/azure-vmware/tutorial-network-checklist#routing-and-subnet-considerations", + "category": "Operational Excellence", + "checklist": "Multitenant architecture", + "guid": "dfb42da5-f871-4953-9e5c-da6fda3f1411", "services": [ - "AVS" + "Monitor" ], "severity": "Medium", - "subcategory": "Pre-deployment", - "text": "Network space for AVS management layer", - "waf": "Reliability" + "subcategory": "Operational Excellence", + "text": "Configure and test alerts to notify you when specific tenants are experiencing issues or are exceeding their consumption limits." }, { - "category": "Planning", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "vNets used by workloads running in AVS (non-stretched)", - "guid": "0c87f999-e517-21ef-f355-f210ad4134d2", - "id": "H01.10", - "link": "https://docs.vmware.com/en/VMware-NSX-T-Data-Center/3.2/installation/GUID-4B3860B8-1883-48CA-B2F3-7C2205D91D6D.html", - "services": [ - "AVS", - "VNet" - ], - "severity": "Medium", - "subcategory": "Pre-deployment", - "text": "Network space for AVS NSX-T segments", - "waf": "Reliability" + "category": "Operational Excellence", + "checklist": "Multitenant architecture", + "guid": "c0c72a1b-e34d-4b3d-b808-2e49f51ce47e", + "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/approaches/resource-organization", + "services": [], + "severity": "High", + "subcategory": "Operational Excellence", + "text": "Organize your Azure resources for isolation and scale." }, { - "category": "Planning", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Choose AV36, AV36P, AV52, AV36T (AV36T = Trial)", - "guid": "946c8966-f902-6f53-4f37-00847e8895c2", - "id": "H01.11", - "link": "https://azure.microsoft.com/pricing/details/azure-vmware/", - "services": [ - "AVS" - ], + "category": "Operational Excellence", + "checklist": "Multitenant architecture", + "guid": "c5c5e22d-4b51-4cac-a980-f7aac1a4b427", + "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/approaches/deployment-configuration", + "services": [], "severity": "Medium", - "subcategory": "Pre-deployment", - "text": "AVS SKU (region dependent)", - "waf": "Performance" + "subcategory": "Operational Excellence", + "text": "Avoid deployment and configuration antipatterns. Antipatterns include running separate versions of the solution for each tenant, hardcoding tenant-specific configurations or logic, and manual deployments." + }, + { + "category": "Performance Efficiency", + "checklist": "Multitenant architecture", + "guid": "f0b1fbd8-689c-4ab3-be1d-ad7607d2fbfd", + "link": "https://learn.microsoft.com/azure/architecture/framework/scalability/performance-efficiency", + "services": [], + "severity": "High", + "subcategory": "Performance Efficiency", + "text": "Review the Azure Well-Architected Performance Efficiency checklist, which is applicable to all workloads." }, { - "category": "Planning", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Use the Azure migration assessment tool to determine the minimum number of nodes required (consider BCDR as well)", - "guid": "31833808-26ba-9c31-416f-d54a89a17f5d", - "id": "H01.12", - "link": "https://learn.microsoft.com/azure/migrate/how-to-assess", - "services": [ - "AVS" - ], - "severity": "Medium", - "subcategory": "Pre-deployment", - "text": "Number of hosts to be deployed", - "waf": "Performance" + "category": "Performance Efficiency", + "checklist": "Multitenant architecture", + "guid": "18911c4c-934c-49a8-839a-60c092afce30", + "link": "https://learn.microsoft.com/azure/architecture/antipatterns/noisy-neighbor/noisy-neighbor", + "services": [], + "severity": "High", + "subcategory": "Performance Efficiency", + "text": "If you use shared infrastructure, plan for how you'll mitigate Noisy Neighbor concerns. Ensure that one tenant can't reduce the performance of the system for other tenants." }, { - "category": "Planning", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Understand how and if you should be using reserved instances (cost control)", - "guid": "f2b73c4f-3d46-32c9-5df1-5b8dfcd3947f", - "id": "H01.13", - "link": "https://azure.microsoft.com/en-ca/pricing/details/azure-vmware/#:~:text=Azure%20VMware%20Solution%20%20%20%20Instance%20size,TB%20%28all%20NVMe%29%20%20%20N%2FA%20%2Fhour%20", + "category": "Performance Efficiency", + "checklist": "Multitenant architecture", + "guid": "6acf7eb5-24a3-47c7-ae87-1196cd96048e", + "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/approaches/compute", "services": [ - "AVS", - "Cost" + "Storage" ], "severity": "Medium", - "subcategory": "Pre-deployment", - "text": "Reserverd Instances", - "waf": "Cost" + "subcategory": "Performance Efficiency", + "text": "Determine how you'll scale your compute, storage, networking, and other Azure resources to match the demands of your tenants." }, { - "category": "Planning", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Ensure that you have requested enough quota, ensuring you have considered growth and Disaster Recovery requirement", - "guid": "94ac48ab-ade5-3fa7-f800-263feeb97070", - "id": "H01.14", - "link": "https://docs.microsoft.com/azure/azure-vmware/concepts-storage#storage-policies-and-fault-tolerance", + "category": "Performance Efficiency", + "checklist": "Multitenant architecture", + "guid": "ea55400d-f97d-45aa-b71b-34224bf91ed4", + "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/approaches/resource-organization", + "services": [], + "severity": "High", + "subcategory": "Performance Efficiency", + "text": "Consider each Azure resource's scale limits. Organize your resources appropriately, in order to avoid resource organization antipatterns. For example, don't over-architect your solution to work within unrealistic scale requirements." + }, + { + "category": "Security", + "checklist": "Azure Event Hub Review", + "description": "Azure Event Hub provides encryption of data at rest. If you use your own key, the data is still encrypted using the Microsoft-managed key, but in addition the Microsoft-managed key will be encrypted using the customer-managed key. ", + "guid": "7aaf12e7-b94e-4f6e-847d-2d92981b1cd6", + "link": "https://learn.microsoft.com/azure/event-hubs/configure-customer-managed-key", "services": [ - "AVS", - "ASR" + "EventHubs" ], - "severity": "Medium", - "subcategory": "Pre-deployment", - "text": "Capacity ", - "waf": "Performance" + "severity": "Low", + "subcategory": "Data Protection", + "text": "Use customer-managed key option in data at rest encryption when required", + "training": "https://learn.microsoft.com/learn/modules/plan-implement-administer-conditional-access/" }, { - "category": "Planning", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Identify which of the networking scenarios make ", - "guid": "1f9d4bd5-14b8-928c-b4cb-eb211f9b8de5", - "id": "H01.15", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/azure-vmware/eslz-network-topology-connectivity", + "category": "Security", + "checklist": "Azure Event Hub Review", + "description": "Azure Event Hubs namespaces permit clients to send and receive data with TLS 1.0 and above. To enforce stricter security measures, you can configure your Event Hubs namespace to require that clients send and receive data with a newer version of TLS. If an Event Hubs namespace requires a minimum version of TLS, then any requests made with an older version will fail. ", + "guid": "d2f54b29-769e-43a6-a0e7-828ac936657e", + "link": "https://learn.microsoft.com/azure/event-hubs/transport-layer-security-configure-minimum-version", "services": [ - "AVS" + "EventHubs" ], "severity": "Medium", - "subcategory": "Pre-deployment", - "text": "Networking & Connectivity See docs describing scenrario 1 through 5", - "waf": "Reliability" + "subcategory": "Data Protection", + "text": "Enforce a minimum required version of Transport Layer Security (TLS) for requests ", + "training": "https://learn.microsoft.com/learn/modules/secure-aad-users-with-mfa/" }, { - "category": "Planning", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Ensure that access constraints to ESXi are understood, there are access limits which might affect 3rd party solutions.", - "guid": "070db19b-8a2a-fd6a-c39b-4488d8780da9", - "id": "H01.16", - "link": "Please Check Partner Ecosystem", + "category": "Security", + "checklist": "Azure Event Hub Review", + "description": "When you create an Event Hubs namespace, a policy rule named RootManageSharedAccessKey is automatically created for the namespace. This policy has manage permissions for the entire namespace. It’s recommended that you treat this rule like an administrative root account and don’t use it in your application. Using AAD as an authentication provider with RBAC is recommended. ", + "guid": "13b0f566-4b1e-4944-a459-837ee79d6c6d", + "link": "https://learn.microsoft.com/azure/event-hubs/authorize-access-shared-access-signature#shared-access-authorization-policies", "services": [ - "AVS" + "TrafficManager", + "AzurePolicy", + "RBAC", + "EventHubs", + "Entra" ], "severity": "Medium", - "subcategory": "Pre-deployment", - "text": "3rd party application compatibility ", - "waf": "Reliability" + "subcategory": "Identity and Access Management", + "text": "Avoid using root account when it is not necessary", + "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-identities-governance/" }, { "category": "Security", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "When in-guest encryption is used, store encryption keys in Azure Key vault when possible", - "guid": "70cfbddc-d3d4-9188-77c8-1cabaefef646", - "id": "I01.01", - "link": "General recommendation for storing encryption keys.", + "checklist": "Azure Event Hub Review", + "description": "Managed identities for Azure resources can authorize access to Event Hubs resources using Azure AD credentials from applications running in Azure Virtual Machines (VMs), Function apps, Virtual Machine Scale Sets, and other services. By using managed identities for Azure resources together with Azure AD authentication, you can avoid storing credentials with your applications that run in the cloud. ", + "guid": "3a365a5c-7acb-4e48-abd5-4cd79f2e8776", + "link": "https://learn.microsoft.com/azure/event-hubs/authenticate-managed-identity?tabs=latest", "services": [ - "AVS", - "AKV" + "VM", + "AKV", + "Storage", + "EventHubs", + "Entra" ], "severity": "Medium", - "subcategory": "Encryption", - "text": "Use Azure Key Vault with in-guest encryption ", - "waf": "Security" + "subcategory": "Identity and Access Management", + "text": "When possible, your application should be using a managed identity to authenticate to Azure Event Hub. If not, consider having the storage credential (SAS, service principal credential) in Azure Key Vault or an equivalent service", + "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/" }, { "category": "Security", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Ensure workloads on Azure VMware Solution use sufficient data encryption during run-time (like in-guest disk encryption and SQL TDE). (vSAN encryption at rest is default)", - "guid": "c1a81638-18df-0ce9-a73a-4b9a8a8dd392", - "id": "I01.02", - "link": "https://docs.microsoft.com/azure/azure-vmware/concepts-storage#data-at-rest-encryption", + "checklist": "Azure Event Hub Review", + "description": "When creating permissions, provide fine-grained control over a client's access to Azure Event Hub. Permissions in Azure Event Hub can and should be scoped to the individual resource level e.g. consumer group, event hub entity, event hub namespaces, etc.", + "guid": "8357c559-675c-45ee-a5b8-6ad8844ce3b2", + "link": "https://learn.microsoft.com/azure/event-hubs/authorize-access-azure-active-directory#azure-built-in-roles-for-azure-event-hubs", "services": [ - "AVS", - "SQL" + "RBAC", + "EventHubs", + "Entra" ], - "severity": "Medium", - "subcategory": "Encryption", - "text": "Use in-guest encryption", - "waf": "Security" + "severity": "High", + "subcategory": "Identity and Access Management", + "text": "Use least privilege data plane RBAC", + "training": "https://learn.microsoft.com/learn/modules/explore-basic-services-identity-types/" }, { "category": "Security", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Use Key vault to store secrets and authorization keys when separate Service Principles are used for deploying Azure VMware Solution and ExpressRoute", - "guid": "8d0a8f51-8d35-19cd-c2fe-4e3512fb467e", - "id": "I01.03", - "link": "https://docs.microsoft.com/azure/key-vault/general/authentication", + "checklist": "Azure Event Hub Review", + "description": "Azure Event Hub resource logs include operational logs, virtual network and Kafka logs. Runtime audit logs capture aggregated diagnostic information for all data plane access operations (such as send or receive events) in Event Hubs.", + "guid": "b38b875b-a1cf-4104-a900-3a4d3ce474db", + "link": "https://learn.microsoft.com/azure/event-hubs/monitor-event-hubs-reference", "services": [ - "AVS", - "ExpressRoute", - "AKV" + "Monitor", + "EventHubs", + "VNet" ], "severity": "Medium", - "subcategory": "Encryption", - "text": "Keyvault use for secrets", - "waf": "Security" + "subcategory": "Monitoring", + "text": "Enable logging for security investigation. Use Azure Monitor to captured metrics and logs such as resource logs, runtime audit logs and Kafka logs", + "training": "https://learn.microsoft.com/learn/paths/manage-identity-and-access/" }, { "category": "Security", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Older OS security patching configured for workloads running on Azure VMware Solution are eligible for ESU", - "guid": "4f8b20e9-a2a1-f80f-af9b-8aa3b26dca08", - "id": "I02.01", - "link": "https://docs.microsoft.com/windows-server/get-started/extended-security-updates-deploy", + "checklist": "Azure Event Hub Review", + "description": "Azure Event Hub by default has a public IP address and is Internet-reachable. Private endpoints allow traffic between your virtual network and Azure Event Hub traverses over the Microsoft backbone network. In addition to that, you should disable public endpoints if those are not used. ", + "guid": "5abca2a4-eda1-4dae-8cc9-5d48c6b791dc", + "link": "https://learn.microsoft.com/azure/event-hubs/private-link-service", "services": [ - "AVS" + "EventHubs", + "PrivateLink", + "VNet" ], "severity": "Medium", - "subcategory": "Extended support", - "text": "Ensure extended security update support ", - "waf": "Security" + "subcategory": "Networking", + "text": "Consider using private endpoints to access Azure Event Hub and disable public network access when applicable.", + "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/" }, { "category": "Security", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Use a SIEM/SOAR", - "guid": "9bb22fec-4d00-3b95-7136-e225d0f5c63a", - "id": "I03.01", - "link": "https://learn.microsoft.com/azure/sentinel/overview", + "checklist": "Azure Event Hub Review", + "description": "With IP firewall, you can restrict public endpoint further to only a set of IPv4 addresses or IPv4 address ranges in CIDR (Classless Inter-Domain Routing) notation. ", + "guid": "a0e6c465-89e5-458b-a37d-3974d1112dbd", + "link": "https://learn.microsoft.com/azure/event-hubs/event-hubs-ip-filtering", "services": [ - "AVS", - "Sentinel" + "EventHubs" ], "severity": "Medium", - "subcategory": "Investigation", - "text": "Enable Azure Sentinel or 3rd party SIEM ", - "waf": "Security" + "subcategory": "Networking", + "text": "Consider only allowing access to Azure Event Hub namespace from specific IP addresses or ranges", + "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/" }, { - "category": "Security", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "MS Defender For Cloud, for workloads running on Azure VMware Solution", - "guid": "f42b0b09-c591-238a-1580-2de3c485ebd2", - "id": "I04.01", - "link": "https://learn.microsoft.com/azure/azure-vmware/azure-security-integration#prerequisites", + "category": "Management", + "checklist": "Azure API Management Review", + "guid": "06862505-2d9a-4874-9491-2837b00a3475", + "link": "https://learn.microsoft.com/azure/api-management/backends", "services": [ - "AVS", - "Defender" + "APIM" ], "severity": "Medium", - "subcategory": "Security", - "text": "Enable Advanced Threat Detection ", - "waf": "Security" + "subcategory": "Best practices", + "text": "Use Backends feature to eliminate redundant API backend configurations" }, { - "category": "Security", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Are the applicable policies enabled (compliance baselines added to MDfC)", - "guid": "bcdd2348-3d0e-c6bb-1092-aa4cd1a66d6b", - "id": "I04.02", - "link": "https://docs.microsoft.com/azure/azure-vmware/azure-security-integration", + "category": "Management", + "checklist": "Azure API Management Review", + "guid": "03b125d5-b69b-4739-b7fd-84b86da4933e", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-properties?tabs=azure-portal", "services": [ - "AVS", + "APIM", "AzurePolicy" ], "severity": "Medium", - "subcategory": "Security", - "text": "Policy & Regulatory Compliance", - "waf": "Security" + "subcategory": "Best practices", + "text": "Use Named Values to store common values that can be used in policies" }, { - "category": "VMware", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Azure to Azure (E/W), Azure to On-premises), AVS to Internet, AVS to Azure", - "guid": "607c1ca9-da92-ae19-5a4c-eb1e876acbe7", - "id": "J01.01", - "link": "https://techcommunity.microsoft.com/t5/azure-migration-and/firewall-integration-in-azure-vmware-solution/ba-p/2254961#:~:text=Azure%20VMware%20Solution%20customers%20have%20multiple%20security%20options,the%20box%20to%20provide%20East-West%20and%20North-South%20firewalling.", + "category": "Management", + "checklist": "Azure API Management Review", + "guid": "beae759e-4ddb-4326-bf26-47f87d3454b6", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-deploy-multi-region", "services": [ - "AVS" + "APIM", + "ASR" ], "severity": "Medium", - "subcategory": "Firewalls", - "text": "Azure / 3rd party firewall", - "waf": "Security" + "subcategory": "Business continuity and disaster recovery", + "text": "Deploy to multiple Azure regions" }, { - "category": "VMware", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "To allow HCX appliance to connect/sync", - "guid": "1d87925c-c02b-7fde-a425-7e95ad846a27", - "id": "J01.02", - "link": "https://docs.vmware.com/en/VMware-Cloud-on-AWS/services/com.vmware.vmc-aws-networking-security/GUID-2CFE1654-9CC9-4EDB-A625-21317299E559.html", + "category": "Management", + "checklist": "Azure API Management Review", + "guid": "9c8d1664-dd9a-49d4-bd83-950af0af4044", + "link": "https://learn.microsoft.com/azure/api-management/high-availability", "services": [ - "AVS" + "APIM", + "ASR" ], "severity": "Medium", - "subcategory": "Firewalls", - "text": "Firewalls allow for East/West traffic inside AVS", - "waf": "Security" + "subcategory": "Business continuity and disaster recovery", + "text": "Deploy at least two scale units spread over two availability zones per region for best availability and performance" }, { - "category": "VMware", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Decision on which tool to use (SRM requires additional license - enables automation & other features)", - "guid": "468b3495-2f6e-b65a-38ef-3ba631bcaa46", - "id": "J02.01", - "link": "https://docs.vmware.com/en/VMware-HCX/4.2/hcx-user-guide/GUID-B842696B-89EF-4183-9C73-B77157F56055.html", + "category": "Management", + "checklist": "Azure API Management Review", + "guid": "8d2db6e8-85c6-4118-a52c-ae76a4f27934", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#service-native-backup-capability", "services": [ - "AVS" + "APIM", + "Backup", + "ASR" ], - "severity": "Medium", - "subcategory": "Networking", - "text": "HCX and/or SRM", - "waf": "Reliability" + "severity": "High", + "subcategory": "Business continuity and disaster recovery", + "text": "Ensure there is an automated backup routine" }, { - "category": "VMware", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Read up on requirements for Service Mesh requirements and how HCX ", - "guid": "be2ced52-da08-d366-cf7c-044c19e29509", - "id": "J02.02", - "link": "https://docs.vmware.com/en/VMware-HCX/4.6/hcx-user-guide/GUID-76BCD059-A31A-4041-9105-ACFB56213E7C.html", + "category": "Management", + "checklist": "Azure API Management Review", + "guid": "f96ddac5-77ec-4fa9-8833-4327f052059e", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-cache-external", "services": [ - "AVS" + "APIM", + "AzurePolicy" ], "severity": "Medium", - "subcategory": "Networking", - "text": "Configuring and Managing the HCX Interconnect", - "waf": "Reliability" + "subcategory": "Performance and scalability", + "text": "Consider using a external cache policy for APIs that can benefit from caching", + "training": "https://learn.microsoft.com/training/modules/improve-api-performance-with-apim-caching-policy/" }, { - "category": "VMware", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "If you are planning on using stretch networks ensure that your on-premises environment requirements", - "guid": "7dcac579-fc5c-5c9c-f1f7-9b1149ff2c37", - "id": "J02.03", - "link": "https://docs.vmware.com/en/VMware-HCX/4.2/hcx-user-guide/GUID-DBDB4D1B-60B6-4D16-936B-4AC632606909.html", + "category": "Management", + "checklist": "Azure API Management Review", + "guid": "8210699f-8d43-45c2-8f19-57e54134bd8f", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-log-event-hubs", "services": [ - "AVS" + "APIM", + "AzurePolicy", + "EventHubs" ], - "severity": "Medium", - "subcategory": "Networking", - "text": "Restrictions and limitations for network extensions", - "waf": "Performance" + "severity": "Low", + "subcategory": "Performance and scalability", + "text": "If you need to log at high performance levels, consider Event Hubs policy" }, { - "category": "VMware", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Do workloads require MoN?", - "guid": "cf45c0b9-6c4b-3bfb-86c5-62fe54061c73", - "id": "J02.04", - "link": "https://learn.microsoft.com/azure/azure-vmware/vmware-hcx-mon-guidance", + "category": "Management", + "checklist": "Azure API Management Review", + "guid": "121bfc39-fa7b-4096-b93b-ab56c1bc0bed", + "link": "https://learn.microsoft.com/azure/api-management/api-management-sample-flexible-throttling", "services": [ - "AVS" + "APIM", + "AzurePolicy" ], "severity": "Medium", - "subcategory": "Networking", - "text": "Mobility optimized networking", - "waf": "Performance" + "subcategory": "Performance and scalability", + "text": "Apply throttling policies to control the number of requests per second", + "training": "https://learn.microsoft.com/training/modules/protect-apis-on-api-management/" }, { - "category": "VMware", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Operating system level of Vmware environment", - "guid": "b7cf11f3-b12e-5189-991a-06df5250d2ca", - "id": "J03.01", - "link": "https://learn.microsoft.com/azure/site-recovery/vmware-physical-azure-support-matrix", + "category": "Management", + "checklist": "Azure API Management Review", + "guid": "bb5f356b-3daf-47a2-a9ee-867a8100bbd5", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-autoscale", "services": [ - "AVS" + "APIM" ], "severity": "Medium", - "subcategory": "On-premises pre-requisites", - "text": "Support matrix (OS versions etc).", - "waf": "Operations" + "subcategory": "Performance and scalability", + "text": "Configure autoscaling to scale out the number of instances when the load increases" }, { - "category": "VMware", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Required that all switches are dynamic", - "guid": "45fe9252-aa1b-4e30-45c6-bc02f3b76acf", - "id": "J03.02", - "link": "https://docs.vmware.com/en/VMware-vSphere/7.0/vsan-network-design-guide/GUID-91E1CD6F-33A6-4AC6-BC22-3E4807296F86.html#:~:text=Migrate%20Management%20Network%201%20Add%20hosts%20to%20the,each%20host.%20...%204%20Finish%20the%20configuration.%20", + "category": "Management", + "checklist": "Azure API Management Review", + "guid": "84b94abb-59b6-4b9d-8587-3413669468e8", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-provision-self-hosted-gateway", "services": [ - "AVS" + "APIM" ], "severity": "Medium", - "subcategory": "On-premises pre-requisites", - "text": "Standard switches converted to dynamic switches", - "waf": "Operations" + "subcategory": "Performance and scalability", + "text": "Deploy self-hosted gateways where Azure doesn't have a region close to the backend APIs." }, { - "category": "VMware", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "See sections on sizing and capacity in the link.", - "guid": "e9f6d736-ee44-e2ac-e7f9-e361f8c857f3", - "id": "J03.03", - "link": "https://learn.microsoft.com/azure/azure-vmware/plan-private-cloud-deployment", + "category": "Governance", + "checklist": "Azure API Management Review", + "guid": "d7941d4a-7b6f-458f-8714-2f8f8c059ad4", + "link": "https://learn.microsoft.com/azure/api-management/api-management-error-handling-policies", "services": [ - "AVS" + "APIM", + "AzurePolicy" ], "severity": "Medium", - "subcategory": "On-premises pre-requisites", - "text": "Capacity for HCX appliance", - "waf": "Performance" + "subcategory": "Development best practices", + "text": "Implement an error handling policy at the global level" }, { - "category": "VMware", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Check hardware restrictions to ensure compatibility with AVS/OS ", - "guid": "1be2cdd6-15a7-9a33-aea7-113859035ce9", - "id": "J03.04", - "link": "https://kb.vmware.com/s/article/2007240#:~:text=ESXi%2FESX%20hosts%20and%20compatible%20virtual%20machine%20hardware%20versions,%20Not%20Supported%20%204%20more%20rows", + "category": "Governance", + "checklist": "Azure API Management Review", + "guid": "0b0c0765-ff37-4369-90bd-3eb23ce71b08", + "link": "https://learn.microsoft.com/azure/api-management/set-edit-policies?tabs=form#use-base-element-to-set-policy-evaluation-order", "services": [ - "AVS" + "APIM", + "AzurePolicy" ], "severity": "Medium", - "subcategory": "On-premises pre-requisites", - "text": "Hardware compatibility", - "waf": "Operations" + "subcategory": "Development best practices", + "text": "Ensure all APIs policies include a element." }, { - "category": "VMware", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Need to be converted", - "guid": "16ab821a-27c6-b6d3-6042-10dc4d6dfcb7", - "id": "J04.01", - "link": "https://docs.vmware.com/en/VMware-vSphere/7.0/com.vmware.vsphere.storage.doc/GUID-01D3CF47-A84A-4988-8103-A0487D6441AA.html", + "category": "Governance", + "checklist": "Azure API Management Review", + "guid": "a5c45b03-93b6-42fe-b16b-8fccb6a79902", + "link": "https://learn.microsoft.com/azure/api-management/policy-fragments", "services": [ - "AVS", - "Storage" + "ACR", + "APIM", + "AzurePolicy" ], "severity": "Medium", - "subcategory": "Storage", - "text": "VSAN RDM disks are converted - not supported.", - "waf": "Operations" + "subcategory": "Development best practices", + "text": "Use Policy Fragments to avoid repeating same policies definitions across multiple APIs" }, { - "category": "VMware", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Need to be converted", - "guid": "eb2f9313-afb2-ab35-aa24-6d97a3cb0611", - "id": "J04.02", - "link": "3rd-Party tools", + "category": "Governance", + "checklist": "Azure API Management Review", + "guid": "c3818a95-6ff3-4474-88dc-e809b46dad6a", + "link": "https://learn.microsoft.com/azure/api-management/monetization-support", "services": [ - "AVS", - "VM", - "Storage" + "APIM" ], "severity": "Medium", - "subcategory": "Storage", - "text": "VM with SCSI shared bus are not supported", - "waf": "Operations" + "subcategory": "Monetization", + "text": "If you are planning to monetize your APIs, review the 'monetization support' article for best practices" }, { - "category": "VMware", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Remove Direct IO before migration", - "guid": "3f2a5cff-c8a6-634a-1f1b-53ef9d321381", - "id": "J04.03", - "link": "Contact VMware", + "category": "Governance", + "checklist": "Azure API Management Review", + "guid": "a7d0840a-c8c4-4e83-adec-5ca578eb4049", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-use-azure-monitor#resource-logs", "services": [ - "AVS", - "VM", - "Storage" + "Monitor", + "APIM" ], - "severity": "Medium", - "subcategory": "Storage", - "text": "VM with Direct IO require removing DirectPath device", - "waf": "Operations" + "severity": "High", + "subcategory": "Monitoring", + "text": "Enable Diagnostics Settings to export logs to Azure Monitor" }, { - "category": "VMware", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Cannot migrate clusters ", - "guid": "efc8a311-74f8-0252-c6a0-4bac7610e266", - "id": "J04.04", - "link": "Contact VMware", + "category": "Governance", + "checklist": "Azure API Management Review", + "guid": "8691fa38-45ed-4299-a247-fecd98d35deb", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-app-insights", "services": [ - "AVS", - "Storage" + "Monitor", + "APIM" ], "severity": "Medium", - "subcategory": "Storage", - "text": "Shared VMDK files are not supported", - "waf": "Operations" + "subcategory": "Monitoring", + "text": "Enable Application Insights for more detailed telemetry" }, { - "category": "VMware", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Convert to a different format", - "guid": "ab6c89cd-a26f-b894-fe59-61863975458e", - "id": "J04.05", - "link": "Contact VMware", + "category": "Governance", + "checklist": "Azure API Management Review", + "guid": "55fd27bb-76ac-4a91-bc37-049e885be6b7", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-use-azure-monitor", "services": [ - "AVS", - "Storage" + "Monitor", + "APIM" ], - "severity": "Medium", - "subcategory": "Storage", - "text": "RDM with 'physical compatibility mode' are not supported.", - "waf": "Operations" + "severity": "High", + "subcategory": "Monitoring", + "text": "Configure alerts on the most critical metrics" }, { - "category": "VMware", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Ensure the vSAN storage policy for VM's is NOT the default storage policy as this policy applies thick provisioning 'RAID-1 FTT-1' is default with Thin Provisioning", - "guid": "7628d446-6b10-9678-9cec-f407d990de43", - "id": "J04.06", - "link": "https://learn.microsoft.com/azure/azure-vmware/concepts-storage#storage-policies-and-fault-tolerance", + "category": "Identity and Access Management", + "checklist": "Azure API Management Review", + "guid": "39460bdb-156f-4dc2-a87f-1e8c11ab0998", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#certificate-management-in-azure-key-vault", "services": [ - "AVS", - "AzurePolicy", - "Storage", - "VM" + "APIM", + "AKV", + "Entra" ], - "severity": "Medium", - "subcategory": "Storage", - "text": "Default storage policy", - "waf": "Operations" + "severity": "High", + "subcategory": "Data protection", + "text": "Ensure that custom SSL certificates are stored an Azure Key Vault so they can be securely accessed and updated" }, { - "category": "VMware", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "The default storage policy is set to RAID-1 (Mirroring) FTT-1, with Object Space Reservation set to Thin provisioning.", - "guid": "37fef358-7ab9-43a9-542c-22673955200e", - "id": "J04.07", - "link": "https://learn.microsoft.com/azure/azure-vmware/configure-storage-policy", + "category": "Identity and Access Management", + "checklist": "Azure API Management Review", + "guid": "e9217997-5f6c-479d-8576-8f2adf706ec8", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#azure-ad-authentication-required-for-data-plane-access", "services": [ - "AVS", - "VM", - "Storage", - "AzurePolicy" + "APIM", + "Entra" ], - "severity": "Medium", - "subcategory": "Storage", - "text": "Ensure that the appropriate VM template storage policy is used", - "waf": "Operations" + "severity": "High", + "subcategory": "Identity", + "text": "Protect incoming requests to APIs (data plane) with Azure AD" }, { - "category": "VMware", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "Ensure that the Failure-to-tolerate policy is in place to meet your vSAN storage needs", - "guid": "ebebd109-9f9d-d85e-1b2f-d302012843b7", - "id": "J04.08", - "link": "https://learn.microsoft.com/azure/azure-vmware/concepts-storage#storage-policies-and-fault-tolerance", + "category": "Identity and Access Management", + "checklist": "Azure API Management Review", + "guid": "5e5f64ba-c90e-480e-8888-398d96cf0bfb", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-aad", "services": [ - "AVS", - "AzurePolicy", - "Storage" + "APIM", + "Entra" ], "severity": "Medium", - "subcategory": "Storage", - "text": "Failure to tolerate policy", - "waf": "Operations" + "subcategory": "Identity", + "text": "Use Azure AD to authenticate users in the Developer Portal" }, { - "category": "VMware", - "checklist": "Azure VMware Solution Implementation Checklist", - "description": "ANF can be used to extend storage for Azure VMware Solution,", - "guid": "1be821bd-4f37-216a-3e3d-2a5ac6996863", - "id": "J04.09", - "link": "https://learn.microsoft.com/azure/azure-vmware/netapp-files-with-azure-vmware-solution", + "category": "Identity and Access Management", + "checklist": "Azure API Management Review", + "guid": "f8e574ce-280f-49c8-b2ef-68279b081cf3", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-create-groups", "services": [ - "AVS", - "Storage" + "APIM", + "Entra" ], "severity": "Medium", - "subcategory": "Storage", - "text": "Use ANF for external storage", - "waf": "Operations" + "subcategory": "Privileged access", + "text": "Create appropriate groups to control the visibility of the products" }, { - "category": "Business Continuity and Disaster Recovery", - "checklist": "Azure Landing Zone Review", - "guid": "aff6691b-4935-4ada-9222-3ece81b12318", - "link": "https://learn.microsoft.com/azure/active-directory/reports-monitoring/overview-reports", + "category": "Network Topology and Connectivity", + "checklist": "Azure API Management Review", + "guid": "cd45c90e-7690-4753-930b-bf290c69c074", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#virtual-network-integration", "services": [ - "ASR" + "APIM", + "VNet" ], "severity": "Medium", - "subcategory": " ", - "text": "Do not combine ASCS and Database cluster on to single/same VM" + "subcategory": "Security", + "text": "Deploy the service within a Virtual Network (VNET)" }, { - "category": "Business Continuity and Disaster Recovery", - "checklist": "Azure Landing Zone Review", - "guid": "1a541741-5833-4fb4-ae3c-2df743165c3a", - "link": "https://learn.microsoft.com/azure/azure-monitor/logs/logs-data-export?tabs=portal", + "category": "Network Topology and Connectivity", + "checklist": "Azure API Management Review", + "guid": "02661582-b3d1-48d1-9d7b-c6a918a0ca33", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#network-security-group-support", "services": [ - "ASR", - "LoadBalancer" + "Monitor", + "APIM", + "VNet" ], "severity": "Medium", - "subcategory": " ", - "text": "Make sure the Floating IP is enabled on the Load balancer" + "subcategory": "Security", + "text": "Deploy network security groups (NSG) to your subnets to restrict or monitor traffic" }, { - "category": "Business Continuity and Disaster Recovery", - "checklist": "Azure Landing Zone Review", - "guid": "cbe05bbe-209d-4490-ba47-778424d11678", - "link": "https://learn.microsoft.com/azure/security-center/", + "category": "Network Topology and Connectivity", + "checklist": "Azure API Management Review", + "guid": "67437a28-2721-4a2c-becd-caa54c8237a5", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#azure-private-link", "services": [ - "ASR", - "VM", - "RBAC", - "Entra" + "APIM", + "PrivateLink", + "VNet" ], "severity": "Medium", - "subcategory": " ", - "text": "Do not mix servers of different roles in the same availability set. Keep central services VMs, database VMs, application VMs in their own availability sets" + "subcategory": "Security", + "text": "Deploy Private Endpoints to filter incoming traffic when VNET is not used" }, { - "category": "Business Continuity and Disaster Recovery", - "checklist": "Azure Landing Zone Review", - "guid": "5d2fa56c-56ad-4484-88fe-72734c486ba2", - "link": "https://learn.microsoft.com/azure/security-center/", + "category": "Network Topology and Connectivity", + "checklist": "Azure API Management Review", + "guid": "d698adbd-3288-44cb-b10a-9b572da395ae", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#disable-public-network-access", "services": [ - "SAP", - "ACR", - "ASR" + "APIM" ], - "severity": "Medium", - "subcategory": " ", - "text": "Use one proximity placement group per SAP SID. Groups don't span across Availability Zones or Azure regions" + "severity": "High", + "subcategory": "Security", + "text": "Disable Public Network Access" }, { - "category": "Business Continuity and Disaster Recovery", - "checklist": "Azure Landing Zone Review", - "guid": "80dc0591-cf65-4de8-b130-9cccd579266b", - "link": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", + "category": "Network Topology and Connectivity", + "checklist": "Azure API Management Review", + "guid": "7519e385-a88b-4d34-966b-6269d686e890", + "link": "https://learn.microsoft.com/azure/api-management/front-door-api-management", "services": [ - "ASR", - "VM", - "Entra" + "APIM", + "FrontDoor" ], "severity": "Medium", - "subcategory": " ", - "text": "Azure doesn't currently support combining ASCS and db HA in the same Linux Pacemaker cluster; separate them into individual clusters. However, you can combine up to five multiple central-services clusters into a pair of VMs." + "subcategory": "Connectivity", + "text": "Use Azure Front Door for multi-region deployment" }, { - "category": "Business Continuity and Disaster Recovery", - "checklist": "Azure Landing Zone Review", - "guid": "cca275fa-a1ab-4fe9-b55d-04c3c4919cb1", - "link": "https://learn.microsoft.com/security/benchmark/azure/security-control-incident-response", + "category": "Platform automation and DevOps", + "checklist": "Azure API Management Review", + "guid": "0674d750-0c6f-4ac0-8717-ceec04d0bdbd", + "link": "https://learn.microsoft.com/azure/api-management/automation-manage-api-management", "services": [ - "ASR", - "LoadBalancer" + "APIM" ], "severity": "Medium", - "subcategory": " ", - "text": "Use a Standard Load Balancer SKU in front of ASCS and DB clusters" + "subcategory": "Automation", + "text": "Simplify management with PowerShell automation scripts" }, { - "category": "Business Continuity and Disaster Recovery", - "checklist": "Azure Landing Zone Review", - "guid": "b3d1325a-e124-4ba3-9df6-85eddce9bd3b", - "link": "https://www.microsoft.com/itshowcase/implementing-a-zero-trust-security-model-at-microsoft", + "category": "Platform automation and DevOps", + "checklist": "Azure API Management Review", + "guid": "c385bfcd-49fd-4786-81ba-cedbb4c57345", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/app-platform/api-management/platform-automation-and-devops#design-recommendations", "services": [ - "ASR", - "VM", - "Storage" + "APIM", + "Entra" ], "severity": "Medium", - "subcategory": " ", - "text": "Both VMs in the HA pair should be deployed in an availability set, or Availability Zones should be the same size and have the same storage configuration" + "subcategory": "Best practices", + "text": "Review DevOps best practices from the Cloud Adaption Framework APIM Landing Zone Accelerator" }, { - "category": "Business Continuity and Disaster Recovery", - "checklist": "Azure Landing Zone Review", - "guid": "b0cdb3b5-5eb2-4ec1-9eea-a3592829e2ed", - "link": "https://learn.microsoft.com/security/benchmark/azure/security-control-incident-response", + "category": "Platform automation and DevOps", + "checklist": "Azure API Management Review", + "guid": "6c3a27c0-197f-426c-9ffa-86fed51d9ab6", + "link": "https://learn.microsoft.com/azure/api-management/visual-studio-code-tutorial", "services": [ - "ASR" + "APIM", + "Entra" ], "severity": "Medium", - "subcategory": " ", - "text": "Native database replication technology should be used to synchronize the database in a HA pair." - }, - { - "category": "Business Continuity and Disaster Recovery", - "checklist": "Azure Landing Zone Review", - "guid": "b2173676-aff6-4691-a493-5ada42223ece", - "link": "https://learn.microsoft.com/security/benchmark/azure/security-control-incident-response", + "subcategory": "Best practices", + "text": "Promote usage of Visual Studio Code APIM extension for faster API development" + }, + { + "category": "Platform automation and DevOps", + "checklist": "Azure API Management Review", + "guid": "354f1c03-8112-4965-85ad-c0074bddf231", + "link": "https://learn.microsoft.com/azure/api-management/devops-api-development-templates", "services": [ - "SAP", - "ASR" + "APIM" ], "severity": "Medium", - "subcategory": " ", - "text": "Perform a point-in-time recovery for your production databases at any point and in a time frame that meets your RTO; point-in-time recovery typically includes operator errors deleting data either on the DBMS layer or through SAP, incidentally" + "subcategory": "DevOps", + "text": "Implement DevOps and CI/CD in your workflow" }, { - "category": "Business Continuity and Disaster Recovery", - "checklist": "Azure Landing Zone Review", - "guid": "81b12318-1a54-4174-8583-3fb4ae3c2df7", + "category": "Security", + "checklist": "Azure API Management Review", + "guid": "b6439493-426a-45f3-9697-cf65baee208d", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-mutual-certificates-for-clients", "services": [ - "ASR", - "VNet" + "APIM" ], "severity": "Medium", - "subcategory": " ", - "text": "The CIDR for the primary virtual network (VNet) shouldn't conflict or overlap with the CIDR of the DR site's Vnet" + "subcategory": "APIs", + "text": "Secure APIs using client certificate authentication" }, { - "category": "Business Continuity and Disaster Recovery", - "checklist": "Azure Landing Zone Review", - "guid": "43165c3a-cbe0-45bb-b209-d490da477784", + "category": "Security", + "checklist": "Azure API Management Review", + "guid": "2a67d143-1033-4c0a-8732-680896478f08", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-mutual-certificates", "services": [ - "ASR", - "VM", - "Entra" + "APIM" ], "severity": "Medium", - "subcategory": " ", - "text": "Use Site Recovery to replicate an application server to a DR site. Site Recovery can also help with replicating central-services cluster VMs to the DR site. When you invoke DR, you'll need to reconfigure the Linux Pacemaker cluster on the DR site (for example, replace the VIP or SBD, run corosync.conf, and more)." + "subcategory": "APIs", + "text": "Secure backend services using client certificate authentication" }, { - "category": "Business Continuity and Disaster Recovery", - "checklist": "Azure Landing Zone Review", - "guid": "24d11678-5d2f-4a56-a56a-d48408fe7273", + "category": "Security", + "checklist": "Azure API Management Review", + "guid": "074435f5-4a46-41ac-b521-d6114cb5d845", + "link": "https://learn.microsoft.com/azure/api-management/mitigate-owasp-api-threats", "services": [ - "ASR" + "APIM" ], "severity": "Medium", - "subcategory": " ", - "text": "Native database replication should be used to synchronize data to the DR site, rather than Azure Site Recovery" + "subcategory": "APIs", + "text": "Review 'Recommendations to mitigate OWASP API Security Top 10 threats' article and check what is applicable to your APIs" }, { - "category": "Compute", - "checklist": "Azure Landing Zone Review", - "guid": "2829e2ed-b217-4367-9aff-6691b4935ada", + "category": "Security", + "checklist": "Azure API Management Review", + "guid": "5507c4b8-a7f8-41d6-9661-418c987100c9", + "link": "https://learn.microsoft.com/azure/api-management/authorizations-overview", "services": [ - "VM" + "APIM" ], "severity": "Medium", - "subcategory": " ", - "text": "Make quota requests for correct VM SKU and Zones" + "subcategory": "APIs", + "text": "Use Authorizations feature to simplify management of OAuth 2.0 token for your backend APIs" }, { - "category": "Identity and Access", - "checklist": "Azure Landing Zone Review", - "guid": "fda1dbf3-dc95-4d48-a7c7-91dca0f6c565", - "link": "https://learn.microsoft.com/azure/well-architected/sap/design-areas/security", + "category": "Security", + "checklist": "Azure API Management Review", + "guid": "2deee033-b906-4bc2-9f26-c8d3699fe091", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-manage-protocols-ciphers", "services": [ - "Entra", - "RBAC", - "Subscriptions" + "APIM" ], "severity": "High", - "subcategory": "Identity", - "text": "Enforce a RBAC model for management groups, subscriptions, resource groups and resources", - "training": "https://learn.microsoft.com/training/paths/implement-resource-mgmt-security/" + "subcategory": "Ciphers", + "text": "Use the latest TLS version when encrypting information in transit. Disable outdated and unnecessary protocols and ciphers when possible." }, { - "category": "Identity and Access", - "checklist": "Azure Landing Zone Review", - "guid": "45911475-e39e-4530-accc-d979366bcda2", - "link": "https://learn.microsoft.com/azure/active-directory/fundamentals/scenario-azure-first-sap-identity-integration", + "category": "Security", + "checklist": "Azure API Management Review", + "guid": "f8af3d94-1d2b-4070-846f-849197524258", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#im-8-restrict-the-exposure-of-credential-and-secrets", "services": [ - "SAP", - "Entra" + "APIM", + "AKV" ], - "severity": "Medium", - "subcategory": "Identity", - "text": "Enforce Principle propagation for forwarding the identity from SAP cloud application to SAP on-premises (Including IaaS) through cloud connector", - "training": "https://learn.microsoft.com/training/modules/explore-identity-services/2-explore-azure-virtual-machine-auth-access-control" + "severity": "High", + "subcategory": "Data protection", + "text": "Ensure that secrets (Named values) are stored an Azure Key Vault so they can be securely accessed and updated" }, { - "category": "Identity and Access", - "checklist": "Azure Landing Zone Review", - "guid": "750ab1ab-039d-495d-94c7-c8929cb107d5", - "link": "https://learn.microsoft.com/azure/active-directory/fundamentals/scenario-azure-first-sap-identity-integration", + "category": "Security", + "checklist": "Azure API Management Review", + "guid": "791abd8b-7706-4e31-9569-afefde724be3", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#managed-identities", "services": [ - "SAP", + "APIM", "Entra" ], "severity": "Medium", - "subcategory": "Identity", - "text": "Implement SSO to SAP SaaS applications like SAP Analytics Cloud, SAP Cloud Platform, Business by design, SAP Qualtrics and SAP C4C with Azure AD using SAML." + "subcategory": "Identities", + "text": "Use managed identities to authenticate to other Azure resources whenever possible" }, { - "category": "Identity and Access", - "checklist": "Azure Landing Zone Review", - "guid": "325ae525-ba34-4d46-a5e2-213ace7bb122", - "link": "https://learn.microsoft.com/azure/active-directory/saas-apps/sap-netweaver-tutorial", + "category": "Security", + "checklist": "Azure API Management Review", + "guid": "220c4ca6-6688-476b-b2b5-425a78e6fb87", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#ns-6-deploy-web-application-firewall", "services": [ - "SAP", + "APIM", + "WAF", + "AppGW", "Entra" ], - "severity": "Medium", - "subcategory": "Identity", - "text": "Implement SSO to SAP NetWeaver-based web applications like SAP Fiori and SAP Web GUI by using SAML.", - "training": "https://learn.microsoft.com/training/modules/explore-identity-services/8-exercise-integrate-azure-active-directory-sap-netweaver" + "severity": "High", + "subcategory": "Network", + "text": "Use web application firewall (WAF) by deploying Application Gateway in front of APIM" }, { - "category": "Identity and Access", - "checklist": "Azure Landing Zone Review", - "guid": "9eb54dad-7861-4e1c-973a-f3bb003fc9c1", + "category": "Compute", + "checklist": "Resiliency Review", + "description": "Automatic instance repairs ensure that unhealthy instances are promptly identified and replaced, maintaining a set of healthy instances within your scale set.", + "guid": "7e13c105-675c-41e9-95b4-59837ff7ae7c", + "link": "https://learn.microsoft.com/azure/virtual-machine-scale-sets/virtual-machine-scale-sets-automatic-instance-repairs", "services": [ - "SAP", - "Entra" + "VM" ], - "severity": "Medium", - "subcategory": "Identity", - "text": "Implement SSO to SAP NetWeaver-based web applications like SAP Fiori and SAP Web GUI by using SAML.", - "training": "https://learn.microsoft.com/training/modules/explore-identity-services/6-exercise-integrate-azure-active-directory-sap-fiori" + "severity": "Low", + "subcategory": "VM Scale Sets", + "text": "Enable automatic instance repairs for enhanced VM Scale Sets resiliency", + "waf": "Reliability" }, { - "category": "Identity and Access", - "checklist": "Azure Landing Zone Review", - "guid": "f29676ef-0c9c-4c4d-ab21-a55504c0c829", - "link": "https://learn.microsoft.com/azure/active-directory/saas-apps/sap-netweaver-tutorial", + "category": "Compute", + "checklist": "Resiliency Review", + "description": "Ensure that Azure Backup is utilized appropriately to meet your organization's resiliency requirements for Azure virtual machines (VMs).", + "guid": "4d874a74-8b66-42d6-b150-512a66498f6d", + "link": "https://learn.microsoft.com/azure/backup/backup-azure-vms-introduction", "services": [ - "SAP", - "Entra" + "VM", + "Backup" ], - "severity": "Medium", - "subcategory": "Identity", - "text": "You can implement SSO to SAP GUI by using SAP NetWeaver SSO or a partner solution.", - "training": "https://learn.microsoft.com/training/modules/explore-identity-services/8-exercise-integrate-azure-active-directory-sap-netweaver" + "severity": "High", + "subcategory": "Virtual Machines", + "text": "Consider Azure Backup to meet your resiliency requirements for Azure VMs", + "waf": "Reliability" }, { - "category": "Identity and Access", - "checklist": "Azure Landing Zone Review", - "guid": "23181aa4-1742-4694-9ff8-ae7d7d474317", + "category": "Compute", + "checklist": "Resiliency Review", + "description": "Single Instance VMs using Premium SSD or Ultra Disk for all Operating System Disks and Data Disks are guaranteed to have Virtual Machine Connectivity of at least 99.9%", + "guid": "8052d88e-79d1-47b7-9b22-a5a67e7a8ed4", + "link": "https://learn.microsoft.com/azure/virtual-machines/disks-types", "services": [ - "SAP", - "AKV", - "Entra" + "VM" ], - "severity": "Medium", - "subcategory": "Identity", - "text": "For SSO for SAP GUI and web browser access, implement SNC – Kerberos/SPNEGO (simple and protected GSSAPI negotiation mechanism) due to its ease of configuration and maintenance. For SSO with X.509 client certificates, consider the SAP Secure Login Server, which is a component of the SAP SSO solution.", - "training": "https://learn.microsoft.com/training/modules/explore-identity-services/9-exercise-integrate-active-directory-sap-single-sign-on" + "severity": "High", + "subcategory": "Virtual Machines", + "text": "Use Premium or Ultra disks for production VMs", + "waf": "Reliability" }, { - "category": "Identity and Access", - "checklist": "Azure Landing Zone Review", - "guid": "6c8bcbf4-5bbe-4609-b8a0-3e97778424d6", - "link": "https://blogs.sap.com/2017/07/12/sap-single-sign-on-protect-your-sap-landscape-with-x.509-certificates/", + "category": "Compute", + "checklist": "Resiliency Review", + "description": "Azure automatically replicates managed disks within a region to ensure data durability and protect against single-point failures.", + "guid": "b31e38c3-f298-412b-8363-cffe179b599d", + "link": "https://learn.microsoft.com/azure/virtual-machines/managed-disks-overview", "services": [ - "SAP", - "AKV", - "Entra" + "VM" ], - "severity": "Medium", - "subcategory": "Identity", - "text": "For SSO for SAP GUI and web browser access, implement SNC – Kerberos/SPNEGO (simple and protected GSSAPI negotiation mechanism) due to its ease of configuration and maintenance. For SSO with X.509 client certificates, consider the SAP Secure Login Server, which is a component of the SAP SSO solution." + "severity": "High", + "subcategory": "Virtual Machines", + "text": "Ensure Managed Disks are used for all VMs", + "waf": "Reliability" }, { - "category": "Identity and Access", - "checklist": "Azure Landing Zone Review", - "guid": "16785d6f-a96c-496a-b885-18f482734c88", - "link": "https://learn.microsoft.com/azure/active-directory/saas-apps/sap-netweaver-tutorial#configure-sap-netweaver-for-oauth", + "category": "Compute", + "checklist": "Resiliency Review", + "description": "Temporary disks are intended for short-term storage of non-persistent data such as page files, swap files, or SQL Server tempdb. Storing persistent data on temporary disks can lead to data loss during maintenance events or VM redeployment.", + "guid": "e0d5973c-d4ce-432c-8881-37f6f7c4c0d4", + "link": "https://learn.microsoft.com/azure/virtual-machines/managed-disks-overview#temporary-disk", "services": [ - "SAP", - "Entra" + "VM", + "Storage", + "SQL" ], "severity": "Medium", - "subcategory": "Identity", - "text": "Implement SSO by using OAuth for SAP NetWeaver to allow third-party or custom applications to access SAP NetWeaver OData services." + "subcategory": "Virtual Machines", + "text": "Do not use the Temp disk for anything that is not acceptable to be lost", + "waf": "Reliability" }, { - "category": "Identity and Access", - "checklist": "Azure Landing Zone Review", - "guid": "a747c350-8d4c-449c-93af-393dbca77c48", - "link": "https://learn.microsoft.com/azure/active-directory/saas-apps/saphana-tutorial", + "category": "Compute", + "checklist": "Resiliency Review", + "description": "Co-locate your compute, storage, networking, and data resources across an availability zone, and replicate this arrangement in other availability zones.", + "guid": "e514548d-2447-4ec6-9138-b8200f1ce16e", + "link": "https://learn.microsoft.com/azure/reliability/availability-zones-overview", "services": [ - "SAP", - "Entra" + "ACR", + "VM", + "Storage" ], "severity": "Medium", - "subcategory": "Identity", - "text": "Implement SSO to SAP HANA" + "subcategory": "Virtual Machines", + "text": "Leverage Availability Zones for your VMs in regions where they are supported", + "waf": "Reliability" }, { - "category": "Identity and Access", - "checklist": "Azure Landing Zone Review", - "guid": "c7bae5bf-daf9-4761-9c56-f92891890aa4", - "link": "https://learn.microsoft.com/azure/sap/workloads/rise-integration#connectivity-with-sap-rise", + "category": "Compute", + "checklist": "Resiliency Review", + "description": "Use at least two VMs in Availability Sets to isolate VMs on different fault and update domains.", + "guid": "5a785d6f-e96c-496a-b884-4cf3b2b38c88", + "link": "https://learn.microsoft.com/azure/virtual-machines/availability-set-overview", "services": [ - "SAP", - "Entra" + "VM" ], "severity": "Medium", - "subcategory": "Identity", - "text": "Consider Azure AD an identity provider for SAP systems hosted on RISE. For more information, see Integrating the Service with Azure AD." + "subcategory": "Virtual Machines", + "text": "For regions that do not support Availability Zones deploy VMs into Availability Sets", + "waf": "Reliability" }, { - "category": "Identity and Access", - "checklist": "Azure Landing Zone Review", - "guid": "e4e48226-ce54-44b6-bb6b-bfa15bd8f753", - "link": "https://github.com/azuredevcollege/SAP/blob/master/sap-oauth-saml-flow/README.md", + "category": "Compute", + "checklist": "Resiliency Review", + "description": "Azure provides multiple options for VM redundancy to meet different requirements (Availability Zones, Virtual Machine Scale Sets, Availability Sets, Azure Site Recovery)", + "guid": "6ba2c021-4991-414a-9d3c-e574dccbd979", + "link": "https://learn.microsoft.com/azure/virtual-machines/availability", "services": [ - "SAP", - "Entra" + "VM", + "ASR" ], - "severity": "Medium", - "subcategory": "Identity", - "text": "For applications that access SAP, you might want to use principal propagation to establish SSO." + "severity": "High", + "subcategory": "Virtual Machines", + "text": "Avoid running a production workload on a single VM", + "waf": "Reliability" }, { - "category": "Identity and Access", - "checklist": "Azure Landing Zone Review", - "guid": "59921095-4980-4fc1-a5b6-524a5a560c79", - "link": "https://learn.microsoft.com/azure/active-directory/saas-apps/sap-hana-cloud-platform-identity-authentication-tutorial", + "category": "Compute", + "checklist": "Resiliency Review", + "description": "Azure Site Recovery enables you to achieve low RTO (Recovery Time Objective) for your Azure and hybrid VMs by providing continuous replication and failover capabilities.", + "guid": "2a6bcca2-b5fe-4a1e-af3d-d95d48c7c891", + "link": "https://learn.microsoft.com/azure/site-recovery/site-recovery-overview", "services": [ - "SAP", - "Entra" + "AVS", + "VM", + "ASR" ], - "severity": "Medium", - "subcategory": "Identity", - "text": "If you're using SAP BTP services or SaaS solutions that require SAP Identity Authentication Service (IAS), consider implementing SSO between SAP Cloud Identity Authentication Services and Azure AD to access those SAP services. This integration lets SAP IAS act as a proxy identity provider and forwards authentication requests to Azure AD as the central user store and identity provider." + "severity": "High", + "subcategory": "Virtual Machines", + "text": "For Azure and on-premises VMs (Hyper-V/Phyiscal/VMware) with low RTO requirements use Azure Site Recovery", + "waf": "Reliability" }, { - "category": "Identity and Access", - "checklist": "Azure Landing Zone Review", - "guid": "a709c664-317e-41e4-9e34-67d9016a86f4", - "link": "https://learn.microsoft.com/azure/active-directory/saas-apps/sap-hana-cloud-platform-tutorial", + "category": "Compute", + "checklist": "Resiliency Review", + "description": "By using Capacity Reservations, you can effectively manage capacity for critical workloads, ensuring resource availability in specified regions.", + "guid": "bd7bb012-f7b9-45e0-9e15-8e3ea3992c2d", + "link": "https://learn.microsoft.com/azure/virtual-machines/capacity-reservation-overview", "services": [ - "SAP", - "Entra" + "VM" ], - "severity": "Medium", - "subcategory": "Identity", - "text": "Implement SSO to SAP BTP" + "severity": "Low", + "subcategory": "Virtual Machines", + "text": "Use Capacity Reservations for critical workloads that require guaranteed capacity", + "waf": "Reliability" }, { - "category": "Identity and Access", - "checklist": "Azure Landing Zone Review", - "guid": "01f11b7f-38df-4251-9c76-4dec19abd3e8", - "link": "https://learn.microsoft.com/azure/active-directory/saas-apps/sap-successfactors-inbound-provisioning-cloud-only-tutorial", + "category": "Compute", + "checklist": "Resiliency Review", + "description": "By ensuring that the necessary quotas are increased in your DR region before testing failover with ASR, you can avoid any potential resource constraints during the recovery process for failed over VMs.", + "guid": "e6e2065b-3a76-4af4-a691-e8939ada4666", + "link": "https://learn.microsoft.com/azure/quotas/per-vm-quota-requests", "services": [ - "SAP", - "Entra" + "VM", + "ASR" ], "severity": "Medium", - "subcategory": "Identity", - "text": "If you're using SAP SuccessFactors, consider using the Azure AD automated user provisioning. With this integration, as you add new employees to SAP SuccessFactors, you can automatically create their user accounts in Azure AD. Optionally, you can create user accounts in Microsoft 365 or other SaaS applications that are supported by Azure AD. Use write-back of the email address to SAP SuccessFactors." + "subcategory": "Virtual Machines", + "text": "Increase quotas in DR region before testing failover with ASR", + "waf": "Reliability" }, { - "category": "Management Group and Subscriptions", - "checklist": "Azure Landing Zone Review", - "guid": "6ba28021-4591-4147-9e39-e5309cccd979", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/resource-org-management-groups", + "category": "Compute", + "checklist": "Resiliency Review", + "description": "Scheduled Events is an Azure Metadata Service that provides information about upcoming maintenance events for virtual machines (VMs). By leveraging Scheduled Events, you can proactively prepare your applications for VM maintenance, minimizing disruption and improving the availability of your VMs.", + "guid": "6d3b475a-5c7a-4cbe-99bb-e64dd8902e87", + "link": "https://learn.microsoft.com/azure/virtual-machines/windows/scheduled-events", "services": [ - "SAP", - "AzurePolicy", - "Subscriptions" + "VM" ], - "severity": "Medium", - "subcategory": "Subscriptions", - "text": "enforce existing Management Group policies to SAP Subscriptions", - "training": "https://learn.microsoft.com/training/modules/enterprise-scale-organization/4-management-group-subscription-organization" + "severity": "Low", + "subcategory": "Virtual Machines", + "text": "Utilize Scheduled Events to prepare for VM maintenance", + "waf": "Reliability" }, { - "category": "Management Group and Subscriptions", - "checklist": "Azure Landing Zone Review", - "guid": "366bcda2-750a-4b1a-a039-d95d54c7c892", - "link": "https://learn.microsoft.com/azure/architecture/guide/sap/sap-whole-landscape", + "category": "Data", + "checklist": "Resiliency Review", + "description": "Use Zone-redundant Storage (ZRS) in the primary region for scenarios that require high availability and for restricting replication to a particular country or region. For protection against regional disasters, use Geo-zone-redundant Storage (GZRS), which combines ZRS in the primary region with geo-replication to a secondary region?.", + "guid": "48c7c891-dcb1-4f7d-9769-ae568ba38d4a", + "link": "https://learn.microsoft.com/azure/storage/common/storage-redundancy", "services": [ - "SAP", - "Subscriptions" + "Storage" ], - "severity": "High", - "subcategory": "Subscriptions", - "text": "Integrate tightly coupled applications into the same SAP subscription to avoid additional routing and management complexity", - "training": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/resource-org-subscriptions" + "severity": "Medium", + "subcategory": "Storage Accounts", + "text": "Choose the most appropriate data redundancy option for Azure Storage based on your requirements", + "waf": "Reliability" }, { - "category": "Management Group and Subscriptions", - "checklist": "Azure Landing Zone Review", - "guid": "9cb107d5-325a-4e52-9ba3-4d4685e2213a", - "link": "https://learn.microsoft.com/azure/architecture/guide/sap/sap-whole-landscape", + "category": "Data", + "checklist": "Resiliency Review", + "description": "Assigning a Delete lock to your storage account helps protect the availability of your data, minimizing the risk of disruptions to your business operations.", + "guid": "85e2213d-bd7b-4b01-8f7b-95e06e158e3e", + "link": "https://learn.microsoft.com/azure/storage/common/lock-account-resource", "services": [ - "Subscriptions" + "Storage" ], - "severity": "High", - "subcategory": "Subscriptions", - "text": "Leverage Subscription as scale unit and scaling our resources, consider deploying subscription per environment eg. Sandbox, non-prod, prod ", - "training": "https://learn.microsoft.com/training/modules/configure-subscriptions/?source=recommendations" + "severity": "Low", + "subcategory": "Storage Accounts", + "text": "Apply a Delete lock to prevent accidental or malicious deletion of storage accounts", + "waf": "Reliability" }, { - "category": "Management Group and Subscriptions", - "checklist": "Azure Landing Zone Review", - "guid": "ce7bb122-f7c9-45f0-9e15-4e3aa3592829", - "link": "https://learn.microsoft.com/azure/quotas/quotas-overview", + "category": "Data", + "checklist": "Resiliency Review", + "description": "Container soft delete protects your data from being accidentally deleted by maintaining the deleted data in the system for a specified period of time.", + "guid": "a3992c2d-e6e2-4065-a3a7-6af4a691e893", + "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-container-enable", "services": [ - "VM", - "Subscriptions" + "Storage" ], - "severity": "High", - "subcategory": "Subscriptions", - "text": "Ensure quota increase as a part of subscription provisioning (e.g. total available VM cores within a subscription)", - "training": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits" + "severity": "Low", + "subcategory": "Storage Accounts", + "text": "Enable soft delete for Storage Account Containers", + "waf": "Reliability" }, { - "category": "Management Group and Subscriptions", - "checklist": "Azure Landing Zone Review", - "guid": "ce4fab2f-433a-4d59-a5a9-3d1032e03ebc", - "link": "https://learn.microsoft.com/rest/api/reserved-vm-instances/quotaapi?branch=capacity", + "category": "Data", + "checklist": "Resiliency Review", + "description": "Blob soft delete protects an individual blob and its versions, snapshots, and metadata from accidental deletes or overwrites by maintaining the deleted data in the system for a specified period of time.", + "guid": "9ada4666-7e13-4c10-96b9-153d89f89dc7", + "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-blob-enable", "services": [ - "Subscriptions" + "Storage" ], "severity": "Low", - "subcategory": "Subscriptions", - "text": "The Quota API is a REST API that you can use to view and manage quotas for Azure services. Consider using it if necessary." + "subcategory": "Storage Accounts", + "text": "Enable soft delete for blobs", + "waf": "Reliability" }, { - "category": "Management Group and Subscriptions", - "checklist": "Azure Landing Zone Review", - "guid": "cbfad17b-f240-42bf-a1d8-f4f4cee661c8", - "link": "https://learn.microsoft.com/azure/quotas/quickstart-increase-quota-portal", + "category": "General", + "checklist": "Resiliency Review", + "description": "Azure Backup enhanced soft delete provides critical protection against ransomware attacks by retaining deleted backups, enabling recovery from potential ransomware encryption or deletion.", + "guid": "b44be3b1-a27f-48b9-b91b-e1038df03a82", + "link": "https://learn.microsoft.com/azure/backup/backup-azure-enhanced-soft-delete-about", "services": [ - "VM", - "Subscriptions" + "Backup" ], - "severity": "High", - "subcategory": "Subscriptions", - "text": "If deploying to an availability zone, ensure that the VM's zone deployment is available once the quota has been approved. Submit a support request with the subscription, VM series, number of CPUs and availability zone required." + "severity": "Medium", + "subcategory": "Backup", + "text": "Enable Azure Backup enhanced soft delete for improved data protection and recovery", + "waf": "Reliability" }, { - "category": "Management Group and Subscriptions", - "checklist": "Azure Landing Zone Review", - "guid": "e6e20617-3686-4af4-9791-f8935ada4332", - "link": "https://azure.microsoft.com/explore/global-infrastructure/products-by-region/", + "category": "General", + "checklist": "Resiliency Review", + "description": "Azure Backup's multi-user authorization enables fine-grained control over user access to backup resources, allowing you to restrict privileges and ensure proper authentication and authorization for backup operations.", + "guid": "2cd463cb-bbc8-4ac2-a9eb-c92a43da1dae", + "link": "https://learn.microsoft.com/azure/backup/multi-user-authorization-concept", "services": [ - "Subscriptions" + "Backup" ], - "severity": "High", - "subcategory": "Subscriptions", - "text": "Ensure required services and features are available within the chosen deployment regions eg. ANF , Zone etc.", - "training": "https://learn.microsoft.com/azure/cloud-adoption-framework/migrate/azure-best-practices/multiple-regions?source=recommendations" + "severity": "Low", + "subcategory": "Backup", + "text": "Implement multi-user authorization for Azure Backup to ensure secure and controlled access to backup resources", + "waf": "Reliability" }, { - "category": "Management Group and Subscriptions", - "checklist": "Azure Landing Zone Review", - "guid": "4e138115-2318-41aa-9174-26943ff8ae7d", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/sap/eslz-resource-organization", + "category": "General", + "checklist": "Resiliency Review", + "description": "Azure Immutable Storage provides an additional layer of security by ensuring that backup data stored in the vault cannot be modified or deleted for a specified retention period. This helps safeguard your backups from ransomware attacks that may attempt to compromise or manipulate your backup data.", + "guid": "2cc88147-0607-4c1c-aa0e-614658dd458e", + "link": "https://learn.microsoft.com/azure/backup/backup-azure-immutable-vault-concept?source=recommendations&tabs=recovery-services-vault", "services": [ - "TrafficManager", - "Subscriptions", - "Cost" + "Backup", + "Storage" ], - "severity": "Medium", - "subcategory": "Subscriptions", - "text": "Leverage Azure resource tag for cost categorization and resource grouping (: BillTo, Department (or Business Unit), Environment (Production, Stage, Development), Tier (Web Tier, Application Tier), Application Owner, ProjectName)", - "training": "https://learn.microsoft.com/training/paths/implement-resource-mgmt-security/" + "severity": "Low", + "subcategory": "Backup", + "text": "Implement Immutable Storage for your vaults to protect against ransomware and prevent unauthorized modifications to backups", + "waf": "Reliability" }, { - "category": "Management and Monitoring", - "checklist": "Azure Landing Zone Review", - "guid": "2f7c95f0-6e15-44e3-aa35-92829e6e2061", - "link": "https://learn.microsoft.com/azure/backup/sap-hana-database-about", + "category": "General", + "checklist": "Resiliency Review", + "description": "Clearly define your organization's business continuity and disaster recovery requirements for your Azure environment. This includes identifying the critical applications, data, and services that need to be protected, as well as specifying the desired recovery objectives and strategies.", + "guid": "72e52e36-11dd-458c-9a4b-1521e43a58a9", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/management-business-continuity-disaster-recovery", "services": [ - "Backup", - "Monitor" + "ASR" ], "severity": "High", - "subcategory": "BCDR", - "text": "Help protect your HANA database by using the Azure Backup service.", - "training": "https://learn.microsoft.com/training/modules/implement-azure-backup-sap-workloads-azure-virtual-machines/?source=recommendations" + "subcategory": "Design", + "text": "Define business continuity and disaster recovery requirements", + "waf": "Reliability" }, { - "category": "Management and Monitoring", - "checklist": "Azure Landing Zone Review", - "guid": "302a2fbf-3745-4a5f-a365-c9d1a16ca22c", - "link": "https://learn.microsoft.com/azure/azure-netapp-files/azacsnap-introduction", + "category": "General", + "checklist": "Resiliency Review", + "description": "Ensure that your Azure architectures are designed with a focus on reliability. Consider implementing fault-tolerant mechanisms, redundancy, and resiliency patterns to minimize the impact of failures and maximize the availability of your applications and services.", + "guid": "c2399c4d-7b67-4d0c-9555-62f2b3e4563a", + "link": "https://learn.microsoft.com/azure/architecture/reliability/architect", + "services": [], + "severity": "High", + "subcategory": "Design", + "text": "Implement reliability best practices in Azure architectures", + "waf": "Reliability" + }, + { + "category": "General", + "checklist": "Resiliency Review", + "description": "IaC configurations can play a role in your disaster recovery plan, particularly in situations where recovery time is not time-sensitive. In the event of infrastructure recreation in a second region, IaC can be used to reproduce the necessary infrastructure.", + "guid": "fe237de2-43b1-46c3-8d7a-a9b7570449aa", + "link": "https://learn.microsoft.com/azure/well-architected/devops/automation-infrastructure", "services": [ - "VM", - "Storage", - "Monitor", - "Entra" + "RBAC", + "ASR" ], "severity": "Medium", - "subcategory": "BCDR", - "text": "If you deploy Azure NetApp Files for your HANA, Oracle, or DB2 database, use the Azure Application Consistent Snapshot tool (AzAcSnap) to take application-consistent snapshots. AzAcSnap also supports Oracle databases. Consider using AzAcSnap on a central VM rather than on individual VMs." + "subcategory": "DevOps", + "text": "Implement Infrastructure as Code (IaC) for Rapid Infrastructure Recovery", + "waf": "Reliability" }, { - "category": "Management and Monitoring", - "checklist": "Azure Landing Zone Review", - "guid": "42d37218-a3a7-45df-bff6-1173e7f249ea", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/sap/eslz-management-and-monitoring", + "category": "General", + "checklist": "Resiliency Review", + "description": "Azure offers region pairs that are geographically separated and can be used for cross-region replication and disaster recovery. These region pairs provide redundancy and protection against regional or large-scale disasters.", + "guid": "dcb1f7d5-769a-4e56-aba3-8d4a85e2213d", + "link": "https://learn.microsoft.com/azure/reliability/cross-region-replication-azure", "services": [ - "SAP", - "Monitor" + "ASR" ], - "severity": "High", - "subcategory": "Management", - "text": "Ensure time-zone matches between the operating system and the SAP system." + "severity": "Medium", + "subcategory": "Multi-region", + "text": "Plan for cross-region recovery by leveraging region pairs", + "waf": "Reliability" }, { - "category": "Management and Monitoring", - "checklist": "Azure Landing Zone Review", - "guid": "c3c7abc0-716c-4486-893c-40e181d65539", - "link": "https://learn.microsoft.com/azure/sap/workloads/high-availability-guide-rhel-multi-sid", + "category": "Network", + "checklist": "Resiliency Review", + "description": "By deploying an Application Gateway with a minimum instance count of two, you will have at least two instances available under normal circumstances. In the event that one of the instances encounters a problem, the other instance will handle the traffic while a new instance is being created. This approach significantly reduces the risk of service disruption and ensures a seamless experience for your users.", + "guid": "93c76286-37a5-451c-9b04-e4f1854387e5", + "link": "https://learn.microsoft.com/azure/application-gateway/application-gateway-autoscaling-zone-redundant#autoscaling-and-high-availability", "services": [ - "Monitor", - "Entra" + "AppGW" ], "severity": "Medium", - "subcategory": "Management", - "text": "Don't group different application services in the same cluster. For example, don't combine DRBD and central services clusters on the same cluster. However, you can use the same Pacemaker cluster to manage approximately five different central services (multi-SID cluster).", - "training": "https://learn.microsoft.com/training/modules/implement-ha-sap-netweaver-anydb/?source=recommendations" + "subcategory": "Application Gateways", + "text": "Deploy Application Gateways with a minimum instance count of 2 to avoid instance provisioning downtime", + "waf": "Reliability" }, { - "category": "Management and Monitoring", - "checklist": "Azure Landing Zone Review", - "guid": "a491dfc4-9353-4213-9217-eef0949f9467", - "link": "https://azure.microsoft.com/pricing/offers/dev-test/", + "category": "Network", + "checklist": "Resiliency Review", + "description": "The v2 SKU offers several advantages and critical new features that enhance the availability and resilience of your application infrastructure. One notable feature supported by the v2 SKU is zone redundancy, which allows an Application Gateway deployment to span multiple Availability Zones.", + "guid": "ced126cd-032a-4f5b-8fc6-998a535e3378", + "link": "https://learn.microsoft.com/azure/application-gateway/overview-v2", "services": [ - "Monitor", - "Cost" + "Storage", + "AppGW" ], - "severity": "Low", - "subcategory": "Management", - "text": "Consider running dev/test systems in a snooze model to save and optimize Azure run costs." + "severity": "High", + "subcategory": "Application Gateways", + "text": "Deploy Azure Application Gateway v2 for zone redundancy support", + "waf": "Reliability" }, { - "category": "Management and Monitoring", - "checklist": "Azure Landing Zone Review", - "guid": "b7056168-6199-4732-a514-cdbb2d5c9c54", - "link": "https://learn.microsoft.com/azure/lighthouse/overview", + "category": "Network", + "checklist": "Resiliency Review", + "description": "Azure Front Door provides automatic failover capabilities, ensuring continuity in the event of a primary region becoming unavailable. However, during the failover process, there may be a brief period (typically 20-60 seconds) when clients cannot reach the application. It is essential to review the Azure Front Door service level agreement (SLA) to determine whether relying solely on Front Door meets your business requirements for high availability. ", + "guid": "97e31c67-d68c-4f6a-92a1-194956d697dc", + "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/app-service-web-app/multi-region#azure-front-door", "services": [ - "SAP", - "Monitor", - "Entra" + "FrontDoor" ], - "severity": "Medium", - "subcategory": "Management", - "text": "If you partner with customers by managing their SAP estates, consider Azure Lighthouse. Azure Lighthouse allows managed service providers to use Azure native identity services to authenticate to the customers' environment. It puts the control in the hands of customers, because they can revoke access at any time and audit service providers' actions." + "severity": "Low", + "subcategory": "Azure Front Door", + "text": "Consider a redundant traffic management solution in conjunction with Azure Front Door", + "waf": "Reliability" }, { - "category": "Management and Monitoring", - "checklist": "Azure Landing Zone Review", - "guid": "4d116785-d2fa-456c-96ad-48408fe72734", - "link": "https://learn.microsoft.com/azure/update-manager/scheduled-patching?tabs=schedule-updates-single-machine%2Cschedule-updates-scale-overview", + "category": "Network", + "checklist": "Resiliency Review", + "description": "By implementing Traffic Manager, you can configure it to continuously monitor the health of your application endpoints and automatically redirect traffic to an alternate endpoint when necessary. This automation minimizes downtime and provides a more seamless experience for your users during disaster recovery scenarios.", + "guid": "8df03a82-2cd4-463c-abbc-8ac299ebc92a", + "link": "https://learn.microsoft.com/azure/networking/disaster-recovery-dns-traffic-manager", "services": [ - "VM", - "Monitor" + "TrafficManager", + "Monitor", + "ASR", + "DNS" ], - "severity": "Medium", - "subcategory": "Management", - "text": "Use Azure Update Manager to check the status of available updates for a single VM or multiple VMs and consider scheduling regular patching.", - "training": "https://learn.microsoft.com/training/modules/keep-your-virtual-machines-updated/?source=recommendations" + "severity": "Low", + "subcategory": "DNS", + "text": "Plan for automated failover using Traffic Manager for DNS Traffic", + "waf": "Reliability" }, { - "category": "Management and Monitoring", - "checklist": "Azure Landing Zone Review", - "guid": "76c8bcbf-45bb-4e60-ad8a-03e97778424d", - "link": "https://learn.microsoft.com/azure/sap/workloads/lama-installation", + "category": "Network", + "checklist": "Resiliency Review", + "description": "To eliminate a single point of failure in your on-premises DNS services and ensure reliable DNS resolution during business continuity and disaster recovery scenarios, it is recommended to utilize Azure DNS Private Resolvers in multiple regions. By deploying two or more Azure DNS private resolvers across different regions, you can enable DNS failover and achieve resiliency in your DNS infrastructure.", + "guid": "43da1dae-2cc8-4814-9060-7c1cca0e6146", + "link": "https://learn.microsoft.com/azure/dns/tutorial-dns-private-resolver-failover", "services": [ - "SAP", - "Monitor" + "ACR", + "ASR", + "DNS" ], "severity": "Low", - "subcategory": "Management", - "text": "Optimize and manage SAP Basis operations by using SAP Landscape Management (LaMa). Use the SAP LaMa connector for Azure to relocate, copy, clone, and refresh SAP systems.", - "training": "https://learn.microsoft.com/training/modules/explore-azure-remote-management/?source=recommendations" + "subcategory": "DNS", + "text": "Implement DNS Failover using Azure DNS Private Resolvers", + "waf": "Reliability" }, { - "category": "Management and Monitoring", - "checklist": "Azure Landing Zone Review", - "guid": "14591147-5e39-4e53-89cc-cd979366bcda", - "link": "https://learn.microsoft.com/azure/sap/monitor/about-azure-monitor-sap-solutions", + "category": "Network", + "checklist": "Resiliency Review", + "description": "Use an on-premises data gateway cluster to avoid single points of failure and to load balance traffic across gateways.", + "guid": "89f89dc7-b44b-4e3b-8a27-f8b9e91be103", + "link": "https://learn.microsoft.com/data-integration/gateway/service-gateway-high-availability-clusters", "services": [ - "SAP", - "SQL", - "Monitor" + "ACR" ], "severity": "Medium", - "subcategory": "Monitoring", - "text": "Use Azure Monitor for SAP solutions to monitor your SAP workloads(SAP HANA, high-availability SUSE clusters, and SQL systems) on Azure. Consider supplementing Azure Monitor for SAP solutions with SAP Solution Manager.", - "training": "https://learn.microsoft.com/training/modules/implement-azure-monitoring-sap-workloads-azure-virtual-machines/?source=recommendations" + "subcategory": "Data Gateways", + "text": "Use on-premises data gateway clusters to ensure high availability for business-critical data", + "waf": "Reliability" }, { - "category": "Management and Monitoring", - "checklist": "Azure Landing Zone Review", - "guid": "2750ab1a-b039-4d95-b54c-7c8929cb107d", - "link": "https://learn.microsoft.com/azure/sap/workloads/vm-extension-for-sap", + "category": "Network", + "checklist": "Resiliency Review", + "description": "When using ExpressRoute, it's important to design for high availability by incorporating redundancy in both the partner and customer networks. This can include multiple ExpressRoute circuits, redundant connections from your network to Microsoft, and ensuring your on-premises network equipment has redundant connections.", + "guid": "c0e7c28d-c936-4657-802b-ff4564b0d934", + "link": "https://learn.microsoft.com/azure/expressroute/designing-for-high-availability-with-expressroute", "services": [ - "SAP", - "VM", - "Monitor", - "Entra" + "ExpressRoute" ], - "severity": "High", - "subcategory": "Monitoring", - "text": "Run a VM Extension for SAP check. VM Extension for SAP uses the assigned managed identity of a virtual machine (VM) to access VM monitoring and configuration data. The check ensures that all performance metrics in your SAP application come from the underlying Azure Extension for SAP.", - "training": "https://learn.microsoft.com/training/modules/configure-azure-enhanced-monitoring-extension-for-sap/?source=recommendations" + "severity": "Medium", + "subcategory": "ExpressRoute", + "text": "Ensure redundancy within both the partner network and customer network when utilizing ExpressRoute for high availability", + "waf": "Reliability" }, { - "category": "Management and Monitoring", - "checklist": "Azure Landing Zone Review", - "guid": "5325ae52-5ba3-44d4-985e-2213ace7bb12", - "link": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", + "category": "Network", + "checklist": "Resiliency Review", + "description": "The primary circuit should handle regular traffic while the backup circuit stays ready to take over if the primary circuit fails. Utilize BGP attributes to influence routing and designate your primary and backup circuits effectively.", + "guid": "a359c373-e7dd-4616-83a3-64a907ebae48", + "link": "https://learn.microsoft.com/azure/expressroute/designing-for-disaster-recovery-with-expressroute-privatepeering", "services": [ - "AzurePolicy", - "Monitor" + "ExpressRoute", + "Backup" ], "severity": "Medium", - "subcategory": "Monitoring", - "text": "Use Azure Policy for access control and compliance reporting. Azure Policy provides the ability to enforce organization-wide settings to ensure consistent policy adherence and fast violation detection. ", - "training": "https://learn.microsoft.com/learn/paths/architect-infrastructure-operations/" + "subcategory": "ExpressRoute", + "text": "When using multiple ExpressRoute circuits ensure that routing allows for a primary and backup", + "waf": "Reliability" }, { - "category": "Management and Monitoring", - "checklist": "Azure Landing Zone Review", - "guid": "523181aa-4174-4269-93ff-8ae7d7d47431", - "link": "https://learn.microsoft.com/azure/network-watcher/connection-monitor-overview", + "category": "Network", + "checklist": "Resiliency Review", + "description": "S2S VPN connection can provide a cost-effective, resilient backup solution in the event of an ExpressRoute circuit failure. By using S2S VPN as a failover, you can maintain connectivity to your Azure resources without relying solely on ExpressRoute.", + "guid": "ead53cc7-de2e-48aa-ab35-71549ab9153d", + "link": "https://learn.microsoft.com/azure/expressroute/use-s2s-vpn-as-backup-for-expressroute-privatepeering", "services": [ - "SAP", - "Monitor", - "NetworkWatcher" + "ExpressRoute", + "Cost", + "Backup", + "VPN" ], - "severity": "Medium", - "subcategory": "Monitoring", - "text": "Use Connection Monitor in Azure Network Watcher to monitor latency metrics for SAP databases and application servers. Or collect and display network latency measurements by using Azure Monitor.", - "training": "https://techcommunity.microsoft.com/t5/running-sap-applications-on-the/collecting-and-displaying-niping-network-latency-measurements/ba-p/1833979" + "severity": "Low", + "subcategory": "ExpressRoute", + "text": "Consider deploying site-to-site VPN as a backup for your ExpressRoute private peering", + "waf": "Reliability" }, { - "category": "Management and Monitoring", - "checklist": "Azure Landing Zone Review", - "guid": "d89fd98d-23e4-4b40-a92e-32db9365522c", - "link": "https://learn.microsoft.com/azure/site-recovery/site-recovery-monitor-and-troubleshoot", + "category": "Network", + "checklist": "Resiliency Review", + "description": "Standard Load Balancer SKU offers an SLA of 99.99% and a higher level of service availability compared to the Basic Load Balancer SKU.", + "guid": "778468d5-5a78-45d6-be96-c96ad8844cf3", + "link": "https://learn.microsoft.com/azure/load-balancer/skus", "services": [ - "SAP", - "ASR", - "Monitor" + "LoadBalancer" ], - "severity": "High", - "subcategory": "Monitoring", - "text": "Use Azure Site Recovery monitoring to maintain the health of the disaster recovery service for SAP application servers.", - "training": "https://learn.microsoft.com/training/modules/protect-on-premises-infrastructure-with-azure-site-recovery/?source=recommendations" + "severity": "Medium", + "subcategory": "Load Balancers", + "text": "Leverage the Standard SKU for Load Balancers that handle traffic to production applications", + "waf": "Reliability" }, { - "category": "Management and Monitoring", - "checklist": "Azure Landing Zone Review", - "guid": "73686af4-6791-4f89-95ad-a43324e13811", - "link": "https://github.com/Azure/SAP-on-Azure-Scripts-and-Utilities/tree/main/QualityCheck", + "category": "Network", + "checklist": "Resiliency Review", + "description": "By configuring the load balancer with a zone-redundant frontend, it can serve zonal resources in any zone with a single IP address. As long as at least one zone remains healthy within the region, the IP address associated with the frontend can survive one or more zone failures. It is recommended to have multiple zonal resources, such as virtual machines from different zones, in the backend pool of the load balancer. ", + "guid": "b2b38c88-6ba2-4c02-8499-114a5d3ce574", + "link": "https://learn.microsoft.com/azure/load-balancer/load-balancer-standard-availability-zones", "services": [ - "SAP", "VM", - "Monitor" + "LoadBalancer" ], - "severity": "Medium", - "subcategory": "Monitoring", - "text": "Perform a quality check for SAP HANA on the provisioned Azure infrastructure to verify that provisioned VMs comply with SAP HANA on Azure best practices." + "severity": "Low", + "subcategory": "Load Balancers", + "text": "For load balancers, consider using a zone-redundant frontend with multiple zonal resources in the backend", + "waf": "Reliability" }, { - "category": "Management and Monitoring", - "checklist": "Azure Landing Zone Review", - "guid": "616785d6-fa96-4c96-ad88-518f482734c8", - "link": "https://learn.microsoft.com/azure/sap/workloads/high-availability-zones", + "category": "Network", + "checklist": "Resiliency Review", + "description": "When designing health probes for your Azure Load Balancer, it is important to follow best practices to ensure reliable and accurate monitoring of your backend instances.", + "guid": "dccbd979-2a6b-4cca-8b5f-ea1ebf3dd95d", + "link": "https://learn.microsoft.com/azure/load-balancer/load-balancer-custom-probe-overview#design-guidance", "services": [ - "SAP", "Monitor", - "Subscriptions" + "LoadBalancer" ], - "severity": "High", - "subcategory": "Monitoring", - "text": "For each Azure subscription, run a latency test on Azure availability zones before zonal deployment to choose low-latency zones for deployment of SAP on Azure.", - "training": "https://github.com/Azure/SAP-on-Azure-Scripts-and-Utilities/tree/main/AvZone-Latency-Test" + "severity": "Low", + "subcategory": "Load Balancers", + "text": "Select the right protocol, appropriate intervals and timeouts, representative paths and probe responses when defining Load Balancer Health Probes", + "waf": "Reliability" }, { - "category": "Management and Monitoring", - "checklist": "Azure Landing Zone Review", - "guid": "410adcba-db46-424f-a6c4-05ecde75c52e", - "link": "https://learn.microsoft.com/azure/advisor/advisor-how-to-improve-reliability", + "category": "Network", + "checklist": "Resiliency Review", + "description": "When choosing the best option for deploying NVAs in Azure, it is crucial to consider the vendor's recommendations and validate that the specific design has been vetted and validated by the NVA vendor. The vendor should also provide the necessary NVA configuration for seamless integration in Azure.", + "guid": "8b1188b3-c6a4-46ce-a544-451e192d3442", + "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/dmz/nva-ha", "services": [ - "ASR", - "Storage", - "Monitor" + "NVA" ], - "severity": "Medium", - "subcategory": "Monitoring", - "text": "Run the Resiliency Report to ensure that the configuration of the entire provisioned Azure infrastructure (Compute, Database, Networking, Storage, Site Recovery) complies with the configuration defined by Cloud Adaption Framework for Azure.", - "training": "https://learn.microsoft.com/training/paths/azure-well-architected-framework/" + "severity": "High", + "subcategory": "NVAs", + "text": "Deploy Network Virtual Appliances (NVAs) in a vendor supported configuration for High Availability", + "waf": "Reliability" }, { - "category": "Management and Monitoring", - "checklist": "Azure Landing Zone Review", - "guid": "86ba2802-1459-4114-95e3-9e5309cccd97", - "link": "https://learn.microsoft.com/azure/sentinel/sap/deployment-overview", + "category": "Network", + "checklist": "Resiliency Review", + "description": "By deploying VPN Gateways in an active-active mode, you can distribute VPN traffic across multiple gateways, improving reliability and ensuring continuous connectivity in case of failures or maintenance.", + "guid": "927139b8-2110-42db-b6ea-f11e6f843e53", + "link": "https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-highlyavailable", "services": [ - "SAP", - "Sentinel", - "Monitor" + "ACR", + "VPN" ], "severity": "Medium", - "subcategory": "Monitoring", - "text": "Implement threat protection by using the Microsoft Sentinel solution for SAP. Use this solution to monitor your SAP systems and detect sophisticated threats throughout the business logic and application layers.", - "training": "https://learn.microsoft.com/training/modules/plan-microsoft-sentinel-deployment-sap/?source=recommendations" + "subcategory": "VPN Gateways", + "text": "Deploy Azure VPN Gateways in an active-active mode to ensure high availability and redundancy for your VPN connections.", + "waf": "Reliability" }, { - "category": "Management and Monitoring", - "checklist": "Azure Landing Zone Review", - "guid": "579266bc-ca27-45fa-a1ab-fe9d55d04c3c", - "link": "https://learn.microsoft.com/azure/cost-management-billing/costs/enable-tag-inheritance", + "category": "Network", + "checklist": "Resiliency Review", + "description": "Zone-redundant SKUs ensure that your VPN gateways are physically and logically separated within a region, providing resiliency and scalability. This deployment configuration safeguards your on-premises network connectivity to Azure from zone-level failures.", + "guid": "f4722d92-8c1b-41cd-921f-54b29b9de39a", + "link": "https://learn.microsoft.com/azure/vpn-gateway/about-zone-redundant-vnet-gateways", "services": [ - "Monitor", - "Cost" + "VPN" ], "severity": "Medium", - "subcategory": "Monitoring", - "text": "Azure tagging can be leveraged to logically group and track resources, automate their deployments, and most importantly, provide visibility on the incurred costs.", - "training": "https://learn.microsoft.com/training/modules/analyze-costs-create-budgets-azure-cost-management/?source=recommendations" + "subcategory": "VPN Gateways", + "text": "Use zone-redundant SKUs when deploying VPN Gateways to enhance resilience and protect against zone-level failures", + "waf": "Reliability" }, { - "category": "Management and Monitoring", - "checklist": "Azure Landing Zone Review", - "guid": "04b8e5e5-13cb-4b22-af62-5a8ecfcf0337", - "link": "https://learn.microsoft.com/azure/virtual-network/virtual-network-test-latency?tabs=windows", + "category": "Version Control", + "checklist": "Azure DevOps", + "description": "Implement branching policy in Azure DevOps", + "guid": "eda1dae2-cc85-4c47-a6b7-81cca0e6c465", + "id": "A01.01", + "link": "https://learn.microsoft.com/azure/devops/repos/git/branch-policies-overview?view=azure-devops", "services": [ - "VM", - "Monitor" + "AzurePolicy" ], - "severity": "Low", - "subcategory": "Performance", - "text": "Use inter-VM latency monitoring for latency-sensitive applications." + "severity": "High", + "subcategory": "Branching Policy", + "text": " Branch Policies" }, { - "category": "Management and Monitoring", - "checklist": "Azure Landing Zone Review", - "guid": "07e5ed53-3d96-43d8-87ea-631b77da5aba", - "link": "https://learn.microsoft.com/azure/sap/workloads/planning-guide-storage", + "category": "Version Control", + "checklist": "Azure DevOps", + "description": "Understand branch strategy such as GitFlow or GitHub Flow", + "guid": "bc288bec-6a16-4ca7-8444-51e1add34529", + "id": "A01.02", + "link": "https://learn.microsoft.com/azure/devops/repos/git/git-branching-guidance?view=azure-devops", "services": [ - "SAP", - "ASR", - "Monitor" + "AzurePolicy" ], - "severity": "Medium", - "subcategory": "Performance", - "text": "Use Azure Site Recovery monitoring to maintain the health of the disaster recovery service for SAP application servers.", - "training": "https://learn.microsoft.com/training/modules/explore-azure-storage/?source=recommendations" + "severity": "High", + "subcategory": "Branching Policy", + "text": "Branching strategy" }, { - "category": "Management and Monitoring", - "checklist": "Azure Landing Zone Review", - "guid": "abb6af9c-982c-4cf1-83fb-329fafd1ee56", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/sap/eslz-management-and-monitoring", + "category": "Version Control", + "checklist": "Azure DevOps", + "description": "Understand how teams work with git", + "guid": "ec723823-7a15-41c5-ab4e-401914387e5c", + "id": "A01.03", + "link": "https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow", "services": [ - "SAP", - "Storage", - "Monitor" + "AzurePolicy" ], - "severity": "Medium", - "subcategory": "Performance", - "text": "Exclude all the database file systems and executable programs from antivirus scans. Including them could lead to performance problems. Check with the database vendors for prescriptive details on the exclusion list. For example, Oracle recommends excluding /oracle//sapdata from antivirus scans." + "severity": "High", + "subcategory": "Branching Policy", + "text": "Understand GitFlow Branch Strategy" }, { - "category": "Management and Monitoring", - "checklist": "Azure Landing Zone Review", - "guid": "c027f893-f404-41a9-b33d-39d625a14964", - "link": "https://sapit-forme-prod.authentication.eu11.hana.ondemand.com/login", + "category": "Version Control", + "checklist": "Azure DevOps", + "description": "Merge into higher branches after two or more reviewers in a PR", + "guid": "a9c26c9c-32ab-45bd-8c69-98a246e33899", + "id": "A01.04", + "link": "https://learn.microsoft.com/azure/devops/repos/git/review-pull-requests?view=azure-devops&tabs=browser", "services": [ - "SAP", - "Monitor" + "AzurePolicy" ], - "severity": "Low", - "subcategory": "Performance", - "text": "Consider collecting full database statistics for non-HANA databases after migration. For example, implement SAP note 1020260 - Delivery of Oracle statistics." + "severity": "High", + "subcategory": "Branching Policy", + "text": "Pull Request Review" }, { - "category": "Management and Monitoring", - "checklist": "Azure Landing Zone Review", - "guid": "fdafb1f5-3eee-4354-a8c9-deb8127ebc2e", - "link": "https://learn.microsoft.com/azure/virtual-machines/workloads/oracle/configure-oracle-asm", + "category": "Version Control", + "checklist": "Azure DevOps", + "description": "Implement access control to the branches", + "guid": "7e41c77d-68cb-46a2-8ac1-9f916d697d8e", + "id": "A01.05", + "link": "https://learn.microsoft.com/azure/devops/repos/git/branch-permissions?view=azure-devops", "services": [ - "SAP", - "Storage", - "Monitor" + "AzurePolicy" ], "severity": "Medium", - "subcategory": "Performance", - "text": "Consider using Oracle Automatic Storage Management (ASM) for all Oracle deployments that use SAP on Azure.", - "training": "https://learn.microsoft.com/training/paths/administer-infrastructure-resources-in-azure/?source=recommendations" + "subcategory": "Branching Policy", + "text": "Access Control to the Branch" + }, + { + "category": "Version Control", + "checklist": "Azure DevOps", + "description": "Perform SAST code scan", + "guid": "adfd27bd-e187-401a-a252-baa9b68a088c", + "id": "A02.01", + "link": "https://devblogs.microsoft.com/devops/integrate-security-into-your-developer-workflow-with-github-advanced-security-for-azure-devops/", + "services": [], + "severity": "High", + "subcategory": "Security", + "text": "Code Scan" + }, + { + "category": "Version Control", + "checklist": "Azure DevOps", + "description": "Understand TFVC as Code Repo", + "guid": "9a8f822b-8eb9-4d1b-a77f-26e5e6beba8e", + "id": "A03.01", + "link": "https://learn.microsoft.com/azure/devops/repos/tfvc/what-is-tfvc?view=azure-devops", + "services": [], + "severity": "Low", + "subcategory": "Practice", + "text": "TFVC as Code Repository" + }, + { + "category": "Version Control", + "checklist": "Azure DevOps", + "description": "Compare Git vs TFVC for your project", + "guid": "d4f3437b-c336-4d71-9f27-a71eee0b9b5d", + "id": "A03.02", + "link": "https://learn.microsoft.com/azure/devops/repos/tfvc/comparison-git-tfvc?view=azure-devops", + "services": [], + "severity": "Low", + "subcategory": "Practice", + "text": "Choose Right version control" + }, + { + "category": "Azure Boards", + "checklist": "Azure DevOps", + "description": "Set up your team management", + "guid": "8defd5d7-21d4-41d2-900c-807bf9eab40f", + "id": "B01.01", + "link": "https://learn.microsoft.com/azure/devops/organizations/settings/manage-teams?view=azure-devops", + "services": [], + "severity": "High", + "subcategory": "Team Planning", + "text": "Configure your teams" }, { - "category": "Management and Monitoring", - "checklist": "Azure Landing Zone Review", - "guid": "33c5d5bf-daf3-4f0d-bd50-6010fdcec22e", - "link": "https://techcommunity.microsoft.com/t5/running-sap-applications-on-the/announcement-sap-on-azure-oracle-performance-efficiency-scripts/ba-p/3725178", - "services": [ - "SAP", - "SQL", - "Monitor" - ], + "category": "Azure Boards", + "checklist": "Azure DevOps", + "description": "Start scheduling sprints", + "guid": "9ed5b354-78d4-447a-a26c-2863c00f1cac", + "id": "B01.02", + "link": "https://learn.microsoft.com/azure/devops/boards/sprints/define-sprints?view=azure-devops", + "services": [], "severity": "Medium", - "subcategory": "Performance", - "text": "For SAP on Azure running Oracle, a collection of SQL scripts can help you diagnose performance problems. Automatic Workload Repository (AWR) reports contain valuable information for diagnosing problems in the Oracle system. We recommend that you run an AWR report during several sessions and choose peak times for it, to ensure broad coverage for the analysis.", - "training": "https://learn.microsoft.com/ja-jp/azure/well-architected/oracle-iaas/performance-efficiency" + "subcategory": "Team Planning", + "text": "Configure your sprints" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "5ba34d46-85e2-4213-ace7-bb122f7c95f0", - "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", - "services": [ - "AzurePolicy", - "AppGW", - "WAF" - ], - "severity": "Medium", - "subcategory": "App delivery", - "text": "For secure delivery of HTTP/S apps, use Application Gateway v2 and ensure that WAF protection and policies are enabled.", - "training": "https://learn.microsoft.com/training/modules/introduction-azure-web-application-firewall/" + "category": "Azure Boards", + "checklist": "Azure DevOps", + "description": "Set up your work item heirarchy", + "guid": "699ef1d5-a83d-4e5d-b36c-1c81870a0bc5", + "id": "B01.03", + "link": "https://learn.microsoft.com/azure/devops/organizations/settings/work/customize-process-work-item-type?view=azure-devops", + "services": [], + "severity": "Low", + "subcategory": "Team Planning", + "text": "Choose Work Item types" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "fa9d30bc-1b82-4e4b-bfdf-6b017938b9e6", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/sap/eslz-network-topology-and-connectivity", - "services": [ - "SAP", - "VM", - "DNS" - ], - "severity": "Medium", - "subcategory": "DNS", - "text": "If the virtual machine's DNS or virtual name is not changed during migration to Azure, Background DNS and virtual names connect many system interfaces in the SAP landscape, and customers are only sometimes aware of the interfaces that developers define over time. Connection challenges arise between various systems when virtual or DNS names change after migrations, and it's recommended to retain DNS aliases to prevent these types of difficulties.", - "training": "https://learn.microsoft.com/training/modules/explore-azure-networking/4-explore-name-resolution" + "category": "Azure Boards", + "checklist": "Azure DevOps", + "description": "WIT Processes available in Azure DevOps", + "guid": "c1e43a18-658d-4285-aed6-7179b825546d", + "id": "B01.04", + "link": "https://learn.microsoft.com/azure/devops/boards/work-items/guidance/choose-process?view=azure-devops&tabs=agile-process", + "services": [], + "severity": "High", + "subcategory": "Team Planning", + "text": "Select a WIT Process" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "a2858f78-105b-4f52-b7a9-5b0f4439743b", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/sap/eslz-network-topology-and-connectivity", - "services": [ - "SAP", - "DNS", - "VNet" - ], - "severity": "Medium", - "subcategory": "DNS", - "text": "Use different DNS zones to distinguish each environment (sandbox, development, preproduction, and production) from each other. The exception is for SAP deployments with their own VNet; here, private DNS zones might not be necessary.", - "training": "https://learn.microsoft.com/training/modules/explore-azure-networking/4-explore-name-resolution" + "category": "Azure Boards", + "checklist": "Azure DevOps", + "description": "Use Azure Boards with GitHub", + "guid": "f2aee455-3afc-4833-a248-726dd68c5b5c", + "id": "B02.01", + "link": "https://learn.microsoft.com/azure/devops/cross-service/github-integration?view=azure-devops", + "services": [], + "severity": "Low", + "subcategory": "Tool Integration", + "text": "GitHub Integration" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "a3592829-e6e2-4061-9368-6af46791f893", - "link": "https://learn.microsoft.com/azure/virtual-network/virtual-network-peering-overview", - "services": [ - "SAP", - "ACR", - "VNet" - ], + "category": "Azure Boards", + "checklist": "Azure DevOps", + "description": "Understand the methologies", + "guid": "2925394b-69b9-4d37-aac4-3bc68d1d7665", + "id": "B03.01", + "link": "https://www.atlassian.com/agile/scrum/agile-vs-scrum", + "services": [], "severity": "Medium", - "subcategory": "Hybrid", - "text": "Local and global VNet peering provide connectivity and are the preferred approaches to ensure connectivity between landing zones for SAP deployments across multiple Azure regions", - "training": "https://learn.microsoft.com/training/modules/configure-vnet-peering/?source=recommendations" + "subcategory": "Process Planning", + "text": "Understand Agile Vs Scrum" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "41742694-3ff8-4ae7-b7d4-743176c8bcbf", - "link": "https://learn.microsoft.com/azure/sap/workloads/planning-guide", - "services": [ - "SAP", - "NVA" - ], - "severity": "High", - "subcategory": "Hybrid", - "text": "It is not supported to deploy any NVA between SAP application and SAP Database server", - "training": "https://me.sap.com/notes/2731110" + "category": "Azure Boards", + "checklist": "Azure DevOps", + "description": "Create Dashboard and PowerBI reports", + "guid": "7246b448-564b-44dd-94a7-59c7633bd2a1", + "id": "B04.01", + "link": "https://learn.microsoft.com/azure/devops/report/dashboards/overview?view=azure-devops", + "services": [], + "severity": "Medium", + "subcategory": "Reporting", + "text": "Dashboard" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "7d4bc7d2-c34a-452e-8f1d-6ae3c8eafcc3", - "link": "https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/?source=recommendations", - "services": [ - "SAP", - "ACR", - "VWAN" - ], + "category": "Azure Boards", + "checklist": "Azure DevOps", + "description": "Set up backlog", + "guid": "a27a764a-90be-40e3-98ee-293c1bd363ca", + "id": "B04.02", + "link": "https://learn.microsoft.com/azure/devops/boards/backlogs/set-up-your-backlog?view=azure-devops", + "services": [], "severity": "Medium", - "subcategory": "Hybrid", - "text": "Use Virtual WAN for Azure deployments in new, large, or global networks where you need global transit connectivity across Azure regions and on-premises locations. With this approach, you won't need to manually set up transitive routing for Azure networking, and you can follow a standard for SAP on Azure deployments.", - "training": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-about" + "subcategory": "Reporting", + "text": "Refine your backlog" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "0cedb1f6-ae6c-492b-8b17-8061f50b16d3", - "link": "https://learn.microsoft.com/azure/well-architected/services/networking/network-virtual-appliances/reliability", - "services": [ - "VNet", - "NVA" - ], + "category": "Azure Boards", + "checklist": "Azure DevOps", + "description": "Link your work items", + "guid": "aab75719-49ab-4919-9dc9-fc9d1bb84b37", + "id": "B04.03", + "link": "https://learn.microsoft.com/azure/devops/boards/queries/link-work-items-support-traceability?view=azure-devops&tabs=browser", + "services": [], "severity": "Medium", - "subcategory": "Hybrid", - "text": "Consider deploying network virtual appliances (NVAs) between regions only if partner NVAs are used. NVAs between regions or VNets aren't required if native NVAs are present. When you're deploying partner networking technologies and NVAs, follow the vendor's guidance to verify conflicting configurations with Azure networking.", - "training": "https://learn.microsoft.com/training/modules/control-network-traffic-flow-with-routes/?source=recommendations" + "subcategory": "Reporting", + "text": "Visualize Relationships" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "facc08c6-ea95-4641-91cd-fa09e573adbd", - "link": "https://learn.microsoft.com/azure/architecture/networking/hub-spoke-vwan-architecture", - "services": [ - "SAP", - "VNet", - "NVA", - "VWAN" - ], - "severity": "Medium", - "subcategory": "Hybrid", - "text": "Virtual WAN manages connectivity between spoke VNets for virtual-WAN-based topologies (no need to set up user-defined routing [UDR] or NVAs), and maximum network throughput for VNet-to-VNet traffic in the same virtual hub is 50 gigabits per second. If necessary, SAP landing zones can use VNet peering to connect to other landing zones and overcome this bandwidth limitation.", - "training": "https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/?source=recommendations" + "category": "Azure Pipelines", + "checklist": "Azure DevOps", + "description": "View the velocity report", + "guid": "b5a67fcb-9ed5-4b35-978d-447a826c2863", + "id": "C01.01", + "link": "https://learn.microsoft.com/azure/devops/report/dashboards/team-velocity?view=azure-devops&tabs=in-context", + "services": [], + "severity": "Low", + "subcategory": "Reporting", + "text": "Review Team Velocity" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "82734c88-6ba2-4802-8459-11475e39e530", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing", - "services": [ - "SAP", - "VM", - "VNet" - ], + "category": "Azure Pipelines", + "checklist": "Azure DevOps", + "description": "Create your first pipeline", + "guid": "c00f1cac-699e-4f1d-9a83-de5de36c1c81", + "id": "C02.01", + "link": "https://learn.microsoft.com/azure/devops/pipelines/create-first-pipeline?view=azure-devops&tabs=java%2Ctfs-2018-2%2Cbrowser", + "services": [], "severity": "High", - "subcategory": "IP plan", - "text": "Public I.P assignment to VM running SAP Workload is not recommended.", - "training": "https://learn.microsoft.com/training/modules/design-ip-addressing-for-azure/?source=recommendations" + "subcategory": "Continuous Integration", + "text": "Set up pipeline" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "9cccd979-366b-4cda-8750-ab1ab039d95d", - "link": "https://learn.microsoft.com/training/modules/protect-on-premises-infrastructure-with-azure-site-recovery/?source=recommendations", - "services": [ - "ASR", - "VNet" - ], + "category": "Azure Pipelines", + "checklist": "Azure DevOps", + "description": "Specify events that trigger pipelines", + "guid": "870a0bc5-c1e4-43a1-a658-d2858ed67179", + "id": "C02.02", + "link": "https://learn.microsoft.com/azure/devops/pipelines/build/triggers?view=azure-devops", + "services": [], "severity": "High", - "subcategory": "IP plan", - "text": "Consider reserving I.P address on DR side when configuring ASR", - "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/" + "subcategory": "Continuous Integration", + "text": "Set Build triggers" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "54c7c892-9cb1-407d-9325-ae525ba34d46", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing", - "services": [ - "VNet" - ], - "severity": "High", - "subcategory": "IP plan", - "text": "Avoid using overlapping IP address ranges for production and DR sites.", - "training": "https://learn.microsoft.com/training/modules/design-ip-addressing-for-azure/?source=recommendations" + "category": "Azure Pipelines", + "checklist": "Azure DevOps", + "description": "Use YAML to create build pipeline", + "guid": "b825546d-f2ae-4e45-93af-c8339248726d", + "id": "C02.03", + "link": "https://learn.microsoft.com/azure/devops/pipelines/customize-pipeline?view=azure-devops", + "services": [], + "severity": "Low", + "subcategory": "Continuous Integration", + "text": "Customize YAML Pipeline" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "6e154e3a-a359-4282-ae6e-206173686af4", - "link": "https://learn.microsoft.com/azure/azure-netapp-files/azure-netapp-files-delegate-subnet", - "services": [ - "Storage", - "VNet" - ], + "category": "Azure Pipelines", + "checklist": "Azure DevOps", + "description": "Use classic GUI editor to set up pipeline", + "guid": "d68c5b5c-2925-4394-a69b-9d379ac43bc6", + "id": "C02.04", + "link": "https://learn.microsoft.com/azure/devops/pipelines/get-started/pipelines-get-started?view=azure-devops&source=recommendations#define-pipelines-using-the-classic-interface", + "services": [], "severity": "Medium", - "subcategory": "IP plan", - "text": "While Azure does help you to create multiple delegated subnets in a VNet, only one delegated subnet can exist in a VNet for Azure NetApp Files. Attempts to create a new volume will fail if you use more than one delegated subnet for Azure NetApp Files.", - "training": "https://learn.microsoft.com/azure/azure-netapp-files/azure-netapp-files-network-topologies?source=recommendations" + "subcategory": "Continuous Integration", + "text": "Use GUI for pipeline" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "d8a03e97-7784-424d-9167-85d6fa96c96a", - "link": "https://learn.microsoft.com/azure/well-architected/services/networking/azure-firewall?toc=%2Fazure%2Ffirewall%2Ftoc.json&bc=%2Fazure%2Ffirewall%2Fbreadcrumb%2Ftoc.json", - "services": [ - "Firewall" - ], + "category": "Azure Pipelines", + "checklist": "Azure DevOps", + "description": "Set up templates, parameters and expressions", + "guid": "8d1d7665-7246-4b44-a564-b4dd74a759c7", + "id": "C02.05", + "link": "https://learn.microsoft.com/azure/devops/pipelines/process/templates?view=azure-devops&pivots=templates-includes", + "services": [], "severity": "Medium", - "subcategory": "Internet", - "text": "Use Azure Firewall to govern Azure outbound traffic to the internet, non-HTTP/S inbound connections, and East/West traffic filtering (if the organization requires it)", - "training": "https://learn.microsoft.com/training/paths/secure-networking-infrastructure/" + "subcategory": "Continuous Integration", + "text": "Configure Templates" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "91a65e40-be90-45b3-9f73-f3edbf8dc324", - "link": "https://learn.microsoft.com/azure/sap/workloads/expose-sap-process-orchestration-on-azure", - "services": [ - "SAP", - "AppGW", - "WAF" - ], - "severity": "Medium", - "subcategory": "Internet", - "text": "Application Gateway and Web Application Firewall have limitations when Application Gateway serves as a reverse proxy for SAP web apps, as shown in the comparison between Application Gateway, SAP Web Dispatcher, and other third-party services.", - "training": "https://help.sap.com/docs/SUPPORT_CONTENT/si/3362959506.html" + "category": "Azure Pipelines", + "checklist": "Azure DevOps", + "description": "Set up jobs, stages and dependencies", + "guid": "633bd2a1-a27a-4764-a90b-e0e378ee293c", + "id": "C02.06", + "link": "https://learn.microsoft.com/azure/devops/pipelines/process/stages?view=azure-devops&tabs=yaml", + "services": [], + "severity": "High", + "subcategory": "Continuous Integration", + "text": "Jobs" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "5e39e530-9ccc-4d97-a366-bcda2750ab1a", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", - "services": [ - "ACR", - "AzurePolicy", - "FrontDoor", - "WAF" - ], + "category": "Azure Pipelines", + "checklist": "Azure DevOps", + "description": "Set up conditions and Demands", + "guid": "1bd363ca-aab7-4571-a49a-b9193dc9fc9d", + "id": "C02.07", + "link": "https://learn.microsoft.com/azure/devops/pipelines/process/conditions?view=azure-devops&tabs=yaml%2Cstages", + "services": [], "severity": "Medium", - "subcategory": "Internet", - "text": "Use Azure Front Door and WAF policies to provide global protection across Azure regions for inbound HTTP/S connections to a landing zone.", - "training": "https://learn.microsoft.com/training/paths/secure-application-delivery/" + "subcategory": "Continuous Integration", + "text": "Conditions and Demands" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "b039d95d-54c7-4c89-89cb-107d5325ae52", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/afds-overview", - "services": [ - "AzurePolicy", - "FrontDoor", - "AppGW", - "WAF" - ], - "severity": "Medium", - "subcategory": "Internet", - "text": "Take advantage of Web Application Firewall policies in Azure Front Door when you're using Azure Front Door and Application Gateway to protect HTTP/S applications. Lock down Application Gateway to receive traffic only from Azure Front Door.", - "training": "https://learn.microsoft.com/training/modules/introduction-azure-web-application-firewall/?source=recommendations" + "category": "Azure Pipelines", + "checklist": "Azure DevOps", + "description": "Define Variables", + "guid": "1bb84b37-b5a6-47fc-a9ed-5b35478d447a", + "id": "C02.08", + "link": "https://learn.microsoft.com/azure/devops/pipelines/process/variables?view=azure-devops&tabs=yaml%2Cbatch", + "services": [], + "severity": "High", + "subcategory": "Continuous Integration", + "text": "Variables" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "5ada4332-4e13-4811-9231-81aa41742694", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", - "services": [ - "LoadBalancer", - "AppGW", - "WAF" - ], - "severity": "Medium", - "subcategory": "Internet", - "text": "Use a web application firewall to scan your traffic when it's exposed to the internet. Another option is to use it with your load balancer or with resources that have built-in firewall capabilities like Application Gateway or third-party solutions.", - "training": "https://learn.microsoft.com/training/modules/introduction-azure-web-application-firewall/?source=recommendations" + "category": "Azure Pipelines", + "checklist": "Azure DevOps", + "description": "Set up your deployment pipeline", + "guid": "826c2863-c00f-41ca-a699-ef1d5a83de5d", + "id": "C03.01", + "link": "https://learn.microsoft.com/azure/devops/pipelines/process/create-multistage-pipeline?view=azure-devops", + "services": [], + "severity": "High", + "subcategory": "Continuous Deployment", + "text": "Deployment Pipeline" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "e73de7d5-6f36-4217-a526-e1a621ecddde", - "link": "https://learn.microsoft.com/azure/frontdoor/front-door-overview", - "services": [ - "SAP", - "ACR", - "VWAN" - ], + "category": "Azure Pipelines", + "checklist": "Azure DevOps", + "description": "Select correct branches to deploy from", + "guid": "e36c1c81-870a-40bc-9c1e-43a18658d285", + "id": "C03.02", + "link": "https://learn.microsoft.com/azure/devops/pipelines/release/deploy-multiple-branches?view=azure-devops", + "services": [], "severity": "Medium", - "subcategory": "Internet", - "text": "Use Virtual WAN for Azure deployments in new, large, or global networks where you need global transit connectivity across Azure regions and on-premises locations. With this approach, you won't need to manually set up transitive routing for Azure networking, and you can follow a standard for SAP on Azure deployments.", - "training": "https://learn.microsoft.com/training/modules/explore-azure-networking/10-explore-azure-front-door" + "subcategory": "Continuous Deployment", + "text": "Release branch", + "training": "https://learn.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "3c536a3e-1b6b-4e87-95ca-15edb47251c0", - "link": "https://learn.microsoft.com/azure/virtual-network/vnet-integration-for-azure-services", - "services": [ - "VNet", - "ACR", - "Backup", - "Storage", - "PrivateLink" - ], + "category": "Azure Pipelines", + "checklist": "Azure DevOps", + "description": "use relevant template to deploy to azure", + "guid": "8ed67179-b825-4546-bf2a-ee4553afc833", + "id": "C03.03", + "link": "https://learn.microsoft.com/azure/devops/pipelines/overview-azure?view=azure-devops", + "services": [], "severity": "Medium", - "subcategory": "Internet", - "text": "To prevent data leakage, use Azure Private Link to securely access platform as a service resources like Azure Blob Storage, Azure Files, Azure Data Lake Storage Gen2, Azure Data Factory, and more. Azure Private Endpoint can also help to secure traffic between VNets and services like Azure Storage, Azure Backup, and more. Traffic between your VNet and the Private Endpoint enabled service travels across the Microsoft global network, which prevents its exposure to the public internet.", - "training": "https://learn.microsoft.com/training/modules/design-implement-private-access-to-azure-services/?source=recommendations" + "subcategory": "Continuous Deployment", + "text": "Deploy to Azure" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "85e2213a-ce7b-4b12-8f7c-95f06e154e3a", - "link": "https://learn.microsoft.com/azure/virtual-network/accelerated-networking-overview?tabs=redhat", - "services": [ - "SAP", - "VM" - ], - "severity": "High", - "subcategory": "Segmentation", - "text": "Make sure that Azure accelerated networking is enabled on the VMs used in the SAP application and DBMS layers.", - "training": "https://learn.microsoft.com/training/paths/azure-fundamentals-describe-azure-architecture-services/?source=recommendations" + "category": "Azure Pipelines", + "checklist": "Azure DevOps", + "description": "Define Release Approvals and pre deployment checks", + "guid": "9248726d-d68c-45b5-a292-5394b69b9d37", + "id": "C03.04", + "link": "https://learn.microsoft.com/azure/devops/pipelines/process/approvals?view=azure-devops&tabs=check-pass", + "services": [], + "severity": "Medium", + "subcategory": "Continuous Deployment", + "text": "Approvals and Checks", + "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "3ff8ae7d-7d47-4431-96c8-bcbf45bbe609", - "link": "https://learn.microsoft.com/azure/load-balancer/load-balancer-multivip-overview", - "services": [ - "LoadBalancer" - ], + "category": "Azure Pipelines", + "checklist": "Azure DevOps", + "description": "Define Gates and post deployment checks", + "guid": "9ac43bc6-8d1d-4766-9724-6b448564b4dd", + "id": "C03.05", + "link": "https://learn.microsoft.com/azure/devops/pipelines/release/approvals/?view=azure-devops&tabs=yaml", + "services": [], "severity": "Medium", - "subcategory": "Segmentation", - "text": "Make sure that internal deployments for Azure Load Balancer are set up to use Direct Server Return (DSR). This setting will reduce latency when internal load balancer configurations are used for high-availability configurations on the DBMS layer.", - "training": "https://learn.microsoft.com/ja-jp/training/modules/load-balancing-non-https-traffic-azure/?source=recommendations" + "subcategory": "Continuous Deployment", + "text": "Gates" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "6791f893-5ada-4433-84e1-3811523181aa", - "link": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", - "services": [ - "SAP", - "VM", - "VNet" - ], + "category": "Azure Pipelines", + "checklist": "Azure DevOps", + "description": "Define Azure Function and REST API Checks", + "guid": "74a759c7-633b-4d2a-8a27-a764a90be0e3", + "id": "C03.06", + "link": "https://learn.microsoft.com/azure/devops/pipelines/process/invoke-checks?view=azure-devops", + "services": [], + "severity": "Low", + "subcategory": "Continuous Deployment", + "text": "Azure Function Checks", + "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/" + }, + { + "category": "Azure Pipelines", + "checklist": "Azure DevOps", + "description": "Review pipeline reports", + "guid": "78ee293c-1bd3-463c-aaab-7571949ab919", + "id": "C03.07", + "link": "https://learn.microsoft.com/azure/devops/pipelines/reports/pipelinereport?view=azure-devops", + "services": [], + "severity": "High", + "subcategory": "Continuous Deployment", + "text": "Pipline Reports", + "training": "https://learn.microsoft.com/learn/modules/plan-implement-administer-conditional-access/" + }, + { + "category": "Azure Pipelines", + "checklist": "Azure DevOps", + "description": "configure Trend Result widget", + "guid": "3dc9fc9d-1bb8-44b3-9b5a-67fcb9ed5b35", + "id": "C04.01", + "link": "https://learn.microsoft.com/azure/devops/report/dashboards/analytics-widgets?toc=%2Fazure%2Fdevops%2Fpipelines%2Ftoc.json&view=azure-devops#test-results-trend-advanced", + "services": [], "severity": "Medium", - "subcategory": "Segmentation", - "text": "You can use application security group (ASG) and NSG rules to define network security access-control lists between the SAP application and DBMS layers. ASGs group virtual machines to help manage their security.", - "training": "https://learn.microsoft.com/training/modules/configure-network-security-groups/?source=recommendations" + "subcategory": "Analytics", + "text": "Pipeline Result Trend", + "training": "https://learn.microsoft.com/learn/modules/secure-aad-users-with-mfa/" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "45bbe609-d8a0-43e9-9778-424d616785d6", - "link": "https://me.sap.com/notes/2015553", - "services": [ - "SAP", - "VNet" - ], - "severity": "High", - "subcategory": "Segmentation", - "text": "Placing of the SAP application layer and SAP DBMS in different Azure VNets that aren't peered isn't supported.", - "training": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/sap/eslz-network-topology-and-connectivity" + "category": "Azure Pipelines", + "checklist": "Azure DevOps", + "description": "Connect with WIT to visualize work", + "guid": "478d447a-826c-4286-9c00-f1cac699ef1d", + "id": "C04.02", + "link": "https://learn.microsoft.com/azure/devops/pipelines/integrations/configure-pipelines-work-tracking?view=azure-devops&tabs=yaml", + "services": [], + "severity": "Medium", + "subcategory": "Analytics", + "text": "Work Tracking with Pipeline", + "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-identities-governance/" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "fa96c96a-d885-418f-9827-34c886ba2802", - "link": "https://learn.microsoft.com/azure/sap/workloads/proximity-placement-scenarios", - "services": [ - "SAP" - ], + "category": "Azure Pipelines", + "checklist": "Azure DevOps", + "description": "Understand agent pools", + "guid": "5a83de5d-e36c-41c8-8870-a0bc5c1e43a1", + "id": "C05.01", + "link": "https://learn.microsoft.com/azure/devops/pipelines/agents/agents?view=azure-devops&tabs=yaml%2Cbrowser", + "services": [], "severity": "Medium", - "subcategory": "Segmentation", - "text": "For optimal network latency with SAP applications, consider using Azure proximity placement groups.", - "training": "https://learn.microsoft.com/azure/virtual-machines/co-location#planned-maintenance-and-proximity-placement-groups" + "subcategory": "Continuous Deployment", + "text": " Agents and agent pools", + "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "18c8b61c-855a-4405-b6ed-266455e4f4ce", - "link": "https://me.sap.com/notes/2015553", - "services": [ - "SAP" - ], - "severity": "High", - "subcategory": "Segmentation", - "text": "It is NOT supported at all to run an SAP Application Server layer and DBMS layer split between on-premise and Azure. Both layers need to completely reside either on-premise or in Azure.", - "training": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/sap/eslz-network-topology-and-connectivity" + "category": "Azure Pipelines", + "checklist": "Azure DevOps", + "description": "Understand and provision Deployment Groups when required", + "guid": "8658d285-8ed6-4717-ab82-5546df2aee45", + "id": "C05.02", + "link": "https://learn.microsoft.com/azure/devops/pipelines/release/deployment-groups/?view=azure-devops", + "services": [], + "severity": "Low", + "subcategory": "Continuous Deployment", + "text": "Deployment Groups", + "training": "https://learn.microsoft.com/learn/modules/explore-basic-services-identity-types/" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "b65c878b-4b14-4f4e-92d8-d873936493f2", - "link": "https://me.sap.com/notes/2015553", + "category": "Azure Pipelines", + "checklist": "Azure DevOps", + "description": "Understand Kubernetes Deployment", + "guid": "53afc833-9248-4726-bd68-c5b5c2925394", + "id": "C05.03", + "link": "https://learn.microsoft.com/azure/devops/pipelines/ecosystems/kubernetes/deploy?view=azure-devops", "services": [ - "SAP", - "VNet", - "Cost" + "AKS" ], - "severity": "High", - "subcategory": "Segmentation", - "text": "It isn't recommended to host the database management system (DBMS) and application layers of SAP systems in different VNets and connect them with VNet peering because of the substantial costs that excessive network traffic between the layers can produce. Recommend using subnets within the Azure virtual network to separate the SAP application layer and DBMS layer.", - "training": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/sap/eslz-network-topology-and-connectivity" + "severity": "Low", + "subcategory": "Continuous Deployment", + "text": "Deploy to Kubernetes", + "training": "https://learn.microsoft.com/learn/paths/manage-identity-and-access/" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "85e2213a-ce7b-4b12-8f7c-95f06e154e3a", - "link": "https://learn.microsoft.com/azure/virtual-network/accelerated-networking-overview?tabs=redhat", - "services": [ - "SAP", - "VM" - ], - "severity": "High", - "subcategory": "Segmentation", - "text": "Make sure that Azure accelerated networking is enabled on the VMs used in the SAP application and DBMS layers.", - "training": "https://learn.microsoft.com/training/paths/azure-fundamentals-describe-azure-architecture-services/?source=recommendations" + "category": "Azure Pipelines", + "checklist": "Azure DevOps", + "description": "Perform Dynamic Security Testing", + "guid": "b69b9d37-9ac4-43bc-98d1-d76657246b44", + "id": "C06.01", + "link": "https://devblogs.microsoft.com/premier-developer/azure-devops-pipelines-leveraging-owasp-zap-in-the-release-pipeline/", + "services": [], + "severity": "Medium", + "subcategory": "Security", + "text": "DAST Scan", + "training": "https://learn.microsoft.com/learn/modules/create-custom-azure-roles-with-rbac/" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "402a9846-d515-4061-aff8-cd30088693fa", - "link": "https://learn.microsoft.com/azure/sap/workloads/high-availability-guide-rhel", - "services": [ - "LoadBalancer" - ], - "severity": "High", - "subcategory": "Segmentation", - "text": "If using Load Balancer with Linux guest operating systems, check that the Linux network parameter net.ipv4.tcp_timestamps is set to 0.", - "training": "https://learn.microsoft.com/training/modules/implement-ha-sap-netweaver-anydb/?source=recommendations" + "category": "Azure Pipelines", + "checklist": "Azure DevOps", + "description": "Manage Service Connections", + "guid": "8564b4dd-74a7-459c-9633-bd2a1a27a764", + "id": "C06.02", + "link": "https://learn.microsoft.com/azure/devops/pipelines/library/service-endpoints?view=azure-devops&tabs=yaml", + "services": [], + "severity": "Medium", + "subcategory": "Security", + "text": "Service Connections", + "training": "https://learn.microsoft.com/learn/paths/secure-your-cloud-data/" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "87585797-5551-4d53-bb7d-a94ee415734d", - "link": "https://learn.microsoft.com/azure/sap/workloads/rise-integration", + "category": "Azure Pipelines", + "checklist": "Azure DevOps", + "description": "Set data retention policies for CI and CD", + "guid": "a90be0e3-78ee-4293-a1bd-363caaab7571", + "id": "C06.03", + "link": "https://learn.microsoft.com/azure/devops/pipelines/policies/retention?view=azure-devops&tabs=yaml", "services": [ - "SAP", - "VNet" + "AzurePolicy" ], "severity": "Medium", - "subcategory": "Segmentation", - "text": "For SAP RISE/ECS deployments, virtual peering is the preferred way to establish connectivity with customer’s existing Azure environment. Both the SAP vnet and customer vnet(s) are protected with network security groups (NSG), enabling communication on SAP and database ports through the vnet peering" + "subcategory": "Security", + "text": "Retention Policies", + "training": "https://learn.microsoft.com/learn/modules/azure-active-directory/" }, { - "category": "Security, Governance and Compliance", - "checklist": "Azure Landing Zone Review", - "guid": "209d490d-a477-4784-84d1-16785d2fa56c", - "link": "https://learn.microsoft.com/azure/governance/policy/overview", - "services": [ - "SAP", - "RBAC", - "Subscriptions" - ], - "severity": "High", - "subcategory": "Governance", - "text": "Customize role-based access control (RBAC) roles for SAP on Azure spoke subscriptions to avoid accidental network-related changes" + "category": "Azure Pipelines", + "checklist": "Azure DevOps", + "description": "Set up and pay for concurrent pipelines", + "guid": "949ab919-3dc9-4fc9-b1bb-84b37b5a67fc", + "id": "C07.01", + "link": "https://learn.microsoft.com/azure/devops/pipelines/licensing/concurrent-jobs?view=azure-devops&tabs=ms-hosted", + "services": [], + "severity": "Low", + "subcategory": "Administration", + "text": "Parallel Pipelines", + "training": "https://learn.microsoft.com/learn/modules/implement-hybrid-identity-windows-server/" }, { - "category": "Security, Governance and Compliance", - "checklist": "Azure Landing Zone Review", - "guid": "56ad4840-8fe7-4273-9c48-6ba280dc0591", - "link": "https://learn.microsoft.com/azure/governance/policy/overview", - "services": [ - "SAP", - "PrivateLink", - "NVA" - ], + "category": "Azure Pipelines", + "checklist": "Azure DevOps", + "description": "Set pipeline permissions", + "guid": "b9ed5b35-478d-4447-a826-c2863c00f1ca", + "id": "C08.01", + "link": "https://learn.microsoft.com/azure/devops/pipelines/policies/permissions?view=azure-devops", + "services": [], "severity": "Medium", - "subcategory": "Governance", - "text": "Isolate DMZs and NVAs from the rest of the SAP estate, configure Azure Private Link, and securely manage and control the SAP on Azure resources" + "subcategory": "Security", + "text": "Pipeline Permissions", + "training": "https://learn.microsoft.com/learn/paths/implement-windows-server-iaas-virtual-machine-identity/" }, { - "category": "Security, Governance and Compliance", - "checklist": "Azure Landing Zone Review", - "guid": "cf65de8e-1309-4ccc-b579-266bcca275fa", - "link": "https://learn.microsoft.com/azure/governance/policy/overview", - "services": [ - "SAP", - "Storage", - "SQL", - "Backup" - ], + "category": "Azure Pipelines", + "checklist": "Azure DevOps", + "description": "Add users to pipeline", + "guid": "c699ef1d-5a83-4de5-be36-c1c81870a0bc", + "id": "C08.02", + "link": "https://learn.microsoft.com/azure/devops/pipelines/policies/set-permissions?view=azure-devops", + "services": [], + "severity": "Low", + "subcategory": "Security", + "text": "Pipeline Users", + "training": "https://learn.microsoft.com/learn/paths/implement-applications-external-access-azure-ad/" + }, + { + "category": "Azure Artifact", + "checklist": "Azure DevOps", + "description": "Configure Artifacts", + "guid": "5c1e43a1-8658-4d28-98ed-67179b825546", + "id": "D01.01", + "link": "https://learn.microsoft.com/azure/devops/pipelines/artifacts/artifacts-overview?view=azure-devops&tabs=nuget", + "services": [], "severity": "Medium", - "subcategory": "Governance", - "text": "For SAP database server encryption, use the SAP HANA native encryption technology. If you're using Azure SQL Database, use Transparent Data Encryption (TDE) offered by the DBMS provider to secure your data and log files, and ensure the backups are also encrypted." + "subcategory": "Configuration", + "text": "Artifact In Pipeline", + "training": "https://learn.microsoft.com/learn/modules/design-identity-security-strategy/" }, { - "category": "Security, Governance and Compliance", - "checklist": "Azure Landing Zone Review", - "guid": "a1abfe9d-55d0-44c3-a491-9cb1b3d1325a", - "link": "https://learn.microsoft.com/azure/governance/policy/overview", - "services": [ - "Storage" - ], + "category": "Azure Artifact", + "checklist": "Azure DevOps", + "description": "Publish and consume artifact in pipeline", + "guid": "df2aee45-53af-4c83-9924-8726dd68c5b5", + "id": "D01.02", + "link": "https://learn.microsoft.com/azure/devops/pipelines/artifacts/pipeline-artifacts?view=azure-devops&tabs=yaml", + "services": [], "severity": "Medium", - "subcategory": "Governance", - "text": "Azure Storage encryption is enabled by default" + "subcategory": "Configuration", + "text": "Publish and download Artifact", + "training": "https://learn.microsoft.com/azure/architecture/example-scenario/identity/adds-extend-domain" }, { - "category": "Security, Governance and Compliance", - "checklist": "Azure Landing Zone Review", - "guid": "e124ba34-df68-45ed-bce9-bd3bb0cdb3b5", - "link": "https://learn.microsoft.com/azure/governance/policy/overview", + "category": "Azure Artifact", + "checklist": "Azure DevOps", + "description": "Publish NuGet packages with artifacts", + "guid": "c2925394-b69b-49d3-99ac-43bc68d1d766", + "id": "D01.03", + "link": "https://learn.microsoft.com/azure/devops/pipelines/artifacts/nuget?view=azure-devops&tabs=yaml", "services": [], - "severity": "Medium", - "subcategory": "Governance", - "text": " " + "severity": "Low", + "subcategory": "Configuration", + "text": "NuGet", + "training": "https://learn.microsoft.com/azure/role-based-access-control/overview" }, { - "category": "Security, Governance and Compliance", - "checklist": "Azure Landing Zone Review", - "guid": "5eb2ec14-eeaa-4359-8829-e2edb2173676", - "link": "https://learn.microsoft.com/azure/governance/policy/overview", + "category": "Azure Artifact", + "checklist": "Azure DevOps", + "description": "Publish Maven packages with artifacts", + "guid": "57246b44-8564-4b4d-b74a-759c7633bd2a", + "id": "D01.04", + "link": "https://learn.microsoft.com/azure/devops/pipelines/artifacts/publish-maven-artifacts?view=azure-devops", "services": [], - "severity": "Medium", - "subcategory": "Governance", - "text": " " + "severity": "Low", + "subcategory": "Configuration", + "text": "Maven" }, { - "category": "Security, Governance and Compliance", - "checklist": "Azure Landing Zone Review", - "guid": "ce9bd3bb-0cdb-43b5-9eb2-ec14eeaa3592", - "link": "https://learn.microsoft.com/azure/key-vault/general/overview", - "services": [ - "AKV" - ], - "severity": "High", - "subcategory": "Secrets", - "text": "Use Azure Key Vault to store your secrets and credentials" + "category": "Azure Artifact", + "checklist": "Azure DevOps", + "description": "Publish NPM packages with artifacts", + "guid": "1a27a764-a90b-4e0e-978e-e293c1bd363c", + "id": "D01.05", + "link": "https://learn.microsoft.com/azure/devops/pipelines/artifacts/npm?view=azure-devops&tabs=yaml", + "services": [], + "severity": "Low", + "subcategory": "Configuration", + "text": "NPM" }, { - "category": "Security, Governance and Compliance", - "checklist": "Azure Landing Zone Review", - "guid": "829e2edb-2173-4676-aff6-691b4935ada4", - "link": "https://learn.microsoft.com/azure/key-vault/general/overview-throttling", - "services": [ - "AKV" - ], + "category": "Azure Artifact", + "checklist": "Azure DevOps", + "description": "Best Practices to work with Azure Artifact", + "guid": "aaab7571-949a-4b91-a3dc-9fc9d1bb84b3", + "id": "D01.06", + "link": "https://learn.microsoft.com/azure/devops/artifacts/concepts/best-practices?view=azure-devops", + "services": [], "severity": "Medium", - "subcategory": "Secrets", - "text": "It is recommended to LOCK the Azure Resources post successful deployment to safeguard against unauthorized changes" + "subcategory": "Configuration", + "text": "Best Practices" }, { - "category": "Security, Governance and Compliance", - "checklist": "Azure Landing Zone Review", - "guid": "2223ece8-1b12-4318-8a54-17415833fb4a", - "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", + "category": "DevOps Practice", + "checklist": "Azure DevOps", + "description": "What is monitoring?", + "guid": "7b5a67fc-b9ed-45b3-9478-d447a826c286", + "id": "E01.01", + "link": "https://learn.microsoft.com/devops/operate/what-is-monitoring", "services": [ - "AzurePolicy", - "AKV" + "Monitor" ], - "severity": "Medium", - "subcategory": "Secrets", - "text": "Provision Azure Key Vault with the soft delete and purge policies enabled to allow retention protection for deleted objects." + "severity": "High", + "subcategory": "Practice", + "text": "What to monitor?" }, { - "category": "Security, Governance and Compliance", - "checklist": "Azure Landing Zone Review", - "guid": "e3c2df74-3165-4c3a-abe0-5bbe209d490d", - "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", - "services": [ - "AzurePolicy", - "RBAC", - "AKV" - ], + "category": "DevOps Practice", + "checklist": "Azure DevOps", + "description": "Progressive Exposure Strategy", + "guid": "3c00f1ca-c699-4ef1-b5a8-3de5de36c1c8", + "id": "E01.02", + "link": "https://learn.microsoft.com/devops/operate/safe-deployment-practices", + "services": [], "severity": "Medium", - "subcategory": "Secrets", - "text": "Based on existing requirements, regulatory and compliance controls (internal/external) - Determine what Azure Policies and Azure RBAC role are needed" + "subcategory": "Practice", + "text": "Safe Deployment Practices" }, { - "category": "Security, Governance and Compliance", - "checklist": "Azure Landing Zone Review", - "guid": "a4777842-4d11-4678-9d2f-a56c56ad4840", - "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", - "services": [ - "SAP", - "AzurePolicy", - "Defender", - "AKV" - ], - "severity": "Medium", - "subcategory": "Secrets", - "text": "When you enable Microsoft Defender for Cloud Standard for SAP, make sure to exclude the SAP database servers from any policy that installs endpoint protection." + "category": "DevOps Practice", + "checklist": "Azure DevOps", + "description": "Microsoft runs reliable systems with DevOps", + "guid": "1870a0bc-5c1e-443a-8865-8d2858ed6717", + "id": "E01.03", + "link": "https://learn.microsoft.com/devops/operate/how-microsoft-operates-devops", + "services": [], + "severity": "Low", + "subcategory": "Practice", + "text": "Case Study", + "training": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment" }, { - "category": "Security, Governance and Compliance", - "checklist": "Azure Landing Zone Review", - "guid": "8fe72734-c486-4ba2-a0dc-0591cf65de8e", - "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", - "services": [ - "SAP", - "RBAC", - "AKV" - ], + "category": "DevOps Practice", + "checklist": "Azure DevOps", + "description": "Security in DevOps", + "guid": "9b825546-df2a-4ee4-953a-fc8339248726", + "id": "E01.04", + "link": "https://learn.microsoft.com/devops/operate/security-in-devops", + "services": [], "severity": "Medium", - "subcategory": "Secrets", - "text": "Delegate an SAP admin custom role with just-in-time access." + "subcategory": "Practice", + "text": "DevSecOps" }, { - "category": "Security, Governance and Compliance", - "checklist": "Azure Landing Zone Review", - "guid": "1309cccd-5792-466b-aca2-75faa1abfe9d", - "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", - "services": [ - "SAP", - "AKV" - ], - "severity": "Medium", - "subcategory": "Secrets", - "text": "encrypt data in transit by integrating the third-party security product with secure network communications (SNC) for DIAG (SAP GUI), RFC, and SPNEGO for HTTPS" + "category": "DevOps Practice", + "checklist": "Azure DevOps", + "description": "Enable DevSecops with Azure And GitHub", + "guid": "dd68c5b5-c292-4539-9b69-b9d379ac43bc", + "id": "E01.05", + "link": "https://learn.microsoft.com/devops/devsecops/enable-devsecops-azure-github", + "services": [], + "severity": "Low", + "subcategory": "Practice", + "text": "DevSecops", + "training": "https://learn.microsoft.com/learn/paths/architect-infrastructure-operations/" }, { - "category": "Security, Governance and Compliance", - "checklist": "Azure Landing Zone Review", - "guid": "55d04c3c-4919-4cb1-a3d1-325ae124ba34", - "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", + "category": "DevOps Practice", + "checklist": "Azure DevOps", + "description": "Mirror RBAC in DevOps", + "guid": "68d1d766-5724-46b4-9856-4b4dd74a759c", + "id": "E01.06", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/secure/best-practices/end-to-end-governance", "services": [ - "SAP", - "AKV", - "Entra" + "RBAC" ], - "severity": "Medium", - "subcategory": "Secrets", - "text": "Azure Active Directory (Azure AD) with SAML 2.0 can also provide SSO to a range of SAP applications and platforms like SAP NetWeaver, SAP HANA, and the SAP Cloud Platform" + "severity": "Low", + "subcategory": "Practice", + "text": "Secure DevOps Govenance", + "training": "https://learn.microsoft.com/learn/paths/architect-infrastructure-operations/" }, { - "category": "Security, Governance and Compliance", - "checklist": "Azure Landing Zone Review", - "guid": "df685edd-ce9b-4d3b-a0cd-b3b55eb2ec14", - "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", - "services": [ - "SAP", - "AKV" - ], + "category": "DevOps Practice", + "checklist": "Azure DevOps", + "description": "Governance when using CI/CD", + "guid": "7633bd2a-1a27-4a76-9a90-be0e378ee293", + "id": "E01.07", + "link": "https://learn.microsoft.com/azure/architecture/example-scenario/governance/end-to-end-governance-in-azure", + "services": [], "severity": "Medium", - "subcategory": "Secrets", - "text": "Make sure you harden the operating system to eradicate vulnerabilities that could lead to attacks on the SAP database." + "subcategory": "Practice", + "text": "Azure DevOps Governance", + "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/" }, { - "category": "Security, Governance and Compliance", - "checklist": "Azure Landing Zone Review", - "guid": "eeaa3592-829e-42ed-a217-3676aff6691b", - "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", + "category": "BCDR", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Ensure that your backups are protected against attacks. This should include encryption of the backups to protect against loss of confidentiality. For regular Azure service backup, backup data is automatically encrypted using Azure platform-managed keys. You can also choose to encrypt the backup using a customer-managed key. In this case, ensure this customer-managed key in the key vault is also in the backup scope.", + "guid": "676f6951-0368-49e9-808d-c33a692c9a64", + "id": "A01.01", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/sql-database-security-baseline#br-2-encrypt-backup-data", "services": [ - "AKV" + "Backup", + "AKV", + "SQL" ], "severity": "Medium", - "subcategory": "Secrets", - "text": "Default to Microsoft-managed keys for principal encryption functionality and use customer-managed keys when required." + "subcategory": "Azure Key Vault", + "text": "Protect your backup data with encryption and store keys safely in Azure Key Vault", + "waf": "Security" }, { - "category": "Security, Governance and Compliance", - "checklist": "Azure Landing Zone Review", - "guid": "4935ada4-2223-4ece-a1b1-23181a541741", - "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", + "category": "BCDR", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Azure SQL Database uses SQL Server technology to create full backups every week, differential backup every 12-24 hours, and transaction log backup every 5 to 10 minutes. By default, SQL Database stores data in geo-redundant storage blobs that are replicated to a paired region.", + "guid": "e2518261-b3bc-4bd1-b331-637fb2df833f", + "id": "A02.01", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/sql-database-security-baseline#br-1-ensure-regular-automated-backups", "services": [ - "AKV" + "Backup", + "Storage", + "SQL" ], "severity": "Medium", - "subcategory": "Secrets", - "text": "Use an Azure Key Vault per application per environment per region." + "subcategory": "Backup", + "text": "Configure Azure SQL Database automated backups", + "waf": "Security" }, { - "category": "Security, Governance and Compliance", - "checklist": "Azure Landing Zone Review", - "guid": "5833fb4a-e3c2-4df7-9316-5c3acbe05bbe", - "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", + "category": "BCDR", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "By default, SQL Database stores data in geo-redundant storage blobs that are replicated to a paired region. For SQL Database, the backup storage redundancy can be configured at the time of database creation or can be updated for an existing database; the changes made to an existing database apply to future backups only.", + "guid": "f8c7cda2-3ed7-43fb-a100-85dcd12a0ee4", + "id": "A02.02", + "link": "https://learn.microsoft.com/azure/azure-sql/database/automated-backups-overview?tabs=single-database&view=azuresql#backup-storage-redundancy", "services": [ - "AKV" + "Backup", + "Storage", + "SQL" ], - "severity": "Medium", - "subcategory": "Secrets", - "text": " " + "severity": "Low", + "subcategory": "Backup", + "text": "Enable geo-redundant backup storage to protect against single region failure and data loss", + "waf": "Security" }, { - "category": "Storage", - "checklist": "Azure Landing Zone Review", - "guid": "d579266b-cca2-475f-aa1a-bfe9d55d04c3", + "category": "Code", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Malicious code can potentially circumvent security controls. Before deploying custom code to production, it is essential to review what's being deployed. Use a database tool like Azure Data Studio that supports source control. Implement tools and logic for code analysis, vulnerability and credential scanning.", + "guid": "7ca9f006-d2a9-4652-951c-de8e4ac5e76e", + "id": "B01.01", + "link": "https://learn.microsoft.com/azure/azure-sql/database/transparent-data-encryption-byok-create-server", "services": [ - "Storage", "SQL" ], "severity": "Medium", - "subcategory": " ", - "text": "Disk config for Oracle, SQL, HANA" + "subcategory": "Source Control and Code Review", + "text": "Use Source Control systems to store, maintain and review application code deployed inside Azure SQLDB Database", + "waf": "Security" }, { - "category": "SQL Server on Azure VM", - "checklist": "SQL Migration Review", - "description": "When you are creating a SQL Server on Azure VM, carefully consider the type of workload necessary. If you are migrating an existing environment, collect a performance baseline to determine your SQL Server on Azure VM requirements. If this is a new VM, then create your new SQL Server VM based on your vendor requirements.", - "guid": "1fc3fc14-eea6-4e69-b8d9-a3eec218e687", - "id": "A01.01", - "link": "https://learn.microsoft.com/sql/dma/dma-sku-recommend-sql-db?view=sql-server-ver16", + "category": "Data Discovery and Classification", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "In case of classification requirements Purview is the preferred option. Only use SQL Data Discovery & Classification in case Purview is not an option. Discover columns that potentially contain sensitive data. What is considered sensitive data heavily depends on the customer, compliance regulation, etc., and needs to be evaluated by the users in charge of that data. Classify the columns to use advanced sensitivity-based auditing and protection scenarios. Review results of automated discovery and finalize the classification if necessary.", + "guid": "d401509b-2629-4484-9a7f-af0d29a7778f", + "id": "C01.01", + "link": "https://learn.microsoft.com/azure/azure-sql/database/data-discovery-and-classification-overview?view=azuresql#faq---advanced-classification-capabilities", "services": [ - "VM", "SQL" ], - "severity": "High", - "subcategory": "VM Size", - "text": "Collect the target workload's performance characteristics and use them to determine the appropriate VM size for your business.", - "waf": "Performance" + "severity": "Low", + "subcategory": "Data Discovery and Classification", + "text": "Plan and configure Data Discovery & Classification to protect the sensitive data", + "waf": "Security" }, { - "category": "SQL Server on Azure VM", - "checklist": "SQL Migration Review", - "description": "The memory optimized virtual machine sizes are a primary target for SQL Server VMs and the recommended choice by Microsoft. The memory optimized virtual machines offer stronger memory-to-CPU ratios and medium-to-large cache options.Consider Ebdsv5-series series first for most SQL Server workloads.", - "guid": "e04abe1f-8d39-4fda-9776-8424c116775c", - "id": "A01.02", - "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/performance-guidelines-best-practices-vm-size?view=azuresql#memory-optimized", + "category": "Data Masking", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Usage of this feature is recommended only if column encryption is not an option and there is a specific requirement to preserve data types and formats. Dynamic data masking limits sensitive data exposure by masking it to non-privileged users. Dynamic data masking helps prevent unauthorized access to sensitive data by enabling customers to designate how much of the sensitive data to reveal with minimal impact on the application layer.", + "guid": "9391fd50-135e-453e-90a7-c1a23f88cc13", + "id": "D01.01", + "link": "https://learn.microsoft.com/azure/azure-sql/database/dynamic-data-masking-overview", "services": [ - "VM", "SQL" ], - "severity": "Medium", - "subcategory": "VM Size", - "text": "Use memory optimized virtual machine sizes for the best performance of SQL Server workloads.", - "waf": "Performance" + "severity": "Low", + "subcategory": "Data Masking", + "text": "Use Data Masking to prevent unauthorized non-admin users data access if no encryption is possible", + "waf": "Security" }, { - "category": "SQL Server on Azure VM", - "checklist": "SQL Migration Review", - "description": "To find the most effective configuration for SQL Server workloads on an Azure VM, start by measuring the storage performance of your business application. Once storage requirements are known, select a virtual machine that supports the necessary IOPS and throughput with the appropriate memory-to-vCore ratio.", - "guid": "2ea55b56-ad48-4408-be72-734b476ba18f", - "id": "A02.01", - "link": "https://learn.microsoft.com/azure/virtual-machines/premium-storage-performance#counters-to-measure-application-performance-requirements", + "category": "Defender", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "SQL Advanced Threat Detection (ATP) provides a layer of security that detects potential vulnerabilities and anomalous activity in databases such as SQL injection attacks and unusual behavior patterns. When a potential threat is detected Threat Detection sends an actionable real-time alert by email and in Microsoft Defender for Cloud, which includes clear investigation and remediation steps for the specific threat.", + "guid": "4e52d73f-5d37-428f-b3a2-e6997e835979", + "id": "E01.01", + "link": "https://learn.microsoft.com/azure/azure-sql/database/threat-detection-configure", "services": [ - "VM", - "Storage", + "Defender", + "EventHubs", "SQL" ], - "severity": "Medium", - "subcategory": "Storage", - "text": "Determine storage bandwidth and latency requirements for SQL Server data, log, and tempdb files before choosing the disk type.", - "waf": "Performance" + "severity": "High", + "subcategory": "Advanced Threat Protection", + "text": "Review and complete Advanced Threat Protection (ATP) configuration", + "waf": "Security" }, { - "category": "SQL Server on Azure VM", - "checklist": "SQL Migration Review", - "description": "This provides more dedicated disk IOPS and throughput on the disk level and also allows you to configure the Azure disk host caching setting for each disk to the optimal setting for that data type.", - "guid": "dbf590ce-65de-48e0-9f9c-cbd468266abc", - "id": "A02.02", - "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/performance-guidelines-best-practices-checklist?view=azuresql#storage", + "category": "Defender", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Enable Microsoft Defender for Azure SQL at the subscription level to automatically onboard and protect all existing and future servers and databases. When you enable on the subscription level, all databases in Azure SQL Database and Azure SQL Managed Instance are protected. You can then disable them individually if you choose. If you want to manually manage which databases are protected, disable at the subscription level and enable each database that you want protected.", + "guid": "dff87489-9edb-4cef-bdda-86e8212b2aa1", + "id": "E02.01", + "link": "https://learn.microsoft.com/azure/azure-sql/database/azure-defender-for-sql?view=azuresql#enable-microsoft-defender-for-sql ", "services": [ - "Storage", + "Defender", + "Subscriptions", "SQL" ], "severity": "High", - "subcategory": "Storage", - "text": "Place data, log, and tempdb files on separate drives", - "waf": "Performance" + "subcategory": "Defender for Azure SQL", + "text": "Enable Microsoft Defender for Azure SQL", + "waf": "Security" }, { - "category": "SQL Server on Azure VM", - "checklist": "SQL Migration Review", - "description": "Premium SSD is always recommend as a minimum for SQL Server in order to obtain better performance and lower latency. P30 and P40 are recommended because disk caching is not supported for disks 4 TiB and larger ( P50 and above) and they provide the optimal price to performance ratio", - "guid": "e6a84de5-df43-4d19-a248-1718d5d1e5f6", - "id": "A02.03", - "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/performance-guidelines-best-practices-checklist?view=azuresql#storage", + "category": "Defender", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Microsoft Defender for Azure SQL ATP detects anomalous activities indicating unusual and potentially harmful attempts to access or exploit databases. Alerts can be configured and generated and will be reported in the Defender for console.", + "guid": "ca342fdf-d25a-4427-b105-fcd50ff8a0ea", + "id": "E02.02", + "link": "https://learn.microsoft.com/azure/azure-sql/database/threat-detection-configure", "services": [ - "Storage", + "Monitor", + "Defender", "SQL" ], "severity": "High", - "subcategory": "Storage", - "text": "For the data drive, use premium P30 and P40 or smaller disks to ensure the availability of cache support", - "waf": "Performance" + "subcategory": "Defender for Azure SQL", + "text": "Prepare a security response plan to promptly react to Microsoft Defender for Azure SQL alerts", + "waf": "Security" }, { - "category": "SQL Server on Azure VM", - "checklist": "SQL Migration Review", - "description": "Log files have primarily write-heavy operations. Therefore, they do not benefit from the ReadOnly cache. Hence evaluate your price vs performance vs capacity and chose the right storage disk.", - "guid": "25659d35-58fd-4772-99c9-31112d027fe4", - "id": "A02.04", - "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/performance-guidelines-best-practices-checklist?view=azuresql#storage", + "category": "Defender", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Azure SQLDB vulnerability assessment is a service that provides visibility into your security state. Vulnerability assessment includes actionable steps to resolve security issues and enhance your database security. It can help you to monitor a dynamic database environment where changes are difficult to track and improve your SQL security posture.", + "guid": "a6101ae7-534c-45ab-86fd-b34c55ea21ca", + "id": "E03.01", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/sql-azure-vulnerability-assessment-overview", "services": [ - "Storage", - "SQL", - "Cost" + "Monitor", + "Defender", + "SQL" ], "severity": "High", - "subcategory": "Storage", - "text": "For the log drive plan for capacity and test performance versus cost while evaluating the premium P30 - P80 disks", - "waf": "Performance" + "subcategory": "Vulnerability Assessment", + "text": "Configure Vulnerability Assessment (VA) findings and review recommendations", + "waf": "Security" }, { - "category": "SQL Server on Azure VM", - "checklist": "SQL Migration Review", - "description": "Placing TempDB on the D drive can help performance. Consider the size required and always test performance.", - "guid": "12f70983-f630-4472-8ee6-9d6b5c2622f5", - "id": "A02.05", - "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/performance-guidelines-best-practices-checklist?view=azuresql#storage", + "category": "Defender", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Microsoft Defender for Cloud provides vulnerability assessment for your Azure SQL Databases. Vulnerability assessment scans your databases for software vulnerabilities and provides a list of findings. You can use the findings to remediate software vulnerabilities and disable findings.", + "guid": "c8c5f112-1e50-4f77-9264-8195b4cd61ac", + "id": "E03.02", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/sql-azure-vulnerability-assessment-find?view=azuresql", "services": [ - "VM", - "Storage", + "Defender", "SQL" ], - "severity": "Medium", - "subcategory": "Storage", - "text": "Place tempdb on the local ephemeral SSD (default D:\\) drive for most SQL Server workloads that are not part of Failover Cluster Instance (FCI) after choosing the optimal VM size.", - "waf": "Performance" + "severity": "High", + "subcategory": "Vulnerability Assessment", + "text": "Regularly review of Vulnerability Assessment (VA) findings and recommendations and prepare a plan to fix", + "waf": "Security" }, { - "category": "SQL Server on Azure VM", - "checklist": "SQL Migration Review", - "description": "Striping Data and Log disk can increase bandwidth. Ensure that VM size also matches expected output", - "guid": "4b69bad3-4aad-45e8-a78e-1d76667313c4", - "id": "A02.06", - "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/performance-guidelines-best-practices-checklist?view=azuresql#storage", + "category": "Encryption", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Always Encrypted with Secure Enclaves expands confidential computing capabilities of Always Encrypted by enabling in-place encryption and richer confidential queries. Always Encrypted with Secure Enclaves addresses these limitations by allowing some computations on plaintext data inside a secure enclave on the server side. Usage of this feature is recommended for the cases where you need to limit administrator access and need your queries to support more than equality matching of encrypted columns.", + "guid": "65d7e54a-10a6-4094-b673-9ff3809c9277", + "id": "F01.01", + "link": "https://learn.microsoft.com/sql/relational-databases/security/encryption/always-encrypted-enclaves", "services": [ - "VM", - "Storage", "SQL" ], - "severity": "High", - "subcategory": "Storage", - "text": "Stripe multiple Azure data disks using Storage Spaces to increase I/O bandwidth", - "waf": "Performance" + "severity": "Medium", + "subcategory": "Always Encrypted", + "text": "If protecting sensitive PII data from admin users is a key requirement, but Column Encryption limitations cannot be tolerated, consider the adoption of Always Encrypted with Secure Enclaves", + "waf": "Security" }, { - "category": "SQL Server on Azure VM", - "checklist": "SQL Migration Review", - "description": "Your storage caching policy varies depending on the type of SQL Server data files that are hosted on the drive.Enable Read-only caching for the disks hosting SQL Server data files.Reads from cache will be faster than the uncached reads from the data disk.Set the caching policy to None for disks hosting the transaction log. There is no performance benefit to enabling caching for the Transaction log disk.", - "guid": "05674b5e-985b-4859-a773-e7e261623b77", - "id": "A02.07", - "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/performance-guidelines-best-practices-checklist?view=azuresql#storage", + "category": "Encryption", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "With Azure SQL Database, you can apply symmetric encryption to a column of data by using Transact-SQL. This approach is called column encryption, because you can use it to encrypt specific columns with different encryption keys. Doing so gives you more granular encryption capability than TDE, which encrypts data in pages. Using Always Encrypted to ensure sensitive data isn't exposed in plaintext in Azure SQL Database or SQL Managed Instance, even in memory/in use. Always Encrypted protects the data from Database Administrators (DBAs) and cloud admins (or bad actors who can impersonate high-privileged but unauthorized users) and gives you more control over who can access your data.", + "guid": "c03ce136-e3d5-4e17-bf25-ed955ee480d3", + "id": "F02.01", + "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#control-access-of-application-users-to-sensitive-data-through-encryption", "services": [ - "AzurePolicy", "Storage", + "AKV", "SQL" ], - "severity": "High", - "subcategory": "Storage", - "text": "Set host caching to read-only for data file disks and none for log file disks.", - "waf": "Performance" + "severity": "Low", + "subcategory": "Column Encryption", + "text": "To protect sensitive PII data from non-admin users in specific table columns, consider using Column Encryption", + "waf": "Security" }, { - "category": "SQL Server on Azure VM", - "checklist": "SQL Migration Review", - "description": "Check that you storage is in the same region as your VM. For exaplme if your VM is in EAST US 2 ensure your storage is in East US 2.", - "guid": "5a917e1f-348e-4f35-9c27-d42e8bbac868", - "id": "A02.08", - "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/performance-guidelines-best-practices-checklist?view=azuresql#storage", + "category": "Encryption", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Enabled by default, Transparent data encryption (TDE) helps to protect the database files against information disclosure by performing real-time encryption and decryption of the database, associated backups, and transaction log files 'at rest', without requiring changes to the application.", + "guid": "c614ac47-bebf-4061-b0a1-43e0c6b5e00d", + "id": "F03.01", + "link": "https://learn.microsoft.com/azure/azure-sql/database/transparent-data-encryption-byok-create-server", "services": [ - "VM", + "Backup", "Storage", "SQL" ], "severity": "High", - "subcategory": "Storage", - "text": "Provision the storage account in the same region as the SQL Server VM", - "waf": "Performance" + "subcategory": "Transparent Data Encryption", + "text": "Ensure Transparent Data Encryption (TDE) is kept enabled", + "waf": "Security" }, { - "category": "SQL Server on Azure VM", - "checklist": "SQL Migration Review", - "description": "SQL Server uses extents to store data. These are 64KB in size. Therefore, on a SQL Server machine, the NTFS allocation unit size for hosting SQL database files should be 64 KB.", - "guid": "155abb91-63e9-4908-ae28-c84c33b6b780", - "id": "A02.09", - "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/performance-guidelines-best-practices-checklist?view=azuresql#storage", + "category": "Encryption", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "If separation of duties in the management of keys and data within the organization is required, leverage Customer Managed Keys (CMK) for Transparent Data Encryption (TDE) for your Azure SQLDB and use Azure Key Vault to store (refer to its checklist). Leverage this feature when you have strict security requirements which cannot be met by the managed service keys.", + "guid": "2edb4165-4f54-47cc-a891-5c82c2f21e25", + "id": "F03.02", + "link": "https://learn.microsoft.com/azure/azure-sql/database/transparent-data-encryption-byok-overview", "services": [ - "Storage", + "AKV", "SQL" ], - "severity": "High", - "subcategory": "Storage", - "text": "Format your data disk to use 64 KB block size (allocation unit size) for all data files placed on a drive other than the temporary D:\\ drive", - "waf": "Performance" + "severity": "Medium", + "subcategory": "Transparent Data Encryption", + "text": "Use customer-managed keys (CMK) in Azure Key Vault (AKV) if you need increased transparency and granular control over the TDE protection", + "waf": "Security" }, { - "category": "SQL Server on Azure VM", - "checklist": "SQL Migration Review", - "description": "It is recommended that you determine BCDR needs and requirements ensuring that you are able to meet you SLAs of the environment.", - "guid": "8b9fe5c4-2049-4d41-9a92-3c3474d11028", - "id": "A03.01", - "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/business-continuity-high-availability-disaster-recovery-hadr-overview?view=azuresql#azure-only-disaster-recovery-solutions", + "category": "Encryption", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "The minimal Transport Layer Security (TLS) version setting allows customers to choose which version of TLS their SQL database uses. It's possible to change the minimum TLS version by using the Azure portal, Azure PowerShell, and the Azure CLI.", + "guid": "7754b605-57fd-4bcb-8213-52c39d8e8225", + "id": "F04.01", + "link": "https://learn.microsoft.com/azure/azure-sql/database/connectivity-settings?source=recommendations&view=azuresql&tabs=azure-portal#minimal-tls-version", "services": [ - "VM", "SQL" ], - "severity": "Medium", - "subcategory": "HADR", - "text": "Determine HA/DR requirements for each VM to be migrated.", - "waf": "Reliability" + "severity": "High", + "subcategory": "Transport Layer Security", + "text": "Enforce minimum TLS version to the latest available", + "waf": "Security" }, { - "category": "SQL Server on Azure VM", - "checklist": "SQL Migration Review", - "description": "When depoying High Availability you need to use availability sets or availability zones to avoid unexpected outages.", - "guid": "ac6aae01-e6a8-44de-9df4-3d1992481718", - "id": "A03.02", - "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/business-continuity-high-availability-disaster-recovery-hadr-overview?view=azuresql#high-availability-nodes-in-an-availability-set", + "category": "Identity", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Use Azure Active Directory (Azure AD) authentication for centralized identity management. Use SQL Authentication only if really necessary and document as exceptions.", + "guid": "c9b8b6bf-2c6b-453d-b400-de9a43a549d7", + "id": "G01.01", + "link": "https://learn.microsoft.com/azure/azure-sql/database/authentication-aad-overview", "services": [ - "VM", + "Entra", "SQL" ], - "severity": "High", - "subcategory": "HADR", - "text": "Place your VMs in an availability set or different availability zones.", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "Azure Active Directory", + "text": "Leverage Azure AD authentication for connections to Azure SQL Databases", + "waf": "Security" }, { - "category": "SQL Server on Azure VM", - "checklist": "SQL Migration Review", - "description": "Prefered option when deploying an Availability Group. The recommended solution is to use multi-subnets when deploying Always on Availability Groups.", - "guid": "d5d1e5f6-2565-49d3-958f-d77249c93111", - "id": "A03.03", - "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/availability-group-azure-portal-configure?view=azuresql&tabs=azure-cli", + "category": "Identity", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Using Azure AD groups simplifies permission management and both the group owner, and the resource owner can add/remove members to/from the group. Create a separate group for Azure AD administrators for each logical server. Monitor Azure AD group membership changes using Azure AD audit activity reports.", + "guid": "29820254-1d14-4778-ae90-ff4aeba504a3", + "id": "G01.02", + "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#central-management-for-identities", "services": [ - "LoadBalancer", - "VM", - "VNet", + "Monitor", + "Entra", "SQL" ], "severity": "Medium", - "subcategory": "HADR", - "text": "Deploy your SQL Server VMs to multiple subnets whenever possible to avoid the dependency on an Azure Load Balancer or a distributed network name (DNN) to route traffic to your HADR solution. ( If one is implementing FCI or AG)", - "waf": "Reliability" + "subcategory": "Azure Active Directory", + "text": "Create a separate Azure AD group with two admin accounts for each Azure SQL Database logical server", + "waf": "Security" }, { - "category": "SQL Server on Azure VM", - "checklist": "SQL Migration Review", - "description": "High availability and disaster recovery (HADR) features, such as the Always On availability group and the failover cluster instance rely on underlying Windows Server Failover Cluster technology. Review the best practices for modifying your HADR settings to better support the cloud environment.", - "guid": "2d027fe4-12f7-4098-9f63-04722ee69d6b", - "id": "A03.04", - "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/performance-guidelines-best-practices-checklist?view=azuresql-vm#hadr-configuration", + "category": "Identity", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Ensure that distinct system and user assigned managed identities, that are dedicated to the function, with least permissions assigned, are used for communication from Azure services and applications to the Azure SQLDB databases.", + "guid": "df3a09ee-03bb-4198-8637-d141acf5f289", + "id": "G01.03", + "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#minimize-the-use-of-password-based-authentication-for-applications", "services": [ - "ASR", + "Entra", "SQL" ], - "severity": "High", - "subcategory": "HADR", - "text": "Change the cluster to less aggressive parameters to avoid unexpected outages from transient network failures or Azure platform maintenance. ( If one is implementing FCI or AG)", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "Azure Active Directory", + "text": "Minimize the use of password-based authentication for applications", + "waf": "Security" }, { - "category": "SQL Server on Azure VM", - "checklist": "SQL Migration Review", - "description": "Ensure that quorum is set correct for the number of instances deployed.", - "guid": "5c2622f5-4b69-4bad-94aa-d5e8c78e1d76", - "id": "A03.05", - "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/hadr-cluster-best-practices?view=azuresql-vm&tabs=windows2012#quorum-voting", + "category": "Identity", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "System or User assigned managed identities enable Azure SQLDB to authenticate to other cloud services (e.g. Azure Key Vault) without storing credentials in code. Once enabled, all necessary permissions can be granted via Azure role-based-access-control to the specific Azure SQLDB instance. Do not share user assigned managed identities across multiple services if not strictly required.", + "guid": "69891194-5074-4e30-8f69-4efc3c580900", + "id": "G02.01", + "link": "https://learn.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview", "services": [ - "SQL" + "AKV", + "RBAC", + "ACR", + "SQL", + "Entra" ], - "severity": "High", - "subcategory": "HADR", - "text": "Configure cluster quorum voting to use 3 or more odd number of votes. Don't assign votes to DR regions. ( If one is implementing FCI or AG)", - "waf": "Reliability" + "severity": "Low", + "subcategory": "Managed Identities", + "text": "Assign Azure SQL Database a managed identity for outbound resource access", + "waf": "Security" }, { - "category": "SQL Server on Azure VM", - "checklist": "SQL Migration Review", - "description": "On Azure virtual machines, clusters use a load balancer to hold an IP address that needs to be on one cluster node at a time. In this solution, the load balancer holds the IP address for the virtual network name (VNN) listener for the Always On availability group when the SQL Server VMs are in a single subnet.", - "guid": "667313c4-0567-44b5-b985-b859c773e7e2", - "id": "A03.06", - "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/availability-group-vnn-azure-load-balancer-configure?view=azuresql-vm&tabs=ilb", + "category": "Identity", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Use an Azure AD integrated authentication that eliminates the use of passwords. Password-based authentication methods are a weaker form of authentication. Credentials can be compromised or mistakenly given away. Use single sign-on authentication using Windows credentials. Federate the on-premises AD domain with Azure AD and use integrated Windows authentication (for domain-joined machines with Azure AD).", + "guid": "88287d4a-8bb8-4640-ad78-03f51354d003", + "id": "G03.01", + "link": "https://learn.microsoft.com/azure/azure-sql/database/authentication-aad-configure?view=azuresql&tabs=azure-powershell#active-directory-integrated-authentication", "services": [ - "LoadBalancer", - "VM", - "VNet", + "Entra", "SQL" ], - "severity": "High", - "subcategory": "HADR", - "text": "When using the virtual network name (VNN) and Azure Load Balancer to connect to your HADR solution, specify MultiSubnetFailover = true in the connection string, even if your cluster only spans one subnet. ( If one is implementing FCI or AG)", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "Passwords", + "text": "Minimize the use of password-based authentication for users", + "waf": "Security" }, { - "category": "SQL Server on Azure VM", - "checklist": "SQL Migration Review", - "description": "SQL Server, Azure SQL Database, and Azure SQL Managed Instance support row and page compression for rowstore tables and indexes, and support columnstore and columnstore archival compression for columnstore tables and indexes.", - "guid": "61623b77-5a91-47e1-b348-ef354c27d42e", - "id": "A04.01", - "link": "https://learn.microsoft.com/sql/relational-databases/data-compression/data-compression?view=sql-server-ver16", + "category": "Ledger", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "The hash of the latest block in the database ledger is called the database digest. It represents the state of all ledger tables in the database at the time when the block was generated. Generating a database digest is efficient, because it involves computing only the hashes of the blocks that were recently appended. Azure Confidential Ledger is one of the supported store, it can be used and supports automatic generation and storage of database digests. Azure Ledger provides advanced security features like Blockchain Ledger Proof and Confidential Hardware Enclaves. Use it only if advanced security features are required, otherwise revert to Azure storage.", + "guid": "0e853380-50ba-4bce-b2fd-5c7391c85ecc", + "id": "H01.01", + "link": "https://learn.microsoft.com/azure/architecture/guide/technology-choices/multiparty-computing-service#confidential-ledger-and-azure-blob-storage", "services": [ "Storage", "SQL" ], - "severity": "Low", - "subcategory": "SQL Server", - "text": "Enable database page compression where appropriate.", - "waf": "Performance" + "severity": "Medium", + "subcategory": "Database Digest", + "text": "Use Azure Confidential Ledger to store database digests only if advanced security features are required", + "waf": "Security" }, { - "category": "SQL Server on Azure VM", - "checklist": "SQL Migration Review", - "description": "By default, data and log files are initialized to overwrite any existing data left on the disk from previously deleted files. Data and log files are first initialized by zeroing the files (filling with zeros).In SQL Server, for data files only, instant file initialization (IFI) allows for faster execution of the previously mentioned file operations, since it reclaims used disk space without filling that space with zeros. Instead, disk content is overwritten as new data is written to the files.", - "guid": "8bbac868-155a-4bb9-863e-9908ae28c84c", - "id": "A04.02", - "link": "https://learn.microsoft.com/sql/relational-databases/databases/database-instant-file-initialization?view=sql-server-ver16", + "category": "Ledger", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "The hash of the latest block in the database ledger is called the database digest. It represents the state of all ledger tables in the database at the time when the block was generated. Generating a database digest is efficient, because it involves computing only the hashes of the blocks that were recently appended. Azure Blob Storage with Immutable Storage feature can be used and supports automatic generation and storage of database digests. To prevent tampering of your digest files, configure and lock a retention policy for your container.", + "guid": "afefb2d3-95da-4ac9-acf5-33d18b32ef9a", + "id": "H01.02", + "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-digest-management", "services": [ "Storage", + "AzurePolicy", "SQL" ], - "severity": "High", - "subcategory": "SQL Server", - "text": "Enable instant file initialization for data files.", - "waf": "Operations" + "severity": "Medium", + "subcategory": "Database Digest", + "text": "If Azure storage account is used to store database digests, ensure security is properly configured", + "waf": "Security" }, { - "category": "SQL Server on Azure VM", - "checklist": "SQL Migration Review", - "description": "Recommended for best performance and availability migrate all databases to data and log disks", - "guid": "33b6b780-8b9f-4e5c-9204-9d413a923c34", - "id": "A04.03", - "link": "https://learn.microsoft.com/sql/relational-databases/databases/move-database-files?view=sql-server-ver16", + "category": "Ledger", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Ledger provides a form of data integrity called forward integrity, which provides evidence of data tampering on data in your ledger tables. The database verification process takes as input one or more previously generated database digests. It then recomputes the hashes stored in the database ledger based on the current state of the ledger tables. If the computed hashes don't match the input digests, the verification fails. The failure indicates that the data has been tampered with. The verification process reports all inconsistencies that it detects.", + "guid": "f8d4ffda-8aac-4cc6-b72b-c81cb8625420", + "id": "H02.01", + "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-database-verification", "services": [ + "Storage", "SQL" ], "severity": "Medium", - "subcategory": "SQL Server", - "text": "Move all databases to data disks, including system databases.", - "waf": "Operations" + "subcategory": "Integrity", + "text": "Schedule the Ledger verification process regularly to verify data integrity", + "waf": "Security" }, { - "category": "SQL Server on Azure VM", - "checklist": "SQL Migration Review", - "description": "Part of the SQL Server Feature checklist in the link that is recommended when SQL Server Instance is in an Azure VM.", - "guid": "b824546c-e1ae-4e34-93ae-c8239248725d", - "id": "A04.04", - "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/performance-guidelines-best-practices-checklist?view=azuresql-vm#sql-server-features", + "category": "Ledger", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "The Ledger feature provides tamper-evidence capabilities in your database. You can cryptographically attest to other parties, such as auditors or other business parties, that your data hasn't been tampered with. Ledger helps protect data from any attacker or high-privileged user, including database administrators (DBAs), system administrators, and cloud administrators.", + "guid": "2563f498-e2d3-42ea-9e7b-5517881a06a2", + "id": "H03.01", + "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-overview", "services": [ - "VM", - "Storage", "SQL" ], - "severity": "Low", - "subcategory": "SQL Server", - "text": "Move SQL Server error log and trace file directories to data disks.", - "waf": "Operations" + "severity": "Medium", + "subcategory": "Ledger", + "text": "If cryptographic proof of data integrity is a critical requirement, Ledger feature should be considered", + "waf": "Security" }, { - "category": "SQL Server on Azure VM", - "checklist": "SQL Migration Review", - "description": "Part of the SQL Server Feature checklist in the link that is recommended when SQL Server Instance is in an Azure VM.", - "guid": "d68c5b5c-2925-4394-a69a-9d2799c42bb6", - "id": "A04.05", - "link": "https://learn.microsoft.com/sql/database-engine/configure-windows/server-memory-server-configuration-options#use-", + "category": "Ledger", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Depending on the type of tampering, there are cases where you can repair the ledger without losing data. In the article contained in the --More Info-- column, different scenarios and recovery techniques are described.", + "guid": "804fc554-6554-4842-91c1-713b32f99902", + "id": "H04.01", + "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-how-to-recover-after-tampering", "services": [ - "VM", "SQL" ], - "severity": "High", - "subcategory": "SQL Server", - "text": "Set max SQL Server memory limit to leave enough memory for the Operating System.", - "waf": "Performance" + "severity": "Medium", + "subcategory": "Recovery", + "text": "Prepare a response plan to investigate and repair a database after a tampering event", + "waf": "Security" }, { - "category": "SQL Server on Azure VM", - "checklist": "SQL Migration Review", - "description": "Part of the SQL Server Feature checklist in the link that is recommended when SQL Server Instance is in an Azure VM.", - "guid": "8d1d7555-6246-4b43-a563-b4dc74a748b6", - "id": "A04.06", - "link": "https://learn.microsoft.com/sql/database-engine/configure-windows/enable-the-lock-pages-in-memory-option-windows", + "category": "Logging", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Azure SQL Database Auditing tracks database events and writes them to an audit log in your Azure storage account. Auditing helps you understand database activity and gain insight into discrepancies and anomalies that could indicate business concerns or suspected security violations as well as helps you meet regulatory compliance. By default auditing policy includes all actions (queries, stored procedures and successful and failed logins) against the databases, which may result in high volume of audit logs. It's recommended for customers to configure auditing for different types of actions and action groups using PowerShell.", + "guid": "4082e31d-35f4-4a49-8507-d3172cc930a6", + "id": "I01.01", + "link": "https://learn.microsoft.com/azure/azure-sql/database/auditing-overview", "services": [ - "VM", + "Storage", + "AzurePolicy", "SQL" ], - "severity": "High", - "subcategory": "SQL Server", - "text": "Enable lock pages in memory.", - "waf": "Performance" + "severity": "Medium", + "subcategory": "Auditing", + "text": "Ensure that Azure SQL Database Auditing is enabled at the server level", + "waf": "Security" }, { - "category": "SQL Server on Azure VM", - "checklist": "SQL Migration Review", - "description": "Part of the SQL Server Feature checklist in the link that is recommended when SQL Server Instance is in an Azure VM.", - "guid": "633ad2a0-916a-4664-a8fa-d0e278ee293c", - "id": "A04.07", - "link": "https://learn.microsoft.com/sql/relational-databases/performance/monitoring-performance-by-using-the-query-store", + "category": "Logging", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Azure SQL Database Auditing logs can be written to external storage accounts, Log Analytics workspace or Event Hub. Be sure to protect the target repository using backups and secured configuration. Use Azure SQL Database Managed Identity to access the storage and set an explicit retention period. Do not grant permissions to administrators to the audit log repository. Use a different target storage for --Enabling Auditing of Microsoft support operations--. ", + "guid": "9b64bc50-b60f-4035-bf7a-28c4806dfb46", + "id": "I01.02", + "link": "https://learn.microsoft.com/azure/azure-sql/database/auditing-overview", "services": [ - "VM", + "Monitor", + "Storage", + "Entra", + "EventHubs", + "Backup", "SQL" ], "severity": "Low", - "subcategory": "SQL Server", - "text": "Enable Query Store on all production SQL Server databases following best practices.", - "waf": "Performance" + "subcategory": "Auditing", + "text": "Ensure that Azure SQL Database Auditing logs are backed up and secured in the selected repository type", + "waf": "Security" }, { - "category": "SQL Server on Azure VM", - "checklist": "SQL Migration Review", - "description": "Part of the SQL Server Feature checklist in the link that is recommended when SQL Server Instance is in an Azure VM.", - "guid": "1bc352ba-aab7-4571-a49a-b8093dc9ec9d", - "id": "A04.08", - "link": "https://learn.microsoft.com/sql/relational-databases/databases/tempdb-database#optimizing-tempdb-performance-in-sql-server", + "category": "Logging", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "The Azure Monitor activity log is a platform log in Azure that provides insight into subscription-level events. The activity log includes information like when a resource is modified. It is recommended to send this activity log to the same external storage repository as the Azure SQL Database Audit Log (storage account, Log Analytics workspace, Event Hub).", + "guid": "fcd34708-87ac-4efc-aaf6-57a47f76644a", + "id": "I01.03", + "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", "services": [ - "VM", + "Monitor", + "Storage", + "Subscriptions", + "EventHubs", "SQL" ], - "severity": "High", - "subcategory": "SQL Server", - "text": "Ensure that all tempdb best practices are followed.", - "waf": "Performance" + "severity": "Medium", + "subcategory": "Auditing", + "text": "Ensure that Azure SQL Database Activity Log is collected and integrated with Auditing logs", + "waf": "Security" }, { - "category": "SQL Server on Azure VM", - "checklist": "SQL Migration Review", - "description": "Part of the SQL Server Feature checklist in the link that is recommended when SQL Server Instance is in an Azure VM.", - "guid": "1bb73b36-a5a6-47fb-a9ed-5b35478c3479", - "id": "A04.09", - "link": "https://docs.microsoft.com/azure/governance/management-groups/how-to/protect-resource-hierarchy#setting---require-authorization", + "category": "Logging", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Forward any logs from Azure SQL to your Security Information and Event Management (SIEM) and Security Orchestration Automation and Response (SOAR). Ensure that you are monitoring different types of Azure assets for potential threats and anomalies. Focus on getting high-quality alerts to reduce false positives for analysts to sort through. Alerts can be sourced from log data, agents, or other data.", + "guid": "f96e127e-9572-453a-b325-ff89ae9f6b44", + "id": "I02.01", + "link": "https://learn.microsoft.com/azure/azure-sql/database/auditing-overview", "services": [ - "VM", + "Monitor", "SQL" ], - "severity": "High", - "subcategory": "SQL Server", - "text": "Schedule SQL Server Agent jobs to run DBCC CHECKDB, index reorganize, index rebuild, and update statistics jobs.", - "waf": "Operations" + "severity": "Medium", + "subcategory": "SIEM/SOAR", + "text": "Ensure that Azure SQL Database Auditing logs are being presented in to your organizations SIEM/SOAR", + "waf": "Security" }, { - "category": "SQL Server on Azure VM", - "checklist": "SQL Migration Review", - "description": "Part of the SQL Server Feature checklist in the link that is recommended when SQL Server Instance is in an Azure VM.", - "guid": "816b2863-cffe-41ca-a599-ef0d5a73dd4c", - "id": "A04.10", - "link": "https://docs.microsoft.com/azure/governance/management-groups/how-to/protect-resource-hierarchy#setting---require-authorization", + "category": "Logging", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Forward any logs from Azure SQL to your Security Information and Event Management (SIEM) and Security Orchestration Automation and Response (SOAR), which can be used to set up custom threat detections. Ensure that you are monitoring different types of Azure assets for potential threats and anomalies. Focus on getting high-quality alerts to reduce false positives for analysts to sort through. Alerts can be sourced from log data, agents, or other data.", + "guid": "41503bf8-73da-4a10-af9f-5f7fceb5456f", + "id": "I02.02", + "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", "services": [ - "VM", + "Monitor", "SQL" ], "severity": "Medium", - "subcategory": "SQL Server", - "text": "Limit autogrowth of the database and Disable autoshrink", - "waf": "Operations" + "subcategory": "SIEM/SOAR", + "text": "Ensure that Azure SQL Database Activity Log data is presented in to your SIEM/SOAR", + "waf": "Security" }, { - "category": "SQL Server on Azure VM", - "checklist": "SQL Migration Review", - "description": "Constrained vCPU virtual machines (VMs) are a type of VM where the vCPU count can be constrained to a half or a quarter of the original VM size. This allows customers to reduce the cost of software licensing while maintaining the same memory, storage, and I/O bandwidth", - "guid": "e36c1c81-770a-4fbc-9c0d-43918648d285", - "id": "A05.01", - "link": "https://learn.microsoft.com/azure/virtual-machines/constrained-vcpu", + "category": "Logging", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Security Operation Center (SOC) team should create an incident response plan (playbooks or manual responses) to investigate and mitigate tampering, malicious activities, and other anomalous behaviors.", + "guid": "19ec7c97-c563-4e1d-82f0-54d6ec12e754", + "id": "I02.03", + "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", "services": [ - "VM", - "Storage", - "SQL", - "Cost" + "EventHubs", + "SQL" ], - "severity": "Low", - "subcategory": "Cost Optimization", - "text": "Optimize SQL Server License cost with Constrained vCPU VM's", - "training": "https://learn.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview", - "waf": "Cost" + "severity": "Medium", + "subcategory": "SIEM/SOAR", + "text": "Ensure that you have response plans for malicious or aberrant audit logging events", + "waf": "Security" }, { - "category": "SQL Server on Azure VM", - "checklist": "SQL Migration Review", - "description": "Azure Hybrid Benefit allows you to exchange your existing licenses for discounted rates on Azure SQL Database and Azure SQL Managed Instance. Y", - "guid": "7ed67178-b824-4546-ae1a-ee3453aec823", - "id": "A05.02", - "link": "https://azure.microsoft.com/en-ca/pricing/hybrid-benefit/", + "category": "Networking", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "When you create a logical server from the Azure portal for Azure SQL Database, the result is a public endpoint that is visible and reachable over the public network (Public Access). You can then limit connectivity based on firewall rules and Service Endpoint. You can also configure private connectivity only limiting connections to internal networks using Private Endpoint (Private Access). Private Access using Private Endpoint should be the default unless a business case or performance/technical reason applies that cannot support it. Usage of Private Endpoints has performance implications that need to be considered and assessed.", + "guid": "2c6d356a-1784-475b-a42c-ec187dc8c925", + "id": "J01.01", + "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview", "services": [ - "SQL", - "Cost" + "PrivateLink", + "SQL" ], - "severity": "Low", - "subcategory": "Cost Optimization", - "text": "Leverage Azure Hybrid benefit to maximize the value of your on premises licenses in the cloud", - "waf": "Cost" + "severity": "High", + "subcategory": "Connectivity", + "text": "Review Public vs. Private Access connectivity methods and select the appropriate one for the workload", + "waf": "Security" }, { - "category": "SQL Server on Azure VM", - "checklist": "SQL Migration Review", - "description": "The SQL Server IaaS Agent extension (SqlIaasExtension) runs on SQL Server on Azure Windows Virtual Machines (VMs) to automate management and administration tasks.", - "guid": "9248725d-d68c-45b5-a292-5394a69a9d27", - "id": "A06.01", - "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/sql-agent-extension-automatic-registration-all-vms?view=azuresql-vm&tabs=azure-cli", + "category": "Networking", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "IMPORTANT: Connections to private endpoint only support Proxy as the connection policy. When using private endpoints connections are proxied via the Azure SQL Database gateway to the database nodes. Clients will not have a direct connection.", + "guid": "557b3ce5-bada-4296-8d52-a2d447bc1718", + "id": "J01.02", + "link": "https://learn.microsoft.com/azure/azure-sql/database/connectivity-architecture", "services": [ - "VM", + "PrivateLink", + "AzurePolicy", "SQL" ], - "severity": "Medium", - "subcategory": "Azure", - "text": "Register with the SQL IaaS Agent Extension to unlock a number of feature benefits.", - "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/", - "waf": "Operations" + "severity": "Low", + "subcategory": "Connectivity", + "text": "Keep default Azure SQL Database Connection Policy if not differently required and justified", + "waf": "Security" }, { - "category": "SQL Server on Azure VM", - "checklist": "SQL Migration Review", - "description": "Accelerated Networking provides consistent ultra-low network latency via Azure's in-house programmable hardware and technologies", - "guid": "99c42bb6-8d1d-4755-9624-6b438563b4dc", - "id": "A06.02", - "link": "https://learn.microsoft.com/azure/virtual-network/accelerated-networking-overview?tabs=redhat", + "category": "Networking", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "This option configures the firewall to allow all connections from Azure, including connections from the subscriptions of other customers. If you select this option, make sure that your login and user permissions limit access to authorized users only. If not strictly required, keep this setting to OFF.", + "guid": "f48efacf-4405-4e8d-9dd0-16c5302ed082", + "id": "J01.03", + "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview", "services": [ - "VM", + "Subscriptions", "SQL" ], "severity": "High", - "subcategory": "Azure", - "text": "Ensure Accelerated Networking is enabled on the virtual machine.", - "waf": "Operations" + "subcategory": "Connectivity", + "text": "Ensure Allow Azure Services and Resources to Access this Server setting is disabled in Azure SQL Database firewall", + "waf": "Security" }, { - "category": "SQL Server on Azure VM", - "checklist": "SQL Migration Review", - "description": "Microsoft Defender detects anomalous activities indicating unusual and potentially harmful attempts to access or exploit databases on the SQL server.", - "guid": "74a748b6-633a-4d2a-8916-a66498fad0e2", - "id": "A06.03", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/secure-score-security-controls", + "category": "Networking", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Azure SQL Database has a new built-in feature that allows native integration with external REST endpoints. This means that integration of Azure SQL Database with Azure Functions, Azure Logic Apps, Cognitive Services, Event Hubs, Event Grid, Azure Containers, API Management and in general any REST or even GraphQL endpoint. If not properly restricted, code inside an Azure SQL Database database could leverage this mechanism to exfiltrate data. If not strictly required, it is recommended to block or restrict this feature using Outbound Firewall Rules.", + "guid": "cb3274a7-e36d-46f6-8de5-46d30c8dde8e", + "id": "J02.01", + "link": "https://learn.microsoft.com/sql/relational-databases/system-stored-procedures/sp-invoke-external-rest-endpoint-transact-sql", "services": [ - "VM", - "Defender", + "EventHubs", + "APIM", "SQL" ], - "severity": "High", - "subcategory": "Azure", - "text": "Leverage Microsoft Defender for Cloud to improve the overall security posture of your virtual machine deployment.", - "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", + "severity": "Medium", + "subcategory": "Outbound Control", + "text": "Block or restrict outbound REST API calls to external endpoints", + "waf": "Security" + }, + { + "category": "Networking", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Outbound firewall rules limit network traffic from the Azure SQL Database logical server to a customer defined list of Azure Storage accounts and Azure SQL Database logical servers. Any attempt to access storage accounts or databases not in this list is denied.", + "guid": "a566dd3d-314e-4a94-9378-102c42d82b38", + "id": "J02.02", + "link": "https://learn.microsoft.com/azure/azure-sql/database/outbound-firewall-rule-overview", + "services": [ + "Storage", + "SQL" + ], + "severity": "Medium", + "subcategory": "Outbound Control", + "text": "If outbound network access is required, it is recommended to configure outbound networking restrictions using built-in Azure SQL Database control feature", "waf": "Security" }, { - "category": "SQL Managed Instance", - "checklist": "SQL Migration Review", - "description": "There are some PaaS limitations that are introduced in SQL Managed Instance and some behavior changes compared to SQL Server. It is important to review and understand these differences.", - "guid": "78ee293c-1bc3-452b-aaab-7571849ab809", - "id": "B01.01", - "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/transact-sql-tsql-differences-sql-server?view=azuresql", + "category": "Networking", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Private Endpoint is created inside a subnet in an Azure Virtual Network. Proper security configuration must be applied also to the containing network environment, including NSG/ASG, UDR, firewall, monitoring and auditing.", + "guid": "246cd832-f550-4af0-9c74-ca9baeeb8860", + "id": "J03.01", + "link": "https://learn.microsoft.com/azure/azure-sql/database/private-endpoint-overview?view=azuresql#disable-public-access-to-your-logical-server", "services": [ - "SQL", - "EventHubs" + "Monitor", + "PrivateLink", + "Firewall", + "VNet", + "SQL" ], - "severity": "High", - "subcategory": "Pre Migration", - "text": "Review the major differences between SQL Server and Managed Instance", - "training": "https://learn.microsoft.com/learn/modules/plan-implement-administer-conditional-access/", - "waf": "Operations" + "severity": "Medium", + "subcategory": "Private Access", + "text": "If Private Access connectivity is used, ensure that you are using the Private Endpoint, Azure Virtual Network, Azure Firewall, and Azure Network Security Group checklists", + "waf": "Security" }, { - "category": "SQL Managed Instance", - "checklist": "SQL Migration Review", - "description": "SQL Managed Instance has characteristics and resource limits that depend on the underlying infrastructure and architecture. It is important to review these limits.", - "guid": "3dc9ec9d-1bb7-43b3-9a5a-67fba9ed5b35", - "id": "B01.02", - "link": "https://docs.microsoft.com/azure/azure-sql/managed-instance/resource-limits", + "category": "Networking", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "When adding a Private Endpoint connection, public routing to your logical server isn't blocked by default. In the --Firewall and virtual networks-- pane, the setting --Deny public network access-- is not selected by default. To disable public network access, ensure that you select --Deny public network access--.", + "guid": "3a0808ee-ea7a-47ab-bdce-920a6a2b3881", + "id": "J03.02", + "link": "https://learn.microsoft.com/azure/azure-sql/database/private-endpoint-overview?view=azuresql#disable-public-access-to-your-logical-server", "services": [ + "VNet", + "PrivateLink", "SQL" ], "severity": "High", - "subcategory": "Pre Migration", - "text": "Review capacity limits for SQL MI", - "training": "https://learn.microsoft.com/learn/modules/secure-aad-users-with-mfa/", - "waf": "Performance" + "subcategory": "Private Access", + "text": "If Private Endpoint (Private Access) is used, consider disabling Public Access connectivity", + "waf": "Security" }, { - "category": "SQL Managed Instance", - "checklist": "SQL Migration Review", - "description": "The instance settings between managed instance and your source SQL Server can be different . It is important to review those differences that can impact performance.", - "guid": "8bc178bd-c5a0-46ca-9144-351e19dd3442", - "id": "B01.03", - "link": "https://medium.com/azure-sqldb-managed-instance/compare-environment-settings-on-sql-server-and-azure-sql-that-may-impact-performance-e90c21fa9b08", + "category": "Networking", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Network Security Group (NSG) and Application Security Group (ASG) can be now applied to subnet containing Private Endpoints to restrict connections to Azure SQLDB based on internal source IP ranges.", + "guid": "8600527e-e8c4-4424-90ef-1f0dca0224f2", + "id": "J03.03", + "link": "https://learn.microsoft.com/azure/private-link/private-endpoint-overview#network-security-of-private-endpoints", "services": [ + "VNet", + "PrivateLink", "SQL" ], - "severity": "High", - "subcategory": "Pre Migration", - "text": "Compare instance settings on SQL Server and Azure SQL MI that may impact performance", - "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-identities-governance/", - "waf": "Performance" + "severity": "Medium", + "subcategory": "Private Access", + "text": "If Private Endpoint (Private Access) is used, apply NSG and eventually ASG to limit incoming source IP address ranges", + "waf": "Security" }, { - "category": "SQL Managed Instance", - "checklist": "SQL Migration Review", - "description": "Assess on-premises SQL Server instance(s) migrating to Azure SQL Managed Instance. The assessment workflow helps you to detect issues that block the migration itself and also partially supported and unsupported features", - "guid": "9eb72281-37a1-451c-9bb4-e4f1814287d5", - "id": "B01.04", - "link": "https://docs.microsoft.com/azure/dms/ads-sku-recommend", + "category": "Networking", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "A Managed Instance (SQL MI) can be isolated inside a virtual network to prevent external access. Applications and tools that are in the same or peered virtual network in the same region could access it directly. Applications and tools that are in different region could use virtual-network-to-virtual-network connection or ExpressRoute circuit peering to establish connection. Customer should use Network Security Groups (NSG), and eventually internal firewalls, to restrict access over port 1433 only to resources that require access to a managed instance.", + "guid": "18123ef4-a0a6-45e3-87fe-7f454f65d975", + "id": "J03.04", + "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/connectivity-architecture-overview", "services": [ + "ExpressRoute", + "VNet", "SQL" ], - "severity": "High", - "subcategory": "Pre Migration", - "text": "Run Data Migration assistant or Azure Data Studio Migration Extension to detect compatibility issues that can impact database functionality on Managed Instance", - "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/", - "waf": "Operations" + "severity": "Medium", + "subcategory": "Private Access", + "text": "Apply Network Security Groups (NSG) and firewall rules to restrict access to Azure SQL Managed Instance internal subnet", + "waf": "Security" }, { - "category": "SQL Managed Instance", - "checklist": "SQL Migration Review", - "description": "The SKU recommendation feature can evaluate the source SQL Server performance and utilization characteristics to recommend a right-sized Azure SQL Managed Instance to assist with your migration journey.", - "guid": "ca8c26c9-b32a-4b5b-afc6-898a135e3378", - "id": "B01.05", - "link": "https://learn.microsoft.com/azure/dms/ads-sku-recommend", + "category": "Networking", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Azure Virtual Network Service Endpoint is preferred solution if you want to establish a direct connection to the Azure SQL Database backend nodes using Redirect policy. This will allow access in high performance mode and is the recommended approach from a performance perspective.", + "guid": "55187443-6852-4fbd-99c6-ce303597ca7f", + "id": "J04.01", + "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview?view=azuresql#ip-vs-virtual-network-firewall-rules", "services": [ + "VNet", + "AzurePolicy", "SQL" ], "severity": "High", - "subcategory": "Pre Migration", - "text": "Select the right compute resources for your workload by leveraging the SKU recommendation tools.", - "training": "https://learn.microsoft.com/learn/modules/explore-basic-services-identity-types/", - "waf": "Performance" + "subcategory": "Public Access", + "text": "If Public Access connectivity is used, leverage Service Endpoint to restrict access from selected Azure Virtual Networks", + "waf": "Security" }, { - "category": "SQL Managed Instance", - "checklist": "SQL Migration Review", - "description": "Review Unsupported Features, Migration Blockers and Breaking Changes for each database from the Assessment", - "guid": "97e31c67-d68c-4b69-82ac-19f906d697c8", - "id": "B01.06", - "link": "https://learn.microsoft.com/azure/dms/ads-sku-recommend", + "category": "Networking", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "The Azure SQL Database firewall allows you to specify IP address ranges from which communications are accepted. This approach is fine for stable IP addresses that are outside the Azure private network.", + "guid": "a73e32da-b3f4-4960-b5ec-2f42a557bf31", + "id": "J04.02", + "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview", "services": [ + "Storage", "SQL" ], - "severity": "High", - "subcategory": "Pre Migration", - "text": "Review and address the issues highlighted in DMA/Azure Data Studio", - "training": "https://learn.microsoft.com/learn/paths/manage-identity-and-access/", - "waf": "Operations" + "severity": "Medium", + "subcategory": "Public Access", + "text": "If Public Access connectivity is used, ensure that only specific known IPs are added to the firewall", + "waf": "Security" }, { - "category": "SQL Managed Instance", - "checklist": "SQL Migration Review", - "description": "The SQL Managed Instance default DNS zone .database.windows.net can be changed with your own. However, the managed instance hostname part of its FQDN should remain the same.", - "guid": "eaded26b-dd18-46f0-ac25-1b999a68af87", - "id": "B01.07", - "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/frequently-asked-questions-faq?view=azuresql-mi#can-a-managed-instance-have-the-same-name-as-a-sql-server-on-premises-instance", + "category": "Networking", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "We recommend that you use database-level IP firewall rules whenever possible. This practice enhances security and makes your database more portable. Use server-level IP firewall rules for administrators. Also use them when you have many databases that have the same access requirements, and you don't want to configure each database individually.", + "guid": "e0f31ac9-35c8-4bfd-9865-edb60ffc6768", + "id": "J04.03", + "link": "https://learn.microsoft.com/azure/azure-sql/database/firewall-configure", "services": [ - "DNS", + "Storage", "SQL" ], - "severity": "High", - "subcategory": "Pre Migration", - "text": "Plan for connection string changes as changing a managed instance name is not supported", - "training": "https://learn.microsoft.com/learn/modules/create-custom-azure-roles-with-rbac/", - "waf": "Operations" + "severity": "Low", + "subcategory": "Public Access", + "text": "If Public Access connectivity is used and controlled by Azure SQL Database firewall rules, use database-level over server-level IP rules", + "waf": "Security" }, { - "category": "SQL Managed Instance", - "checklist": "SQL Migration Review", - "description": "There are addional requirements in configuring a vnet and subnet hosting the managed instance.", - "guid": "c9a7f821-b8eb-48c0-aa77-e25e4d5aeaa8", - "id": "B01.08", - "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/vnet-existing-add-subnet?view=azuresql-mi", + "category": "Networking", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "A Managed Instance (SQL MI) can be isolated inside a virtual network to prevent external access. The Managed Instance public endpoint is not enabled by default, must be explicitly enabled, only if strictly required. If company policy disallows the use of public endpoints, use Azure Policy to prevent enabling public endpoints in the first place.", + "guid": "b8435656-143e-41a8-9922-61d34edb751a", + "id": "J04.04", + "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/public-endpoint-overview", "services": [ "VNet", + "AzurePolicy", "SQL" ], - "severity": "Medium", - "subcategory": "Pre Migration", - "text": "Review managed instance VNet requirements", - "training": "https://learn.microsoft.com/learn/paths/secure-your-cloud-data/", - "waf": "Operations" + "severity": "High", + "subcategory": "Public Access", + "text": "Do not enable Azure SQL Managed Instance public endpoint", + "waf": "Security" }, { - "category": "SQL Managed Instance", - "checklist": "SQL Migration Review", - "description": "Though it's possible to deploy managed instances to a subnet with a number of IP addresses that's less than the output of the subnet formula, always consider using bigger subnets instead. Using a bigger subnet can help avoid future issues stemming from a lack of IP addresses, such as the inability to create additional instances within the subnet or scale existing instances.", - "guid": "dc4e2436-bb33-46d7-85f1-7960eee0b9b5", - "id": "B02.01", - "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/vnet-subnet-determine-size?view=azuresql-mi", + "category": "Networking", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "A Managed Instance (SQL MI) public endpoint is not enabled by default, must be explicitly enabled, only if strictly required. In this case, it is recommended to apply a Network Security Groups (NSG) to restrict access to port 3342 only to trusted source IP addresses.", + "guid": "057dd298-8726-4aa6-b590-1f81d2e30421", + "id": "J04.05", + "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/public-endpoint-overview", "services": [ "VNet", "SQL" ], "severity": "High", - "subcategory": "Deployment", - "text": "Ensure managed instance subnet has sufficient IP addresses available", - "training": "https://learn.microsoft.com/learn/modules/azure-active-directory/", - "waf": "Operations" + "subcategory": "Public Access", + "text": "Restrict access if Azure SQL Managed Instance public endpoint is required", + "waf": "Security" }, { - "category": "SQL Managed Instance", - "checklist": "SQL Migration Review", - "description": "SQL Managed Instance has characteristics and resource limits that depend on the underlying infrastructure and architecture. SQL Managed Instance can be deployed on multiple hardware configurations.", - "guid": "c8defc4d-721d-431d-850f-b707ae9eab40", - "id": "B03.01", - "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/resource-limits?view=azuresql-mi#service-tier-characteristics", + "category": "Privileged Access", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Most operations, support, and troubleshooting performed by Microsoft personnel and sub-processors do not require access to customer data. In those rare circumstances where such access is required, Customer Lockbox for Microsoft Azure provides an interface for customers to review and approve or reject customer data access requests. In support scenarios where Microsoft needs to access customer data, Azure SQL Database supports Customer Lockbox to provide an interface for you to review and approve or reject customer data access requests.", + "guid": "37b6eb0f-553d-488f-8a8a-cb9bf97388ff", + "id": "K01.01", + "link": "https://learn.microsoft.com/azure/security/fundamentals/customer-lockbox-overview", "services": [ "SQL" ], - "severity": "High", - "subcategory": "Pre Migration", - "text": "Plan between General Purpose and Business Critical tiers of MI", - "training": "https://learn.microsoft.com/learn/modules/implement-hybrid-identity-windows-server/", - "waf": "Performance" + "severity": "Low", + "subcategory": "Lockbox", + "text": "Review and enable Customer Lockbox for Azure SQL Database access by Microsoft personnel", + "waf": "Security" }, { - "category": "SQL Managed Instance", - "checklist": "SQL Migration Review", - "description": "The auto-failover groups feature allows you to manage the replication and failover of user databases in a managed instance to a managed instance in another Azure region. Auto-failover groups are designed to simplify deployment and management of geo-replicated databases at scale.", - "guid": "ed329079-8bc1-478b-bc5a-06ca7144351e", - "id": "B03.02", - "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/auto-failover-group-sql-mi?view=azuresql-mi&tabs=azure-powershell", + "category": "Privileged Access", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "The principle of least privilege states that users shouldn't have more privileges than needed to complete their tasks. High-privileged database and server users can perform many configuration and maintenance activities on the database and can also drop databases in Azure SQL instance. Tracking database owners and privileged accounts is important to avoid having excessive permission.", + "guid": "5fe5281f-f0f9-4842-a682-8baf18bd8316", + "id": "K02.01", + "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#implement-principle-of-least-privilege", "services": [ "SQL" ], - "severity": "High", - "subcategory": "Pre Migration", - "text": "Based on your RPO/RTO's , determine if Auto failover Group needs to be implemented. If so, plan for the deployment attributes of the second instance.", - "training": "https://learn.microsoft.com/learn/paths/implement-windows-server-iaas-virtual-machine-identity/", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "Permissions", + "text": "Ensure that users are assigned the minimum level of access necessarily to complete their job functions", + "waf": "Security" }, - { - "category": "SQL Managed Instance", - "checklist": "SQL Migration Review", - "description": "There are multiple ways to connect your application to the managed instance. Review and understand the pros and cons and decide on the best approach for your application.", - "guid": "5d226886-d30b-466c-97be-595190f83845", - "id": "B03.03", - "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/connect-application-instance?view=azuresql-mi", + { + "category": "Privileged Access", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Identities (both Users and SPNs) should be scoped to the least amount of access needed to perform the function. A higher number of tightly scoped SPNs should be used, instead of having one SPN with multiple sets of unrelated permissions. For example, if there are three external web applications hosted on-prem that make queries to the Azure SQL Database, they should not all use the same SPN for these activities. Instead, they should each have their own tightly scoped SPN.", + "guid": "7b5b55e5-4750-4920-be97-eb726c256a5c", + "id": "K02.02", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/sql-database-security-baseline#im-3-use-azure-ad-single-sign-on-sso-for-application-access", "services": [ + "Entra", "SQL" ], "severity": "Low", - "subcategory": "Pre Migration", - "text": "Review the Connectivity Design between Database and Application, test & validate it", - "training": "https://learn.microsoft.com/learn/paths/implement-applications-external-access-azure-ad/", - "waf": "Operations" + "subcategory": "Permissions", + "text": "Ensure that distinct applications will be assigned different credentials with minimal permissions to access Azure SQL Database", + "waf": "Security" }, { - "category": "SQL Managed Instance", - "checklist": "SQL Migration Review", - "description": "Compare migration options to choose the path that's appropriate to your business needs.", - "guid": "c586cb29-1ec1-46a1-b076-ef9f141acdce", - "id": "B03.04", - "link": "https://learn.microsoft.com/azure/azure-sql/migration-guides/managed-instance/sql-server-to-managed-instance-overview?view=azuresql-mi#migration-tools", + "category": "Cleanup", + "checklist": "Cost Optimization Checklist", + "guid": "a95b86ad-8840-48e3-9273-4b875ba18f20", + "id": "A01.01", + "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/considerations/tenancy-models", "services": [ - "SQL" + "Monitor", + "Cost" ], - "severity": "Medium", - "subcategory": "Pre Migration", - "text": "Plan for the Migration Method. Depending on the DB Size and Application downtime window, select the preferred Migration Method.", - "training": "https://learn.microsoft.com/learn/modules/design-identity-security-strategy/", - "waf": "Operations" + "subcategory": "Azure Monitor - enforce data collection rules", + "text": "Data collection rules in Azure Monitor -https://learn.microsoft.com/azure/azure-monitor/essentials/data-collection-rule-overview", + "training": "https://azure.microsoft.com/pricing/reservations/" }, { - "category": "SQL Managed Instance", - "checklist": "SQL Migration Review", - "description": "After you verify that data is the same on both source and target, you can cut over from the source to the target environment. It's important to plan the cutover process with business / application teams to ensure minimal interruption during cutover doesn't affect business continuity.", - "guid": "579377bc-db37-451a-a2ac-1fad66e15d4d", - "id": "B03.05", - "link": "https://learn.microsoft.com/azure/dms/tutorial-sql-server-managed-instance-online#performing-migration-cutover", + "category": "Cleanup", + "checklist": "Cost Optimization Checklist", + "guid": "45901365-d38e-443f-abcb-d868266abca2", + "id": "A02.01", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/multi-tenant/automation", "services": [ - "SQL" + "Cost", + "Backup" ], - "severity": "Medium", - "subcategory": "Pre Migration", - "text": "Plan the cutover process with business / application teams to ensure minimal interruption during cutover and it does not affect business continuity.", - "training": "https://learn.microsoft.com/azure/architecture/example-scenario/identity/adds-extend-domain", - "waf": "Reliability" + "subcategory": "Backup", + "text": "check backup instances with the underlying datasource not found" }, { - "category": "SQL Managed Instance", - "checklist": "SQL Migration Review", - "description": "A time zone of a managed instance can be set during instance creation only. The default time zone is UTC", - "guid": "4a2adb1c-3d23-426a-b225-ca44e1695fdd", - "id": "B04.01", - "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/timezones-overview?view=azuresql#set-a-time-zone", + "category": "Cleanup", + "checklist": "Cost Optimization Checklist", + "guid": "64f9a19a-f29c-495d-94c6-c7919ca0f6c5", + "id": "A03.01", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/multi-tenant/lighthouse", "services": [ - "SQL" + "Cost" ], - "severity": "High", - "subcategory": "Deployment", - "text": "Ensure you customize your time zone setting at the instance creation time. One cannot change it later.", - "training": "https://learn.microsoft.com/azure/role-based-access-control/overview", - "waf": "Operations" + "subcategory": "delete/archive", + "text": "delete or archive unassociated services (disks, nics, ip addresses etc)" }, { - "category": "SQL Managed Instance", - "checklist": "SQL Migration Review", - "description": "Server-level collation in Azure SQL Managed Instance can be specified when the instance is created and cannot be changed later.Default server-level collation is SQL_Latin1_General_CP1_CI_AS.", - "guid": "deace4cb-1deb-44c6-90c3-fc14eebb3693", - "id": "B04.02", - "link": "https://learn.microsoft.com/sql/relational-databases/collations/set-or-change-the-server-collation?view=sql-server-ver16", + "category": "Cleanup", + "checklist": "Cost Optimization Checklist", + "guid": "659d3958-fd77-4289-a835-556df2bfe456", + "id": "A03.02", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", "services": [ - "SQL" + "Cost" ], - "severity": "High", - "subcategory": "Deployment", - "text": "Ensure you select the right collation setting at the instance creation time. One cannot change it later", - "waf": "Operations" + "subcategory": "delete/archive", + "text": "consider snooze and stop technique (snooze a service after x days, stop after 2x, delete/deallocate after 3x)" }, { - "category": "SQL Managed Instance", - "checklist": "SQL Migration Review", - "description": "When you're migrating a database protected by Transparent Data Encryption (TDE) to Azure SQL Managed Instance using the native restore option, the corresponding certificate from the SQL Server instance needs to be migrated before database restore.", - "guid": "829e3eec-2183-4687-a007-7a2b5945bda4", - "id": "B04.03", - "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/tde-certificate-migrate?view=azuresql-mi&tabs=azure-powershell", + "category": "Cleanup", + "checklist": "Cost Optimization Checklist", + "guid": "3b0d834a-3487-426d-b69c-6b5c2a26494b", + "id": "A03.03", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", "services": [ - "VM", - "SQL" + "Cost", + "Backup", + "Storage" ], - "severity": "Medium", - "subcategory": "Deployment", - "text": "For TDE Enabled Database, corresponding certificate from the on-premises or Azure VM SQL Server needs to be migrated before database restore", - "waf": "Operations" + "subcategory": "delete/archive", + "text": "delete or archive unused resources (old backups, logs, storage accounts, etc...)" }, { - "category": "SQL Managed Instance", - "checklist": "SQL Migration Review", - "description": "System databases can be restored only from backups that are created on the version of SQL Server that the server instance is currently running. This is not the case when you are migrating to SQL Managed Instance.Azure PowerShell and DBATools PowerShell libraries enable you to easily script and automate and customize all parts of the migration process.", - "guid": "3334fdf9-1c23-4418-8b65-275269440b4b", - "id": "B05.01", - "link": "https://learn.microsoft.com/azure/azure-sql/migration-guides/managed-instance/sql-server-to-managed-instance-guide?view=azuresql-mi#backup-and-restore", + "category": "Cleanup", + "checklist": "Cost Optimization Checklist", + "guid": "69bad37a-ad53-4cc7-ae1d-76667357c449", + "id": "A03.04", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", "services": [ - "Backup", - "SQL" + "Cost", + "ASR", + "Storage", + "Backup" ], - "severity": "Low", - "subcategory": "Migration", - "text": "Restore of system databases is not supported. To migrate instance-level objects (stored in master or msdb databases), we recommend to script them out and run T-SQL scripts on the destination instance.", - "waf": "Operations" + "subcategory": "delete/archive", + "text": "consider a good balance between site recovery storage and backup for non mission critical applications" }, { - "category": "SQL Managed Instance", - "checklist": "SQL Migration Review", - "description": "When using migration options that continuously replicate / sync data changes from source to the target, the source data and schema can change and drift from the target. During data sync, ensure that all changes on the source are captured and applied to the target during the migration process.", - "guid": "e3d3e084-3276-4d4b-bc01-5bcf219e4a1e", - "id": "B05.02", + "category": "Cleanup", + "checklist": "Cost Optimization Checklist", + "guid": "674b5ed8-5a85-49c7-933b-e2a1a27b765a", + "id": "A04.01", + "link": "https://learn.microsoft.com/azure/cost-management-billing/manage/direct-ea-administration#manage-notification-contacts", "services": [ - "SQL" + "Monitor", + "Cost" ], - "severity": "High", - "subcategory": "Migration", - "text": "Ensure that all changes on the source are captured and applied to the target during the migration process.", - "waf": "Operations" + "subcategory": "Log Analytics retention for workspaces", + "text": "check spending and savings opportunities among the 40 different log analytics workspaces- use different retention and data collection for nonprod workspaces-create daily cap for awareness and tier sizing - If you do set a daily cap, in addition to creating an alert when the cap is reached,ensure that you also create an alert rule to be notified when some percentage has been reached (90% for example). - consider workspace transformation if possible - https://learn.microsoft.com/azure/azure-monitor/essentials/data-collection-transformations#workspace-transformation-dcr ", + "training": "https://learn.microsoft.com/azure/cost-management-billing/costs/understand-work-scopes" }, { - "category": "SQL Managed Instance", - "checklist": "SQL Migration Review", - "description": "Ensure that the application is able to succesffuly connect to the managed instance post migration of the databases.", - "guid": "b5887952-5d22-4688-9d30-b66c57be5951", - "id": "B05.03", - "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/connect-application-instance?view=azuresql-mi", + "category": "Cleanup", + "checklist": "Cost Optimization Checklist", + "guid": "91be1f38-8ef3-494c-8bd4-63cbbac75819", + "id": "A05.01", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-enterprise-agreement#design-considerations", "services": [ - "SQL" + "Cost", + "Storage", + "AzurePolicy" ], - "severity": "Medium", - "subcategory": "Migration", - "text": "Test Application Connectivity to MI and Databases", - "waf": "Operations" + "subcategory": "Policy", + "text": "enforce a purging log policy and automation (if needed, logs can be moved to cold storage)", + "training": "https://www.youtube.com/watch?v=nHQYcYGKuyw" }, { - "category": "SQL Managed Instance", - "checklist": "SQL Migration Review", - "description": "High availability is a fundamental part of SQL Managed Instance platform that works transparently for your database applications. Failovers from primary to secondary nodes in case of node degradation or fault detection, or during regular monthly software updates are an expected occurrence for all applications using SQL Managed Instance in Azure.", - "guid": "90f83845-c586-4cb2-a1ec-16a1d076ef9f", - "id": "B06.01", - "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/user-initiated-failover?view=azuresql", + "category": "Cleanup", + "checklist": "Cost Optimization Checklist", + "guid": "59bb91a3-ed90-4cae-8cc8-4c37b6b780cb", + "id": "A06.01", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-enterprise-agreement#design-considerations", "services": [ - "SQL" + "Cost" ], - "severity": "High", - "subcategory": "Post Migration", - "text": "Consider executing a manual failover on SQL Managed Instance to test for fault and failover resiliency.", - "training": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", - "waf": "Reliability" + "subcategory": "run orphaned resources workbook - delete or snooze ghost items", + "text": "https://github.com/dolevshor/azure-orphan-resources", + "training": "https://learn.microsoft.com/azure/cost-management-billing/costs/tutorial-acm-create-budgets" }, { - "category": "SQL Managed Instance", - "checklist": "SQL Migration Review", - "description": "Ensuring that your applications are failover resilient prior to deploying to production will help mitigate the risk of application faults in production and will contribute to application availability for your customers.", - "guid": "141acdce-5793-477b-adb3-751ab2ac1fad", - "id": "B06.02", - "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/auto-failover-group-configure-sql-mi?view=azuresql&tabs=azure-portal#test-failover", + "category": "Cleanup", + "checklist": "Cost Optimization Checklist", + "guid": "9fe5c464-89d4-457a-a27c-3874d0102cac", + "id": "A07.01", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-enterprise-agreement#design-considerations", "services": [ - "LoadBalancer", - "SQL", - "EventHubs" + "Cost" ], - "severity": "High", - "subcategory": "Post Migration", - "text": "If failover groups have been implemented, Test Manual Failover and Failback and test application connectivity behavior during failover/failback", - "waf": "Reliability" + "subcategory": "shutdown/deallocate", + "text": "shutdown underutilized instances", + "training": "https://learn.microsoft.com/azure/cost-management-billing/understand/analyze-unexpected-charges" }, { - "category": "SQL Managed Instance", - "checklist": "SQL Migration Review", - "description": "This provides more dedicated disk IOPS and throughput", - "guid": "aa359272-8e6e-4205-8726-76ae46691e88", - "id": "B06.03", - "link": "https://techcommunity.microsoft.com/t5/azure-sql-blog/storage-performance-best-practices-and-considerations-for-azure/ba-p/305525", + "category": "Cleanup", + "checklist": "Cost Optimization Checklist", + "guid": "6aae01e6-a84d-4e5d-b36d-1d92881a1bd5", + "id": "A08.01", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-enterprise-agreement#design-considerations", "services": [ + "Cost", + "Backup", "Storage", - "SQL" + "VM" ], - "severity": "High", - "subcategory": "Post Migration", - "text": "Optimize Storage Performance for General Purpose Managed Instance", - "training": "https://learn.microsoft.com/learn/paths/architect-infrastructure-operations/", - "waf": "Performance" + "subcategory": "stopped/deallocated VMs: check disks", + "text": "check that the disks are really needed, if not: delete. If they are needed, find lower storage tiers or use backup -", + "training": "https://learn.microsoft.com/azure/cost-management-billing/costs/manage-automation" }, { - "category": "SQL Managed Instance", - "checklist": "SQL Migration Review", - "description": "Many organizations have policies that require that certificates or encryption keys be created and managed internally. If your organization has a similar policy, this architecture might apply to you. If your customers require internal management of these items, the architecture also might apply to you.", - "guid": "35ad9422-23e1-4381-8523-081a94174158", - "id": "B06.04", - "link": "https://learn.microsoft.com/azure/architecture/example-scenario/data/sql-managed-instance-cmk", + "category": "Cleanup", + "checklist": "Cost Optimization Checklist", + "guid": "d1e44a19-659d-4395-afd7-7289b835556d", + "id": "A09.01", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-enterprise-agreement#design-considerations", "services": [ - "Backup", - "AzurePolicy", - "SQL", - "AKV" + "Cost", + "Storage", + "AzurePolicy" ], - "severity": "Low", - "subcategory": "Post Migration", - "text": "Enable Customer managed TDE for taking your own copy only full backups", - "training": "https://learn.microsoft.com/learn/paths/architect-infrastructure-operations/", - "waf": "Security" + "subcategory": "storage accounts lifecycle policy", + "text": "consider moving unused storage to lower tier, with customized rule - https://learn.microsoft.com/azure/storage/blobs/lifecycle-management-policy-configure ", + "training": "https://learn.microsoft.com/azure/cost-management-billing/costs/enable-tag-inheritance" }, { - "category": "SQL Managed Instance", - "checklist": "SQL Migration Review", - "description": "The maintenance window feature provides you with the ability to onboard Azure SQL resource to prescheduled time blocks outside of business hours.", - "guid": "33ef7ad7-c6d3-4733-865c-7acbe44bbe60", - "id": "B06.05", - "link": "https://learn.microsoft.com/azure/azure-sql/database/planned-maintenance?view=azuresql", + "category": "Cleanup", + "checklist": "Cost Optimization Checklist", + "guid": "f2bfe456-3b0d-4834-a348-726de69c6b5c", + "id": "A10.01", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", "services": [ - "SQL" + "Cost" ], - "severity": "Medium", - "subcategory": "Post Migration", - "text": "Plan for Azure maintenance events", - "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", - "waf": "Operations" + "subcategory": "Tagging", + "text": "use specific tags for temporary items with 'delete by DATE' format - and automate monthly cleanup" }, { - "category": "SQL Managed Instance", - "checklist": "SQL Migration Review", - "description": "By using the long-term retention (LTR) feature, you can store specified SQL Database and SQL Managed Instance full backups in Azure Blob storage with configured redundancy for up to 10 years.", - "guid": "9d89f2e8-7778-4424-b516-785c6fa96b96", - "id": "B06.06", - "link": "https://learn.microsoft.com/azure/azure-sql/database/long-term-retention-overview?view=azuresql-mi", + "category": "DB/APP tuning", + "checklist": "Cost Optimization Checklist", + "guid": "2a26494b-69ba-4d37-aad5-3cc78e1d7666", + "id": "B01.01", + "link": "https://learn.microsoft.com/azure/cost-management-billing/manage/mca-section-invoice", "services": [ - "Backup", - "Storage", - "SQL", - "ARS" + "Cost" ], - "severity": "Low", - "subcategory": "Post Migration", - "text": "Configure Long Term backup retention, view backups and restore from backups", - "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-compute-resources/", - "waf": "Reliability" + "subcategory": "db optimization", + "text": "plan for db optimization with the intent of downsizing the related services (and improve performance)" }, { - "category": "SQL Managed Instance", - "checklist": "SQL Migration Review", - "description": "By using Azure Hybrid Benefit, you can achieve cost savings, modernise and maintain a flexible hybrid environment while optimising business applications.", - "guid": "ad88408f-3727-434c-a76b-a28021459014", - "id": "B06.07", - "link": "https://azure.microsoft.com/en-gb/pricing/hybrid-benefit/#overview", + "category": "DB/APP tuning", + "checklist": "Cost Optimization Checklist", + "guid": "7357c449-674b-45ed-a5a8-59c7733be2a1", + "id": "B02.01", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", "services": [ - "SQL", "Cost" ], - "severity": "Low", - "subcategory": "Post Migration", - "text": "Take advantage of Azure Hybrid Benefit and Azure Reservations where applicable.", - "training": "https://learn.microsoft.com/learn/modules/configure-network-watcher/", - "waf": "Cost" + "subcategory": "app modernization", + "text": "modernizing the app towards a microservices architecture will have the effect of letting the app scale according to the single service and not the entire stack" }, { - "category": "SQL Managed Instance", - "checklist": "SQL Migration Review", - "description": "If you don't have threat protection Advanced Threat Protection is part of the Microsoft Defender for SQL offering, which is a unified package for advanced SQL security capabilities.", - "guid": "65d38e53-f9cc-4bd8-9926-6acca274faa1", - "id": "B06.08", - "link": "https://learn.microsoft.com/azure/azure-sql/database/threat-detection-overview?view=azuresql", + "category": "DB/APP tuning", + "checklist": "Cost Optimization Checklist", + "guid": "a27b765a-91be-41f3-a8ef-394c2bd463cb", + "id": "B03.01", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", "services": [ - "Defender", - "SQL" + "Cost", + "Storage", + "VM" ], - "severity": "Medium", - "subcategory": "Post Migration", - "text": "Leverage Microsoft Defender for Cloud to improve the overall security posture", - "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", - "waf": "Security" + "subcategory": "db optimization", + "text": "optimizing the DB queries will increase performance and allow better right-sizing of storage and VMs" }, { - "category": "Security", - "checklist": "Azure Service Bus Review", - "description": "Azure Service Bus Premium provides encryption of data at rest. If you use your own key, the data is still encrypted using the Microsoft-managed key, but in addition the Microsoft-managed key will be encrypted using the customer-managed key. ", - "guid": "87af4a79-1f89-439b-ba47-768e14c11567", - "link": "https://learn.microsoft.com/azure/service-bus-messaging/configure-customer-managed-key", + "category": "DB/APP tuning", + "checklist": "Cost Optimization Checklist", + "guid": "bac75819-59bb-491a-9ed9-0cae2cc84c37", + "id": "B04.01", + "link": "https://learn.microsoft.com/azure/governance/policy/overview", "services": [ - "ServiceBus" + "Cost" ], - "severity": "Low", - "subcategory": "Data Protection", - "text": "Use customer-managed key option in data at rest encryption when required", - "training": "https://learn.microsoft.com/learn/modules/plan-implement-administer-conditional-access/" + "subcategory": "demand shaping", + "text": "using demand shaping on PaaS services will optimize costs and performances" }, { - "category": "Security", - "checklist": "Azure Service Bus Review", - "description": "Communication between a client application and an Azure Service Bus namespace is encrypted using Transport Layer Security (TLS). Azure Service Bus namespaces permit clients to send and receive data with TLS 1.0 and above. To enforce stricter security measures, you can configure your Service Bus namespace to require that clients send and receive data with a newer version of TLS.", - "guid": "5c1ea55b-46a9-448f-b8ae-7d7e4b475b6c", - "link": "https://learn.microsoft.com/azure/service-bus-messaging/transport-layer-security-enforce-minimum-version", + "category": "Process Administration", + "checklist": "Cost Optimization Checklist", + "guid": "b6b780cb-9fe5-4c46-989d-457a927c3874", + "id": "C01.01", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/naming-and-tagging", "services": [ - "ServiceBus" + "Cost", + "Entra" ], - "severity": "Medium", - "subcategory": "Data Protection", - "text": "Enforce a minimum required version of Transport Layer Security (TLS) for requests ", - "training": "https://learn.microsoft.com/learn/modules/secure-aad-users-with-mfa/" + "subcategory": "Advisor", + "text": "Start from the Azure Advisor page suggestions." }, { - "category": "Security", - "checklist": "Azure Service Bus Review", - "description": "When you create a Service Bus namespace, a SAS rule named RootManageSharedAccessKey is automatically created for the namespace. This policy has Manage permissions for the entire namespace. It's recommended that you treat this rule like an administrative root account and don't use it in your application. Using AAD as an authentication provider with RBAC is recommended. ", - "guid": "8bcbf59b-ce65-4de8-a03f-97879468d66a", - "link": "https://learn.microsoft.com/azure/service-bus-messaging/service-bus-sas#shared-access-authorization-policies", + "category": "Process Administration", + "checklist": "Cost Optimization Checklist", + "guid": "d0102cac-6aae-401e-9a84-de5de36d1d92", + "id": "C01.02", + "link": "https://learn.microsoft.com/azure/governance/policy/overview", "services": [ - "RBAC", - "Entra", - "AzurePolicy", - "ServiceBus", - "TrafficManager" + "Cost", + "VM" ], - "severity": "Medium", - "subcategory": "Identity and Access Management", - "text": "Avoid using root account when it is not necessary", - "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-identities-governance/" + "subcategory": "Advisor", + "text": "make sure advisor is configured for VM right sizing " }, { - "category": "Security", - "checklist": "Azure Service Bus Review", - "description": "A Service Bus client app running inside an Azure App Service application or in a virtual machine with enabled managed entities for Azure resources support does not need to handle SAS rules and keys, or any other access tokens. The client app only needs the endpoint address of the Service Bus Messaging namespace. ", - "guid": "786d60f9-6c96-4ad8-a55d-04c2b39c986b", - "link": "https://learn.microsoft.com/azure/service-bus-messaging/service-bus-managed-service-identity", + "category": "Process Administration", + "checklist": "Cost Optimization Checklist", + "guid": "881a1bd5-d1e4-44a1-a659-d3958fd77289", + "id": "C02.01", + "link": "https://learn.microsoft.com/azure/governance/policy/overview", "services": [ - "AKV", - "Entra", - "VM", - "ServiceBus", - "Storage", - "AppSvc" + "Cost" ], - "severity": "Medium", - "subcategory": "Identity and Access Management", - "text": "When possible, your application should be using a managed identity to authenticate to Azure Service Bus. If not, consider having the storage credential (SAS, service principal credential) in Azure Key Vault or an equivalent service", - "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/" + "subcategory": "Automation", + "text": "consider implementing IAC scripts or devops pipelines to match the cost governance process" }, { - "category": "Security", - "checklist": "Azure Service Bus Review", - "description": "When creating permissions, provide fine-grained control over a client's access to Azure Service Bus. Permissions in Azure Service Bus can and should be scoped to the individual resource level e.g. queue, topic or subscription. ", - "guid": "f615658d-e558-4f93-9249-b831112dbd7e", - "link": "https://learn.microsoft.com/azure/service-bus-messaging/authenticate-application#azure-built-in-roles-for-azure-service-bus", + "category": "Process Administration", + "checklist": "Cost Optimization Checklist", + "guid": "b835556d-f2bf-4e45-93b0-d834a348726d", + "id": "C02.02", + "link": "https://learn.microsoft.com/azure/governance/policy/overview", "services": [ - "RBAC", - "Entra", - "ServiceBus", - "Storage", - "Subscriptions" + "Monitor", + "Cost" ], - "severity": "High", - "subcategory": "Identity and Access Management", - "text": "Use least privilege data plane RBAC", - "training": "https://learn.microsoft.com/learn/modules/explore-basic-services-identity-types/" + "subcategory": "Automation", + "text": "set up cost alerts for applications that have variable costs (ideally for all of them)" }, { - "category": "Security", - "checklist": "Azure Service Bus Review", - "description": "Azure Service Bus resource logs include operational logs, virtual network and IP filtering logs. Runtime audit logs capture aggregated diagnostic information for various data plane access operations (such as send or receive messages) in Service Bus.", - "guid": "af12e7f9-43f6-4304-922d-929c2b1cd622", - "link": "https://learn.microsoft.com/azure/service-bus-messaging/monitor-service-bus-reference", + "category": "Process Administration", + "checklist": "Cost Optimization Checklist", + "guid": "e69c6b5c-2a26-4494-a69b-ad37aad53cc7", + "id": "C02.03", + "link": "https://learn.microsoft.com/security/benchmark/azure/mcsb-asset-management#am-2-use-only-approved-services", "services": [ - "VNet", - "Monitor", - "ServiceBus" + "Cost" ], - "severity": "Medium", - "subcategory": "Monitoring", - "text": "Enable logging for security investigation. Use Azure Monitor to trace resource logs and runtime audit logs (currently available only in the premium tier)", - "training": "https://learn.microsoft.com/learn/paths/manage-identity-and-access/" + "subcategory": "Automation", + "text": "Use Azure Automation: Automate repetitive tasks can help you save time and resources, reducing costs in the process. " }, { - "category": "Security", - "checklist": "Azure Service Bus Review", - "description": "Azure Service Bus by default has a public IP address and is Internet-reachable. Private endpoints allow traffic between your virtual network and Azure Service Bus traverses over the Microsoft backbone network. In addition to that, you should disable public endpoints if those are not used. ", - "guid": "9ae669ca-48e4-4a85-b222-3ece8bb12307", - "link": "https://learn.microsoft.com/azure/service-bus-messaging/private-link-service", + "category": "Process Administration", + "checklist": "Cost Optimization Checklist", + "guid": "8e1d7666-7357-4c44-a674-b5ed85a859c7", + "id": "C02.04", + "link": "https://learn.microsoft.com/azure/governance/policy/overview", "services": [ - "VNet", - "PrivateLink", - "ServiceBus" + "Cost" ], - "severity": "Medium", - "subcategory": "Networking", - "text": "Consider using private endpoints to access Azure Service Bus and disable public network access when applicable.", - "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/" + "subcategory": "Automation", + "text": "run orphaned resources workbook" }, { - "category": "Security", - "checklist": "Azure Service Bus Review", - "description": "With IP firewall, you can restrict the public endpoint further to only a set of IPv4 addresses or IPv4 address ranges in CIDR (Classless Inter-Domain Routing) notation. ", - "guid": "ca5f06f1-58e3-4ea3-a92c-2de7e2165c3a", - "link": "https://learn.microsoft.com/azure/service-bus-messaging/service-bus-ip-filtering", + "category": "Process Administration", + "checklist": "Cost Optimization Checklist", + "guid": "733be2a1-a27b-4765-a91b-e1f388ef394c", + "id": "C03.01", + "link": "https://learn.microsoft.com/azure/governance/policy/overview#azure-rbac-permissions-in-azure-policy", "services": [ - "ServiceBus" + "Cost", + "Storage" ], - "severity": "Medium", - "subcategory": "Networking", - "text": "Consider only allowing access to Azure Service Bus namespace from specific IP addresses or ranges", - "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/" + "subcategory": "Baseline", + "text": "try and establish a baseline of monthly spending and an acceptable saving target against the baseline (new services will not be optimized at this stage)" }, { - "category": "Application Deployment", - "checklist": "Azure Spring Apps Review", - "cost": 1, - "guid": "6d8e32a8-3892-479d-a40b-10f6b4f6f298", - "link": "https://learn.microsoft.com/azure/spring-apps/concepts-blue-green-deployment-strategies", - "services": [], - "severity": "Medium", - "subcategory": "DevOps", - "text": "Azure Spring Apps permits two deployments for every app, only one of which receives production traffic. You can achieve zero downtime with blue green deployment strategies. Blue green deployment is only available in Standard and Enterprise tiers. You could automate deployment using CI/CD with ADO/GitHub actions", - "waf": "Reliability" + "category": "Process Administration", + "checklist": "Cost Optimization Checklist", + "guid": "2bd463cb-bac7-4581-a59b-b91a3ed90cae", + "id": "C03.02", + "link": "https://learn.microsoft.com/azure/governance/policy/overview", + "services": [ + "Cost", + "AzurePolicy" + ], + "subcategory": "Baseline", + "text": "establish a cost optimization baseline by using a policy that tags every new resource as #NEW" }, { - "category": "BC and DR", - "checklist": "Azure Spring Apps Review", - "cost": 1, - "guid": "fbcb40ac-9480-4a6d-bcf4-8081252a6716", - "link": "https://learn.microsoft.com/azure/architecture/web-apps/spring-apps/architectures/spring-apps-multi-region", + "category": "Process Administration", + "checklist": "Cost Optimization Checklist", + "guid": "2cc84c37-b6b7-480c-a9fe-5c46489d457a", + "id": "C03.03", + "link": "https://learn.microsoft.com/azure/automation/automation-solution-vm-management-config", "services": [ - "ASR", - "TrafficManager", - "FrontDoor" + "Cost" ], - "severity": "Medium", - "subcategory": "Disaster Recovery", - "text": "Azure Spring Apps instances could be created in multiple regions for your applications and traffic could be routed by Traffic Manager/Front Door.", - "waf": "Reliability" + "subcategory": "Baseline", + "text": "Organize resources to maximize cost insights and accountability" }, { - "category": "BC and DR", - "checklist": "Azure Spring Apps Review", - "cost": 1, - "guid": "ff1ae6a7-9301-4feb-9d11-56cd72f1d4ef", - "link": "https://learn.microsoft.com/azure/reliability/reliability-spring-apps", + "category": "Process Administration", + "checklist": "Cost Optimization Checklist", + "guid": "927c3874-d010-42ca-a6aa-e01e6a84de5d", + "id": "C04.01", + "link": "https://learn.microsoft.com/azure/cost-management-billing/costs/tutorial-acm-create-budgets?bc=%2Fazure%2Fcloud-adoption-framework%2F_bread%2Ftoc.json&toc=%2Fazure%2Fcloud-adoption-framework%2Ftoc.json", "services": [ - "ACR" + "Cost" ], - "severity": "Medium", - "subcategory": "High Availability", - "text": "In supported region, Azure Spring Apps can be deployed as zone redundant, which means that instances are automatically distributed across availability zones. This feature is only available in Standard and Enterprise tiers.", - "waf": "Reliability" + "subcategory": "Budgets", + "text": "Create budgets" }, { - "category": "BC and DR", - "checklist": "Azure Spring Apps Review", - "cost": 1, - "guid": "ffc735ad-fbb1-4802-b43f-ad6387c4c066", - "link": "https://learn.microsoft.com/azure/spring-apps/concept-understand-app-and-deployment", - "services": [], - "severity": "Medium", - "subcategory": "High Availability", - "text": "Use more than 1 app instance for your apps", - "waf": "Reliability" + "category": "Process Administration", + "checklist": "Cost Optimization Checklist", + "guid": "e36d1d92-881a-41bd-9d1e-44a19659d395", + "id": "C05.01", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/identity-access-landing-zones#identity-and-access-management-in-the-azure-landing-zone-accelerator", + "services": [ + "Cost" + ], + "subcategory": "Cost Analysis", + "text": "in cost analysis - use daily granularity, grouped by service name to analyze the spending of the past 3 months and identify the top 3 spenders" }, { - "category": "Operations", - "checklist": "Azure Spring Apps Review", - "cost": 1, - "guid": "7504c230-6035-4183-95a5-85762acc6075", - "link": "https://learn.microsoft.com/azure/spring-apps/diagnostic-services", + "category": "Process Administration", + "checklist": "Cost Optimization Checklist", + "guid": "8fd77289-b835-4556-bf2b-fe4563b0d834", + "id": "C05.02", + "link": "https://learn.microsoft.com/azure/active-directory/hybrid/how-to-connect-sync-staging-server", "services": [ - "Monitor" + "Cost" ], - "severity": "Medium", - "subcategory": "Monitoring", - "text": "Monitor Azure Spring Apps with logs, metrics and tracing. Integrate ASA with application insights and track failures and create workbooks.", - "waf": "Reliability" + "subcategory": "Cost Analysis", + "text": "check daily for cost spikes and anomalies (ideally with automatic billing exports)" }, { - "category": "Operations", - "checklist": "Azure Spring Apps Review", - "cost": 1, - "guid": "1eb48d58-3eec-4ef5-80b0-d2b0dde3f0c6", - "link": "https://learn.microsoft.com/azure/spring-apps/how-to-configure-enterprise-spring-cloud-gateway", - "services": [], - "severity": "Medium", - "subcategory": "Scalability", - "text": "Set up autoscaling in Spring Cloud Gateway", - "waf": "Reliability" + "category": "Process Administration", + "checklist": "Cost Optimization Checklist", + "guid": "a348726d-e69c-46b5-a2a2-6494b69bad37", + "id": "C05.03", + "link": "https://learn.microsoft.com/azure/active-directory/roles/security-emergency-access", + "services": [ + "Cost" + ], + "subcategory": "Cost Analysis", + "text": "automate cost retrieval for deep analysis or integration" }, { - "category": "Operations", - "checklist": "Azure Spring Apps Review", - "cost": 1, - "guid": "97411607-b6fd-4335-99d1-9885faf4e392", - "link": "https://learn.microsoft.com/azure/spring-apps/how-to-setup-autoscale", - "services": [], - "severity": "Low", - "subcategory": "Scalability", - "text": "Enable autoscale for the apps with Standard consumption & dedicated plan.", - "waf": "Reliability" + "category": "Process Administration", + "checklist": "Cost Optimization Checklist", + "guid": "aad53cc7-8e1d-4766-9735-7c449674b5ed", + "id": "C06.01", + "link": "https://learn.microsoft.com/azure/active-directory/reports-monitoring/concept-activity-logs-azure-monitor", + "services": [ + "ACR", + "Cost" + ], + "subcategory": "free services", + "text": "Take advantage of Azure free services: Azure offers a number of free services, such as DevOps, Azure Container Registry, and Azure Logic Apps, that can help you save costs on development and operations. " }, { - "category": "Operations", - "checklist": "Azure Spring Apps Review", - "cost": 1, - "guid": "dfcaffd1-d27c-4ef2-998d-64c1df3a7ac3", - "link": "https://learn.microsoft.com/azure/spring-apps/overview", - "services": [], - "severity": "Medium", - "subcategory": "Support", - "text": "Use Enterprise plan for commercial support of spring boot for mission critical apps. With other tiers you get OSS support.", - "waf": "Reliability" + "category": "Process Administration", + "checklist": "Cost Optimization Checklist", + "guid": "96c96ad8-844c-4f3b-8b38-c886ba2c0214", + "id": "C07.01", + "link": "https://learn.microsoft.com/azure/role-based-access-control/overview", + "services": [ + "Cost" + ], + "subcategory": "Tagging", + "text": "Tag shared resources" }, { - "category": "Compute", - "checklist": "Resiliency Review", - "description": "Automatic instance repairs ensure that unhealthy instances are promptly identified and replaced, maintaining a set of healthy instances within your scale set.", - "guid": "7e13c105-675c-41e9-95b4-59837ff7ae7c", - "link": "https://learn.microsoft.com/azure/virtual-machine-scale-sets/virtual-machine-scale-sets-automatic-instance-repairs", + "category": "Process Administration", + "checklist": "Cost Optimization Checklist", + "guid": "99014a5d-3ce5-474d-acbd-9792a6bcca2b", + "id": "C07.02", + "link": "https://learn.microsoft.com/azure/active-directory/conditional-access/overview", "services": [ - "VM" + "Cost" ], - "severity": "Low", - "subcategory": "VM Scale Sets", - "text": "Enable automatic instance repairs for enhanced VM Scale Sets resiliency", - "waf": "Reliability" + "subcategory": "Tagging", + "text": "consider using tags to all services for cost allocation" }, { - "category": "Compute", - "checklist": "Resiliency Review", - "description": "Ensure that Azure Backup is utilized appropriately to meet your organization's resiliency requirements for Azure virtual machines (VMs).", - "guid": "4d874a74-8b66-42d6-b150-512a66498f6d", - "link": "https://learn.microsoft.com/azure/backup/backup-azure-vms-introduction", + "category": "reservations", + "checklist": "Cost Optimization Checklist", + "guid": "4fea1dbf-3dd9-45d4-ac7c-891dcb1f7d57", + "id": "D01.01", + "link": "https://learn.microsoft.com/azure/active-directory/authentication/concept-mfa-howitworks", "services": [ - "Backup", - "VM" + "Cost" ], - "severity": "High", - "subcategory": "Virtual Machines", - "text": "Consider Azure Backup to meet your resiliency requirements for Azure VMs", - "waf": "Reliability" + "subcategory": "automation", + "text": "consider Reservation automation to track and promptly react to changes" }, { - "category": "Compute", - "checklist": "Resiliency Review", - "description": "Single Instance VMs using Premium SSD or Ultra Disk for all Operating System Disks and Data Disks are guaranteed to have Virtual Machine Connectivity of at least 99.9%", - "guid": "8052d88e-79d1-47b7-9b22-a5a67e7a8ed4", - "link": "https://learn.microsoft.com/azure/virtual-machines/disks-types", + "category": "reservations", + "checklist": "Cost Optimization Checklist", + "description": "check by searching the Meter Category Licenses in the Cost analysys", + "guid": "59ae568b-a38d-4498-9e22-13dbd7bb012f", + "id": "D02.01", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/manage/centralize-operations", "services": [ - "VM" + "Cost", + "AzurePolicy", + "VM", + "SQL" ], - "severity": "High", - "subcategory": "Virtual Machines", - "text": "Use Premium or Ultra disks for production VMs", - "waf": "Reliability" + "subcategory": "check AHUB is applied to all Windows VMs, RHEL and SQL", + "text": "run the script on all windows VMs https://learn.microsoft.com/azure/virtual-machines/windows/hybrid-use-benefit-licensing?ref=andrewmatveychuk.com#convert-an-existing-vm-using-azure-hybrid-benefit-for-windows-server- consider implementing a policy if windows VMs are created frequently" }, { - "category": "Compute", - "checklist": "Resiliency Review", - "description": "Azure automatically replicates managed disks within a region to ensure data durability and protect against single-point failures.", - "guid": "b31e38c3-f298-412b-8363-cffe179b599d", - "link": "https://learn.microsoft.com/azure/virtual-machines/managed-disks-overview", + "category": "reservations", + "checklist": "Cost Optimization Checklist", + "guid": "7b95e06e-158e-42ea-9992-c2de6e2065b3", + "id": "D03.01", + "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-configure", "services": [ - "VM" + "Cost", + "LoadBalancer" ], - "severity": "High", - "subcategory": "Virtual Machines", - "text": "Ensure Managed Disks are used for all VMs", - "waf": "Reliability" + "subcategory": "check Red Hat Licences if applicable", + "text": " this can be also put under AHUB if you already have licenses https://learn.microsoft.com/azure/virtual-machines/linux/azure-hybrid-benefit-linux?tabs=rhelpayg%2Crhelbyos%2CrhelEnablebyos%2Crhelcompliance" }, { - "category": "Compute", - "checklist": "Resiliency Review", - "description": "Temporary disks are intended for short-term storage of non-persistent data such as page files, swap files, or SQL Server tempdb. Storing persistent data on temporary disks can lead to data loss during maintenance events or VM redeployment.", - "guid": "e0d5973c-d4ce-432c-8881-37f6f7c4c0d4", - "link": "https://learn.microsoft.com/azure/virtual-machines/managed-disks-overview#temporary-disk", + "category": "reservations", + "checklist": "Cost Optimization Checklist", + "guid": "a76af4a6-91e8-4839-ada4-6667e13c1056", + "id": "D04.01", + "link": "https://learn.microsoft.com/azure/active-directory/roles/security-planning#identify-microsoft-accounts-in-administrative-roles-that-need-to-be-switched-to-work-or-school-accounts", "services": [ - "VM", - "Storage", - "SQL" + "Cost", + "AppSvc" ], - "severity": "Medium", - "subcategory": "Virtual Machines", - "text": "Do not use the Temp disk for anything that is not acceptable to be lost", - "waf": "Reliability" + "subcategory": "Functions", + "text": "saving plans will provide 17% on select app service plans" }, { - "category": "Compute", - "checklist": "Resiliency Review", - "description": "Co-locate your compute, storage, networking, and data resources across an availability zone, and replicate this arrangement in other availability zones.", - "guid": "e514548d-2447-4ec6-9138-b8200f1ce16e", - "link": "https://learn.microsoft.com/azure/reliability/availability-zones-overview", + "category": "reservations", + "checklist": "Cost Optimization Checklist", + "guid": "75c1e945-b459-4837-bf7a-e7c6d3b475a5", + "id": "D05.01", + "link": "https://learn.microsoft.com/azure/active-directory/fundamentals/active-directory-groups-create-azure-portal", "services": [ - "ACR", - "VM", - "Storage" + "Cost", + "VM" ], - "severity": "Medium", - "subcategory": "Virtual Machines", - "text": "Leverage Availability Zones for your VMs in regions where they are supported", - "waf": "Reliability" + "subcategory": "planning", + "text": "consolidate reserved VM families with flexibility option (no more than 4-5 families)", + "training": "https://learn.microsoft.com/azure/automation/automation-solution-vm-management" }, { - "category": "Compute", - "checklist": "Resiliency Review", - "description": "Use at least two VMs in Availability Sets to isolate VMs on different fault and update domains.", - "guid": "5a785d6f-e96c-496a-b884-4cf3b2b38c88", - "link": "https://learn.microsoft.com/azure/virtual-machines/availability-set-overview", + "category": "reservations", + "checklist": "Cost Optimization Checklist", + "guid": "c7acbe49-bbe6-44dd-a9f2-e87778468d55", + "id": "D06.01", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/identity-access#prerequisites-for-a-landing-zone---design-recommendations", "services": [ + "Cost", + "ARS", "VM" ], - "severity": "Medium", - "subcategory": "Virtual Machines", - "text": "For regions that do not support Availability Zones deploy VMs into Availability Sets", - "waf": "Reliability" + "subcategory": "reservations/savings plans", + "text": "Utilize Azure Reserved Instances: This feature allows you to reserve VMs for a period of 1 or 3 years, providing significant cost savings compared to PAYG prices." }, { - "category": "Compute", - "checklist": "Resiliency Review", - "description": "Azure provides multiple options for VM redundancy to meet different requirements (Availability Zones, Virtual Machine Scale Sets, Availability Sets, Azure Site Recovery)", - "guid": "6ba2c021-4991-414a-9d3c-e574dccbd979", - "link": "https://learn.microsoft.com/azure/virtual-machines/availability", + "category": "reservations", + "checklist": "Cost Optimization Checklist", + "guid": "a785c6fe-96c9-46ad-a844-cf3b2b38c886", + "id": "D06.02", + "link": "https://azure.microsoft.com/resources/achieving-compliant-data-residency-and-security-with-azure/", "services": [ - "ASR", - "VM" + "Cost" ], - "severity": "High", - "subcategory": "Virtual Machines", - "text": "Avoid running a production workload on a single VM", - "waf": "Reliability" + "subcategory": "reservations/savings plans", + "text": "plan for Azure Savings Plans for all the workloads that are dynamic and need maximum flexibility" }, { - "category": "Compute", - "checklist": "Resiliency Review", - "description": "Azure Site Recovery enables you to achieve low RTO (Recovery Time Objective) for your Azure and hybrid VMs by providing continuous replication and failover capabilities.", - "guid": "2a6bcca2-b5fe-4a1e-af3d-d95d48c7c891", - "link": "https://learn.microsoft.com/azure/site-recovery/site-recovery-overview", + "category": "reservations", + "checklist": "Cost Optimization Checklist", + "guid": "ba2c0214-9901-44a5-b3ce-574dccbd9792", + "id": "D06.03", + "link": "https://learn.microsoft.com/azure/active-directory-domain-services/overview", "services": [ - "AVS", - "VM", - "ASR" + "Cost" ], - "severity": "High", - "subcategory": "Virtual Machines", - "text": "For Azure and on-premises VMs (Hyper-V/Phyiscal/VMware) with low RTO requirements use Azure Site Recovery", - "waf": "Reliability" + "subcategory": "reservations/savings plans", + "text": "plan for Azure Reservations for all the workloads that are less dynamic and won't change much" }, { - "category": "Compute", - "checklist": "Resiliency Review", - "description": "By using Capacity Reservations, you can effectively manage capacity for critical workloads, ensuring resource availability in specified regions.", - "guid": "bd7bb012-f7b9-45e0-9e15-8e3ea3992c2d", - "link": "https://learn.microsoft.com/azure/virtual-machines/capacity-reservation-overview", + "category": "reservations", + "checklist": "Cost Optimization Checklist", + "guid": "a6bcca2b-4fea-41db-b3dd-95d48c7c891d", + "id": "D07.01", + "link": "https://learn.microsoft.com/azure/active-directory-domain-services/overview", "services": [ - "VM" + "Cost", + "Storage" ], - "severity": "Low", - "subcategory": "Virtual Machines", - "text": "Use Capacity Reservations for critical workloads that require guaranteed capacity", - "waf": "Reliability" + "subcategory": "reserve storage", + "text": "only larger disks can be reserved =>1TiB -" }, { - "category": "Compute", - "checklist": "Resiliency Review", - "description": "By ensuring that the necessary quotas are increased in your DR region before testing failover with ASR, you can avoid any potential resource constraints during the recovery process for failed over VMs.", - "guid": "e6e2065b-3a76-4af4-a691-e8939ada4666", - "link": "https://learn.microsoft.com/azure/quotas/per-vm-quota-requests", + "category": "reservations", + "checklist": "Cost Optimization Checklist", + "guid": "cb1f7d57-59ae-4568-aa38-d4985e2213db", + "id": "D08.01", + "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/identity/adds-extend-domain", "services": [ - "ASR", + "Cost", "VM" ], - "severity": "Medium", - "subcategory": "Virtual Machines", - "text": "Increase quotas in DR region before testing failover with ASR", - "waf": "Reliability" + "subcategory": "reserve VMs with normalized and rationalized sizes", + "text": "after the right-sizing optimization" }, { - "category": "Compute", - "checklist": "Resiliency Review", - "description": "Scheduled Events is an Azure Metadata Service that provides information about upcoming maintenance events for virtual machines (VMs). By leveraging Scheduled Events, you can proactively prepare your applications for VM maintenance, minimizing disruption and improving the availability of your VMs.", - "guid": "6d3b475a-5c7a-4cbe-99bb-e64dd8902e87", - "link": "https://learn.microsoft.com/azure/virtual-machines/windows/scheduled-events", + "category": "reservations", + "checklist": "Cost Optimization Checklist", + "guid": "d7bb012f-7b95-4e06-b158-e2ea3992c2de", + "id": "D09.01", + "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy", "services": [ - "VM" + "Cost", + "AzurePolicy", + "SQL" ], - "severity": "Low", - "subcategory": "Virtual Machines", - "text": "Utilize Scheduled Events to prepare for VM maintenance", - "waf": "Reliability" + "subcategory": "SQL Database AHUB", + "text": "check if applicable and enforce policy/change https://learn.microsoft.com/azure/azure-sql/azure-hybrid-benefit?view=azuresql&tabs=azure-portalhttps://learn.microsoft.com/azure/cost-management-billing/scope-level/create-sql-license-assignments?source=recommendations" }, { - "category": "Data", - "checklist": "Resiliency Review", - "description": "Use Zone-redundant Storage (ZRS) in the primary region for scenarios that require high availability and for restricting replication to a particular country or region. For protection against regional disasters, use Geo-zone-redundant Storage (GZRS), which combines ZRS in the primary region with geo-replication to a secondary region?.", - "guid": "48c7c891-dcb1-4f7d-9769-ae568ba38d4a", - "link": "https://learn.microsoft.com/azure/storage/common/storage-redundancy", + "category": "reservations", + "checklist": "Cost Optimization Checklist", + "guid": "6e2065b3-a76a-4f4a-991e-8839ada46667", + "id": "D10.01", + "link": "https://learn.microsoft.com/azure/active-directory/roles/best-practices", "services": [ - "Storage" + "Cost", + "VM", + "SQL" ], - "severity": "Medium", - "subcategory": "Storage Accounts", - "text": "Choose the most appropriate data redundancy option for Azure Storage based on your requirements", - "waf": "Reliability" + "subcategory": "SQL Database Reservations", + "text": "the VM + licence part discount (ahub+3YRI) is around 70% discount" }, { - "category": "Data", - "checklist": "Resiliency Review", - "description": "Assigning a Delete lock to your storage account helps protect the availability of your data, minimizing the risk of disruptions to your business operations.", - "guid": "85e2213d-bd7b-4b01-8f7b-95e06e158e3e", - "link": "https://learn.microsoft.com/azure/storage/common/lock-account-resource", + "category": "reservations", + "checklist": "Cost Optimization Checklist", + "guid": "e13c1056-75c1-4e94-9b45-9837ff7ae7c6", + "id": "D11.01", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/identity-access-landing-zones#managed-identities", "services": [ - "Storage" + "Cost" ], - "severity": "Low", - "subcategory": "Storage Accounts", - "text": "Apply a Delete lock to prevent accidental or malicious deletion of storage accounts", - "waf": "Reliability" + "subcategory": "tracking", + "text": "Make sure you Azure Reservations and Savings plans are close to 100% utilization or make the necessary changes to reach it." }, { - "category": "Data", - "checklist": "Resiliency Review", - "description": "Container soft delete protects your data from being accidentally deleted by maintaining the deleted data in the system for a specified period of time.", - "guid": "a3992c2d-e6e2-4065-a3a7-6af4a691e893", - "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-container-enable", + "category": "reservations", + "checklist": "Cost Optimization Checklist", + "guid": "d3b475a5-c7ac-4be4-abbe-64dd89f2e877", + "id": "D11.02", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/identity-access-landing-zones#rbac-recommendations", "services": [ - "Storage" + "Cost", + "AzurePolicy" ], - "severity": "Low", - "subcategory": "Storage Accounts", - "text": "Enable soft delete for Storage Account Containers", - "waf": "Reliability" + "subcategory": "tracking", + "text": "make sure that your reservations usage is close to 100%. If not, either enforce an allowed SKU policy or exchange the reservation" }, { - "category": "Data", - "checklist": "Resiliency Review", - "description": "Blob soft delete protects an individual blob and its versions, snapshots, and metadata from accidental deletes or overwrites by maintaining the deleted data in the system for a specified period of time.", - "guid": "9ada4666-7e13-4c10-96b9-153d89f89dc7", - "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-blob-enable", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "78468d55-a785-4c6f-b96c-96ad8844cf3b", + "id": "E01.01", + "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-create-roles-and-resource-roles-review", "services": [ - "Storage" + "Cost", + "AzurePolicy" ], - "severity": "Low", - "subcategory": "Storage Accounts", - "text": "Enable soft delete for blobs", - "waf": "Reliability" + "subcategory": "Automation", + "text": "plan and enforce a ON/OFF policy for production services, where possible" }, { - "category": "General", - "checklist": "Resiliency Review", - "description": "Azure Backup enhanced soft delete provides critical protection against ransomware attacks by retaining deleted backups, enabling recovery from potential ransomware encryption or deletion.", - "guid": "b44be3b1-a27f-48b9-b91b-e1038df03a82", - "link": "https://learn.microsoft.com/azure/backup/backup-azure-enhanced-soft-delete-about", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "2b38c886-ba2c-4021-9990-14a5d3ce574d", + "id": "E01.02", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#add-diagnostic-settings-to-save-your-wafs-logs", "services": [ - "Backup" + "Cost", + "AzurePolicy" ], - "severity": "Medium", - "subcategory": "Backup", - "text": "Enable Azure Backup enhanced soft delete for improved data protection and recovery", - "waf": "Reliability" + "subcategory": "Automation", + "text": "plan and enforce a ON-DEMAND policy with auto-shutdown for non-production services, where possible" }, { - "category": "General", - "checklist": "Resiliency Review", - "description": "Azure Backup's multi-user authorization enables fine-grained control over user access to backup resources, allowing you to restrict privileges and ensure proper authentication and authorization for backup operations.", - "guid": "2cd463cb-bbc8-4ac2-a9eb-c92a43da1dae", - "link": "https://learn.microsoft.com/azure/backup/multi-user-authorization-concept", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "ccbd9792-a6bc-4ca2-a4fe-a1dbf3dd95d4", + "id": "E02.01", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#send-logs-to-microsoft-sentinel", "services": [ - "Backup" + "Cost", + "VM" ], - "severity": "Low", - "subcategory": "Backup", - "text": "Implement multi-user authorization for Azure Backup to ensure secure and controlled access to backup resources", - "waf": "Reliability" + "subcategory": "Autoscale", + "text": "consider using a VMSS to match demand rather than flat sizing" }, { - "category": "General", - "checklist": "Resiliency Review", - "description": "Azure Immutable Storage provides an additional layer of security by ensuring that backup data stored in the vault cannot be modified or deleted for a specified retention period. This helps safeguard your backups from ransomware attacks that may attempt to compromise or manipulate your backup data.", - "guid": "2cc88147-0607-4c1c-aa0e-614658dd458e", - "link": "https://learn.microsoft.com/azure/backup/backup-azure-immutable-vault-concept?source=recommendations&tabs=recovery-services-vault", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "c1b1cd52-1e54-4a29-a9de-39ac0e7c28dc", + "id": "E02.02", + "link": "https://learn.microsoft.com/azure/reliability/cross-region-replication-azure", "services": [ - "Backup", - "Storage" + "Cost", + "AKS" ], - "severity": "Low", - "subcategory": "Backup", - "text": "Implement Immutable Storage for your vaults to protect against ransomware and prevent unauthorized modifications to backups", - "waf": "Reliability" + "subcategory": "Autoscale", + "text": "use AKS autoscaler to match your clusters usage (make sure the pods requirements match the scaler)" }, { - "category": "General", - "checklist": "Resiliency Review", - "description": "Clearly define your organization's business continuity and disaster recovery requirements for your Azure environment. This includes identifying the critical applications, data, and services that need to be protected, as well as specifying the desired recovery objectives and strategies.", - "guid": "72e52e36-11dd-458c-9a4b-1521e43a58a9", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/management-business-continuity-disaster-recovery", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "93665720-2bff-4456-9b0d-934a359c363e", + "id": "E02.03", + "link": "https://learn.microsoft.com/azure/storage/common/storage-redundancy", "services": [ - "ASR" + "Cost" ], - "severity": "High", - "subcategory": "Design", - "text": "Define business continuity and disaster recovery requirements", - "waf": "Reliability" - }, - { - "category": "General", - "checklist": "Resiliency Review", - "description": "Ensure that your Azure architectures are designed with a focus on reliability. Consider implementing fault-tolerant mechanisms, redundancy, and resiliency patterns to minimize the impact of failures and maximize the availability of your applications and services.", - "guid": "c2399c4d-7b67-4d0c-9555-62f2b3e4563a", - "link": "https://learn.microsoft.com/azure/architecture/reliability/architect", - "services": [], - "severity": "High", - "subcategory": "Design", - "text": "Implement reliability best practices in Azure architectures", - "waf": "Reliability" + "subcategory": "Autoscale", + "text": "right-size PaaS service according to average use and accomodate spikes with auto or manual scaling" }, { - "category": "General", - "checklist": "Resiliency Review", - "description": "IaC configurations can play a role in your disaster recovery plan, particularly in situations where recovery time is not time-sensitive. In the event of infrastructure recreation in a second region, IaC can be used to reproduce the necessary infrastructure.", - "guid": "fe237de2-43b1-46c3-8d7a-a9b7570449aa", - "link": "https://learn.microsoft.com/azure/well-architected/devops/automation-infrastructure", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "7dd61623-a364-4a90-9eba-e38ead53cc7d", + "id": "E02.04", + "link": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", "services": [ - "ASR", - "RBAC" + "Cost" ], - "severity": "Medium", - "subcategory": "DevOps", - "text": "Implement Infrastructure as Code (IaC) for Rapid Infrastructure Recovery", - "waf": "Reliability" + "subcategory": "Autoscale", + "text": "plan for demand shaping where applicable" }, { - "category": "General", - "checklist": "Resiliency Review", - "description": "Azure offers region pairs that are geographically separated and can be used for cross-region replication and disaster recovery. These region pairs provide redundancy and protection against regional or large-scale disasters.", - "guid": "dcb1f7d5-769a-4e56-aba3-8d4a85e2213d", - "link": "https://learn.microsoft.com/azure/reliability/cross-region-replication-azure", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "e2e8aaab-3571-4549-ab91-53d89f89dc7b", + "id": "E02.05", "services": [ - "ASR" + "Cost" ], - "severity": "Medium", - "subcategory": "Multi-region", - "text": "Plan for cross-region recovery by leveraging region pairs", - "waf": "Reliability" + "subcategory": "Autoscale", + "text": "consider implementing a service re-scaling logic within the application", + "training": "https://learn.microsoft.com/azure/cost-management-billing/savings-plan/" }, { - "category": "Network", - "checklist": "Resiliency Review", - "description": "By deploying an Application Gateway with a minimum instance count of two, you will have at least two instances available under normal circumstances. In the event that one of the instances encounters a problem, the other instance will handle the traffic while a new instance is being created. This approach significantly reduces the risk of service disruption and ensures a seamless experience for your users.", - "guid": "93c76286-37a5-451c-9b04-e4f1854387e5", - "link": "https://learn.microsoft.com/azure/application-gateway/application-gateway-autoscaling-zone-redundant#autoscaling-and-high-availability", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "44be3b1a-27f8-4b9e-a1be-1f38df03a822", + "id": "E03.01", + "link": "https://learn.microsoft.com/azure/azure-monitor/logs/data-retention-archive?tabs=portal-1%2Cportal-2#how-retention-and-archiving-work", "services": [ - "AppGW" + "Cost", + "Backup" ], - "severity": "Medium", - "subcategory": "Application Gateways", - "text": "Deploy Application Gateways with a minimum instance count of 2 to avoid instance provisioning downtime", - "waf": "Reliability" + "subcategory": "Backup", + "text": "Move recovery points to vault-archive where applicable (Validate)", + "training": "https://azure.microsoft.com/pricing/reservations/" }, { - "category": "Network", - "checklist": "Resiliency Review", - "description": "The v2 SKU offers several advantages and critical new features that enhance the availability and resilience of your application infrastructure. One notable feature supported by the v2 SKU is zone redundancy, which allows an Application Gateway deployment to span multiple Availability Zones.", - "guid": "ced126cd-032a-4f5b-8fc6-998a535e3378", - "link": "https://learn.microsoft.com/azure/application-gateway/overview-v2", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "cd463cbb-bc8a-4c29-aebc-91a43da1dae2", + "id": "E04.01", + "link": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", "services": [ - "Storage", - "AppGW" + "Cost", + "LoadBalancer", + "VM" ], - "severity": "High", - "subcategory": "Application Gateways", - "text": "Deploy Azure Application Gateway v2 for zone redundancy support", - "waf": "Reliability" + "subcategory": "databricks", + "text": "consider using Spot VMs with fallback where possibleconsider autotermination of clusters https://learn.microsoft.com/azure/databricks/clusters/cluster-config-best-practices#automatic-termination ", + "training": "https://andrewmatveychuk.com/how-to-audit-azure-hybrid-benefit-usage-with-azure-workbooks/" }, { - "category": "Network", - "checklist": "Resiliency Review", - "description": "Azure Front Door provides automatic failover capabilities, ensuring continuity in the event of a primary region becoming unavailable. However, during the failover process, there may be a brief period (typically 20-60 seconds) when clients cannot reach the application. It is essential to review the Azure Front Door service level agreement (SLA) to determine whether relying solely on Front Door meets your business requirements for high availability. ", - "guid": "97e31c67-d68c-4f6a-92a1-194956d697dc", - "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/app-service-web-app/multi-region#azure-front-door", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "cc881470-607c-41cc-a0e6-14658dd458e9", + "id": "E05.01", + "link": "https://learn.microsoft.com/azure/governance/policy/how-to/guest-configuration-create", "services": [ - "FrontDoor" + "Cost" ], - "severity": "Low", - "subcategory": "Azure Front Door", - "text": "Consider a redundant traffic management solution in conjunction with Azure Front Door", - "waf": "Reliability" + "subcategory": "Functions", + "text": "Functions - Reuse connections", + "training": "https://learn.microsoft.com/azure/cost-management-billing/reservations/reservation-apis?toc=%2Fazure%2Fcost-management-billing%2Ftoc.json" }, { - "category": "Network", - "checklist": "Resiliency Review", - "description": "By implementing Traffic Manager, you can configure it to continuously monitor the health of your application endpoints and automatically redirect traffic to an alternate endpoint when necessary. This automation minimizes downtime and provides a more seamless experience for your users during disaster recovery scenarios.", - "guid": "8df03a82-2cd4-463c-abbc-8ac299ebc92a", - "link": "https://learn.microsoft.com/azure/networking/disaster-recovery-dns-traffic-manager", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "27139b82-1102-4dbd-9eaf-11e6f843e52f", + "id": "E05.02", + "link": "https://learn.microsoft.com/azure/automation/update-management/overview", "services": [ - "ASR", - "DNS", - "Monitor", - "TrafficManager" + "Cost" ], - "severity": "Low", - "subcategory": "DNS", - "text": "Plan for automated failover using Traffic Manager for DNS Traffic", - "waf": "Reliability" + "subcategory": "Functions", + "text": "functions -Cache data locally", + "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-compute-resources/" }, { - "category": "Network", - "checklist": "Resiliency Review", - "description": "To eliminate a single point of failure in your on-premises DNS services and ensure reliable DNS resolution during business continuity and disaster recovery scenarios, it is recommended to utilize Azure DNS Private Resolvers in multiple regions. By deploying two or more Azure DNS private resolvers across different regions, you can enable DNS failover and achieve resiliency in your DNS infrastructure.", - "guid": "43da1dae-2cc8-4814-9060-7c1cca0e6146", - "link": "https://learn.microsoft.com/azure/dns/tutorial-dns-private-resolver-failover", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "4722d928-c1b1-4cd5-81e5-4a29b9de39ac", + "id": "E05.03", + "link": "https://learn.microsoft.com/azure/network-watcher/network-watcher-monitoring-overview", "services": [ - "ACR", - "DNS", - "ASR" + "Cost", + "Storage" ], - "severity": "Low", - "subcategory": "DNS", - "text": "Implement DNS Failover using Azure DNS Private Resolvers", - "waf": "Reliability" + "subcategory": "Functions", + "text": "functions - Cold starts-Use the 'Run from package' functionality. This way, the code is downloaded as a single zip file. This can, for example, result in significant improvements with Javascript functions, which have a lot of node modules.Use language specific tools to reduce the package size, for example, tree shaking Javascript applications.", + "training": "https://learn.microsoft.com/learn/modules/configure-network-watcher/" }, { - "category": "Network", - "checklist": "Resiliency Review", - "description": "Use an on-premises data gateway cluster to avoid single points of failure and to load balance traffic across gateways.", - "guid": "89f89dc7-b44b-4e3b-8a27-f8b9e91be103", - "link": "https://learn.microsoft.com/data-integration/gateway/service-gateway-high-availability-clusters", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "0e7c28dc-9366-4572-82bf-f4564b0d934a", + "id": "E05.04", + "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/lock-resources?tabs=json", "services": [ - "ACR" + "Cost" ], - "severity": "Medium", - "subcategory": "Data Gateways", - "text": "Use on-premises data gateway clusters to ensure high availability for business-critical data", - "waf": "Reliability" + "subcategory": "Functions", + "text": "Functions -Keep your functions warm", + "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/" }, { - "category": "Network", - "checklist": "Resiliency Review", - "description": "When using ExpressRoute, it's important to design for high availability by incorporating redundancy in both the partner and customer networks. This can include multiple ExpressRoute circuits, redundant connections from your network to Microsoft, and ensuring your on-premises network equipment has redundant connections.", - "guid": "c0e7c28d-c936-4657-802b-ff4564b0d934", - "link": "https://learn.microsoft.com/azure/expressroute/designing-for-high-availability-with-expressroute", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "359c363e-7dd6-4162-9a36-4a907ebae38e", + "id": "E05.05", + "link": "https://learn.microsoft.com/azure/governance/policy/overview", "services": [ - "ExpressRoute" + "Cost" ], - "severity": "Medium", - "subcategory": "ExpressRoute", - "text": "Ensure redundancy within both the partner network and customer network when utilizing ExpressRoute for high availability", - "waf": "Reliability" + "subcategory": "Functions", + "text": "when using autoscale with different functions, there might be one driving all the autoscale for all the resources - consider moving it to a separate consumption plan (and consider higher plan for CPU)" }, { - "category": "Network", - "checklist": "Resiliency Review", - "description": "The primary circuit should handle regular traffic while the backup circuit stays ready to take over if the primary circuit fails. Utilize BGP attributes to influence routing and designate your primary and backup circuits effectively.", - "guid": "a359c373-e7dd-4616-83a3-64a907ebae48", - "link": "https://learn.microsoft.com/azure/expressroute/designing-for-disaster-recovery-with-expressroute-privatepeering", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "ad53cc7d-e2e8-4aaa-a357-1549ab9153d8", + "id": "E05.06", + "link": "https://learn.microsoft.com/azure/service-health/alerts-activity-log-service-notifications-portal", "services": [ - "Backup", - "ExpressRoute" + "Cost" ], - "severity": "Medium", - "subcategory": "ExpressRoute", - "text": "When using multiple ExpressRoute circuits ensure that routing allows for a primary and backup", - "waf": "Reliability" + "subcategory": "Functions", + "text": "Function apps in a given plan are all scaled together, so any issues with scaling can affect all apps in the plan." }, { - "category": "Network", - "checklist": "Resiliency Review", - "description": "S2S VPN connection can provide a cost-effective, resilient backup solution in the event of an ExpressRoute circuit failure. By using S2S VPN as a failover, you can maintain connectivity to your Azure resources without relying solely on ExpressRoute.", - "guid": "ead53cc7-de2e-48aa-ab35-71549ab9153d", - "link": "https://learn.microsoft.com/azure/expressroute/use-s2s-vpn-as-backup-for-expressroute-privatepeering", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "9f89dc7b-44be-43b1-a27f-8b9e91be1f38", + "id": "E05.07", + "link": "https://learn.microsoft.com/azure/azure-monitor/alerts/action-groups", "services": [ - "Backup", - "ExpressRoute", - "VPN", "Cost" ], - "severity": "Low", - "subcategory": "ExpressRoute", - "text": "Consider deploying site-to-site VPN as a backup for your ExpressRoute private peering", - "waf": "Reliability" + "subcategory": "Functions", + "text": "Am I billed for 'await time' ?This question is typically asked in the context of a C# function that does an async operation and waits for the result, e.g. await Task.Delay(1000) or await client.GetAsync('http://google.com'). The answer is yes - the GB second calculation is based on the start and end time of the function and the memory usage over that period. What actually happens over that time in terms of CPU activity is not factored into the calculation.One exception to this rule is if you are using durable functions. You are not billed for time spent at awaits in orchestrator functions.apply demand shaping techinques where possible (dev environments?) https://github.com/Azure-Samples/functions-csharp-premium-scaler" }, { - "category": "Network", - "checklist": "Resiliency Review", - "description": "Standard Load Balancer SKU offers an SLA of 99.99% and a higher level of service availability compared to the Basic Load Balancer SKU.", - "guid": "778468d5-5a78-45d6-be96-c96ad8844cf3", - "link": "https://learn.microsoft.com/azure/load-balancer/skus", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "df03a822-cd46-43cb-abc8-ac299ebc91a4", + "id": "E06.01", + "link": "https://learn.microsoft.com/azure/sentinel/quickstart-onboard", "services": [ - "LoadBalancer" + "Cost" ], - "severity": "Medium", - "subcategory": "Load Balancers", - "text": "Leverage the Standard SKU for Load Balancers that handle traffic to production applications", - "waf": "Reliability" + "subcategory": "Networking", + "text": "evaluate your network topology against networking costs and where applicable reduce the egress and peering data" }, { - "category": "Network", - "checklist": "Resiliency Review", - "description": "By configuring the load balancer with a zone-redundant frontend, it can serve zonal resources in any zone with a single IP address. As long as at least one zone remains healthy within the region, the IP address associated with the frontend can survive one or more zone failures. It is recommended to have multiple zonal resources, such as virtual machines from different zones, in the backend pool of the load balancer. ", - "guid": "b2b38c88-6ba2-4c02-8499-114a5d3ce574", - "link": "https://learn.microsoft.com/azure/load-balancer/load-balancer-standard-availability-zones", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "3da1dae2-cc88-4147-8607-c1cca0e61465", + "id": "E06.02", + "link": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", "services": [ - "VM", - "LoadBalancer" + "Cost", + "FrontDoor", + "EventHubs" ], - "severity": "Low", - "subcategory": "Load Balancers", - "text": "For load balancers, consider using a zone-redundant frontend with multiple zonal resources in the backend", - "waf": "Reliability" + "subcategory": "Networking", + "text": "Frontdoor - Turn off the default homepageIn the application settings of your App, set AzureWebJobsDisableHomepage to true. This will return a 204 (No Content) to the PoP so only header data is returned." }, { - "category": "Network", - "checklist": "Resiliency Review", - "description": "When designing health probes for your Azure Load Balancer, it is important to follow best practices to ensure reliable and accurate monitoring of your backend instances.", - "guid": "dccbd979-2a6b-4cca-8b5f-ea1ebf3dd95d", - "link": "https://learn.microsoft.com/azure/load-balancer/load-balancer-custom-probe-overview#design-guidance", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "8dd458e9-2713-49b8-8110-2dbd6eaf11e6", + "id": "E06.03", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-setup-guide/monitoring-reporting?tabs=AzureMonitor", "services": [ - "LoadBalancer", - "Monitor" + "Cost", + "FrontDoor", + "AppSvc" ], - "severity": "Low", - "subcategory": "Load Balancers", - "text": "Select the right protocol, appropriate intervals and timeouts, representative paths and probe responses when defining Load Balancer Health Probes", - "waf": "Reliability" + "subcategory": "Networking", + "text": "Frontdoor -Route to something that returns nothingEither set up a Function, Function Proxy, or add a route in your WebApp that returns 200 (OK) and sends no or minimal content. The advantage of this is you will be able to log out when it is called." }, { - "category": "Network", - "checklist": "Resiliency Review", - "description": "When choosing the best option for deploying NVAs in Azure, it is crucial to consider the vendor's recommendations and validate that the specific design has been vetted and validated by the NVA vendor. The vendor should also provide the necessary NVA configuration for seamless integration in Azure.", - "guid": "8b1188b3-c6a4-46ce-a544-451e192d3442", - "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/dmz/nva-ha", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "f843e52f-4722-4d92-ac1b-1cd521e54a29", + "id": "E07.01", + "link": "https://learn.microsoft.com/azure/azure-monitor/agents/diagnostics-extension-overview", "services": [ - "NVA" + "Cost" ], - "severity": "High", - "subcategory": "NVAs", - "text": "Deploy Network Virtual Appliances (NVAs) in a vendor supported configuration for High Availability", - "waf": "Reliability" + "subcategory": "PaaS", + "text": "consider using free tiers where applicable for all non-production environments" }, { - "category": "Network", - "checklist": "Resiliency Review", - "description": "By deploying VPN Gateways in an active-active mode, you can distribute VPN traffic across multiple gateways, improving reliability and ensuring continuous connectivity in case of failures or maintenance.", - "guid": "927139b8-2110-42db-b6ea-f11e6f843e53", - "link": "https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-highlyavailable", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "b9de39ac-0e7c-428d-a936-657202bff456", + "id": "E08.01", + "link": "https://learn.microsoft.com/azure/azure-monitor/alerts/alerts-overview", "services": [ - "ACR", - "VPN" + "Cost" ], - "severity": "Medium", - "subcategory": "VPN Gateways", - "text": "Deploy Azure VPN Gateways in an active-active mode to ensure high availability and redundancy for your VPN connections.", - "waf": "Reliability" + "subcategory": "serverless", + "text": "using serverless patterns for spikes can help keeping costs down" }, { - "category": "Network", - "checklist": "Resiliency Review", - "description": "Zone-redundant SKUs ensure that your VPN gateways are physically and logically separated within a region, providing resiliency and scalability. This deployment configuration safeguards your on-premises network connectivity to Azure from zone-level failures.", - "guid": "f4722d92-8c1b-41cd-921f-54b29b9de39a", - "link": "https://learn.microsoft.com/azure/vpn-gateway/about-zone-redundant-vnet-gateways", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "7e31c67d-68cf-46a6-8a11-94956d697dc3", + "id": "E09.01", + "link": "https://learn.microsoft.com/azure/architecture/best-practices/monitoring", "services": [ - "VPN" + "Cost", + "Storage" ], - "severity": "Medium", - "subcategory": "VPN Gateways", - "text": "Use zone-redundant SKUs when deploying VPN Gateways to enhance resilience and protect against zone-level failures", - "waf": "Reliability" + "subcategory": "Storage", + "text": "consider archiving tiers for less used data" }, { - "category": "Security", - "checklist": "Azure App Security Review", - "description": "Use Azure Key Vault to store any secrets the application needs. Key Vault provides a safe and audited environment for storing secrets and is well-integrated with App Service through the Key Vault SDK or App Service Key Vault References.", - "guid": "834ac932-223e-4ce8-8b12-3071a5416415", - "id": "A01.01", - "link": "https://learn.microsoft.com/azure/app-service/app-service-key-vault-references", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "a2ed27b2-d186-4f1a-8252-bddde68a487c", + "id": "E09.02", + "link": "https://learn.microsoft.com/azure/automation/how-to/region-mappings", "services": [ - "AppSvc", - "AKV" + "Cost", + "Storage" ], - "severity": "High", - "subcategory": "Data Protection", - "text": "Use Key Vault to store secrets", - "waf": "Security" + "subcategory": "Storage", + "text": "check disk sizes where the size does not match the tier (i.e. A 513 GiB disk will pay a P30 (1TiB) and consider resizing" }, { - "category": "Security", - "checklist": "Azure App Security Review", - "description": "Use a Managed Identity to connect to Key Vault either using the Key Vault SDK or through App Service Key Vault References.", - "guid": "833ea3ad-2c2d-4e73-8165-c3acbef4abe1", - "id": "A01.02", - "link": "https://learn.microsoft.com/azure/app-service/app-service-key-vault-references", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "dec4861b-c3bc-410a-b77e-26e4d5a3bec2", + "id": "E09.03", + "link": "https://learn.microsoft.com/azure/governance/policy/concepts/guest-configuration", "services": [ - "AppSvc", - "AKV", - "Entra" + "Cost", + "Storage" ], - "severity": "High", - "subcategory": "Data Protection", - "text": "Use Managed Identity to connect to Key Vault", - "waf": "Security" + "subcategory": "Storage", + "text": "consider using standard SSD rather than Premium or Ultra where possible" }, { - "category": "Security", - "checklist": "Azure App Security Review", - "description": "Store the App Service TLS certificate in Key Vault.", - "guid": "f8d39fda-4776-4831-9c11-5775c2ea55b4", - "id": "A01.03", - "link": "https://learn.microsoft.com/azure/app-service/configure-ssl-certificate", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "c4e2436b-1336-4db5-9f17-960eee0bdf5c", + "id": "E09.04", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/management-operational-compliance#monitoring-for-configuration-drift", "services": [ - "AppSvc", - "AKV" + "Cost", + "Storage" ], - "severity": "High", - "subcategory": "Data Protection", - "text": "Use Key Vault to store TLS certificate.", - "waf": "Security" + "subcategory": "Storage", + "text": "For storage accounts, make sure that the chosen tier is not adding up transaction charges (it might be cheaper to move to the next tier)" }, { - "category": "Security", - "checklist": "Azure App Security Review", - "description": "Systems that process sensitive information should be isolated. To do so, use separate App Service Plans or App Service Environments and consider the use of different subscriptions or management groups.", - "guid": "6ad48408-ee72-4734-a475-ba18fdbf590c", - "id": "A01.04", - "link": "https://learn.microsoft.com/azure/app-service/overview-hosting-plans", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "c2efc5d7-61d4-41d2-900b-b47a393a040f", + "id": "E09.05", + "link": "https://learn.microsoft.com/azure/site-recovery/site-recovery-overview", "services": [ - "AppSvc", - "Subscriptions" + "Cost", + "ASR", + "Storage" ], - "severity": "Medium", - "subcategory": "Data Protection", - "text": "Isolate systems that process sensitive information", - "waf": "Security" + "subcategory": "Storage", + "text": "for ASR, consider using Standard SSD disks if the RPO/RTO and replication throughput allow it" }, { - "category": "Security", - "checklist": "Azure App Security Review", - "description": "Local disks on App Service are not encrypted and sensitive data should not be stored on those. (For example: D:\\\\Local and %TMP%).", - "guid": "e65de8e0-3f9b-4cbd-9682-66abca264f9a", - "id": "A01.05", - "link": "https://learn.microsoft.com/azure/app-service/operating-system-functionality#file-access", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "d3294798-b118-48b2-a5a4-6ceb544451e1", + "id": "E10.01", + "link": "https://learn.microsoft.com/azure/architecture/framework/resiliency/backup-and-recovery", "services": [ - "TrafficManager", - "AppSvc" + "Cost", + "Storage" ], - "severity": "Medium", - "subcategory": "Data Protection", - "text": "Do not store sensitive data on local disk", - "waf": "Security" + "subcategory": "storage", + "text": "storage accounts: check hot tier and/or GRS necessary" }, { - "category": "Security", - "checklist": "Azure App Security Review", - "description": "For authenticated web application, use a well established Identity Provider like Azure AD or Azure AD B2C. Leverage the application framework of your choice to integrate with this provider or use the App Service Authentication / Authorization feature.", - "guid": "919ca0b2-c121-459e-814b-933df574eccc", - "id": "A02.01", - "link": "https://learn.microsoft.com/azure/app-service/overview-authentication-authorization", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "92d34429-3c76-4286-97a5-51c5b04e4f18", + "id": "E10.02", + "link": "https://learn.microsoft.com/azure/backup/backup-center-overview", "services": [ - "AppSvc", - "Entra" + "Cost", + "Storage" ], - "severity": "Medium", - "subcategory": "Identity and Access Control", - "text": "Use an established Identity Provider for authentication", - "waf": "Security" + "subcategory": "storage", + "text": "Disks -validate use of Premium SSD disks everywhere: for example, non-prod could swap to Standard SSD or On demand Premium SSD " }, { - "category": "Security", - "checklist": "Azure App Security Review", - "description": "Deploy code to App Service from a controlled and trusted environment, like a well-managed and secured DevOps deployment pipeline. This avoids code that was not version controlled and verified to be deployed from a malicious host.", - "guid": "3f9bcbd4-6826-46ab-aa26-4f9a19aed9c5", - "id": "A02.02", - "link": "https://learn.microsoft.com/azure/app-service/deploy-best-practices", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "54387e5c-ed12-46cd-832a-f5b2fc6998a5", + "id": "E11.01", + "link": "https://learn.microsoft.com/azure/reliability/availability-zones-overview", "services": [ - "AppSvc", - "Entra" + "Monitor", + "Cost", + "EventHubs" ], - "severity": "High", - "subcategory": "Identity and Access Control", - "text": "Deploy from a trusted environment", - "waf": "Security" + "subcategory": "Synapse", + "text": "Create budgets to manage costs and create alerts that automatically notify stakeholders of spending anomalies and overspending risks." }, { - "category": "Security", - "checklist": "Azure App Security Review", - "description": "Disable basic authentication for both FTP/FTPS and for WebDeploy/SCM. This disables access to these services and enforces the use of Azure AD secured endpoints for deployment. Note that the SCM site can also be opened using Azure AD credentials.", - "guid": "5d04c2c3-919c-4a0b-8c12-159e114b933d", - "id": "A02.03", - "link": "https://learn.microsoft.com/azure/app-service/deploy-configure-credentials#disable-basic-authentication", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "35e33789-7e31-4c67-b68c-f6a62a119495", + "id": "E11.02", + "link": "https://learn.microsoft.com/azure/virtual-machines/availability", "services": [ - "Entra" + "Cost", + "Storage" ], - "severity": "High", - "subcategory": "Identity and Access Control", - "text": "Disable basic authentication", - "waf": "Security" + "subcategory": "Synapse", + "text": "Export cost data to a storage account for additional data analysis." }, { - "category": "Security", - "checklist": "Azure App Security Review", - "description": "Where possible use Managed Identity to connect to Azure AD secured resources. If this is not possible, store secrets in Key Vault and connect to Key Vault using a Managed Identity instead.", - "guid": "f574eccc-d9bd-43ba-bcda-3b54eb2eb03d", - "id": "A02.04", - "link": "https://learn.microsoft.com/azure/app-service/overview-managed-identity?tabs=portal%2Chttp", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "6d697dc3-a2ed-427b-8d18-6f1a1252bddd", + "id": "E11.03", + "link": "https://learn.microsoft.com/azure/load-balancer/load-balancer-overview", "services": [ - "AKV", - "Entra" + "Cost", + "SQL" ], - "severity": "High", - "subcategory": "Identity and Access Control", - "text": "Use Managed Identity to connect to resources", - "waf": "Security" + "subcategory": "Synapse", + "text": "Control costs for a dedicated SQL pool by pausing the resource when it is not in use." }, { - "category": "Security", - "checklist": "Azure App Security Review", - "description": "Where using images stored in Azure Container Registry, pull these using a Managed Identity.", - "guid": "d9a25827-18d2-4ddb-8072-5769ee6691a4", - "id": "A02.05", - "link": "https://learn.microsoft.com/azure/app-service/configure-custom-container#use-managed-identity-to-pull-image-from-azure-container-registry", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "e68a487c-dec4-4861-ac3b-c10ae77e26e4", + "id": "E11.04", + "link": "https://learn.microsoft.com/azure/virtual-machine-scale-sets/overview", "services": [ - "ACR", - "Entra" + "Cost" ], - "severity": "High", - "subcategory": "Identity and Access Control", - "text": "Pull containers using a Managed Identity", - "waf": "Security" + "subcategory": "Synapse", + "text": "Enable the serverless Apache Spark automatic pause feature and set your timeout value accordingly." }, { - "category": "Security", - "checklist": "Azure App Security Review", - "description": "By configuring the diagnostic settings of App Service, you can send all telemetry to Log Analytics as the central destination for logging and monitoring. This allows you to monitor runtime activity of App Service such as HTTP logs, application logs, platform logs, ...", - "guid": "47768314-c115-4775-a2ea-55b46ad48408", - "id": "A03.01", - "link": "https://learn.microsoft.com/azure/app-service/troubleshoot-diagnostic-logs", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "d5a3bec2-c4e2-4436-a133-6db55f17960e", + "id": "E11.05", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-latest-version-for-customer-managed-certificates", "services": [ - "AppSvc", - "Monitor", - "Entra" + "Cost" ], - "severity": "Medium", - "subcategory": "Logging and Monitoring", - "text": "Send App Service runtime logs to Log Analytics", - "waf": "Security" + "subcategory": "Synapse", + "text": "Create multiple Apache Spark pool definitions of various sizes." }, { - "category": "Security", - "checklist": "Azure App Security Review", - "description": "Set up a diagnostic setting to send the activity log to Log Analytics as the central destination for logging and monitoring. This allows you to monitor control plane activity on the App Service resource itself.", - "guid": "ee72734b-475b-4a18-bdbf-590ce65de8e0", - "id": "A03.02", - "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "ee0bdf5c-c2ef-4c5d-961d-41d2500bb47a", + "id": "E11.06", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/resource-org-management-groups#management-groups-in-the-azure-landing-zone-accelerator", "services": [ - "AppSvc", - "Monitor", - "Entra" + "Cost" ], - "severity": "Medium", - "subcategory": "Logging and Monitoring", - "text": "Send App Service activity logs to Log Analytics", - "waf": "Security" + "subcategory": "Synapse", + "text": "Purchase Azure Synapse commit units (SCU) for one year with a pre-purchase plan to save on your Azure Synapse Analytics costs.", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/" }, { - "category": "Security", - "checklist": "Azure App Security Review", - "description": "Control outbound network access using a combination of regional VNet integration, network security groups and UDR's. Traffic should be routed to an NVA such as Azure Firewall. Ensure to monitor the Firewall's logs.", - "guid": "c12159e1-14b9-433d-b574-ecccd9bd3baf", - "id": "A04.01", - "link": "https://learn.microsoft.com/azure/app-service/overview-vnet-integration", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "393a040f-d329-4479-ab11-88b2c5a46ceb", + "id": "E12.01", + "link": "https://learn.microsoft.com/azure/application-gateway/overview-v2", "services": [ - "Firewall", - "VNet", - "NVA", - "Monitor" + "Cost", + "VM" ], - "severity": "Medium", - "subcategory": "Network Security", - "text": "Outbound network access should be controlled", - "waf": "Security" + "subcategory": "VM", + "text": "Use SPOT VMs for interruptible jobs: These are VMs that can be bid on and purchased at a discounted price, providing a cost-effective solution for non-critical workloads.", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/" }, { - "category": "Security", - "checklist": "Azure App Security Review", - "description": "You can provide a stable outbound IP by using VNet integration and using a VNet NAT Gateway or an NVA like Azure Firewall. This allows the receiving party to allow-list based on IP, should that be needed. Note that for communications towards Azure Services often there's no need to depend on the IP address and mechanics like Service Endpoints should be used instead. (Also the use of private endpoints on the receiving end avoids for SNAT to happen and provides a stable outbound IP range.)", - "guid": "cda3b54e-b2eb-403d-b9a2-582718d2ddb1", - "id": "A04.02", - "link": "https://learn.microsoft.com/azure/app-service/networking/nat-gateway-integration", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "544451e1-92d3-4442-a3c7-628637a551c5", + "id": "E12.02", + "link": "https://learn.microsoft.com/azure/load-balancer/load-balancer-overview", "services": [ - "VNet", - "Firewall", - "Storage", - "PrivateLink", - "NVA" + "Cost", + "VM" ], - "severity": "Low", - "subcategory": "Network Security", - "text": "Ensure a stable IP for outbound communications towards internet addresses", - "waf": "Security" + "subcategory": "VM", + "text": "right-sizing all VMs" }, { - "category": "Security", - "checklist": "Azure App Security Review", - "description": "Control inbound network access using a combination of App Service Access Restrictions, Service Endpoints or Private Endpoints. Different access restrictions can be required and configured for the web app itself and the SCM site.", - "guid": "0725769e-e669-41a4-a34a-c932223ece80", - "id": "A04.03", - "link": "https://learn.microsoft.com/azure/app-service/networking-features#access-restrictions", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "b04e4f18-5438-47e5-aed1-26cd032af5b2", + "id": "E12.03", + "link": "https://learn.microsoft.com/azure/application-gateway/configuration-infrastructure#size-of-the-subnet", "services": [ - "PrivateLink", - "AppSvc" + "Cost", + "VM" ], - "severity": "High", - "subcategory": "Network Security", - "text": "Inbound network access should be controlled", - "waf": "Security" + "subcategory": "VM", + "text": "swap VM sized with normalized and most recent sizes", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/" }, { - "category": "Security", - "checklist": "Azure App Security Review", - "description": "Protect against malicious inbound traffic using a Web Application Firewall like Application Gateway or Azure Front Door. Make sure to monitor the WAF's logs.", - "guid": "b123071a-5416-4415-a33e-a3ad2c2de732", - "id": "A04.04", - "link": "https://learn.microsoft.com/azure/app-service/networking/app-gateway-with-service-endpoints", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "fc6998a5-35e3-4378-a7e3-1c67d68cf6a6", + "id": "E12.04", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", "services": [ "Monitor", - "WAF", - "FrontDoor", - "AppSvc", - "AppGW" + "Cost", + "VM" ], - "severity": "High", - "subcategory": "Network Security", - "text": "Use a WAF in front of App Service", - "waf": "Security" + "subcategory": "VM", + "text": "right-sizing VMs - start with monitoring usage below 5% and then work up to 40%", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/" }, { - "category": "Security", - "checklist": "Azure App Security Review", - "description": "Make sure the WAF cannot be bypassed by locking down access to only the WAF. Use a combination of Access Restrictions, Service Endpoints and Private Endpoints.", - "guid": "165c3acb-ef4a-4be1-b8d3-9fda47768314", - "id": "A04.05", - "link": "https://learn.microsoft.com/azure/app-service/networking-features#access-restrictions", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "2a119495-6d69-47dc-9a2e-d27b2d186f1a", + "id": "E12.05", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", "services": [ - "PrivateLink", - "WAF" + "Cost", + "VM" ], - "severity": "High", - "subcategory": "Network Security", - "text": "Avoid for WAF to be bypassed", - "waf": "Security" + "subcategory": "VM", + "text": "containerizing an application can improve VM density and save money on scaling it", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/" }, { - "category": "Security", - "checklist": "Azure App Security Review", - "description": "Set minimum TLS policy to 1.2 in App Service configuration.", - "graph": "appserviceresources | where type =~ 'microsoft.web/sites/config' | extend compliant = (properties.MinTlsVersion>=1.2) | distinct id,compliant", - "guid": "c115775c-2ea5-45b4-9ad4-8408ee72734b", - "id": "A04.06", - "link": "https://learn.microsoft.com/azure/app-service/configure-ssl-bindings#enforce-tls-versions", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "f00a69de-7076-4734-a734-6e4552cad9e1", + "id": "A01.01", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-latest-version-for-customer-managed-certificates", "services": [ - "AzurePolicy", - "AppSvc" + "FrontDoor", + "AKV" ], "severity": "Medium", - "subcategory": "Network Security", - "text": "Set minimum TLS policy to 1.2", - "waf": "Security" + "subcategory": "App delivery - Front Door", + "text": "If you use customer-managed TLS certificates with Azure Front Door, use the 'Latest' certificate version. Reduce the risk of outages caused by manual certificate renewal.", + "waf": "Operations" }, { - "category": "Security", - "checklist": "Azure App Security Review", - "description": "Configure App Service to use HTTPS only. This causes App Service to redirect from HTTP to HTTPS. Strongly consider the use of HTTP Strict Transport Security (HSTS) in your code or from your WAF, which informs browsers that the site should only be accessed using HTTPS.", - "graph": "where (type=='microsoft.web/sites' and (kind == 'app' or kind == 'app,linux' )) | extend compliant = (properties.httpsOnly==true) | distinct id,compliant", - "guid": "475ba18f-dbf5-490c-b65d-e8e03f9bcbd4", - "id": "A04.07", - "link": "https://learn.microsoft.com/azure/app-service/configure-ssl-bindings#enforce-https", - "services": [ - "AppSvc", - "WAF" - ], - "severity": "High", - "subcategory": "Network Security", - "text": "Use HTTPS only", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "6138a720-0f1c-4e16-bd30-1d6e872e52e3", + "id": "A01.02", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/resource-org-management-groups#management-groups-in-the-azure-landing-zone-accelerator", + "services": [], + "severity": "Medium", + "subcategory": "App delivery", + "text": "Perform app delivery within landing zones for both internal-facing (corp) and external-facing apps (online).", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure App Security Review", - "description": "Do not use wildcards in your CORS configuration, as this allows all origins to access the service (thereby defeating the purpose of CORS). Specifically only allow the origins that you expect to be able to access the service.", - "guid": "68266abc-a264-4f9a-89ae-d9c55d04c2c3", - "id": "A04.08", - "link": "https://learn.microsoft.com/azure/app-service/app-service-web-tutorial-rest-api", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "graph": "resources | where type == 'microsoft.network/applicationgateways' | project id, compliant = properties.sku.name in ('Standard_v2', 'WAF_v2') | project id,compliant", + "guid": "553585a6-abe0-11ed-afa1-0242ac120002", + "id": "A01.03", + "link": "https://learn.microsoft.com/azure/application-gateway/overview-v2", "services": [ - "Storage" + "AppGW" ], - "severity": "High", - "subcategory": "Network Security", - "text": "Wildcards must not be used for CORS", - "waf": "Security" - }, - { - "category": "Security", - "checklist": "Azure App Security Review", - "description": "Remote debugging must not be turned on in production as this opens additional ports on the service which increases the attack surface. Note that the service does turn of remote debugging automatically after 48 hours.", - "graph": "appserviceresources | where type =~ 'microsoft.web/sites/config' | extend compliant = (properties.RemoteDebuggingEnabled == false) | distinct id,compliant", - "guid": "d9bd3baf-cda3-4b54-bb2e-b03dd9a25827", - "id": "A04.09", - "link": "https://learn.microsoft.com/azure/app-service/configure-common#configure-general-settings", - "services": [], - "severity": "High", - "subcategory": "Network Security", - "text": "Turn off remote debugging", + "severity": "Medium", + "subcategory": "App delivery - App Gateway", + "text": "Ensure you are using Application Gateway v2 SKU", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure App Security Review", - "description": "Enable Defender for App Service. This (amongst other threats) detects communications to known malicious IP addresses. Review the recommendations from Defender for App Service as part of your operations.", - "guid": "18d2ddb1-0725-4769-be66-91a4834ac932", - "id": "A04.10", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-app-service-introduction", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "graph": "resources | where type == 'microsoft.network/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard')", + "guid": "4e35fbf5-0ae2-48b2-97ce-753353edbd1a", + "id": "A01.04", + "link": "https://learn.microsoft.com/azure/load-balancer/load-balancer-overview", "services": [ - "Defender", - "AppSvc" + "LoadBalancer" ], "severity": "Medium", - "subcategory": "Network Security", - "text": "Enable Defender for Cloud - Defender for App Service", + "subcategory": "App delivery - Load Balancer", + "text": "Ensure you are using the Standard SKU for your Azure Load Balancers", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure App Security Review", - "description": "Azure provides DDoS Basic protection on its network, which can be improved with intelligent DDoS Standard capabilities which learns about normal traffic patterns and can detect unusual behavior. DDoS Standard applies to a Virtual Network so it must be configured for the network resource in front of the app, such as Application Gateway or an NVA.", - "guid": "223ece80-b123-4071-a541-6415833ea3ad", - "id": "A04.11", - "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "graph": "resources | where type=='microsoft.network/applicationgateways' | extend subnetId = tostring(properties.gatewayIPConfigurations[0].properties.subnet.id) | project id, subnetId | join (resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | mv-expand subnets.properties.addressPrefixes | project id, subnetId = tostring(subnets.id), prefix1 = subnets.properties.addressPrefix, prefix2 = subnets.properties.addressPrefixes | mv-expand prefix2 | extend prefix = iff(isnotnull(prefix1), prefix1, prefix2) | extend subnetPrefixLength = split(prefix, '/')[1])on subnetId | extend compliant = (subnetPrefixLength <= 24 or subnetPrefixLength == 64) | distinct id,compliant", + "guid": "dfc50f87-3800-424c-937b-ed5f186e7c15", + "id": "A01.05", + "link": "https://learn.microsoft.com/azure/application-gateway/configuration-infrastructure#size-of-the-subnet", "services": [ - "EventHubs", - "DDoS", - "WAF", "VNet", - "NVA", "AppGW" ], "severity": "Medium", - "subcategory": "Network Security", - "text": "Enable DDOS Protection Standard on the WAF VNet", + "subcategory": "App delivery - App Gateway", + "text": "Your Application Gateways v2 should be deployed in subnets with IP prefixes equal or larger than /24", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure App Security Review", - "description": "Where using images stored in Azure Container Registry, pull these over a virtual network from Azure Container Registry using its private endpoint and the app setting 'WEBSITE_PULL_IMAGE_OVER_VNET'.", - "guid": "2c2de732-165c-43ac-aef4-abe1f8d39fda", - "id": "A04.12", - "link": "https://learn.microsoft.com/azure/app-service/configure-custom-container#use-an-image-from-a-network-protected-registry", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "description": "Administration of reverse proxies in general and WAF in particular is closer to the application than to networking, so they belong in the same subscription as the app. Centralizing the Application Gateway and WAF in the connectivity subscription might be OK if it is managed by one single team.", + "guid": "48b662d6-d15f-4512-a654-98f6dfe237de", + "id": "A01.06", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", "services": [ - "ACR", + "Subscriptions", + "WAF", + "NVA", "VNet", - "PrivateLink" + "AppGW", + "Entra" ], "severity": "Medium", - "subcategory": "Network Security", - "text": "Pull containers over a Virtual Network", + "subcategory": "App delivery - App Gateway", + "text": "Deploy Azure Application Gateway v2 or partner NVAs used for proxying inbound HTTP(S) connections within the landing-zone virtual network and with the apps that they're securing.", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure App Security Review", - "description": "Conduct a penetration test on the web application following the penetration testing rules of engagement.", - "guid": "eb2eb03d-d9a2-4582-918d-2ddb10725769", - "id": "A05.01", - "link": "https://learn.microsoft.com/azure/security/fundamentals/pen-testing", - "services": [], + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "143b16c3-1d7a-4a9b-9470-4489a8042d88", + "id": "A01.07", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "services": [ + "DDoS" + ], "severity": "Medium", - "subcategory": "Penetration Testing", - "text": "Conduct a penetration test", + "subcategory": "App delivery - App Gateway", + "text": "Use a DDoS Network or IP protection plans for all Public IP addresses in application landing zones.", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure App Security Review", - "description": "Deploy trusted code that was validated and scanned for vulnerabilities according to DevSecOps practices.", - "guid": "19aed9c5-5d04-4c2c-9919-ca0b2c12159e", - "id": "A06.01", - "link": "https://learn.microsoft.com/azure/architecture/solution-ideas/articles/devsecops-in-azure", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "graph": "resources | where type =~ 'microsoft.network/applicationGateways' | extend compliant = (isnotnull(properties.autoscaleConfiguration) and properties.autoscaleConfiguration.minCapacity >= 2) | distinct id,compliant", + "guid": "135bf4ac-f9db-461f-b76b-2ee9e30b12c0", + "id": "A01.08", + "link": "https://learn.microsoft.com/azure/application-gateway/application-gateway-autoscaling-zone-redundant", "services": [], "severity": "Medium", - "subcategory": "Vulnerability Management", - "text": "Deploy validated code", - "waf": "Security" + "subcategory": "App delivery - App Gateway", + "text": "Configure autoscaling with a minimum amount of instances of two.", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "Reliability" }, { - "category": "Security", - "checklist": "Azure App Security Review", - "description": "Use the latest versions of supported platforms, programming languages, protocols, and frameworks.", - "guid": "114b933d-f574-4ecc-ad9b-d3bafcda3b54", - "id": "A06.02", - "link": "https://learn.microsoft.com/azure/app-service/overview-patch-os-runtime", - "services": [], - "severity": "High", - "subcategory": "Vulnerability Management", - "text": "Use up-to-date platforms, languages, protocols and frameworks", - "waf": "Security" + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "graph": "resources | where type =~ 'microsoft.network/applicationGateways' | extend compliant = (isnotnull(zones) and array_length(zones) > 1) | distinct id,compliant", + "guid": "060c6964-52b5-48db-af8b-83e4b2d85349", + "id": "A01.09", + "link": "https://learn.microsoft.com/azure/reliability/migrate-app-gateway-v2", + "services": [ + "ACR", + "AppGW" + ], + "severity": "Medium", + "subcategory": "App delivery - App Gateway", + "text": "Deploy Application Gateway across Availability Zones", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "Reliability" }, { - "category": "Application Deployment", - "checklist": "Azure AKS Review", - "cost": 1, - "guid": "785c2fa5-5b56-4ad4-a408-fe72734c476b", - "id": "01.01.01", - "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/containers/aks/secure-baseline-aks", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "e79d17b7-3b22-4a5a-97e7-a8ed4b30e38c", + "id": "A01.10", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", "services": [ - "AKS" + "FrontDoor", + "AzurePolicy", + "WAF" ], "severity": "Medium", - "subcategory": "Development", - "text": "Use canary or blue/green deployments", - "waf": "Operations" + "subcategory": "App delivery - Front Door", + "text": "Use Azure Front Door with WAF policies to deliver and help protect global HTTP/S apps that span multiple Azure regions.", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "Security" }, { - "category": "Application Deployment", - "checklist": "Azure AKS Review", - "cost": 1, - "guid": "ab5351f6-383a-45ed-9c5e-b143b16db40a", - "id": "01.01.02", - "link": "https://learn.microsoft.com/azure/aks/use-windows-hpc", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "3f29812b-2363-4cef-b179-b599de0d5973", + "id": "A01.11", + "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", "services": [ - "AKS" + "FrontDoor", + "AzurePolicy", + "WAF", + "AppGW" ], - "severity": "Low", - "subcategory": "Development", - "text": "If required for AKS Windows workloads HostProcess containers can be used", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "App delivery", + "text": "When using Front Door and Application Gateway to help protect HTTP/S apps, use WAF policies in Front Door. Lock down Application Gateway to receive traffic only from Front Door.", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "Security" }, { - "category": "Application Deployment", - "checklist": "Azure AKS Review", - "guid": "a280dcf5-90ce-465d-b8e1-3f9ccbd46926", - "id": "01.01.03", - "link": "https://learn.microsoft.com/azure/azure-functions/functions-kubernetes-keda", - "scale": 1, + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "cd4cd21b-0881-437f-9e6c-4cfd3e504547", + "id": "A01.12", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", "services": [ - "AKS" + "TrafficManager" ], - "severity": "Low", - "simple": -1, - "subcategory": "Development", - "text": "Use KEDA if running event-driven workloads", - "waf": "Performance" + "severity": "High", + "subcategory": "App delivery - Traffic Manager", + "text": "Use Traffic Manager to deliver global apps that span protocols other than HTTP/S.", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "Reliability" }, { - "category": "Application Deployment", - "checklist": "Azure AKS Review", - "guid": "26886d20-b66c-457b-a591-19bf8e8f5c58", - "id": "01.01.04", - "link": "https://dapr.io/", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "3b4b3e88-a459-4ed5-a22f-644dfbc58204", + "id": "A01.13", + "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy#how-application-proxy-works", "services": [ - "AKS" + "AVD", + "Entra" ], "severity": "Low", - "simple": 1, - "subcategory": "Development", - "text": "Use Dapr to ease microservice development", - "waf": "Operations" + "subcategory": "App delivery", + "text": "If users only need access to internal applications, has Microsoft Entra ID Application Proxy been considered as an alternative to Azure Virtual Desktop (AVD)?", + "training": "https://learn.microsoft.com/learn/modules/configure-azure-ad-application-proxy/", + "waf": "Security" }, { - "category": "Application Deployment", - "checklist": "Azure AKS Review", - "guid": "3acbe04b-be20-49d3-afda-47778424d116", - "ha": 1, - "id": "01.02.01", - "link": "https://learn.microsoft.com/azure/developer/terraform/create-k8s-cluster-with-tf-and-aks", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "01ca7cf1-5754-442d-babb-8ba6772e5c30", + "id": "A01.14", + "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy#how-application-proxy-works", "services": [ - "AKS" + "Entra" ], "severity": "Medium", - "simple": -1, - "subcategory": "Infrastructure as Code", - "text": "Use automation through ARM/TF to create your Azure resources", - "waf": "Operations" + "subcategory": "App delivery", + "text": "To reduce the number of firewall ports open for incoming connections in your network, consider using Microsoft Entra ID Application Proxy to give remote users secure and authenticated access to internal applications.", + "training": "https://learn.microsoft.com/learn/paths/implement-applications-external-access-azure-ad/", + "waf": "Security" }, { - "category": "BC and DR", - "checklist": "Azure AKS Review", - "guid": "36cb45e5-7960-4332-9bdf-8cc23318da61", - "ha": 1, - "id": "02.01.01", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/enterprise-scale/business-continuity-and-disaster-recovery", + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "graph": "resources | where type == 'microsoft.network/frontdoorwebapplicationfirewallpolicies' | project policyName=name, policyId=id,policySku=sku.name, links=properties.securityPolicyLinks, enabledState=properties.policySettings.enabledState, mode=properties.policySettings.mode | mvexpand links | extend securityPolicy=links.id | extend securityPolicyParts=split(securityPolicy, '/') | extend profileId=strcat_array(array_slice(securityPolicyParts, 0, -3), '/') | project id=profileId, compliant=((enabledState=='Enabled') and (mode=='Prevention')), enabledState, mode", + "guid": "ae248989-b306-4591-9186-de482e3f0f0e", + "id": "A01.15", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-policy-settings", "services": [ - "ASR", - "AKS" + "FrontDoor", + "Storage", + "WAF" ], "severity": "High", - "subcategory": "Disaster Recovery", - "text": "Schedule and perform DR tests regularly", - "waf": "Reliability" + "subcategory": "App delivery - Front Door", + "text": "Deploy your WAF profiles for Front Door in 'Prevention' mode.", + "waf": "Security" }, { - "category": "BC and DR", - "checklist": "Azure AKS Review", - "guid": "170265f4-bb46-4a39-9af7-f317284797b1", - "ha": 1, - "id": "02.02.01", - "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-multi-region", + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "062d5839-4d36-402f-bfa4-02811eb936e9", + "id": "A01.16", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#avoid-combining-traffic-manager-and-front-door", "services": [ - "FrontDoor", "TrafficManager", - "AKS", - "LoadBalancer" - ], - "severity": "Medium", - "subcategory": "High Availability", - "text": "Use Azure Traffic Manager or Azure Front Door as a global load balancer for region failover", - "waf": "Reliability" - }, - { - "category": "BC and DR", - "checklist": "Azure AKS Review", - "graph": "resources | where type=='microsoft.containerservice/managedclusters' | extend compliant= isnotnull(properties.agentPoolProfiles[0].availabilityZones) | distinct id,compliant", - "guid": "578a219a-46be-4b54-9350-24922634292b", - "ha": 1, - "id": "02.02.02", - "link": "https://learn.microsoft.com/azure/aks/availability-zones", - "services": [ - "AKS" + "FrontDoor" ], - "severity": "Medium", - "subcategory": "High Availability", - "text": "Use Availability Zones if they are supported in your Azure region", - "waf": "Reliability" + "severity": "High", + "subcategory": "App delivery - Front Door", + "text": "Avoid combining Azure Traffic Manager and Azure Front Door.", + "waf": "Security" }, { - "category": "BC and DR", - "checklist": "Azure AKS Review", - "cost": -2, - "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (sku.tier=='Paid') | distinct id,compliant", - "guid": "71d41e36-10cc-457b-9a4b-1410d4395898", - "ha": 2, - "id": "02.02.03", - "link": "https://learn.microsoft.com/azure/aks/uptime-sla", + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "5efeb96a-003f-4b18-8fcd-b4d84459c2b2", + "id": "A01.17", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-the-same-domain-name-on-front-door-and-your-origin", "services": [ - "AKS" + "FrontDoor" ], "severity": "High", - "subcategory": "High Availability", - "text": "Use the SLA-backed AKS offering", - "waf": "Reliability" + "subcategory": "App delivery - Front Door", + "text": "Use the same domain name on Azure Front Door and your origin. Mismatched host names can cause subtle bugs.", + "waf": "Security" }, { - "category": "BC and DR", - "checklist": "Azure AKS Review", - "guid": "c1288b3c-6a57-4cfc-9444-51e1a3d3453a", - "ha": 1, - "id": "02.02.04", - "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-scheduler", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "0b5a380c-4bfb-47bc-b1d7-dcfef363a61b", + "id": "A01.18", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#disable-health-probes-when-theres-only-one-origin-in-an-origin-group", "services": [ - "AKS", - "Cost" + "FrontDoor" ], "severity": "Low", - "simple": -1, - "subcategory": "High Availability", - "text": "Use Disruption Budgets in your pod and deployment definitions", - "waf": "Reliability" + "subcategory": "App delivery - Front Door", + "text": "Disable health probes when there is only one origin in an Azure Front Door origin group.", + "waf": "Performance" }, { - "category": "BC and DR", - "checklist": "Azure AKS Review", - "cost": -1, - "guid": "3c763963-7a55-42d5-a15e-401955387e5c", - "ha": 1, - "id": "02.02.05", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-geo-replication", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "5567048e-e5d7-4206-9c55-b5ed45d2cc0c", + "id": "A01.19", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#select-good-health-probe-endpoints", "services": [ - "ACR", - "AKS" + "FrontDoor" ], - "severity": "High", - "subcategory": "High Availability", - "text": "If using a private registry, configure region replication to store images in multiple regions", + "severity": "Medium", + "subcategory": "App delivery - Front Door", + "text": "Select good health probe endpoints for Azure Front Door. Consider building health endpoints that check all of your application's dependencies.", "waf": "Reliability" }, { - "category": "BC and DR", - "checklist": "Azure AKS Review", - "guid": "bc14aea6-e65d-48d9-a3ad-c218e6436b06", - "ha": 1, - "id": "02.03.01", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/enterprise-scale/business-continuity-and-disaster-recovery", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "a13f72f3-8f5c-4864-95e5-75bf37fbbeb1", + "id": "A01.20", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-head-health-probes", "services": [ - "AKS" + "FrontDoor" ], - "severity": "High", - "subcategory": "Requirements", - "text": "Define non-functional requirements such as SLAs, RTO (Recovery Time Objective) and RPO (Recovery Point Objective).", - "waf": "Reliability" + "severity": "Low", + "subcategory": "App delivery - Front Door", + "text": "Use HEAD health probes with Azure Front Door, to reduce the traffic that Front Door sends to your application.", + "waf": "Performance" }, { - "category": "Cost Governance", - "checklist": "Azure AKS Review", - "cost": 1, - "guid": "f82cb8eb-8c0a-4a63-a25a-4956eaa8dc4a", - "id": "03.01.01", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/aks/eslz-cost-governance-with-kubecost", + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "graph": "resources | where type=='microsoft.network/loadbalancers' | extend countOutRules=array_length(properties.outboundRules) | extend compliant = (countOutRules == 0) | distinct id,compliant", + "guid": "97a2fd46-64b0-1dfa-b72d-9c8869496d75", + "id": "A01.21", + "link": "https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity", "services": [ - "AKS", - "Cost" + "LoadBalancer" ], - "severity": "Low", - "subcategory": "Cost", - "text": "Use an external application such as kubecost to allocate costs to different users", - "waf": "Cost" + "severity": "High", + "subcategory": "App delivery - Load Balancer", + "text": "Use Azure NAT Gateway instead of Load Balancer outbound rules for better SNAT scalability", + "waf": "Reliability" }, { - "category": "Cost Governance", - "checklist": "Azure AKS Review", - "cost": 1, - "guid": "4d3dfbab-9924-4831-a68d-fdf0d72f462c", - "id": "03.01.02", - "link": "https://learn.microsoft.com/azure/aks/scale-down-mode", + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "af95c92d-d723-4f4a-98d7-8722324efd4d", + "id": "A01.22", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-managed-tls-certificates", "services": [ - "AKS", - "Cost" + "Cost", + "FrontDoor", + "AKV" ], - "severity": "Low", - "subcategory": "Cost", - "text": "Use scale down mode to delete/delallocate nodes", - "waf": "Cost" + "severity": "High", + "subcategory": "App delivery - Front Door", + "text": "Use managed TLS certificates with Azure Front Door. Reduce operational cost and risk of outages due to certificate renewals.", + "waf": "Operations" }, { - "category": "Cost Governance", - "checklist": "Azure AKS Review", - "cost": 1, - "guid": "87e651ea-bc4a-4a87-a6df-c06a4b570ebc", - "id": "03.01.03", - "link": "https://learn.microsoft.com/azure/aks/gpu-multi-instance", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "189ea962-3969-4863-8f5a-5ad808c2cf4b", + "id": "A01.23", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#define-your-waf-configuration-as-code", "services": [ - "AKS", - "Cost" + "FrontDoor", + "WAF" ], "severity": "Medium", - "subcategory": "Cost", - "text": "When required use multi-instance partioning GPU on AKS Clusters", - "waf": "Cost" + "subcategory": "App delivery - Front Door", + "text": "Define your Azure Front Door WAF configuration as code. By using code, you can more easily adopt new ruleset versions and gain additional protection.", + "waf": "Operations" }, { - "category": "Cost Governance", - "checklist": "Azure AKS Review", - "cost": 1, - "guid": "2b72a08b-0410-4cd6-9093-e068a5cf27e8", - "id": "03.01.04", - "link": "https://learn.microsoft.com/azure/aks/start-stop-nodepools", + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "2e30abab-5478-417c-81bf-bf1ad4ed1ed4", + "id": "A01.24", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-end-to-end-tls", "services": [ - "AKS", - "Cost" + "FrontDoor" ], - "severity": "Low", - "subcategory": "Cost", - "text": "If running a Dev/Test cluster use NodePool Start/Stop", - "waf": "Cost" + "severity": "High", + "subcategory": "App delivery - Front Door", + "text": "Use end-to-end TLS with Azure Front Door. Use TLS for connections from your clients to Front Door, and from Front Door to your origin.", + "waf": "Security" }, { - "category": "Governance and Security", - "checklist": "Azure AKS Review", - "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (isnotnull(properties.addonProfiles.azurepolicy) and properties.addonProfiles.azurepolicy.enabled==true) | distinct id,compliant", - "guid": "9ca48e4a-85e2-4223-bce8-bb12307ca5f1", - "id": "04.01.01", - "link": "https://learn.microsoft.com/azure/governance/policy/concepts/policy-for-kubernetes", - "security": 1, + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "10aa45af-166f-44c4-9f36-b6d592dac2ca", + "id": "A01.25", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-http-to-https-redirection", "services": [ - "AzurePolicy", - "AKS" + "FrontDoor" ], "severity": "Medium", - "simple": -1, - "subcategory": "Compliance", - "text": "Use Azure Policy for Kubernetes to ensure cluster compliance", + "subcategory": "App delivery - Front Door", + "text": "Use HTTP to HTTPS redirection with Azure Front Door. Support older clients by redirecting them to an HTTPS request automatically.", "waf": "Security" }, { - "category": "Governance and Security", - "checklist": "Azure AKS Review", - "cost": -1, - "graph": "where type=='microsoft.containerservice/managedclusters' | project id,resourceGroup,name,pools=properties.agentPoolProfiles | project id,name,resourceGroup,poolcount=array_length(pools) | extend compliant = (poolcount > 1)", - "guid": "6f158e3e-a3a9-42c2-be7e-2165c3a87af4", - "id": "04.01.02", - "link": "https://learn.microsoft.com/azure/aks/use-system-pools", - "security": 1, + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "28b9ee82-b2c7-45aa-bc98-6de6f59a095d", + "id": "A01.26", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#enable-the-waf", "services": [ - "AKS" + "FrontDoor", + "WAF" ], - "severity": "Medium", - "simple": -1, - "subcategory": "Compliance", - "text": "Separate applications from the control plane with user/system nodepools", + "severity": "High", + "subcategory": "App delivery - Front Door", + "text": "Enable the Azure Front Door WAF. Protect your application from a range of attacks.", "waf": "Security" }, { - "category": "Governance and Security", - "checklist": "Azure AKS Review", - "guid": "a7a1f893-9bda-4477-98f2-4c116775c2ea", - "ha": 1, - "id": "04.01.03", - "link": "https://learn.microsoft.com/azure/aks/use-system-pools", + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "2902d8cc-1b0c-4495-afad-624ab70f7bd6", + "id": "A01.27", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#tune-your-waf", "services": [ - "AKS" + "FrontDoor", + "WAF" ], - "severity": "Low", - "simple": -1, - "subcategory": "Compliance", - "text": "Add taint to your system nodepool to make it dedicated", + "severity": "High", + "subcategory": "App delivery - Front Door", + "text": "Tune the Azure Front Door WAF for your workload. Reduce false positive detections.", "waf": "Security" }, { - "category": "Governance and Security", - "checklist": "Azure AKS Review", - "guid": "55b46a94-8008-4ae7-b7e4-b475b6c8bdbf", - "id": "04.01.04", - "link": "https://learn.microsoft.com/azure/container-registry/", - "security": 1, + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "17ba124b-127d-42b6-9322-388d5b2bbcfc", + "id": "A01.28", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-prevention-mode", "services": [ - "ACR", - "AKS" + "FrontDoor", + "WAF" ], - "severity": "Medium", - "simple": -1, - "subcategory": "Compliance", - "text": "Use a private registry for your images, such as ACR", + "severity": "High", + "subcategory": "App delivery - Front Door", + "text": "Use prevention mode with the Azure Front Door WAF. Prevention mode ensures that the WAF blocks malicious requests.", "waf": "Security" }, { - "category": "Governance and Security", - "checklist": "Azure AKS Review", - "cost": -1, - "guid": "59bce65d-e8a0-43f9-9879-468d66a786d6", - "id": "04.01.05", - "link": "https://learn.microsoft.com/azure/security-center/container-security", - "security": 1, + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "49a98f2b-ec22-4a87-9415-6a10b00d6555", + "id": "A01.29", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#enable-default-rule-sets", "services": [ - "AKS" + "FrontDoor", + "WAF" ], - "severity": "Medium", - "subcategory": "Compliance", - "text": "Scan your images for vulnerabilities", + "severity": "High", + "subcategory": "App delivery - Front Door", + "text": "Enable the Azure Front Door WAF default rule sets. The default rule sets detect and block common attacks.", "waf": "Security" }, { - "category": "Governance and Security", - "checklist": "Azure AKS Review", - "cost": -1, - "guid": "cc639637-a652-42ac-89e8-06965388e9de", - "id": "04.01.06", - "link": "https://learn.microsoft.com/azure/security-center/container-security", - "security": 1, + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "147a13d4-2a2f-4824-a524-f5855b52b946", + "id": "A01.30", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#enable-bot-management-rules", "services": [ - "AKS", - "Defender" + "FrontDoor", + "WAF" ], - "severity": "Medium", - "subcategory": "Compliance", - "text": "Use Azure Security Center to detect security posture vulnerabilities", + "severity": "High", + "subcategory": "App delivery - Front Door", + "text": "Enable the Azure Front Door WAF bot management rules. The bot rules detect good and bad bots.", "waf": "Security" }, { - "category": "Governance and Security", - "checklist": "Azure AKS Review", - "cost": -1, - "guid": "42d4aefe-2383-470e-b019-c30df24996b2", - "id": "04.01.07", - "link": "https://learn.microsoft.com/azure/aks/use-multiple-node-pools#add-a-fips-enabled-node-pool", - "security": 1, + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "d7dcdcb9-0d99-44b9-baab-ac7570ede79a", + "id": "A01.31", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-the-latest-ruleset-versions", "services": [ - "AKS" + "FrontDoor", + "WAF" ], - "severity": "Low", - "subcategory": "Compliance", - "text": "If required configure FIPS", + "severity": "Medium", + "subcategory": "App delivery - Front Door", + "text": "Use the latest Azure Front Door WAF ruleset versions. Ruleset updates are regularly updated to take account of the current threat landscape.", "waf": "Security" }, { - "category": "Governance and Security", - "checklist": "Azure AKS Review", - "guid": "d167dd18-2b0a-4c24-8b99-9a646f8389a7", - "id": "04.01.08", - "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-cluster-isolation", - "security": 1, + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "b9620385-1cde-418f-914b-a84a06982ffc", + "id": "A01.32", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#add-rate-limiting", "services": [ - "AKS" + "FrontDoor", + "WAF" ], - "severity": "High", - "subcategory": "Compliance", - "text": "Define app separation requirements (namespace/nodepool/cluster)", + "severity": "Medium", + "subcategory": "App delivery - Front Door", + "text": "Add rate limiting to the Azure Front Door WAF. Rate limiting blocks clients accidentally or intentionally sending large amounts of traffic in a short period of time.", "waf": "Security" }, { - "category": "Governance and Security", - "checklist": "Azure AKS Review", - "guid": "5e3df584-eccc-4d97-a3b6-bcda3b50eb2e", - "id": "04.02.01", - "link": "https://github.com/Azure/secrets-store-csi-driver-provider-azure", - "security": 1, + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "6dc36c52-0124-4ffe-9eaf-23ec1282dedb", + "id": "A01.33", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-a-high-threshold-for-rate-limits", "services": [ - "AKS", - "AKV" + "FrontDoor", + "WAF" ], "severity": "Medium", - "simple": -1, - "subcategory": "Secrets", - "text": "Store your secrets in Azure Key Vault with the CSI Secrets Store driver", + "subcategory": "App delivery - Front Door", + "text": "Use a high threshold for Azure Front Door WAF rate limits. High rate limit thresholds avoid blocking legitimate traffic, while still providing protection against extremely high numbers of requests that might overwhelm your infrastructure. ", + "waf": "Security" + }, + { + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "388a3d0e-0a43-4367-90b2-3dd2aeece5ee", + "id": "A01.34", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#geo-filter-traffic", + "services": [ + "FrontDoor", + "WAF" + ], + "severity": "Low", + "subcategory": "App delivery - Front Door", + "text": "Geo-filter traffic by using the Azure Front Door WAF. Allow traffic only from expected regions, and block traffic from other regions.", "waf": "Security" }, { - "category": "Governance and Security", - "checklist": "Azure AKS Review", - "guid": "b03dda6d-58d7-4c89-8ddb-107d5769ae66", - "id": "04.02.02", - "link": "https://learn.microsoft.com/azure/aks/update-credentials", - "security": 1, + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "00acd8a9-6975-414f-8491-2be6309893b8", + "id": "A01.35", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#specify-the-unknown-zz-location", "services": [ - "AKS", - "AKV" + "FrontDoor", + "WAF" ], - "severity": "High", - "subcategory": "Secrets", - "text": "If using Service Principals for the cluster, refresh credentials periodically (like quarterly)", + "severity": "Medium", + "subcategory": "App delivery - Front Door", + "text": "Specify the unknown (ZZ) location when geo-filtering traffic with the Azure Front Door WAF. Avoid accidentally blocking legitimate requests when IP addresses can't be geo-matched.", "waf": "Security" }, { - "category": "Governance and Security", - "checklist": "Azure AKS Review", - "cost": -1, - "guid": "e7ba73a3-0508-4f80-806f-527db30cee96", - "id": "04.02.03", - "link": "https://learn.microsoft.com/azure/aks/use-kms-etcd-encryption", - "security": 1, + "category": "Security", + "checklist": "Azure Blob Storage Review", + "description": "Apply guidance from the Microsoft cloud security benchmark related to Storage", + "guid": "d237de14-3b16-4c21-b7aa-9b64604489a8", + "id": "A01.01", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/storage-security-baseline", "services": [ - "AKS", - "AKV" + "Storage" ], "severity": "Medium", - "subcategory": "Secrets", - "text": "If required add Key Management Service etcd encryption", + "subcategory": " Overview", + "text": "Consider the 'Azure security baseline for storage'", "waf": "Security" }, { - "category": "Governance and Security", - "checklist": "Azure AKS Review", - "cost": -1, - "guid": "ec8e4e42-0344-41b0-b865-9123e8956d31", - "id": "04.02.04", - "link": "https://learn.microsoft.com/azure/confidential-computing/confidential-nodes-aks-overview", - "security": 1, + "category": "Security", + "checklist": "Azure Blob Storage Review", + "description": "Azure Storage by default has a public IP address and is Internet-reachable. Private endpoints allow to securely expose Azure Storage only to those Azure Compute resources that need access, thus eliminating exposure to the public Internet", + "guid": "f42d78e7-9d17-4a73-a22a-5a67e7a8ed4b", + "id": "A02.01", + "link": "https://learn.microsoft.com/azure/storage/common/storage-private-endpoints", "services": [ - "AKS", - "AKV" + "PrivateLink", + "Storage" ], - "severity": "Low", - "subcategory": "Secrets", - "text": "If required consider using Confidential Compute for AKS", + "severity": "High", + "subcategory": "Networking", + "text": "Consider using private endpoints for Azure Storage", "waf": "Security" }, { - "category": "Governance and Security", - "checklist": "Azure AKS Review", - "cost": -1, - "guid": "c9e95ffe-6dd1-4a17-8c5f-110389ca9b21", - "id": "04.02.05", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-enable", - "security": 1, + "category": "Security", + "checklist": "Azure Blob Storage Review", + "description": "Newly created storage accounts are created using the ARM deployment model, so that RBAC, auditing etc. are all enabled. Ensure that there are no old storage accounts with classic deployment model in a subscription", + "guid": "30e37c3e-2971-41b2-963c-eee079b598de", + "id": "A03.01", + "link": "https://learn.microsoft.com/azure/virtual-machines/migration-classic-resource-manager-overview#migration-of-storage-accounts", "services": [ - "AKS", - "Defender", - "AKV" + "Subscriptions", + "RBAC", + "Storage" ], "severity": "Medium", - "subcategory": "Secrets", - "text": "Consider using Defender for Containers", + "subcategory": "Governance", + "text": "Ensure older storage accounts are not using 'classic deployment model'", "waf": "Security" }, { - "category": "Identity and Access Management", - "checklist": "Azure AKS Review", - "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (properties.servicePrincipalProfile.clientId=='msi') | distinct id,compliant", - "guid": "ed127dd1-42b0-46b2-8c69-99a646f3389a", - "id": "05.01.01", - "link": "https://learn.microsoft.com/azure/aks/use-managed-identity", + "category": "Security", + "checklist": "Azure Blob Storage Review", + "description": "Leverage Microsoft Defender to learn about suspicious activity and misconfigurations.", + "guid": "fc5972cd-4cd2-41b0-a803-7f5e6b4bfd3d", + "id": "A03.02", + "link": "https://learn.microsoft.com/azure/storage/common/azure-defender-storage-configure", "services": [ - "AKS", - "Entra" + "Storage", + "Defender" ], "severity": "High", - "simple": 1, - "subcategory": "Identity", - "text": "Use managed identities instead of Service Principals", + "subcategory": "Governance", + "text": "Enable Microsoft Defender for all of your storage accounts", "waf": "Security" }, { - "category": "Identity and Access Management", - "checklist": "Azure AKS Review", - "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = isnotnull(properties.aadProfile) | distinct id,compliant", - "guid": "7e42c78e-78c0-46a6-8a21-94956e698dc4", - "id": "05.01.02", - "link": "https://learn.microsoft.com/azure/aks/managed-aad", + "category": "Security", + "checklist": "Azure Blob Storage Review", + "description": "The soft-delete mechanism allows to recover accidentally deleted blobs.", + "guid": "503547c1-447e-4c66-828a-7100f1ce16dd", + "id": "A04.01", + "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-blob-overview", "services": [ - "AKS", - "Entra" + "Storage" ], "severity": "Medium", - "simple": 1, - "subcategory": "Identity", - "text": "Integrate authentication with AAD (using the managed integration)", + "subcategory": "Data Availability", + "text": "Enable 'soft delete' for blobs", "waf": "Security" }, { - "category": "Identity and Access Management", - "checklist": "Azure AKS Review", - "guid": "a2fe27b2-e287-401a-8352-beedf79b488d", - "id": "05.01.03", - "link": "https://learn.microsoft.com/azure/aks/control-kubeconfig-access", - "security": 1, + "category": "Security", + "checklist": "Azure Blob Storage Review", + "description": "Consider selectively disabling 'soft delete' for certain blob containers, for example if the application must ensure that deleted information is immediately deleted, e.g. for confidentiality, privacy or compliance reasons. ", + "guid": "3f1d5e87-2e52-4e36-81cc-58b4a4b1510e", + "id": "A05.01", + "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-blob-enable", "services": [ - "AKS", - "Entra" + "Storage" ], "severity": "Medium", - "simple": -1, - "subcategory": "Identity", - "text": "Limit access to admin kubeconfig (get-credentials --admin)", + "subcategory": "Confidentiality", + "text": "Disable 'soft delete' for blobs", "waf": "Security" }, { - "category": "Identity and Access Management", - "checklist": "Azure AKS Review", - "guid": "eec4962c-c3bd-421b-b77f-26e5e6b3bec3", - "id": "05.01.04", - "link": "https://learn.microsoft.com/azure/aks/manage-azure-rbac", - "security": 1, + "category": "Security", + "checklist": "Azure Blob Storage Review", + "description": "Soft delete for containers enables you to recover a container after it has been deleted, for example recover from an accidental delete operation.", + "guid": "43a58a9c-2289-4c3d-9b57-d0c655462f2a", + "id": "A06.01", + "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-container-overview", "services": [ - "AKS", - "RBAC", - "Entra" + "Storage" ], - "severity": "Medium", - "simple": -1, - "subcategory": "Identity", - "text": "Integrate authorization with AAD RBAC", + "severity": "High", + "subcategory": "Data Availability", + "text": "Enable 'soft delete' for containers", "waf": "Security" }, { - "category": "Identity and Access Management", - "checklist": "Azure AKS Review", - "guid": "d4f3537c-1346-4dc5-9027-a71ffe1bd05d", - "ha": 1, - "id": "05.01.05", - "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-identity", - "security": 1, + "category": "Security", + "checklist": "Azure Blob Storage Review", + "description": "Consider selectively disabling 'soft delete' for certain blob containers, for example if the application must ensure that deleted information is immediately deleted, e.g. for confidentiality, privacy or compliance reasons. ", + "guid": "3e3453a3-c863-4964-ab65-2d6c15f51296", + "id": "A07.01", + "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-container-enable", "services": [ - "AKS", - "RBAC", - "Entra" + "Storage" ], - "severity": "High", - "simple": -1, - "subcategory": "Identity", - "text": "Use namespaces for restricting RBAC privilege in Kubernetes", + "severity": "Medium", + "subcategory": "Confidentiality", + "text": "Disable 'soft delete' for containers", "waf": "Security" }, { - "category": "Identity and Access Management", - "checklist": "Azure AKS Review", - "guid": "d2e0d5d7-71d4-41e3-910c-c57b4a4b1410", - "id": "05.01.06", - "link": "https://learn.microsoft.com/azure/aks/workload-identity-migration-sidecar", - "security": 1, + "category": "Security", + "checklist": "Azure Blob Storage Review", + "description": "Prevents accidental deletion of a storage account, by forcing the user to first remove the deletion lock, prior to deletion", + "guid": "5398e6de-d227-4dd1-92b0-6c21d7999a64", + "id": "A08.01", + "link": "https://learn.microsoft.com/azure/storage/common/lock-account-resource", "services": [ - "AKS", - "Entra" + "Storage" ], - "severity": "Medium", - "simple": -1, - "subcategory": "Identity", - "text": "For POD Identity Access Management use Azure AD Workload Identity (preview)", + "severity": "High", + "subcategory": "Data Availability", + "text": "Enable resource locks on storage accounts", "waf": "Security" }, { - "category": "Identity and Access Management", - "checklist": "Azure AKS Review", - "guid": "f4dcf690-1b30-407d-abab-6f8aa780d3a3", - "id": "05.01.07", - "link": "https://learn.microsoft.com/azure/aks/managed-aad#non-interactive-sign-in-with-kubelogin", - "security": 1, + "category": "Security", + "checklist": "Azure Blob Storage Review", + "description": "Consider 'legal hold' or 'time-based retention' policies for blobs, so that is is impossible to delete the blob, the container, or the storage account. Please note that 'impossible' actually means 'impossible'; once a storage account contains an immutable blob, the only way to 'get rid' of that storage account is by cancelling the Azure subscription.", + "guid": "6f4389a8-f42c-478e-98c0-6a73a22a4956", + "id": "A09.01", + "link": "https://learn.microsoft.com/azure/storage/blobs/immutable-storage-overview", "services": [ - "AKS", - "Entra" + "Subscriptions", + "Storage", + "AzurePolicy" ], - "severity": "Medium", - "simple": -1, - "subcategory": "Identity", - "text": "For AKS non-interactive logins use kubelogin (preview)", + "severity": "High", + "subcategory": "Data Availability, Compliance", + "text": "Consider immutable blobs", "waf": "Security" }, { - "category": "Identity and Access Management", - "checklist": "Azure AKS Review", - "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (properties.disableLocalAccounts==true) | distinct id,compliant", - "guid": "b085b1f2-3119-4771-8c9a-bbf4411810ec", - "id": "05.01.08", - "link": "https://learn.microsoft.com/azure/aks/managed-aad#disable-local-accounts", - "security": 1, + "category": "Security", + "checklist": "Azure Blob Storage Review", + "description": "Consider disabling unprotected HTTP/80 access to the storage account, so that all data transfers are encrypted, integrity protected, and the server is authenticated. ", + "guid": "e7a8dc4a-20e2-47c3-b297-11b1352beee0", + "id": "A10.01", + "link": "https://learn.microsoft.com/azure/storage/common/storage-require-secure-transfer", "services": [ - "AKS", - "Entra" + "Storage" ], - "severity": "Medium", - "simple": -1, - "subcategory": "Identity", - "text": "Disable AKS local accounts", + "severity": "High", + "subcategory": "Networking", + "text": "Require HTTPS, i.e. disable port 80 on the storage account", "waf": "Security" }, { - "category": "Identity and Access Management", - "checklist": "Azure AKS Review", - "guid": "36abb0db-c118-4f4c-9880-3f30f9a2deb6", - "id": "05.01.09", - "link": "https://learn.microsoft.com/azure/aks/managed-aad#configure-just-in-time-cluster-access-with-azure-ad-and-aks", - "security": 1, + "category": "Security", + "checklist": "Azure Blob Storage Review", + "description": "When configuring a custom domain (hostname) on a storage account, check whether you need TLS/HTTPS; if so, you might have to put Azure CDN in front of your storage account.", + "guid": "79b588de-fc49-472c-b3cd-21bf77036e5e", + "id": "A10.02", + "link": "https://learn.microsoft.com/azure/storage/blobs/storage-custom-domain-name", "services": [ - "AKS", - "Entra" + "Storage" ], - "severity": "Low", - "simple": -1, - "subcategory": "Identity", - "text": "Configure if required Just-in-time cluster access", + "severity": "High", + "subcategory": "Networking", + "text": "When enforcing HTTPS (disabling HTTP), check that you do not use custom domains (CNAME) for the storage account.", "waf": "Security" }, { - "category": "Identity and Access Management", - "checklist": "Azure AKS Review", - "guid": "c4d7f4c6-79bf-45d0-aa05-ce8fc717e150", - "id": "05.01.10", - "link": "https://learn.microsoft.com/azure/aks/managed-aad#use-conditional-access-with-azure-ad-and-aks", - "security": 1, + "category": "Security", + "checklist": "Azure Blob Storage Review", + "description": "Requiring HTTPS when a client uses a SAS token to access blob data helps to minimize the risk of credential loss.", + "guid": "6b4bed3d-5035-447c-8347-dc56028a71ff", + "id": "A10.03", + "link": "https://learn.microsoft.com/azure/storage/common/storage-sas-overview", "services": [ - "AKS", - "Entra" + "Storage" ], - "severity": "Low", - "simple": -1, - "subcategory": "Identity", - "text": "Configure if required AAD conditional access for AKS", + "severity": "Medium", + "subcategory": "Networking", + "text": "Limit shared access signature (SAS) tokens to HTTPS connections only", "waf": "Security" }, { - "category": "Identity and Access Management", - "checklist": "Azure AKS Review", - "guid": "e1123a7c-a333-4eb4-a120-4ee3f293c9f3", - "id": "05.01.11", - "link": "https://learn.microsoft.com/azure/aks/use-group-managed-service-accounts", - "security": 1, + "category": "Security", + "checklist": "Azure Blob Storage Review", + "description": "AAD tokens should be favored over shared access signatures, wherever possible", + "guid": "e1ce15dd-3f0d-45e7-92d4-1e3611cc57b4", + "id": "A11.01", + "link": "https://learn.microsoft.com/azure/storage/common/authorize-data-access", "services": [ - "AKS", + "Storage", "Entra" ], - "severity": "Low", - "simple": -1, - "subcategory": "Identity", - "text": "If required for Windows AKS workloads configure gMSA ", + "severity": "High", + "subcategory": "Identity and Access Management", + "text": "Use Azure Active Directory (Azure AD) tokens for blob access", "waf": "Security" }, { - "category": "Identity and Access Management", - "checklist": "Azure AKS Review", - "guid": "1f711a74-3672-470b-b8b8-a2148d640d79", - "id": "05.01.12", - "link": "https://learn.microsoft.com/azure/aks/use-managed-identity#use-a-pre-created-kubelet-managed-identity", - "security": 1, + "category": "Security", + "checklist": "Azure Blob Storage Review", + "description": "When assigning a role to a user, group, or application, grant that security principal only those permissions that are necessary for them to perform their tasks. Limiting access to resources helps prevent both unintentional and malicious misuse of your data.", + "guid": "a4b1410d-4395-48a8-a228-9b3d6b57cfc6", + "id": "A11.02", "services": [ - "AKS", + "RBAC", + "Storage", "Entra" ], "severity": "Medium", - "simple": -1, - "subcategory": "Identity", - "text": "For finer control consider using a managed Kubelet Identity", + "subcategory": "Identity and Access Management", + "text": "Least privilege in IaM permissions", "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure AKS Review", - "guid": "cbd8ac2a-aebc-4a2a-94da-1dbf3dc99248", - "id": "06.01.01", - "link": "https://azure.github.io/application-gateway-kubernetes-ingress/setup/install-existing/", - "security": 1, + "category": "Security", + "checklist": "Azure Blob Storage Review", + "description": "A user delegation SAS is secured with Azure Active Directory (Azure AD) credentials and also by the permissions specified for the SAS. A user delegation SAS is analogous to a service SAS in terms of its scope and function, but offers security benefits over the service SAS. ", + "guid": "55461e1a-3e34-453a-9c86-39648b652d6c", + "id": "A11.03", + "link": "https://learn.microsoft.com/azure/storage/common/storage-sas-overview?toc=%2Fazure%2Fstorage%2Fblobs%2Ftoc.json#best-practices-when-using-sas", "services": [ - "ACR", - "AKS", - "AppGW" + "Storage", + "Entra" ], - "severity": "Medium", - "simple": -1, - "subcategory": "Best practices", - "text": "If using AGIC, do not share an AppGW across clusters", - "waf": "Reliability" + "severity": "High", + "subcategory": "Identity and Access Management", + "text": "When using SAS, prefer 'user delegation SAS' over storage-account-key based SAS.", + "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure AKS Review", - "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (isnull(properties.addonProfiles.httpApplicationRouting) or properties.addonProfiles.httpApplicationRouting.enabled==false) | distinct id,compliant", - "guid": "8008ae7d-7e4b-4475-a6c8-bdbf59bce65d", - "id": "06.01.02", - "link": "https://learn.microsoft.com/azure/aks/http-application-routing", - "scale": 1, + "category": "Security", + "checklist": "Azure Blob Storage Review", + "description": "Storage account keys ('shared keys') have very little audit capabilities. While it can be monitored on who/when fetched a copy of the keys, once the keys are in the hands of multiple people, it is impossible to attribute usage to a specific user. Solely relying on AAD authentication makes it easier to tie storage access to a user. ", + "guid": "15f51296-5398-4e6d-bd22-7dd142b06c21", + "id": "A11.04", + "link": "https://learn.microsoft.com/rest/api/storageservices/authorize-with-shared-key", "services": [ - "AKS" + "Monitor", + "Storage", + "AKV", + "Entra" ], "severity": "High", - "simple": -1, - "subcategory": "Best practices", - "text": "Do not use AKS Application Routing Add-On", - "waf": "Reliability" + "subcategory": "Identity and Access Management", + "text": "Consider disabling storage account keys, so that only AAD access (and user delegation SAS) is supported.", + "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure AKS Review", - "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (isnull(properties.addonProfiles.httpApplicationRouting) or properties.addonProfiles.httpApplicationRouting.enabled==false) | distinct id,compliant", - "guid": "7bacd7b9-c025-4a9d-a5d2-25d6bc5439d9", - "id": "06.01.03", - "link": "https://learn.microsoft.com/azure/virtual-network/accelerated-networking-overview", - "scale": 1, + "category": "Security", + "checklist": "Azure Blob Storage Review", + "description": "Use Activity Log data to identify 'when', 'who', 'what' and 'how' the security of your storage account is being viewed or changed (i.e. storage account keys, access policies, etc.).", + "guid": "d7999a64-6f43-489a-af42-c78e78c06a73", + "id": "A12.01", + "link": "https://learn.microsoft.com/azure/storage/blobs/blob-storage-monitoring-scenarios#audit-account-activity", "services": [ - "AKS" + "Monitor", + "Storage", + "AzurePolicy", + "AKV" ], - "severity": "Medium", - "simple": -1, - "subcategory": "Best practices", - "text": "For Windows workloads use Accelerated Networking", - "waf": "Performance" + "severity": "High", + "subcategory": "Monitoring", + "text": "Consider using Azure Monitor to audit control plane operations on the storage account", + "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure AKS Review", - "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (tolower(properties.networkProfile.loadBalancerSku)=='standard') | distinct id,compliant", - "guid": "ba7da7be-9952-4914-a384-5d997cb39132", - "id": "06.01.04", - "link": "https://learn.microsoft.com/azure/aks/load-balancer-standard", - "scale": 1, + "category": "Security", + "checklist": "Azure Blob Storage Review", + "description": "A key expiration policy enables you to set a reminder for the rotation of the account access keys. The reminder is displayed if the specified interval has elapsed and the keys have not yet been rotated.", + "guid": "a22a4956-e7a8-4dc4-a20e-27c3e29711b1", + "id": "A13.01", + "link": "https://learn.microsoft.com/azure/storage/common/storage-account-keys-manage?tabs=azure-portal#create-a-key-expiration-policy", "services": [ - "AKS", - "LoadBalancer" + "Storage", + "AzurePolicy", + "AKV", + "Entra" ], - "severity": "High", - "subcategory": "Best practices", - "text": "Use the standard ALB (as opposed to the basic one)", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "Identity and Access Management", + "text": "When using storage account keys, consider enabling a 'key expiration policy'", + "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure AKS Review", - "guid": "22fbe8d6-9b40-47ef-9011-25bb1a555a6b", - "id": "06.01.05", - "link": "https://learn.microsoft.com/azure/aks/use-multiple-node-pools#add-a-node-pool-with-a-unique-subnet", - "security": 1, + "category": "Security", + "checklist": "Azure Blob Storage Review", + "description": "A SAS expiration policy specifies a recommended interval over which the SAS is valid. SAS expiration policies apply to a service SAS or an account SAS. When a user generates service SAS or an account SAS with a validity interval that is larger than the recommended interval, they'll see a warning.", + "guid": "352beee0-79b5-488d-bfc4-972cd3cd21bf", + "id": "A13.02", + "link": "https://learn.microsoft.com/azure/storage/common/sas-expiration-policy", "services": [ - "AKS", - "VNet" + "Storage", + "AzurePolicy", + "Entra" ], "severity": "Medium", - "simple": -2, - "subcategory": "Best practices", - "text": "If using Azure CNI, consider using different Subnets for NodePools", + "subcategory": "Identity and Access Management", + "text": "Consider configuring an SAS expiration policy", "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure AKS Review", - "guid": "c3c39c98-6bb2-4c12-859a-114b5e3df584", - "id": "06.02.01", - "link": "https://learn.microsoft.com/azure/private-link/private-link-overview", - "security": 1, + "category": "Security", + "checklist": "Azure Blob Storage Review", + "description": "Stored access policies give you the option to revoke permissions for a service SAS without having to regenerate the storage account keys. ", + "guid": "77036e5e-6b4b-4ed3-b503-547c1347dc56", + "id": "A13.03", + "link": "https://learn.microsoft.com/rest/api/storageservices/define-stored-access-policy", "services": [ - "Cost", - "AKS", - "PrivateLink", - "VNet" + "Storage", + "AzurePolicy", + "AKV", + "Entra" ], "severity": "Medium", - "simple": -1, - "subcategory": "Cost", - "text": "Use Private Endpoints (preferred) or Virtual Network Service Endpoints to access PaaS services from the cluster", + "subcategory": "Identity and Access Management", + "text": "Consider linking SAS to a stored access policy", "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure AKS Review", - "cost": -1, - "guid": "e8a03f97-8794-468d-96a7-86d60f96c97b", - "ha": 1, - "id": "06.03.01", - "link": "https://learn.microsoft.com/azure/expressroute/designing-for-disaster-recovery-with-expressroute-privatepeering", + "category": "Security", + "checklist": "Azure Blob Storage Review", + "guid": "028a71ff-e1ce-415d-b3f0-d5e772d41e36", + "id": "A14.01", + "link": "https://microsoft.github.io/code-with-engineering-playbook/continuous-integration/dev-sec-ops/secret-management/recipes/detect-secrets-ado/", "services": [ - "AKS", - "VPN" + "Storage", + "AKV" ], "severity": "Medium", - "subcategory": "HA", - "text": "If hybrid connectivity is required, use 2xER or ER+VPN for better availability", - "waf": "Reliability" + "subcategory": "CI/CD", + "text": "Consider configuring your application's source code repository to detect checked-in connection strings and storage account keys.", + "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure AKS Review", - "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (properties.networkProfile.networkPlugin=='azure') | distinct id,compliant", - "guid": "a0f61565-9de5-458f-a372-49c831112dbd", - "id": "06.04.01", - "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-network", + "category": "Security", + "checklist": "Azure Blob Storage Review", + "description": "Ideally, your application should be using a managed identity to authenticate to Azure Storage. If that is not possible, consider having the storage credential (connection string, storage account key, SAS, service principal credential) in Azure KeyVault or an equivalent service.", + "guid": "11cc57b4-a4b1-4410-b439-58a8c2289b3d", + "id": "A15.01", + "link": "https://learn.microsoft.com/azure/architecture/framework/security/design-storage-keys", "services": [ - "AKS" + "Storage", + "Entra" ], "severity": "High", - "simple": 1, - "subcategory": "IPAM", - "text": "Choose the best CNI network plugin for your requirements (Azure CNI recommended)", - "waf": "Reliability" + "subcategory": "Identity and Access Management", + "text": "Consider storing connection strings in Azure KeyVault (in scenarios where managed identities are not possible)", + "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure AKS Review", - "guid": "7faf12e7-0943-4f63-8472-2da29c2b1cd6", - "id": "06.04.02", - "link": "https://learn.microsoft.com/azure/aks/configure-azure-cni", - "scale": 1, + "category": "Security", + "checklist": "Azure Blob Storage Review", + "description": "Use near-term expiration times on an ad hoc SAS service SAS or account SAS. In this way, even if a SAS is compromised, it's valid only for a short time. This practice is especially important if you cannot reference a stored access policy. Near-term expiration times also limit the amount of data that can be written to a blob by limiting the time available to upload to it.", + "guid": "27138b82-1102-4cac-9eae-01e6e842e52f", + "id": "A15.02", + "link": "https://learn.microsoft.com/rest/api/storageservices/delegate-access-with-shared-access-signature", "services": [ - "AKS", - "VNet" + "Storage", + "AzurePolicy", + "Entra" ], "severity": "High", - "subcategory": "IPAM", - "text": "If using Azure CNI, size your subnet accordingly considering the maximum number of pods per node", - "waf": "Performance" + "subcategory": "Identity and Access Management", + "text": "Strive for short validity periods for ad-hoc SAS", + "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure AKS Review", - "guid": "22f54b29-bade-43aa-b1e8-c38ec9366673", - "id": "06.04.03", - "link": "https://learn.microsoft.com/azure/aks/configure-azure-cni", - "scale": 1, + "category": "Security", + "checklist": "Azure Blob Storage Review", + "description": "When creating a SAS, be as specific and restrictive as possible. Prefer a SAS for a single resource and operation over a SAS which gives much broader access.", + "guid": "4721d928-c1b1-4cd5-81e5-4a29a9de399c", + "id": "A15.03", + "link": "https://learn.microsoft.com/rest/api/storageservices/delegate-access-with-shared-access-signature", "services": [ - "AKS" + "Storage", + "Entra" ], - "severity": "High", - "simple": -1, - "subcategory": "IPAM", - "text": "If using Azure CNI, check the maximum pods/node (default 30)", - "waf": "Performance" + "severity": "Medium", + "subcategory": "Identity and Access Management", + "text": "Apply a narrow scope to a SAS", + "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure AKS Review", - "description": "For internal apps organizations often open the whole AKS subnet in their firewalls. This opens network access to the nodes too, and potentially to the pods as well (if using Azure CNI). If LoadBalancer IPs are in a different subnet, only this one needs to be available to the app clients. Another reason is that if the IP addresses in the AKS subnet are a scarce resource, consuming its IP addresses for services will reduce the maximum scalability of the cluster .", - "guid": "13c00567-4b1e-4945-a459-c373e7ed6162", - "id": "06.04.04", - "link": "https://learn.microsoft.com/azure/aks/internal-lb", - "security": 1, + "category": "Security", + "checklist": "Azure Blob Storage Review", + "description": "A SAS can include parameters on which client IP addresses or address ranges are authorized to request a resource using the SAS. ", + "guid": "fd7b28dc-9355-4562-82bf-e4564b0d834a", + "id": "A15.04", + "link": "https://learn.microsoft.com/rest/api/storageservices/create-account-sas", "services": [ - "AKS", - "VNet" + "Storage", + "Entra" ], - "severity": "Low", - "simple": -1, - "subcategory": "IPAM", - "text": "If using private-IP LoadBalancer services, use a dedicated subnet (not the AKS subnet)", + "severity": "Medium", + "subcategory": "Identity and Access Management", + "text": "Consider scoping SAS to a specific client IP address, wherever possible", "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure AKS Review", - "guid": "43f63047-22d9-429c-8b1c-d622f54b29ba", - "id": "06.04.05", - "link": "https://learn.microsoft.com/azure/aks/configure-azure-cni", - "scale": 1, + "category": "Security", + "checklist": "Azure Blob Storage Review", + "description": "A SAS cannot constrain how much data a client uploads; given the pricing model of amount of storage over time, it might make sense to validate whether clients uploaded maliciously large contents.", + "guid": "348b263e-6dd6-4051-8a36-498f6dbad38e", + "id": "A15.05", "services": [ - "AKS" + "Storage", + "Entra" ], - "severity": "High", - "subcategory": "IPAM", - "text": "Size the service IP address range accordingly (it is going to limit the cluster scalability)", - "waf": "Reliability" + "severity": "Low", + "subcategory": "Identity and Access Management", + "text": "Consider checking uploaded data, after clients used a SAS to upload a file. ", + "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure AKS Review", - "guid": "57bf217f-6dc8-481c-81e2-785773e9c00f", - "id": "06.05.01", - "link": "https://learn.microsoft.com/azure/aks/use-byo-cni", - "security": 1, + "category": "Security", + "checklist": "Azure Blob Storage Review", + "description": "When accessing blob storage via SFTP using a 'local user account', the 'usual' RBAC controls do not apply. Blob access via NFS or REST might be more restrictive than SFTP access. Unfortunately, as of early 2023, local users are the only form of identity management that is currently supported for the SFTP endpoint", + "guid": "ad53cc7c-e1d7-4aaa-a357-1449ab8053d8", + "id": "A15.06", + "link": "https://learn.microsoft.com/azure/storage/blobs/secure-file-transfer-protocol-support#sftp-permission-model", "services": [ - "AKS" + "RBAC", + "Storage", + "Entra" ], - "severity": "Low", - "simple": -2, - "subcategory": "Operations", - "text": "If required add your own CNI plugin", + "severity": "High", + "subcategory": "Identity and Access Management", + "text": "SFTP: Limit the amount of 'local users' for SFTP access, and audit whether access is needed over time.", "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure AKS Review", - "guid": "4b3bb365-9458-44d9-9ed1-5c8f52890364", - "id": "06.05.02", - "link": "https://learn.microsoft.com/azure/aks/use-multiple-node-pools#assign-a-public-ip-per-node-for-your-node-pools", - "security": 1, + "category": "Security", + "checklist": "Azure Blob Storage Review", + "guid": "9f89dc7b-33be-42a1-a27f-7b9e91be1f38", + "id": "A15.07", + "link": "https://learn.microsoft.com/azure/storage/blobs/secure-file-transfer-protocol-known-issues#authentication-and-authorization", "services": [ - "AKS" + "Storage", + "Entra" ], - "severity": "Low", - "simple": -2, - "subcategory": "Operations", - "text": "If required configure Public IP per node in AKS", - "waf": "Performance" + "severity": "Medium", + "subcategory": "Identity and Access Management", + "text": "SFTP: The SFTP endpoint does not support POSIX-like ACLs.", + "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure AKS Review", - "guid": "b3808b9f-a1cf-4204-ad01-3a923ce474db", - "id": "06.06.01", - "link": "https://learn.microsoft.com/azure/aks/concepts-network", - "scale": 1, + "category": "Security", + "checklist": "Azure Blob Storage Review", + "description": "Storage supports CORS (Cross-Origin Resource Sharing), i.e. an HTTP feature that enables web apps from a different domain to loosen the same-origin policy. When enabling CORS, keep the CorsRules to the least privilege.", + "guid": "cef39812-bd46-43cb-aac8-ac199ebb91a3", + "id": "A16.01", + "link": "https://learn.microsoft.com/rest/api/storageservices/cross-origin-resource-sharing--cors--support-for-the-azure-storage-services", "services": [ - "AKS" + "Storage", + "AzurePolicy" ], - "severity": "Medium", - "simple": -1, - "subcategory": "Scalability", - "text": "Use an ingress controller to expose web-based apps instead of exposing them with LoadBalancer-type services", - "waf": "Reliability" + "severity": "High", + "subcategory": "Networking", + "text": "Avoid overly broad CORS policies", + "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure AKS Review", - "guid": "ccb534e7-416e-4a1d-8e93-533b53199085", - "id": "06.06.02", - "link": "https://learn.microsoft.com/azure/aks/nat-gateway", - "scale": 1, + "category": "Security", + "checklist": "Azure Blob Storage Review", + "description": "Data at rest is always encrypted server-side, and in addition might be encrypted client-side as well. Server-side encryption might happen using a platform-managed key (default) or customer-managed key. Client-side encryption might happen by either having the client supply an encryption/decryption key on a per-blob basis to Azure storage, or by completely handling encryption on the client-side. thus not relying on Azure Storage at all for confidentiality guarantees.", + "guid": "3d90cae2-cc88-4137-86f7-c0cbafe61464", + "id": "A17.01", + "link": "https://learn.microsoft.com/azure/storage/common/storage-service-encryption", "services": [ - "AKS" + "Storage" ], - "severity": "Low", - "simple": -1, - "subcategory": "Scalability", - "text": "Use Azure NAT Gateway as outboundType for scaling egress traffic", - "waf": "Reliability" + "severity": "High", + "subcategory": "Confidentiality and Encryption", + "text": "Determine how data at rest should be encrypted. Understand the thread model for data.", + "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure AKS Review", - "guid": "8ee9a69a-1b58-4b1e-9c61-476e110a160b", - "id": "06.06.03", - "link": "https://learn.microsoft.com/azure/aks/configure-azure-cni#dynamic-allocation-of-ips-and-enhanced-subnet-support", - "scale": 1, + "category": "Security", + "checklist": "Azure Blob Storage Review", + "guid": "8dd457e9-2713-48b8-8110-2cac6eae01e6", + "id": "A17.02", + "link": "https://learn.microsoft.com/azure/storage/common/customer-managed-keys-overview?toc=%2Fazure%2Fstorage%2Fblobs%2Ftoc.json&bc=%2Fazure%2Fstorage%2Fblobs%2Fbreadcrumb%2Ftoc.json", "services": [ - "AKS" + "Storage" ], "severity": "Medium", - "simple": -1, - "subcategory": "Scalability", - "text": "Use Dynamic allocations of IPs in order to avoid Azure CNI IP exhaustion", - "waf": "Reliability" + "subcategory": "Confidentiality and Encryption", + "text": "Determine which/if platform encryption should be used.", + "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure AKS Review", - "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (properties.networkProfile.outboundType=='userDefinedRouting') | distinct id,compliant", - "guid": "3b365a91-7ecb-4e48-bbe5-4cd7df2e8bba", - "id": "06.07.01", - "link": "https://learn.microsoft.com/azure/aks/limit-egress-traffic", - "security": 2, + "category": "Security", + "checklist": "Azure Blob Storage Review", + "guid": "e842e52f-4721-4d92-ac1b-1cd521e54a29", + "id": "A17.03", + "link": "https://learn.microsoft.com/azure/storage/blobs/encryption-customer-provided-keys", + "services": [ + "Storage" + ], + "severity": "Medium", + "subcategory": "Confidentiality and Encryption", + "text": "Determine which/if client-side encryption should be used.", + "waf": "Security" + }, + { + "category": "Security", + "checklist": "Azure Blob Storage Review", + "description": "Leverage Resource Graph Explorer (resources | where type == 'microsoft.storage/storageaccounts' | where properties['allowBlobPublicAccess'] == true) to find storage accounts which allow anonymous blob access.", + "guid": "659ae558-b937-4d49-a5e1-112dbd7ba012", + "id": "A18.01", + "link": "https://learn.microsoft.com/azure/storage/blobs/anonymous-read-access-configure?tabs=portal#allow-or-disallow-public-read-access-for-a-storage-account", "services": [ - "AKS", - "NVA" + "Storage", + "Entra" ], "severity": "High", - "simple": -2, - "subcategory": "Security", - "text": "Filter egress traffic with AzFW/NVA if your security requirements mandate it", + "subcategory": "Identity and Access Management", + "text": "Consider whether public blob access is needed, or whether it can be disabled for certain storage accounts. ", "waf": "Security" }, { - "category": "Network Topology and Connectivity", + "category": "Application Deployment", "checklist": "Azure AKS Review", - "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = ((isnull(properties.apiServerAccessProfile.enablePrivateCluster) or properties.apiServerAccessProfile.enablePrivateCluster==false) and isnotnull(properties.apiServerAccessProfile.authorizedIPRanges)) | distinct id,compliant", - "guid": "c4581559-bb91-463e-a908-aed8c44ce3b2", - "id": "06.07.02", - "link": "https://learn.microsoft.com/azure/aks/api-server-authorized-ip-ranges", - "security": 1, + "cost": 1, + "guid": "785c2fa5-5b56-4ad4-a408-fe72734c476b", + "id": "01.01.01", + "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/containers/aks/secure-baseline-aks", "services": [ "AKS" ], "severity": "Medium", - "simple": -1, - "subcategory": "Security", - "text": "If using a public API endpoint, restrict the IP addresses that can access it", - "waf": "Security" + "subcategory": "Development", + "text": "Use canary or blue/green deployments", + "waf": "Operations" }, { - "category": "Network Topology and Connectivity", + "category": "Application Deployment", "checklist": "Azure AKS Review", - "graph": "where type=='microsoft.containerservice/managedclusters' | where isnotnull(properties.apiServerAccessProfile.enablePrivateCluster) | extend compliant = (properties.apiServerAccessProfile.enablePrivateCluster==true) | distinct id, compliant", - "guid": "ecccd979-3b6b-4cda-9b50-eb2eb03dda6d", - "id": "06.07.03", - "link": "https://learn.microsoft.com/azure/aks/private-clusters", - "security": 1, + "cost": 1, + "guid": "ab5351f6-383a-45ed-9c5e-b143b16db40a", + "id": "01.01.02", + "link": "https://learn.microsoft.com/azure/aks/use-windows-hpc", "services": [ "AKS" ], - "severity": "High", - "simple": -1, - "subcategory": "Security", - "text": "Use private clusters if your requirements mandate it", - "waf": "Security" + "severity": "Low", + "subcategory": "Development", + "text": "If required for AKS Windows workloads HostProcess containers can be used", + "waf": "Reliability" }, { - "category": "Network Topology and Connectivity", + "category": "Application Deployment", "checklist": "Azure AKS Review", - "graph": "where type=='microsoft.containerservice/managedclusters' | where isnotnull(properties.apiServerAccessProfile.enablePrivateCluster) | extend compliant = (properties.apiServerAccessProfile.enablePrivateCluster==true) | distinct id, compliant", - "guid": "ce7f2a7c-297c-47c6-adea-a6ff838db665", - "id": "06.07.04", - "link": "https://learn.microsoft.com/azure/aks/use-network-policies", - "security": 1, + "guid": "a280dcf5-90ce-465d-b8e1-3f9ccbd46926", + "id": "01.01.03", + "link": "https://learn.microsoft.com/azure/azure-functions/functions-kubernetes-keda", + "scale": 1, "services": [ - "AzurePolicy", "AKS" ], - "severity": "Medium", + "severity": "Low", "simple": -1, - "subcategory": "Security", - "text": "For Windows 2019 and 2022 AKS nodes Calico Network Policies can be used ", - "waf": "Security" + "subcategory": "Development", + "text": "Use KEDA if running event-driven workloads", + "waf": "Performance" }, { - "category": "Network Topology and Connectivity", + "category": "Application Deployment", "checklist": "Azure AKS Review", - "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = isnotnull(properties.networkProfile.networkPolicy) | distinct id,compliant", - "guid": "58d7c892-ddb1-407d-9769-ae669ca48e4a", - "id": "06.07.05", - "link": "https://learn.microsoft.com/azure/aks/use-network-policies", - "security": 1, + "guid": "26886d20-b66c-457b-a591-19bf8e8f5c58", + "id": "01.01.04", + "link": "https://dapr.io/", "services": [ - "AzurePolicy", "AKS" ], - "severity": "High", - "subcategory": "Security", - "text": "Enable a Kubernetes Network Policy option (Calico/Azure)", - "waf": "Security" + "severity": "Low", + "simple": 1, + "subcategory": "Development", + "text": "Use Dapr to ease microservice development", + "waf": "Operations" }, { - "category": "Network Topology and Connectivity", + "category": "Application Deployment", "checklist": "Azure AKS Review", - "guid": "85e2223e-ce8b-4b12-907c-a5f16f158e3e", - "id": "06.07.06", - "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-network", - "security": 1, + "guid": "3acbe04b-be20-49d3-afda-47778424d116", + "ha": 1, + "id": "01.02.01", + "link": "https://learn.microsoft.com/azure/developer/terraform/create-k8s-cluster-with-tf-and-aks", "services": [ - "AzurePolicy", "AKS" ], - "severity": "High", + "severity": "Medium", "simple": -1, - "subcategory": "Security", - "text": "Use Kubernetes network policies to increase intra-cluster security", - "waf": "Security" + "subcategory": "Infrastructure as Code", + "text": "Use automation through ARM/TF to create your Azure resources", + "waf": "Operations" }, { - "category": "Network Topology and Connectivity", + "category": "BC and DR", "checklist": "Azure AKS Review", - "cost": -1, - "guid": "a3a92c2d-e7e2-4165-a3a8-7af4a7a1f893", - "id": "06.07.07", - "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-network", - "security": 2, + "guid": "36cb45e5-7960-4332-9bdf-8cc23318da61", + "ha": 1, + "id": "02.01.01", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/enterprise-scale/business-continuity-and-disaster-recovery", "services": [ - "AKS", - "WAF" + "ASR", + "AKS" ], "severity": "High", - "simple": -1, - "subcategory": "Security", - "text": "Use a WAF for web workloads (UIs or APIs)", - "waf": "Security" - }, - { - "category": "Network Topology and Connectivity", - "checklist": "Azure AKS Review", - "cost": -2, - "graph": "Resources | where type=~'microsoft.containerservice/managedclusters' | project resourceGroup,name,pools=properties.agentPoolProfiles | mv-expand pools | project subnetId=tostring(pools.vnetSubnetID) | where isnotempty(subnetId) | join (Resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,enableDdosProtection=tostring(properties.enableDdosProtection),subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,enableDdosProtection,subnetId=tostring(subnets.id)) on subnetId | distinct id,resourceGroup,name,enableDdosProtection | extend compliant = (enableDdosProtection == 'true')", - "guid": "9bda4776-8f24-4c11-9775-c2ea55b46a94", - "id": "06.07.08", - "link": "https://learn.microsoft.com/azure/virtual-network/ddos-protection-overview", - "security": 2, - "services": [ - "AKS", - "VNet", - "DDoS" - ], - "severity": "Medium", - "subcategory": "Security", - "text": "Use DDoS Standard in the AKS Virtual Network", - "waf": "Security" + "subcategory": "Disaster Recovery", + "text": "Schedule and perform DR tests regularly", + "waf": "Reliability" }, { - "category": "Network Topology and Connectivity", + "category": "BC and DR", "checklist": "Azure AKS Review", - "cost": -2, - "graph": "Resources | where type=~'microsoft.containerservice/managedclusters' | project resourceGroup,name,pools=properties.agentPoolProfiles | mv-expand pools | project subnetId=tostring(pools.vnetSubnetID) | where isnotempty(subnetId) | join (Resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,enableDdosProtection=tostring(properties.enableDdosProtection),subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,enableDdosProtection,subnetId=tostring(subnets.id)) on subnetId | distinct id,resourceGroup,name,enableDdosProtection | extend compliant = (enableDdosProtection == 'true')", - "guid": "6c46b91a-1107-4485-ad66-3183e2a8c266", - "id": "06.07.09", - "link": "https://learn.microsoft.com/azure/aks/http-proxy", - "security": 2, + "guid": "170265f4-bb46-4a39-9af7-f317284797b1", + "ha": 1, + "id": "02.02.01", + "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-multi-region", "services": [ + "TrafficManager", + "FrontDoor", + "LoadBalancer", "AKS" ], - "severity": "Low", - "subcategory": "Security", - "text": "If required add company HTTP Proxy", - "waf": "Security" + "severity": "Medium", + "subcategory": "High Availability", + "text": "Use Azure Traffic Manager or Azure Front Door as a global load balancer for region failover", + "waf": "Reliability" }, { - "category": "Network Topology and Connectivity", + "category": "BC and DR", "checklist": "Azure AKS Review", - "guid": "e9855d04-c3c3-49c9-a6bb-2c12159a114b", - "id": "06.07.10", - "link": "https://learn.microsoft.com/azure/aks/servicemesh-about", - "security": 1, + "graph": "resources | where type=='microsoft.containerservice/managedclusters' | extend compliant= isnotnull(properties.agentPoolProfiles[0].availabilityZones) | distinct id,compliant", + "guid": "578a219a-46be-4b54-9350-24922634292b", + "ha": 1, + "id": "02.02.02", + "link": "https://learn.microsoft.com/azure/aks/availability-zones", "services": [ "AKS" ], "severity": "Medium", - "simple": -2, - "subcategory": "Security", - "text": "Consider using a service mesh for advanced microservice communication management", - "waf": "Security" + "subcategory": "High Availability", + "text": "Use Availability Zones if they are supported in your Azure region", + "waf": "Reliability" }, { - "category": "Operations", + "category": "BC and DR", "checklist": "Azure AKS Review", - "guid": "67f7a9ed-5b31-4f38-a3f3-9812b2463cff", - "ha": 1, - "id": "07.01.01", - "link": "https://learn.microsoft.com/azure/azure-monitor/insights/container-insights-metric-alerts", + "cost": -2, + "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (sku.tier=='Paid') | distinct id,compliant", + "guid": "71d41e36-10cc-457b-9a4b-1410d4395898", + "ha": 2, + "id": "02.02.03", + "link": "https://learn.microsoft.com/azure/aks/uptime-sla", "services": [ - "AKS", - "Monitor" + "AKS" ], "severity": "High", - "simple": -1, - "subcategory": "Alerting", - "text": "Configure alerts on the most critical metrics (see Container Insights for recommendations)", - "waf": "Operations" + "subcategory": "High Availability", + "text": "Use the SLA-backed AKS offering", + "waf": "Reliability" }, { - "category": "Operations", + "category": "BC and DR", "checklist": "Azure AKS Review", - "guid": "337453a3-cc63-4963-9a65-22ac19e80696", + "guid": "c1288b3c-6a57-4cfc-9444-51e1a3d3453a", "ha": 1, - "id": "07.02.01", - "link": "https://learn.microsoft.com/azure/advisor/advisor-get-started", + "id": "02.02.04", + "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-scheduler", "services": [ - "AKS", - "Entra" + "Cost", + "AKS" ], "severity": "Low", "simple": -1, - "subcategory": "Compliance", - "text": "Check regularly Azure Advisor for recommendations on your cluster", - "waf": "Operations" + "subcategory": "High Availability", + "text": "Use Disruption Budgets in your pod and deployment definitions", + "waf": "Reliability" }, { - "category": "Operations", + "category": "BC and DR", "checklist": "Azure AKS Review", - "guid": "3aa70560-e7e7-4968-be3d-628af35b2ced", - "id": "07.02.03", - "link": "https://learn.microsoft.com/azure/aks/certificate-rotation", + "cost": -1, + "guid": "3c763963-7a55-42d5-a15e-401955387e5c", + "ha": 1, + "id": "02.02.05", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-geo-replication", "services": [ + "ACR", "AKS" ], - "severity": "Low", - "simple": 1, - "subcategory": "Compliance", - "text": "Enable AKS auto-certificate rotation", - "waf": "Operations" + "severity": "High", + "subcategory": "High Availability", + "text": "If using a private registry, configure region replication to store images in multiple regions", + "waf": "Reliability" }, { - "category": "Operations", + "category": "BC and DR", "checklist": "Azure AKS Review", - "guid": "e189c599-df0d-45a7-9dd4-ce32c1881370", - "id": "07.02.04", - "link": "https://learn.microsoft.com/azure/aks/supported-kubernetes-versions", - "security": 1, + "guid": "bc14aea6-e65d-48d9-a3ad-c218e6436b06", + "ha": 1, + "id": "02.03.01", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/enterprise-scale/business-continuity-and-disaster-recovery", "services": [ "AKS" ], "severity": "High", - "simple": -1, - "subcategory": "Compliance", - "text": "Have a regular process to upgrade your kubernetes version periodically (quarterly, for example), or use the AKS autoupgrade feature", - "waf": "Operations" + "subcategory": "Requirements", + "text": "Define non-functional requirements such as SLAs, RTO (Recovery Time Objective) and RPO (Recovery Point Objective).", + "waf": "Reliability" }, { - "category": "Operations", + "category": "Cost Governance", "checklist": "Azure AKS Review", - "guid": "6f7c4c0d-4e51-4464-ad24-57ed67138b82", - "id": "07.02.05", - "link": "https://learn.microsoft.com/azure/aks/node-updates-kured", + "cost": 1, + "guid": "f82cb8eb-8c0a-4a63-a25a-4956eaa8dc4a", + "id": "03.01.01", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/aks/eslz-cost-governance-with-kubecost", "services": [ + "Cost", "AKS" ], - "severity": "High", - "simple": -1, - "subcategory": "Compliance", - "text": "Use kured for Linux node upgrades in case you are not using node-image upgrade", - "waf": "Operations" + "severity": "Low", + "subcategory": "Cost", + "text": "Use an external application such as kubecost to allocate costs to different users", + "waf": "Cost" }, { - "category": "Operations", + "category": "Cost Governance", "checklist": "Azure AKS Review", - "guid": "139c9580-ade3-426a-ba09-cf157d9f6477", - "id": "07.02.06", - "link": "https://learn.microsoft.com/azure/aks/node-image-upgrade", - "security": 1, + "cost": 1, + "guid": "4d3dfbab-9924-4831-a68d-fdf0d72f462c", + "id": "03.01.02", + "link": "https://learn.microsoft.com/azure/aks/scale-down-mode", "services": [ + "Cost", "AKS" ], - "severity": "High", - "simple": -1, - "subcategory": "Compliance", - "text": "Have a regular process to upgrade the cluster node images periodically (weekly, for example)", - "waf": "Operations" + "severity": "Low", + "subcategory": "Cost", + "text": "Use scale down mode to delete/delallocate nodes", + "waf": "Cost" }, { - "category": "Operations", + "category": "Cost Governance", "checklist": "Azure AKS Review", - "guid": "0102ce16-ee30-41e6-b882-e52e4621dd68", - "id": "07.02.07", - "link": "https://learn.microsoft.com/azure/architecture/example-scenario/bedrock/bedrock-automated-deployments", + "cost": 1, + "guid": "87e651ea-bc4a-4a87-a6df-c06a4b570ebc", + "id": "03.01.03", + "link": "https://learn.microsoft.com/azure/aks/gpu-multi-instance", "services": [ + "Cost", "AKS" ], - "severity": "Low", - "subcategory": "Compliance", - "text": "Consider gitops to deploy applications or cluster configuration to multiple clusters", - "waf": "Operations" + "severity": "Medium", + "subcategory": "Cost", + "text": "When required use multi-instance partioning GPU on AKS Clusters", + "waf": "Cost" }, { - "category": "Operations", + "category": "Cost Governance", "checklist": "Azure AKS Review", - "guid": "d7672c26-7602-4482-85a4-14527fbe855c", - "id": "07.02.08", - "link": "https://learn.microsoft.com/azure/aks/command-invoke", + "cost": 1, + "guid": "2b72a08b-0410-4cd6-9093-e068a5cf27e8", + "id": "03.01.04", + "link": "https://learn.microsoft.com/azure/aks/start-stop-nodepools", "services": [ + "Cost", "AKS" ], "severity": "Low", - "subcategory": "Compliance", - "text": "Consider using AKS command invoke on private clusters", - "waf": "Operations" + "subcategory": "Cost", + "text": "If running a Dev/Test cluster use NodePool Start/Stop", + "waf": "Cost" }, { - "category": "Operations", + "category": "Governance and Security", "checklist": "Azure AKS Review", - "guid": "31d7aaab-7571-4449-ab80-53d89e89d17b", - "id": "07.02.09", - "link": "https://learn.microsoft.com/azure/aks/node-auto-repair#node-autodrain", + "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (isnotnull(properties.addonProfiles.azurepolicy) and properties.addonProfiles.azurepolicy.enabled==true) | distinct id,compliant", + "guid": "9ca48e4a-85e2-4223-bce8-bb12307ca5f1", + "id": "04.01.01", + "link": "https://learn.microsoft.com/azure/governance/policy/concepts/policy-for-kubernetes", "security": 1, "services": [ + "AzurePolicy", "AKS" ], - "severity": "Low", + "severity": "Medium", + "simple": -1, "subcategory": "Compliance", - "text": "For planned events consider using Node Auto Drain", - "waf": "Operations" + "text": "Use Azure Policy for Kubernetes to ensure cluster compliance", + "waf": "Security" }, { - "category": "Operations", + "category": "Governance and Security", "checklist": "Azure AKS Review", - "guid": "ed0fda7f-211b-47c7-8b6e-c18873fb473c", - "id": "07.02.10", - "link": "https://learn.microsoft.com/azure/aks/faq", + "cost": -1, + "graph": "where type=='microsoft.containerservice/managedclusters' | project id,resourceGroup,name,pools=properties.agentPoolProfiles | project id,name,resourceGroup,poolcount=array_length(pools) | extend compliant = (poolcount > 1)", + "guid": "6f158e3e-a3a9-42c2-be7e-2165c3a87af4", + "id": "04.01.02", + "link": "https://learn.microsoft.com/azure/aks/use-system-pools", "security": 1, "services": [ "AKS" ], - "severity": "High", + "severity": "Medium", + "simple": -1, "subcategory": "Compliance", - "text": "Develop own governance practices to make sure no changes are performed by operators in the node RG (aka 'infra RG')", - "waf": "Operations" + "text": "Separate applications from the control plane with user/system nodepools", + "waf": "Security" }, { - "category": "Operations", + "category": "Governance and Security", "checklist": "Azure AKS Review", - "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (properties.nodeResourceGroup !startswith 'MC_') | distinct id,compliant", - "guid": "73b32a5a-67f7-4a9e-b5b3-1f38c3f39812", - "id": "07.02.11", - "link": "https://learn.microsoft.com/azure/aks/cluster-configuration", + "guid": "a7a1f893-9bda-4477-98f2-4c116775c2ea", + "ha": 1, + "id": "04.01.03", + "link": "https://learn.microsoft.com/azure/aks/use-system-pools", "services": [ "AKS" ], "severity": "Low", - "simple": 1, + "simple": -1, "subcategory": "Compliance", - "text": "Use custom Node RG (aka 'Infra RG') name", - "waf": "Operations" + "text": "Add taint to your system nodepool to make it dedicated", + "waf": "Security" }, { - "category": "Operations", + "category": "Governance and Security", "checklist": "Azure AKS Review", - "guid": "b2463cff-e189-4c59-adf0-d5a73dd4ce32", - "ha": 1, - "id": "07.02.12", - "link": "https://kubernetes.io/docs/setup/release/notes/", + "guid": "55b46a94-8008-4ae7-b7e4-b475b6c8bdbf", + "id": "04.01.04", + "link": "https://learn.microsoft.com/azure/container-registry/", + "security": 1, "services": [ + "ACR", "AKS" ], "severity": "Medium", "simple": -1, "subcategory": "Compliance", - "text": "Do not use deprecated Kubernetes APIs in your YAML manifests", - "waf": "Operations" + "text": "Use a private registry for your images, such as ACR", + "waf": "Security" }, { - "category": "Operations", + "category": "Governance and Security", "checklist": "Azure AKS Review", - "guid": "c1881370-6f7c-44c0-b4e5-14648d2457ed", - "ha": 1, - "id": "07.02.13", - "link": "https://learn.microsoft.com/azure-stack/aks-hci/adapt-apps-mixed-os-clusters", + "cost": -1, + "guid": "59bce65d-e8a0-43f9-9879-468d66a786d6", + "id": "04.01.05", + "link": "https://learn.microsoft.com/azure/security-center/container-security", + "security": 1, "services": [ "AKS" ], - "severity": "Low", - "simple": -1, + "severity": "Medium", "subcategory": "Compliance", - "text": "Taint Windows nodes", - "waf": "Operations" + "text": "Scan your images for vulnerabilities", + "waf": "Security" }, { - "category": "Operations", + "category": "Governance and Security", "checklist": "Azure AKS Review", - "guid": "67138b82-0102-4ce1-9ee3-01e6e882e52e", - "id": "07.02.14", - "link": "https://learn.microsoft.com/virtualization/windowscontainers/deploy-containers/version-compatibility?tabs=windows-server-20H2%2Cwindows-10-20H2", + "cost": -1, + "guid": "cc639637-a652-42ac-89e8-06965388e9de", + "id": "04.01.06", + "link": "https://learn.microsoft.com/azure/security-center/container-security", + "security": 1, "services": [ + "Defender", "AKS" ], - "severity": "Low", + "severity": "Medium", "subcategory": "Compliance", - "text": "Keep windows containers patch level in sync with host patch level", - "waf": "Operations" + "text": "Use Azure Security Center to detect security posture vulnerabilities", + "waf": "Security" }, { - "category": "Operations", + "category": "Governance and Security", "checklist": "Azure AKS Review", "cost": -1, - "description": "Via Diagnostic Settings at the cluster level", - "guid": "5b56ad48-408f-4e72-934c-476ba280dcf5", - "ha": 1, - "id": "07.02.15", - "link": "https://learn.microsoft.com/azure/aks/monitor-aks", + "guid": "42d4aefe-2383-470e-b019-c30df24996b2", + "id": "04.01.07", + "link": "https://learn.microsoft.com/azure/aks/use-multiple-node-pools#add-a-fips-enabled-node-pool", + "security": 1, "services": [ - "AKS", - "Monitor" + "AKS" ], "severity": "Low", "subcategory": "Compliance", - "text": "Send master logs (aka API logs) to Azure Monitor or your preferred log management solution", - "waf": "Operations" + "text": "If required configure FIPS", + "waf": "Security" }, { - "category": "Operations", + "category": "Governance and Security", "checklist": "Azure AKS Review", - "cost": 1, - "guid": "64d1a846-e28a-4b6b-9a33-22a635c15a21", - "id": "07.02.16", - "link": "https://learn.microsoft.com/azure/aks/node-pool-snapshot", + "guid": "d167dd18-2b0a-4c24-8b99-9a646f8389a7", + "id": "04.01.08", + "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-cluster-isolation", + "security": 1, "services": [ "AKS" ], - "severity": "Low", + "severity": "High", "subcategory": "Compliance", - "text": "If required use nodePool snapshots", - "waf": "Cost" + "text": "Define app separation requirements (namespace/nodepool/cluster)", + "waf": "Security" }, { - "category": "Operations", + "category": "Governance and Security", "checklist": "Azure AKS Review", - "cost": 1, - "guid": "c5a5b252-1e44-4a59-a9d2-399c4d7b68d0", - "id": "07.03.01", - "link": "https://learn.microsoft.com/azure/aks/spot-node-pool", + "guid": "5e3df584-eccc-4d97-a3b6-bcda3b50eb2e", + "id": "04.02.01", + "link": "https://github.com/Azure/secrets-store-csi-driver-provider-azure", + "security": 1, "services": [ - "AKS", - "Cost" + "AKV", + "AKS" ], - "severity": "Low", + "severity": "Medium", "simple": -1, - "subcategory": "Cost", - "text": "Consider spot node pools for non time-sensitive workloads", - "waf": "Operations" + "subcategory": "Secrets", + "text": "Store your secrets in Azure Key Vault with the CSI Secrets Store driver", + "waf": "Security" }, { - "category": "Operations", + "category": "Governance and Security", "checklist": "Azure AKS Review", - "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (isnotnull(properties.addonProfiles.aciConnectorLinux) and properties.addonProfiles.aciConnectorLinux.enabled==true) | distinct id,compliant", - "guid": "c755562f-2b4e-4456-9b4d-874a748b662e", - "id": "07.03.02", - "link": "https://learn.microsoft.com/azure/aks/concepts-scale", - "scale": 1, + "guid": "b03dda6d-58d7-4c89-8ddb-107d5769ae66", + "id": "04.02.02", + "link": "https://learn.microsoft.com/azure/aks/update-credentials", + "security": 1, "services": [ - "AKS", - "Cost" + "AKV", + "AKS" ], - "severity": "Low", - "simple": -1, - "subcategory": "Cost", - "text": "Consider AKS virtual node for quick bursting", - "waf": "Operations" + "severity": "High", + "subcategory": "Secrets", + "text": "If using Service Principals for the cluster, refresh credentials periodically (like quarterly)", + "waf": "Security" }, { - "category": "Operations", + "category": "Governance and Security", "checklist": "Azure AKS Review", - "guid": "6f8389a7-f82c-4b8e-a8c0-aa63a25a4956", - "ha": 1, - "id": "07.04.01", - "link": "https://learn.microsoft.com/azure/azure-monitor/insights/container-insights-overview", + "cost": -1, + "guid": "e7ba73a3-0508-4f80-806f-527db30cee96", + "id": "04.02.03", + "link": "https://learn.microsoft.com/azure/aks/use-kms-etcd-encryption", + "security": 1, "services": [ - "AKS", - "Monitor" + "AKV", + "AKS" ], - "severity": "High", - "simple": -1, - "subcategory": "Monitoring", - "text": "Monitor your cluster metrics with Container Insights (or other tools like Prometheus)", - "waf": "Operations" + "severity": "Medium", + "subcategory": "Secrets", + "text": "If required add Key Management Service etcd encryption", + "waf": "Security" }, { - "category": "Operations", + "category": "Governance and Security", "checklist": "Azure AKS Review", - "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (isnotnull(properties.addonProfiles.omsagent) and properties.addonProfiles.omsagent.enabled==true) | distinct id,compliant", - "guid": "eaa8dc4a-2436-47b3-9697-15b1752beee0", - "ha": 1, - "id": "07.04.02", - "link": "https://learn.microsoft.com/azure/azure-monitor/insights/container-insights-overview", + "cost": -1, + "guid": "ec8e4e42-0344-41b0-b865-9123e8956d31", + "id": "04.02.04", + "link": "https://learn.microsoft.com/azure/confidential-computing/confidential-nodes-aks-overview", + "security": 1, "services": [ - "AKS", - "Monitor" + "AKV", + "AKS" ], - "severity": "High", - "simple": -1, - "subcategory": "Monitoring", - "text": "Store and analyze your cluster logs with Container Insights (or other tools like Telegraf/ElasticSearch)", - "waf": "Operations" + "severity": "Low", + "subcategory": "Secrets", + "text": "If required consider using Confidential Compute for AKS", + "waf": "Security" }, { - "category": "Operations", + "category": "Governance and Security", "checklist": "Azure AKS Review", - "guid": "4621dd68-c5a5-4be2-bdb1-1726769ef669", - "ha": 1, - "id": "07.04.03", - "link": "https://learn.microsoft.com/azure/azure-monitor/containers/container-insights-analyze", + "cost": -1, + "guid": "c9e95ffe-6dd1-4a17-8c5f-110389ca9b21", + "id": "04.02.05", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-enable", + "security": 1, "services": [ - "AKS", - "Monitor" + "Defender", + "AKV", + "AKS" ], "severity": "Medium", - "simple": -1, - "subcategory": "Monitoring", - "text": "Monitor CPU and memory utilization of the nodes", - "waf": "Operations" + "subcategory": "Secrets", + "text": "Consider using Defender for Containers", + "waf": "Security" }, { - "category": "Operations", + "category": "Identity and Access Management", "checklist": "Azure AKS Review", - "guid": "1a4835ac-9422-423e-ae80-b123081a5417", - "ha": 1, - "id": "07.04.04", - "link": "https://learn.microsoft.com/azure/aks/configure-azure-cni", + "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (properties.servicePrincipalProfile.clientId=='msi') | distinct id,compliant", + "guid": "ed127dd1-42b0-46b2-8c69-99a646f3389a", + "id": "05.01.01", + "link": "https://learn.microsoft.com/azure/aks/use-managed-identity", "services": [ - "AKS", - "Monitor" + "Entra", + "AKS" ], - "severity": "Medium", - "simple": -1, - "subcategory": "Monitoring", - "text": "If using Azure CNI, monitor % of pod IPs consumed per node", - "waf": "Operations" + "severity": "High", + "simple": 1, + "subcategory": "Identity", + "text": "Use managed identities instead of Service Principals", + "waf": "Security" }, { - "category": "Operations", + "category": "Identity and Access Management", "checklist": "Azure AKS Review", - "description": "I/O in the OS disk is a critical resource. If the OS in the nodes gets throttled on I/O, this could lead to unpredictable behavior, typically ending up in node being declared NotReady", - "guid": "415833ea-3ad3-4c2d-b733-165c3acbe04b", - "ha": 1, - "id": "07.04.05", - "link": "https://learn.microsoft.com/azure/virtual-machines/premium-storage-performance", + "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = isnotnull(properties.aadProfile) | distinct id,compliant", + "guid": "7e42c78e-78c0-46a6-8a21-94956e698dc4", + "id": "05.01.02", + "link": "https://learn.microsoft.com/azure/aks/managed-aad", "services": [ - "EventHubs", - "AKS", - "Monitor", - "ServiceBus", - "Storage" + "Entra", + "AKS" ], "severity": "Medium", - "simple": -1, - "subcategory": "Monitoring", - "text": "Monitor OS disk queue depth in nodes", - "waf": "Operations" + "simple": 1, + "subcategory": "Identity", + "text": "Integrate authentication with AAD (using the managed integration)", + "waf": "Security" }, { - "category": "Operations", + "category": "Identity and Access Management", "checklist": "Azure AKS Review", - "guid": "be209d39-fda4-4777-a424-d116785c2fa5", - "ha": 1, - "id": "07.04.06", - "link": "https://learn.microsoft.com/azure/aks/load-balancer-standard", + "guid": "a2fe27b2-e287-401a-8352-beedf79b488d", + "id": "05.01.03", + "link": "https://learn.microsoft.com/azure/aks/control-kubeconfig-access", + "security": 1, "services": [ - "AKS", - "LoadBalancer", - "NVA", - "Monitor" + "Entra", + "AKS" ], "severity": "Medium", "simple": -1, - "subcategory": "Monitoring", - "text": "If not using egress filtering with AzFW/NVA, monitor standard ALB allocated SNAT ports", - "waf": "Operations" + "subcategory": "Identity", + "text": "Limit access to admin kubeconfig (get-credentials --admin)", + "waf": "Security" }, { - "category": "Operations", + "category": "Identity and Access Management", "checklist": "Azure AKS Review", - "guid": "74c2ee76-569b-4a79-a57e-dedf91b022c9", - "ha": 1, - "id": "07.04.07", - "link": "https://learn.microsoft.com/azure/aks/aks-resource-health", + "guid": "eec4962c-c3bd-421b-b77f-26e5e6b3bec3", + "id": "05.01.04", + "link": "https://learn.microsoft.com/azure/aks/manage-azure-rbac", + "security": 1, "services": [ - "AKS", - "Monitor" + "RBAC", + "Entra", + "AKS" ], "severity": "Medium", - "subcategory": "Monitoring", - "text": "Subscribe to resource health notifications for your AKS cluster", - "waf": "Operations" + "simple": -1, + "subcategory": "Identity", + "text": "Integrate authorization with AAD RBAC", + "waf": "Security" }, { - "category": "Operations", + "category": "Identity and Access Management", "checklist": "Azure AKS Review", - "guid": "b54eb2eb-03dd-4aa3-9927-18e2edb11726", + "guid": "d4f3537c-1346-4dc5-9027-a71ffe1bd05d", "ha": 1, - "id": "07.05.01", - "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-scheduler", + "id": "05.01.05", + "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-identity", + "security": 1, "services": [ + "RBAC", + "Entra", "AKS" ], "severity": "High", "simple": -1, - "subcategory": "Resources", - "text": "Configure requests and limits in your pod specs", - "waf": "Operations" + "subcategory": "Identity", + "text": "Use namespaces for restricting RBAC privilege in Kubernetes", + "waf": "Security" }, { - "category": "Operations", + "category": "Identity and Access Management", "checklist": "Azure AKS Review", - "guid": "769ef669-1a48-435a-a942-223ece80b123", - "ha": 1, - "id": "07.05.02", - "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-scheduler", + "guid": "d2e0d5d7-71d4-41e3-910c-c57b4a4b1410", + "id": "05.01.06", + "link": "https://learn.microsoft.com/azure/aks/workload-identity-migration-sidecar", + "security": 1, "services": [ + "Entra", "AKS" ], "severity": "Medium", "simple": -1, - "subcategory": "Resources", - "text": "Enforce resource quotas for namespaces", - "waf": "Operations" + "subcategory": "Identity", + "text": "For POD Identity Access Management use Azure AD Workload Identity (preview)", + "waf": "Security" }, { - "category": "Operations", + "category": "Identity and Access Management", "checklist": "Azure AKS Review", - "cost": 1, - "guid": "081a5417-4158-433e-a3ad-3c2de733165c", - "id": "07.05.03", - "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits", + "guid": "f4dcf690-1b30-407d-abab-6f8aa780d3a3", + "id": "05.01.07", + "link": "https://learn.microsoft.com/azure/aks/managed-aad#non-interactive-sign-in-with-kubelogin", + "security": 1, "services": [ - "AKS", - "Subscriptions" + "Entra", + "AKS" ], - "severity": "High", - "subcategory": "Resources", - "text": "Ensure your subscription has enough quota to scale out your nodepools", - "waf": "Operations" + "severity": "Medium", + "simple": -1, + "subcategory": "Identity", + "text": "For AKS non-interactive logins use kubelogin (preview)", + "waf": "Security" }, { - "category": "Operations", + "category": "Identity and Access Management", "checklist": "Azure AKS Review", - "cost": -1, - "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (isnotnull(properties.autoScalerProfile)) | distinct id,compliant", - "guid": "90ce65de-8e13-4f9c-abd4-69266abca264", - "ha": 1, - "id": "07.06.01", - "link": "https://learn.microsoft.com/azure/aks/concepts-scale", + "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (properties.disableLocalAccounts==true) | distinct id,compliant", + "guid": "b085b1f2-3119-4771-8c9a-bbf4411810ec", + "id": "05.01.08", + "link": "https://learn.microsoft.com/azure/aks/managed-aad#disable-local-accounts", + "security": 1, "services": [ + "Entra", "AKS" ], - "severity": "Medium", - "subcategory": "Scalability", - "text": "Use the Cluster Autoscaler", - "waf": "Performance" + "severity": "Medium", + "simple": -1, + "subcategory": "Identity", + "text": "Disable AKS local accounts", + "waf": "Security" }, { - "category": "Operations", + "category": "Identity and Access Management", "checklist": "Azure AKS Review", - "cost": -1, - "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (isnotnull(properties.austoscalerProfile)) | distinct id,compliant", - "guid": "831c2872-c693-4b39-a887-a561bada49bc", - "ha": 1, - "id": "07.06.02", - "link": "https://learn.microsoft.com/azure/aks/custom-node-configuration", + "guid": "36abb0db-c118-4f4c-9880-3f30f9a2deb6", + "id": "05.01.09", + "link": "https://learn.microsoft.com/azure/aks/managed-aad#configure-just-in-time-cluster-access-with-azure-ad-and-aks", + "security": 1, "services": [ + "Entra", "AKS" ], "severity": "Low", - "subcategory": "Scalability", - "text": "Customize node configuration for AKS node pools", - "waf": "Performance" + "simple": -1, + "subcategory": "Identity", + "text": "Configure if required Just-in-time cluster access", + "waf": "Security" }, { - "category": "Operations", + "category": "Identity and Access Management", "checklist": "Azure AKS Review", - "guid": "faa19bfe-9d55-4d04-a3c4-919ca1b2d121", - "id": "07.06.03", - "link": "https://learn.microsoft.com/azure/aks/concepts-scale", - "scale": 1, + "guid": "c4d7f4c6-79bf-45d0-aa05-ce8fc717e150", + "id": "05.01.10", + "link": "https://learn.microsoft.com/azure/aks/managed-aad#use-conditional-access-with-azure-ad-and-aks", + "security": 1, "services": [ + "Entra", "AKS" ], - "severity": "Medium", + "severity": "Low", "simple": -1, - "subcategory": "Scalability", - "text": "Use the Horizontal Pod Autoscaler when required", - "waf": "Performance" + "subcategory": "Identity", + "text": "Configure if required AAD conditional access for AKS", + "waf": "Security" }, { - "category": "Operations", + "category": "Identity and Access Management", "checklist": "Azure AKS Review", - "cost": 1, - "description": "Larger nodes will bring higher performance and features such as ephemeral disks and accelerated networking, but they will increase the blast radius and decrease the scaling granularity", - "guid": "5ae124ba-34df-4585-bcdc-e9bd3bb0cdb3", - "id": "07.06.04", - "link": "https://blog.cloudtrooper.net/2020/10/23/which-vm-size-should-i-choose-as-aks-node/", + "guid": "e1123a7c-a333-4eb4-a120-4ee3f293c9f3", + "id": "05.01.11", + "link": "https://learn.microsoft.com/azure/aks/use-group-managed-service-accounts", + "security": 1, "services": [ + "Entra", "AKS" ], - "severity": "High", - "subcategory": "Scalability", - "text": "Consider an appropriate node size, not too large or too small", - "waf": "Performance" + "severity": "Low", + "simple": -1, + "subcategory": "Identity", + "text": "If required for Windows AKS workloads configure gMSA ", + "waf": "Security" }, { - "category": "Operations", + "category": "Identity and Access Management", "checklist": "Azure AKS Review", - "cost": 1, - "guid": "38800e6a-ae01-40a2-9fbc-ae5a06e5462d", - "id": "07.06.05", - "link": "https://learn.microsoft.com/azure/aks/quotas-skus-regions#service-quotas-and-limits", + "guid": "1f711a74-3672-470b-b8b8-a2148d640d79", + "id": "05.01.12", + "link": "https://learn.microsoft.com/azure/aks/use-managed-identity#use-a-pre-created-kubelet-managed-identity", + "security": 1, "services": [ + "Entra", "AKS" ], - "severity": "Low", - "subcategory": "Scalability", - "text": "If more than 5000 nodes are required for scalability then consider using an additional AKS cluster", - "waf": "Performance" + "severity": "Medium", + "simple": -1, + "subcategory": "Identity", + "text": "For finer control consider using a managed Kubelet Identity", + "waf": "Security" }, { - "category": "Operations", + "category": "Network Topology and Connectivity", "checklist": "Azure AKS Review", - "cost": 1, - "guid": "9583c0f6-6083-43f6-aa6b-df7102c901bb", - "id": "07.06.06", - "link": "https://learn.microsoft.com/azure/event-grid/event-schema-aks", + "guid": "cbd8ac2a-aebc-4a2a-94da-1dbf3dc99248", + "id": "06.01.01", + "link": "https://azure.github.io/application-gateway-kubernetes-ingress/setup/install-existing/", + "security": 1, "services": [ + "ACR", + "AppGW", "AKS" ], - "severity": "Low", - "subcategory": "Scalability", - "text": "Consider subscribing to EventGrid Events for AKS automation", - "waf": "Performance" + "severity": "Medium", + "simple": -1, + "subcategory": "Best practices", + "text": "If using AGIC, do not share an AppGW across clusters", + "waf": "Reliability" }, { - "category": "Operations", + "category": "Network Topology and Connectivity", "checklist": "Azure AKS Review", - "cost": 1, - "guid": "c5016d8c-c6c9-4165-89ae-673ef0fff19d", - "id": "07.06.07", - "link": "https://learn.microsoft.com/azure/aks/manage-abort-operations", + "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (isnull(properties.addonProfiles.httpApplicationRouting) or properties.addonProfiles.httpApplicationRouting.enabled==false) | distinct id,compliant", + "guid": "8008ae7d-7e4b-4475-a6c8-bdbf59bce65d", + "id": "06.01.02", + "link": "https://learn.microsoft.com/azure/aks/http-application-routing", + "scale": 1, "services": [ "AKS" ], - "severity": "Low", - "subcategory": "Scalability", - "text": "For long running operation on an AKS cluster consider event termination", - "waf": "Performance" + "severity": "High", + "simple": -1, + "subcategory": "Best practices", + "text": "Do not use AKS Application Routing Add-On", + "waf": "Reliability" }, { - "category": "Operations", + "category": "Network Topology and Connectivity", "checklist": "Azure AKS Review", - "cost": 1, - "guid": "c4e37133-f186-4ce1-aed9-9f1b32f6e021", - "id": "07.06.08", - "link": "https://learn.microsoft.com/azure/aks/use-azure-dedicated-hosts", + "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (isnull(properties.addonProfiles.httpApplicationRouting) or properties.addonProfiles.httpApplicationRouting.enabled==false) | distinct id,compliant", + "guid": "7bacd7b9-c025-4a9d-a5d2-25d6bc5439d9", + "id": "06.01.03", + "link": "https://learn.microsoft.com/azure/virtual-network/accelerated-networking-overview", + "scale": 1, "services": [ "AKS" ], - "severity": "Low", - "subcategory": "Scalability", - "text": "If required consider using Azure Dedicated Hosts for AKS nodes", + "severity": "Medium", + "simple": -1, + "subcategory": "Best practices", + "text": "For Windows workloads use Accelerated Networking", "waf": "Performance" }, { - "category": "Operations", + "category": "Network Topology and Connectivity", "checklist": "Azure AKS Review", - "cost": -1, - "graph": "where type=='microsoft.containerservice/managedclusters' | project id,resourceGroup,name,pools=properties.agentPoolProfiles | mvexpand pools | extend compliant = (pools.osDiskType=='Ephemeral') | project id,name=strcat(name,'-',pools.name), resourceGroup, compliant", - "guid": "24367b33-6971-45b1-952b-eee0b9b588de", - "id": "07.07.01", - "link": "https://learn.microsoft.com/azure/aks/cluster-configuration", + "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (tolower(properties.networkProfile.loadBalancerSku)=='standard') | distinct id,compliant", + "guid": "ba7da7be-9952-4914-a384-5d997cb39132", + "id": "06.01.04", + "link": "https://learn.microsoft.com/azure/aks/load-balancer-standard", "scale": 1, "services": [ - "Storage", + "LoadBalancer", "AKS" ], "severity": "High", - "subcategory": "Storage", - "text": "Use ephemeral OS disks", - "waf": "Performance" + "subcategory": "Best practices", + "text": "Use the standard ALB (as opposed to the basic one)", + "waf": "Reliability" }, { - "category": "Operations", + "category": "Network Topology and Connectivity", "checklist": "Azure AKS Review", - "cost": -1, - "guid": "fc4972cc-3cd2-45bf-a707-6e9eab4bed32", - "id": "07.07.02", - "link": "https://learn.microsoft.com/azure/virtual-machines/disks-types", - "scale": 1, + "guid": "22fbe8d6-9b40-47ef-9011-25bb1a555a6b", + "id": "06.01.05", + "link": "https://learn.microsoft.com/azure/aks/use-multiple-node-pools#add-a-node-pool-with-a-unique-subnet", + "security": 1, "services": [ - "Storage", + "VNet", "AKS" ], - "severity": "High", - "subcategory": "Storage", - "text": "For non-ephemeral disks, use high IOPS and larger OS disks for the nodes when running many pods/node since it requires high performance for running multiple pods and will generate huge logs with default AKS log rotation thresholds", - "waf": "Performance" + "severity": "Medium", + "simple": -2, + "subcategory": "Best practices", + "text": "If using Azure CNI, consider using different Subnets for NodePools", + "waf": "Security" }, { - "category": "Operations", + "category": "Network Topology and Connectivity", "checklist": "Azure AKS Review", - "cost": -1, - "guid": "39c486ce-d5af-4062-89d5-18bb5fd795db", - "id": "07.07.03", - "link": "https://learn.microsoft.com/azure/aks/use-ultra-disks", - "scale": 1, + "guid": "c3c39c98-6bb2-4c12-859a-114b5e3df584", + "id": "06.02.01", + "link": "https://learn.microsoft.com/azure/private-link/private-link-overview", + "security": 1, "services": [ - "Storage", + "Cost", + "VNet", + "PrivateLink", "AKS" ], - "severity": "Low", - "subcategory": "Storage", - "text": "For hyper performance storage option use Ultra Disks on AKS", - "waf": "Performance" + "severity": "Medium", + "simple": -1, + "subcategory": "Cost", + "text": "Use Private Endpoints (preferred) or Virtual Network Service Endpoints to access PaaS services from the cluster", + "waf": "Security" }, { - "category": "Operations", + "category": "Network Topology and Connectivity", "checklist": "Azure AKS Review", - "guid": "9f7547c1-747d-4c56-868a-714435bd19dd", + "cost": -1, + "guid": "e8a03f97-8794-468d-96a7-86d60f96c97b", "ha": 1, - "id": "07.07.04", - "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-multi-region", + "id": "06.03.01", + "link": "https://learn.microsoft.com/azure/expressroute/designing-for-disaster-recovery-with-expressroute-privatepeering", "services": [ - "Storage", - "AKS", - "SQL" + "VPN", + "AKS" ], "severity": "Medium", - "simple": -1, - "subcategory": "Storage", - "text": "Avoid keeping state in the cluster, and store data outside (AzStorage, AzSQL, Cosmos, etc)", - "waf": "Performance" + "subcategory": "HA", + "text": "If hybrid connectivity is required, use 2xER or ER+VPN for better availability", + "waf": "Reliability" }, { - "category": "Operations", + "category": "Network Topology and Connectivity", "checklist": "Azure AKS Review", - "cost": -1, - "guid": "24429eb7-2281-4376-85cc-57b4a4b18142", - "id": "07.07.05", - "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-storage", + "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (properties.networkProfile.networkPlugin=='azure') | distinct id,compliant", + "guid": "a0f61565-9de5-458f-a372-49c831112dbd", + "id": "06.04.01", + "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-network", + "services": [ + "AKS" + ], + "severity": "High", + "simple": 1, + "subcategory": "IPAM", + "text": "Choose the best CNI network plugin for your requirements (Azure CNI recommended)", + "waf": "Reliability" + }, + { + "category": "Network Topology and Connectivity", + "checklist": "Azure AKS Review", + "guid": "7faf12e7-0943-4f63-8472-2da29c2b1cd6", + "id": "06.04.02", + "link": "https://learn.microsoft.com/azure/aks/configure-azure-cni", "scale": 1, "services": [ - "Storage", + "VNet", "AKS" ], - "severity": "Medium", - "subcategory": "Storage", - "text": "If using AzFiles Standard, consider AzFiles Premium and/or ANF for performance reasons", + "severity": "High", + "subcategory": "IPAM", + "text": "If using Azure CNI, size your subnet accordingly considering the maximum number of pods per node", "waf": "Performance" }, { - "category": "Operations", + "category": "Network Topology and Connectivity", "checklist": "Azure AKS Review", - "guid": "83958a8c-2689-4b32-ab57-cfc64546135a", - "ha": 1, - "id": "07.07.06", - "link": "https://learn.microsoft.com/azure/aks/availability-zones#azure-disk-availability-zone-support", + "guid": "22f54b29-bade-43aa-b1e8-c38ec9366673", + "id": "06.04.03", + "link": "https://learn.microsoft.com/azure/aks/configure-azure-cni", + "scale": 1, "services": [ - "Storage", "AKS" ], - "severity": "Medium", + "severity": "High", "simple": -1, - "subcategory": "Storage", - "text": "If using Azure Disks and AZs, consider having nodepools within a zone for LRS disk with VolumeBindingMode:WaitForFirstConsumer for provisioning storage in right zone or use ZRS disk for nodepools spanning multiple zones", + "subcategory": "IPAM", + "text": "If using Azure CNI, check the maximum pods/node (default 30)", "waf": "Performance" }, { - "category": "Security", - "checklist": "Azure Blob Storage Review", - "description": "Apply guidance from the Microsoft cloud security benchmark related to Storage", - "guid": "d237de14-3b16-4c21-b7aa-9b64604489a8", - "id": "A01.01", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/storage-security-baseline", + "category": "Network Topology and Connectivity", + "checklist": "Azure AKS Review", + "description": "For internal apps organizations often open the whole AKS subnet in their firewalls. This opens network access to the nodes too, and potentially to the pods as well (if using Azure CNI). If LoadBalancer IPs are in a different subnet, only this one needs to be available to the app clients. Another reason is that if the IP addresses in the AKS subnet are a scarce resource, consuming its IP addresses for services will reduce the maximum scalability of the cluster .", + "guid": "13c00567-4b1e-4945-a459-c373e7ed6162", + "id": "06.04.04", + "link": "https://learn.microsoft.com/azure/aks/internal-lb", + "security": 1, "services": [ - "Storage" + "VNet", + "AKS" ], - "severity": "Medium", - "subcategory": " Overview", - "text": "Consider the 'Azure security baseline for storage'", + "severity": "Low", + "simple": -1, + "subcategory": "IPAM", + "text": "If using private-IP LoadBalancer services, use a dedicated subnet (not the AKS subnet)", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure Blob Storage Review", - "description": "Azure Storage by default has a public IP address and is Internet-reachable. Private endpoints allow to securely expose Azure Storage only to those Azure Compute resources that need access, thus eliminating exposure to the public Internet", - "guid": "f42d78e7-9d17-4a73-a22a-5a67e7a8ed4b", - "id": "A02.01", - "link": "https://learn.microsoft.com/azure/storage/common/storage-private-endpoints", + "category": "Network Topology and Connectivity", + "checklist": "Azure AKS Review", + "guid": "43f63047-22d9-429c-8b1c-d622f54b29ba", + "id": "06.04.05", + "link": "https://learn.microsoft.com/azure/aks/configure-azure-cni", + "scale": 1, "services": [ - "Storage", - "PrivateLink" + "AKS" ], "severity": "High", - "subcategory": "Networking", - "text": "Consider using private endpoints for Azure Storage", - "waf": "Security" + "subcategory": "IPAM", + "text": "Size the service IP address range accordingly (it is going to limit the cluster scalability)", + "waf": "Reliability" }, { - "category": "Security", - "checklist": "Azure Blob Storage Review", - "description": "Newly created storage accounts are created using the ARM deployment model, so that RBAC, auditing etc. are all enabled. Ensure that there are no old storage accounts with classic deployment model in a subscription", - "guid": "30e37c3e-2971-41b2-963c-eee079b598de", - "id": "A03.01", - "link": "https://learn.microsoft.com/azure/virtual-machines/migration-classic-resource-manager-overview#migration-of-storage-accounts", + "category": "Network Topology and Connectivity", + "checklist": "Azure AKS Review", + "guid": "57bf217f-6dc8-481c-81e2-785773e9c00f", + "id": "06.05.01", + "link": "https://learn.microsoft.com/azure/aks/use-byo-cni", + "security": 1, "services": [ - "Storage", - "RBAC", - "Subscriptions" + "AKS" ], - "severity": "Medium", - "subcategory": "Governance", - "text": "Ensure older storage accounts are not using 'classic deployment model'", + "severity": "Low", + "simple": -2, + "subcategory": "Operations", + "text": "If required add your own CNI plugin", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure Blob Storage Review", - "description": "Leverage Microsoft Defender to learn about suspicious activity and misconfigurations.", - "guid": "fc5972cd-4cd2-41b0-a803-7f5e6b4bfd3d", - "id": "A03.02", - "link": "https://learn.microsoft.com/azure/storage/common/azure-defender-storage-configure", + "category": "Network Topology and Connectivity", + "checklist": "Azure AKS Review", + "guid": "4b3bb365-9458-44d9-9ed1-5c8f52890364", + "id": "06.05.02", + "link": "https://learn.microsoft.com/azure/aks/use-multiple-node-pools#assign-a-public-ip-per-node-for-your-node-pools", + "security": 1, "services": [ - "Storage", - "Defender" + "AKS" ], - "severity": "High", - "subcategory": "Governance", - "text": "Enable Microsoft Defender for all of your storage accounts", - "waf": "Security" + "severity": "Low", + "simple": -2, + "subcategory": "Operations", + "text": "If required configure Public IP per node in AKS", + "waf": "Performance" }, { - "category": "Security", - "checklist": "Azure Blob Storage Review", - "description": "The soft-delete mechanism allows to recover accidentally deleted blobs.", - "guid": "503547c1-447e-4c66-828a-7100f1ce16dd", - "id": "A04.01", - "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-blob-overview", + "category": "Network Topology and Connectivity", + "checklist": "Azure AKS Review", + "guid": "b3808b9f-a1cf-4204-ad01-3a923ce474db", + "id": "06.06.01", + "link": "https://learn.microsoft.com/azure/aks/concepts-network", + "scale": 1, "services": [ - "Storage" + "AKS" ], "severity": "Medium", - "subcategory": "Data Availability", - "text": "Enable 'soft delete' for blobs", - "waf": "Security" + "simple": -1, + "subcategory": "Scalability", + "text": "Use an ingress controller to expose web-based apps instead of exposing them with LoadBalancer-type services", + "waf": "Reliability" }, { - "category": "Security", - "checklist": "Azure Blob Storage Review", - "description": "Consider selectively disabling 'soft delete' for certain blob containers, for example if the application must ensure that deleted information is immediately deleted, e.g. for confidentiality, privacy or compliance reasons. ", - "guid": "3f1d5e87-2e52-4e36-81cc-58b4a4b1510e", - "id": "A05.01", - "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-blob-enable", + "category": "Network Topology and Connectivity", + "checklist": "Azure AKS Review", + "guid": "ccb534e7-416e-4a1d-8e93-533b53199085", + "id": "06.06.02", + "link": "https://learn.microsoft.com/azure/aks/nat-gateway", + "scale": 1, "services": [ - "Storage" + "AKS" + ], + "severity": "Low", + "simple": -1, + "subcategory": "Scalability", + "text": "Use Azure NAT Gateway as outboundType for scaling egress traffic", + "waf": "Reliability" + }, + { + "category": "Network Topology and Connectivity", + "checklist": "Azure AKS Review", + "guid": "8ee9a69a-1b58-4b1e-9c61-476e110a160b", + "id": "06.06.03", + "link": "https://learn.microsoft.com/azure/aks/configure-azure-cni#dynamic-allocation-of-ips-and-enhanced-subnet-support", + "scale": 1, + "services": [ + "AKS" ], "severity": "Medium", - "subcategory": "Confidentiality", - "text": "Disable 'soft delete' for blobs", - "waf": "Security" + "simple": -1, + "subcategory": "Scalability", + "text": "Use Dynamic allocations of IPs in order to avoid Azure CNI IP exhaustion", + "waf": "Reliability" }, { - "category": "Security", - "checklist": "Azure Blob Storage Review", - "description": "Soft delete for containers enables you to recover a container after it has been deleted, for example recover from an accidental delete operation.", - "guid": "43a58a9c-2289-4c3d-9b57-d0c655462f2a", - "id": "A06.01", - "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-container-overview", + "category": "Network Topology and Connectivity", + "checklist": "Azure AKS Review", + "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (properties.networkProfile.outboundType=='userDefinedRouting') | distinct id,compliant", + "guid": "3b365a91-7ecb-4e48-bbe5-4cd7df2e8bba", + "id": "06.07.01", + "link": "https://learn.microsoft.com/azure/aks/limit-egress-traffic", + "security": 2, "services": [ - "Storage" + "NVA", + "AKS" ], "severity": "High", - "subcategory": "Data Availability", - "text": "Enable 'soft delete' for containers", + "simple": -2, + "subcategory": "Security", + "text": "Filter egress traffic with AzFW/NVA if your security requirements mandate it", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure Blob Storage Review", - "description": "Consider selectively disabling 'soft delete' for certain blob containers, for example if the application must ensure that deleted information is immediately deleted, e.g. for confidentiality, privacy or compliance reasons. ", - "guid": "3e3453a3-c863-4964-ab65-2d6c15f51296", - "id": "A07.01", - "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-container-enable", + "category": "Network Topology and Connectivity", + "checklist": "Azure AKS Review", + "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = ((isnull(properties.apiServerAccessProfile.enablePrivateCluster) or properties.apiServerAccessProfile.enablePrivateCluster==false) and isnotnull(properties.apiServerAccessProfile.authorizedIPRanges)) | distinct id,compliant", + "guid": "c4581559-bb91-463e-a908-aed8c44ce3b2", + "id": "06.07.02", + "link": "https://learn.microsoft.com/azure/aks/api-server-authorized-ip-ranges", + "security": 1, "services": [ - "Storage" + "AKS" ], "severity": "Medium", - "subcategory": "Confidentiality", - "text": "Disable 'soft delete' for containers", + "simple": -1, + "subcategory": "Security", + "text": "If using a public API endpoint, restrict the IP addresses that can access it", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure Blob Storage Review", - "description": "Prevents accidental deletion of a storage account, by forcing the user to first remove the deletion lock, prior to deletion", - "guid": "5398e6de-d227-4dd1-92b0-6c21d7999a64", - "id": "A08.01", - "link": "https://learn.microsoft.com/azure/storage/common/lock-account-resource", + "category": "Network Topology and Connectivity", + "checklist": "Azure AKS Review", + "graph": "where type=='microsoft.containerservice/managedclusters' | where isnotnull(properties.apiServerAccessProfile.enablePrivateCluster) | extend compliant = (properties.apiServerAccessProfile.enablePrivateCluster==true) | distinct id, compliant", + "guid": "ecccd979-3b6b-4cda-9b50-eb2eb03dda6d", + "id": "06.07.03", + "link": "https://learn.microsoft.com/azure/aks/private-clusters", + "security": 1, "services": [ - "Storage" + "AKS" ], "severity": "High", - "subcategory": "Data Availability", - "text": "Enable resource locks on storage accounts", + "simple": -1, + "subcategory": "Security", + "text": "Use private clusters if your requirements mandate it", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure Blob Storage Review", - "description": "Consider 'legal hold' or 'time-based retention' policies for blobs, so that is is impossible to delete the blob, the container, or the storage account. Please note that 'impossible' actually means 'impossible'; once a storage account contains an immutable blob, the only way to 'get rid' of that storage account is by cancelling the Azure subscription.", - "guid": "6f4389a8-f42c-478e-98c0-6a73a22a4956", - "id": "A09.01", - "link": "https://learn.microsoft.com/azure/storage/blobs/immutable-storage-overview", + "category": "Network Topology and Connectivity", + "checklist": "Azure AKS Review", + "graph": "where type=='microsoft.containerservice/managedclusters' | where isnotnull(properties.apiServerAccessProfile.enablePrivateCluster) | extend compliant = (properties.apiServerAccessProfile.enablePrivateCluster==true) | distinct id, compliant", + "guid": "ce7f2a7c-297c-47c6-adea-a6ff838db665", + "id": "06.07.04", + "link": "https://learn.microsoft.com/azure/aks/use-network-policies", + "security": 1, + "services": [ + "AzurePolicy", + "AKS" + ], + "severity": "Medium", + "simple": -1, + "subcategory": "Security", + "text": "For Windows 2019 and 2022 AKS nodes Calico Network Policies can be used ", + "waf": "Security" + }, + { + "category": "Network Topology and Connectivity", + "checklist": "Azure AKS Review", + "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = isnotnull(properties.networkProfile.networkPolicy) | distinct id,compliant", + "guid": "58d7c892-ddb1-407d-9769-ae669ca48e4a", + "id": "06.07.05", + "link": "https://learn.microsoft.com/azure/aks/use-network-policies", + "security": 1, "services": [ "AzurePolicy", - "Storage", - "Subscriptions" + "AKS" ], "severity": "High", - "subcategory": "Data Availability, Compliance", - "text": "Consider immutable blobs", + "subcategory": "Security", + "text": "Enable a Kubernetes Network Policy option (Calico/Azure)", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure Blob Storage Review", - "description": "Consider disabling unprotected HTTP/80 access to the storage account, so that all data transfers are encrypted, integrity protected, and the server is authenticated. ", - "guid": "e7a8dc4a-20e2-47c3-b297-11b1352beee0", - "id": "A10.01", - "link": "https://learn.microsoft.com/azure/storage/common/storage-require-secure-transfer", + "category": "Network Topology and Connectivity", + "checklist": "Azure AKS Review", + "guid": "85e2223e-ce8b-4b12-907c-a5f16f158e3e", + "id": "06.07.06", + "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-network", + "security": 1, "services": [ - "Storage" + "AzurePolicy", + "AKS" ], "severity": "High", - "subcategory": "Networking", - "text": "Require HTTPS, i.e. disable port 80 on the storage account", + "simple": -1, + "subcategory": "Security", + "text": "Use Kubernetes network policies to increase intra-cluster security", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure Blob Storage Review", - "description": "When configuring a custom domain (hostname) on a storage account, check whether you need TLS/HTTPS; if so, you might have to put Azure CDN in front of your storage account.", - "guid": "79b588de-fc49-472c-b3cd-21bf77036e5e", - "id": "A10.02", - "link": "https://learn.microsoft.com/azure/storage/blobs/storage-custom-domain-name", + "category": "Network Topology and Connectivity", + "checklist": "Azure AKS Review", + "cost": -1, + "guid": "a3a92c2d-e7e2-4165-a3a8-7af4a7a1f893", + "id": "06.07.07", + "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-network", + "security": 2, "services": [ - "Storage" + "WAF", + "AKS" ], "severity": "High", - "subcategory": "Networking", - "text": "When enforcing HTTPS (disabling HTTP), check that you do not use custom domains (CNAME) for the storage account.", + "simple": -1, + "subcategory": "Security", + "text": "Use a WAF for web workloads (UIs or APIs)", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure Blob Storage Review", - "description": "Requiring HTTPS when a client uses a SAS token to access blob data helps to minimize the risk of credential loss.", - "guid": "6b4bed3d-5035-447c-8347-dc56028a71ff", - "id": "A10.03", - "link": "https://learn.microsoft.com/azure/storage/common/storage-sas-overview", + "category": "Network Topology and Connectivity", + "checklist": "Azure AKS Review", + "cost": -2, + "graph": "Resources | where type=~'microsoft.containerservice/managedclusters' | project resourceGroup,name,pools=properties.agentPoolProfiles | mv-expand pools | project subnetId=tostring(pools.vnetSubnetID) | where isnotempty(subnetId) | join (Resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,enableDdosProtection=tostring(properties.enableDdosProtection),subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,enableDdosProtection,subnetId=tostring(subnets.id)) on subnetId | distinct id,resourceGroup,name,enableDdosProtection | extend compliant = (enableDdosProtection == 'true')", + "guid": "9bda4776-8f24-4c11-9775-c2ea55b46a94", + "id": "06.07.08", + "link": "https://learn.microsoft.com/azure/virtual-network/ddos-protection-overview", + "security": 2, "services": [ - "Storage" + "VNet", + "DDoS", + "AKS" ], "severity": "Medium", - "subcategory": "Networking", - "text": "Limit shared access signature (SAS) tokens to HTTPS connections only", + "subcategory": "Security", + "text": "Use DDoS Standard in the AKS Virtual Network", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure Blob Storage Review", - "description": "AAD tokens should be favored over shared access signatures, wherever possible", - "guid": "e1ce15dd-3f0d-45e7-92d4-1e3611cc57b4", - "id": "A11.01", - "link": "https://learn.microsoft.com/azure/storage/common/authorize-data-access", + "category": "Network Topology and Connectivity", + "checklist": "Azure AKS Review", + "cost": -2, + "graph": "Resources | where type=~'microsoft.containerservice/managedclusters' | project resourceGroup,name,pools=properties.agentPoolProfiles | mv-expand pools | project subnetId=tostring(pools.vnetSubnetID) | where isnotempty(subnetId) | join (Resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,enableDdosProtection=tostring(properties.enableDdosProtection),subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,enableDdosProtection,subnetId=tostring(subnets.id)) on subnetId | distinct id,resourceGroup,name,enableDdosProtection | extend compliant = (enableDdosProtection == 'true')", + "guid": "6c46b91a-1107-4485-ad66-3183e2a8c266", + "id": "06.07.09", + "link": "https://learn.microsoft.com/azure/aks/http-proxy", + "security": 2, "services": [ - "Storage", - "Entra" + "AKS" ], - "severity": "High", - "subcategory": "Identity and Access Management", - "text": "Use Azure Active Directory (Azure AD) tokens for blob access", + "severity": "Low", + "subcategory": "Security", + "text": "If required add company HTTP Proxy", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure Blob Storage Review", - "description": "When assigning a role to a user, group, or application, grant that security principal only those permissions that are necessary for them to perform their tasks. Limiting access to resources helps prevent both unintentional and malicious misuse of your data.", - "guid": "a4b1410d-4395-48a8-a228-9b3d6b57cfc6", - "id": "A11.02", + "category": "Network Topology and Connectivity", + "checklist": "Azure AKS Review", + "guid": "e9855d04-c3c3-49c9-a6bb-2c12159a114b", + "id": "06.07.10", + "link": "https://learn.microsoft.com/azure/aks/servicemesh-about", + "security": 1, "services": [ - "Storage", - "RBAC", - "Entra" + "AKS" ], "severity": "Medium", - "subcategory": "Identity and Access Management", - "text": "Least privilege in IaM permissions", + "simple": -2, + "subcategory": "Security", + "text": "Consider using a service mesh for advanced microservice communication management", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure Blob Storage Review", - "description": "A user delegation SAS is secured with Azure Active Directory (Azure AD) credentials and also by the permissions specified for the SAS. A user delegation SAS is analogous to a service SAS in terms of its scope and function, but offers security benefits over the service SAS. ", - "guid": "55461e1a-3e34-453a-9c86-39648b652d6c", - "id": "A11.03", - "link": "https://learn.microsoft.com/azure/storage/common/storage-sas-overview?toc=%2Fazure%2Fstorage%2Fblobs%2Ftoc.json#best-practices-when-using-sas", + "category": "Operations", + "checklist": "Azure AKS Review", + "guid": "67f7a9ed-5b31-4f38-a3f3-9812b2463cff", + "ha": 1, + "id": "07.01.01", + "link": "https://learn.microsoft.com/azure/azure-monitor/insights/container-insights-metric-alerts", "services": [ - "Storage", - "Entra" + "Monitor", + "AKS" ], "severity": "High", - "subcategory": "Identity and Access Management", - "text": "When using SAS, prefer 'user delegation SAS' over storage-account-key based SAS.", - "waf": "Security" + "simple": -1, + "subcategory": "Alerting", + "text": "Configure alerts on the most critical metrics (see Container Insights for recommendations)", + "waf": "Operations" }, { - "category": "Security", - "checklist": "Azure Blob Storage Review", - "description": "Storage account keys ('shared keys') have very little audit capabilities. While it can be monitored on who/when fetched a copy of the keys, once the keys are in the hands of multiple people, it is impossible to attribute usage to a specific user. Solely relying on AAD authentication makes it easier to tie storage access to a user. ", - "guid": "15f51296-5398-4e6d-bd22-7dd142b06c21", - "id": "A11.04", - "link": "https://learn.microsoft.com/rest/api/storageservices/authorize-with-shared-key", + "category": "Operations", + "checklist": "Azure AKS Review", + "guid": "337453a3-cc63-4963-9a65-22ac19e80696", + "ha": 1, + "id": "07.02.01", + "link": "https://learn.microsoft.com/azure/advisor/advisor-get-started", "services": [ - "Storage", - "Monitor", - "AKV", - "Entra" + "Entra", + "AKS" ], - "severity": "High", - "subcategory": "Identity and Access Management", - "text": "Consider disabling storage account keys, so that only AAD access (and user delegation SAS) is supported.", - "waf": "Security" + "severity": "Low", + "simple": -1, + "subcategory": "Compliance", + "text": "Check regularly Azure Advisor for recommendations on your cluster", + "waf": "Operations" }, { - "category": "Security", - "checklist": "Azure Blob Storage Review", - "description": "Use Activity Log data to identify 'when', 'who', 'what' and 'how' the security of your storage account is being viewed or changed (i.e. storage account keys, access policies, etc.).", - "guid": "d7999a64-6f43-489a-af42-c78e78c06a73", - "id": "A12.01", - "link": "https://learn.microsoft.com/azure/storage/blobs/blob-storage-monitoring-scenarios#audit-account-activity", + "category": "Operations", + "checklist": "Azure AKS Review", + "guid": "3aa70560-e7e7-4968-be3d-628af35b2ced", + "id": "07.02.03", + "link": "https://learn.microsoft.com/azure/aks/certificate-rotation", "services": [ - "AzurePolicy", - "Storage", - "Monitor", - "AKV" + "AKS" + ], + "severity": "Low", + "simple": 1, + "subcategory": "Compliance", + "text": "Enable AKS auto-certificate rotation", + "waf": "Operations" + }, + { + "category": "Operations", + "checklist": "Azure AKS Review", + "guid": "e189c599-df0d-45a7-9dd4-ce32c1881370", + "id": "07.02.04", + "link": "https://learn.microsoft.com/azure/aks/supported-kubernetes-versions", + "security": 1, + "services": [ + "AKS" ], "severity": "High", - "subcategory": "Monitoring", - "text": "Consider using Azure Monitor to audit control plane operations on the storage account", - "waf": "Security" + "simple": -1, + "subcategory": "Compliance", + "text": "Have a regular process to upgrade your kubernetes version periodically (quarterly, for example), or use the AKS autoupgrade feature", + "waf": "Operations" }, { - "category": "Security", - "checklist": "Azure Blob Storage Review", - "description": "A key expiration policy enables you to set a reminder for the rotation of the account access keys. The reminder is displayed if the specified interval has elapsed and the keys have not yet been rotated.", - "guid": "a22a4956-e7a8-4dc4-a20e-27c3e29711b1", - "id": "A13.01", - "link": "https://learn.microsoft.com/azure/storage/common/storage-account-keys-manage?tabs=azure-portal#create-a-key-expiration-policy", + "category": "Operations", + "checklist": "Azure AKS Review", + "guid": "6f7c4c0d-4e51-4464-ad24-57ed67138b82", + "id": "07.02.05", + "link": "https://learn.microsoft.com/azure/aks/node-updates-kured", "services": [ - "AzurePolicy", - "Storage", - "AKV", - "Entra" + "AKS" ], - "severity": "Medium", - "subcategory": "Identity and Access Management", - "text": "When using storage account keys, consider enabling a 'key expiration policy'", - "waf": "Security" + "severity": "High", + "simple": -1, + "subcategory": "Compliance", + "text": "Use kured for Linux node upgrades in case you are not using node-image upgrade", + "waf": "Operations" }, { - "category": "Security", - "checklist": "Azure Blob Storage Review", - "description": "A SAS expiration policy specifies a recommended interval over which the SAS is valid. SAS expiration policies apply to a service SAS or an account SAS. When a user generates service SAS or an account SAS with a validity interval that is larger than the recommended interval, they'll see a warning.", - "guid": "352beee0-79b5-488d-bfc4-972cd3cd21bf", - "id": "A13.02", - "link": "https://learn.microsoft.com/azure/storage/common/sas-expiration-policy", + "category": "Operations", + "checklist": "Azure AKS Review", + "guid": "139c9580-ade3-426a-ba09-cf157d9f6477", + "id": "07.02.06", + "link": "https://learn.microsoft.com/azure/aks/node-image-upgrade", + "security": 1, + "services": [ + "AKS" + ], + "severity": "High", + "simple": -1, + "subcategory": "Compliance", + "text": "Have a regular process to upgrade the cluster node images periodically (weekly, for example)", + "waf": "Operations" + }, + { + "category": "Operations", + "checklist": "Azure AKS Review", + "guid": "0102ce16-ee30-41e6-b882-e52e4621dd68", + "id": "07.02.07", + "link": "https://learn.microsoft.com/azure/architecture/example-scenario/bedrock/bedrock-automated-deployments", "services": [ - "AzurePolicy", - "Storage", - "Entra" + "AKS" ], - "severity": "Medium", - "subcategory": "Identity and Access Management", - "text": "Consider configuring an SAS expiration policy", - "waf": "Security" + "severity": "Low", + "subcategory": "Compliance", + "text": "Consider gitops to deploy applications or cluster configuration to multiple clusters", + "waf": "Operations" }, { - "category": "Security", - "checklist": "Azure Blob Storage Review", - "description": "Stored access policies give you the option to revoke permissions for a service SAS without having to regenerate the storage account keys. ", - "guid": "77036e5e-6b4b-4ed3-b503-547c1347dc56", - "id": "A13.03", - "link": "https://learn.microsoft.com/rest/api/storageservices/define-stored-access-policy", + "category": "Operations", + "checklist": "Azure AKS Review", + "guid": "d7672c26-7602-4482-85a4-14527fbe855c", + "id": "07.02.08", + "link": "https://learn.microsoft.com/azure/aks/command-invoke", "services": [ - "AzurePolicy", - "Storage", - "AKV", - "Entra" + "AKS" ], - "severity": "Medium", - "subcategory": "Identity and Access Management", - "text": "Consider linking SAS to a stored access policy", - "waf": "Security" + "severity": "Low", + "subcategory": "Compliance", + "text": "Consider using AKS command invoke on private clusters", + "waf": "Operations" }, { - "category": "Security", - "checklist": "Azure Blob Storage Review", - "guid": "028a71ff-e1ce-415d-b3f0-d5e772d41e36", - "id": "A14.01", - "link": "https://microsoft.github.io/code-with-engineering-playbook/continuous-integration/dev-sec-ops/secret-management/recipes/detect-secrets-ado/", + "category": "Operations", + "checklist": "Azure AKS Review", + "guid": "31d7aaab-7571-4449-ab80-53d89e89d17b", + "id": "07.02.09", + "link": "https://learn.microsoft.com/azure/aks/node-auto-repair#node-autodrain", + "security": 1, "services": [ - "Storage", - "AKV" + "AKS" ], - "severity": "Medium", - "subcategory": "CI/CD", - "text": "Consider configuring your application's source code repository to detect checked-in connection strings and storage account keys.", - "waf": "Security" + "severity": "Low", + "subcategory": "Compliance", + "text": "For planned events consider using Node Auto Drain", + "waf": "Operations" }, { - "category": "Security", - "checklist": "Azure Blob Storage Review", - "description": "Ideally, your application should be using a managed identity to authenticate to Azure Storage. If that is not possible, consider having the storage credential (connection string, storage account key, SAS, service principal credential) in Azure KeyVault or an equivalent service.", - "guid": "11cc57b4-a4b1-4410-b439-58a8c2289b3d", - "id": "A15.01", - "link": "https://learn.microsoft.com/azure/architecture/framework/security/design-storage-keys", + "category": "Operations", + "checklist": "Azure AKS Review", + "guid": "ed0fda7f-211b-47c7-8b6e-c18873fb473c", + "id": "07.02.10", + "link": "https://learn.microsoft.com/azure/aks/faq", + "security": 1, "services": [ - "Storage", - "Entra" + "AKS" ], "severity": "High", - "subcategory": "Identity and Access Management", - "text": "Consider storing connection strings in Azure KeyVault (in scenarios where managed identities are not possible)", - "waf": "Security" + "subcategory": "Compliance", + "text": "Develop own governance practices to make sure no changes are performed by operators in the node RG (aka 'infra RG')", + "waf": "Operations" }, { - "category": "Security", - "checklist": "Azure Blob Storage Review", - "description": "Use near-term expiration times on an ad hoc SAS service SAS or account SAS. In this way, even if a SAS is compromised, it's valid only for a short time. This practice is especially important if you cannot reference a stored access policy. Near-term expiration times also limit the amount of data that can be written to a blob by limiting the time available to upload to it.", - "guid": "27138b82-1102-4cac-9eae-01e6e842e52f", - "id": "A15.02", - "link": "https://learn.microsoft.com/rest/api/storageservices/delegate-access-with-shared-access-signature", + "category": "Operations", + "checklist": "Azure AKS Review", + "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (properties.nodeResourceGroup !startswith 'MC_') | distinct id,compliant", + "guid": "73b32a5a-67f7-4a9e-b5b3-1f38c3f39812", + "id": "07.02.11", + "link": "https://learn.microsoft.com/azure/aks/cluster-configuration", "services": [ - "AzurePolicy", - "Storage", - "Entra" + "AKS" ], - "severity": "High", - "subcategory": "Identity and Access Management", - "text": "Strive for short validity periods for ad-hoc SAS", - "waf": "Security" + "severity": "Low", + "simple": 1, + "subcategory": "Compliance", + "text": "Use custom Node RG (aka 'Infra RG') name", + "waf": "Operations" }, { - "category": "Security", - "checklist": "Azure Blob Storage Review", - "description": "When creating a SAS, be as specific and restrictive as possible. Prefer a SAS for a single resource and operation over a SAS which gives much broader access.", - "guid": "4721d928-c1b1-4cd5-81e5-4a29a9de399c", - "id": "A15.03", - "link": "https://learn.microsoft.com/rest/api/storageservices/delegate-access-with-shared-access-signature", + "category": "Operations", + "checklist": "Azure AKS Review", + "guid": "b2463cff-e189-4c59-adf0-d5a73dd4ce32", + "ha": 1, + "id": "07.02.12", + "link": "https://kubernetes.io/docs/setup/release/notes/", "services": [ - "Storage", - "Entra" + "AKS" ], "severity": "Medium", - "subcategory": "Identity and Access Management", - "text": "Apply a narrow scope to a SAS", - "waf": "Security" + "simple": -1, + "subcategory": "Compliance", + "text": "Do not use deprecated Kubernetes APIs in your YAML manifests", + "waf": "Operations" }, { - "category": "Security", - "checklist": "Azure Blob Storage Review", - "description": "A SAS can include parameters on which client IP addresses or address ranges are authorized to request a resource using the SAS. ", - "guid": "fd7b28dc-9355-4562-82bf-e4564b0d834a", - "id": "A15.04", - "link": "https://learn.microsoft.com/rest/api/storageservices/create-account-sas", + "category": "Operations", + "checklist": "Azure AKS Review", + "guid": "c1881370-6f7c-44c0-b4e5-14648d2457ed", + "ha": 1, + "id": "07.02.13", + "link": "https://learn.microsoft.com/azure-stack/aks-hci/adapt-apps-mixed-os-clusters", "services": [ - "Storage", - "Entra" + "AKS" ], - "severity": "Medium", - "subcategory": "Identity and Access Management", - "text": "Consider scoping SAS to a specific client IP address, wherever possible", - "waf": "Security" + "severity": "Low", + "simple": -1, + "subcategory": "Compliance", + "text": "Taint Windows nodes", + "waf": "Operations" }, { - "category": "Security", - "checklist": "Azure Blob Storage Review", - "description": "A SAS cannot constrain how much data a client uploads; given the pricing model of amount of storage over time, it might make sense to validate whether clients uploaded maliciously large contents.", - "guid": "348b263e-6dd6-4051-8a36-498f6dbad38e", - "id": "A15.05", + "category": "Operations", + "checklist": "Azure AKS Review", + "guid": "67138b82-0102-4ce1-9ee3-01e6e882e52e", + "id": "07.02.14", + "link": "https://learn.microsoft.com/virtualization/windowscontainers/deploy-containers/version-compatibility?tabs=windows-server-20H2%2Cwindows-10-20H2", "services": [ - "Storage", - "Entra" + "AKS" ], "severity": "Low", - "subcategory": "Identity and Access Management", - "text": "Consider checking uploaded data, after clients used a SAS to upload a file. ", - "waf": "Security" + "subcategory": "Compliance", + "text": "Keep windows containers patch level in sync with host patch level", + "waf": "Operations" }, { - "category": "Security", - "checklist": "Azure Blob Storage Review", - "description": "When accessing blob storage via SFTP using a 'local user account', the 'usual' RBAC controls do not apply. Blob access via NFS or REST might be more restrictive than SFTP access. Unfortunately, as of early 2023, local users are the only form of identity management that is currently supported for the SFTP endpoint", - "guid": "ad53cc7c-e1d7-4aaa-a357-1449ab8053d8", - "id": "A15.06", - "link": "https://learn.microsoft.com/azure/storage/blobs/secure-file-transfer-protocol-support#sftp-permission-model", + "category": "Operations", + "checklist": "Azure AKS Review", + "cost": -1, + "description": "Via Diagnostic Settings at the cluster level", + "guid": "5b56ad48-408f-4e72-934c-476ba280dcf5", + "ha": 1, + "id": "07.02.15", + "link": "https://learn.microsoft.com/azure/aks/monitor-aks", "services": [ - "Storage", - "RBAC", - "Entra" + "Monitor", + "AKS" ], - "severity": "High", - "subcategory": "Identity and Access Management", - "text": "SFTP: Limit the amount of 'local users' for SFTP access, and audit whether access is needed over time.", - "waf": "Security" + "severity": "Low", + "subcategory": "Compliance", + "text": "Send master logs (aka API logs) to Azure Monitor or your preferred log management solution", + "waf": "Operations" }, { - "category": "Security", - "checklist": "Azure Blob Storage Review", - "guid": "9f89dc7b-33be-42a1-a27f-7b9e91be1f38", - "id": "A15.07", - "link": "https://learn.microsoft.com/azure/storage/blobs/secure-file-transfer-protocol-known-issues#authentication-and-authorization", + "category": "Operations", + "checklist": "Azure AKS Review", + "cost": 1, + "guid": "64d1a846-e28a-4b6b-9a33-22a635c15a21", + "id": "07.02.16", + "link": "https://learn.microsoft.com/azure/aks/node-pool-snapshot", "services": [ - "Storage", - "Entra" + "AKS" ], - "severity": "Medium", - "subcategory": "Identity and Access Management", - "text": "SFTP: The SFTP endpoint does not support POSIX-like ACLs.", - "waf": "Security" + "severity": "Low", + "subcategory": "Compliance", + "text": "If required use nodePool snapshots", + "waf": "Cost" }, { - "category": "Security", - "checklist": "Azure Blob Storage Review", - "description": "Storage supports CORS (Cross-Origin Resource Sharing), i.e. an HTTP feature that enables web apps from a different domain to loosen the same-origin policy. When enabling CORS, keep the CorsRules to the least privilege.", - "guid": "cef39812-bd46-43cb-aac8-ac199ebb91a3", - "id": "A16.01", - "link": "https://learn.microsoft.com/rest/api/storageservices/cross-origin-resource-sharing--cors--support-for-the-azure-storage-services", + "category": "Operations", + "checklist": "Azure AKS Review", + "cost": 1, + "guid": "c5a5b252-1e44-4a59-a9d2-399c4d7b68d0", + "id": "07.03.01", + "link": "https://learn.microsoft.com/azure/aks/spot-node-pool", "services": [ - "AzurePolicy", - "Storage" + "Cost", + "AKS" ], - "severity": "High", - "subcategory": "Networking", - "text": "Avoid overly broad CORS policies", - "waf": "Security" + "severity": "Low", + "simple": -1, + "subcategory": "Cost", + "text": "Consider spot node pools for non time-sensitive workloads", + "waf": "Operations" }, { - "category": "Security", - "checklist": "Azure Blob Storage Review", - "description": "Data at rest is always encrypted server-side, and in addition might be encrypted client-side as well. Server-side encryption might happen using a platform-managed key (default) or customer-managed key. Client-side encryption might happen by either having the client supply an encryption/decryption key on a per-blob basis to Azure storage, or by completely handling encryption on the client-side. thus not relying on Azure Storage at all for confidentiality guarantees.", - "guid": "3d90cae2-cc88-4137-86f7-c0cbafe61464", - "id": "A17.01", - "link": "https://learn.microsoft.com/azure/storage/common/storage-service-encryption", + "category": "Operations", + "checklist": "Azure AKS Review", + "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (isnotnull(properties.addonProfiles.aciConnectorLinux) and properties.addonProfiles.aciConnectorLinux.enabled==true) | distinct id,compliant", + "guid": "c755562f-2b4e-4456-9b4d-874a748b662e", + "id": "07.03.02", + "link": "https://learn.microsoft.com/azure/aks/concepts-scale", + "scale": 1, "services": [ - "Storage" + "Cost", + "AKS" ], - "severity": "High", - "subcategory": "Confidentiality and Encryption", - "text": "Determine how data at rest should be encrypted. Understand the thread model for data.", - "waf": "Security" + "severity": "Low", + "simple": -1, + "subcategory": "Cost", + "text": "Consider AKS virtual node for quick bursting", + "waf": "Operations" }, { - "category": "Security", - "checklist": "Azure Blob Storage Review", - "guid": "8dd457e9-2713-48b8-8110-2cac6eae01e6", - "id": "A17.02", - "link": "https://learn.microsoft.com/azure/storage/common/customer-managed-keys-overview?toc=%2Fazure%2Fstorage%2Fblobs%2Ftoc.json&bc=%2Fazure%2Fstorage%2Fblobs%2Fbreadcrumb%2Ftoc.json", + "category": "Operations", + "checklist": "Azure AKS Review", + "guid": "6f8389a7-f82c-4b8e-a8c0-aa63a25a4956", + "ha": 1, + "id": "07.04.01", + "link": "https://learn.microsoft.com/azure/azure-monitor/insights/container-insights-overview", "services": [ - "Storage" + "Monitor", + "AKS" ], - "severity": "Medium", - "subcategory": "Confidentiality and Encryption", - "text": "Determine which/if platform encryption should be used.", - "waf": "Security" + "severity": "High", + "simple": -1, + "subcategory": "Monitoring", + "text": "Monitor your cluster metrics with Container Insights (or other tools like Prometheus)", + "waf": "Operations" }, { - "category": "Security", - "checklist": "Azure Blob Storage Review", - "guid": "e842e52f-4721-4d92-ac1b-1cd521e54a29", - "id": "A17.03", - "link": "https://learn.microsoft.com/azure/storage/blobs/encryption-customer-provided-keys", + "category": "Operations", + "checklist": "Azure AKS Review", + "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (isnotnull(properties.addonProfiles.omsagent) and properties.addonProfiles.omsagent.enabled==true) | distinct id,compliant", + "guid": "eaa8dc4a-2436-47b3-9697-15b1752beee0", + "ha": 1, + "id": "07.04.02", + "link": "https://learn.microsoft.com/azure/azure-monitor/insights/container-insights-overview", "services": [ - "Storage" + "Monitor", + "AKS" ], - "severity": "Medium", - "subcategory": "Confidentiality and Encryption", - "text": "Determine which/if client-side encryption should be used.", - "waf": "Security" + "severity": "High", + "simple": -1, + "subcategory": "Monitoring", + "text": "Store and analyze your cluster logs with Container Insights (or other tools like Telegraf/ElasticSearch)", + "waf": "Operations" }, { - "category": "Security", - "checklist": "Azure Blob Storage Review", - "description": "Leverage Resource Graph Explorer (resources | where type == 'microsoft.storage/storageaccounts' | where properties['allowBlobPublicAccess'] == true) to find storage accounts which allow anonymous blob access.", - "guid": "659ae558-b937-4d49-a5e1-112dbd7ba012", - "id": "A18.01", - "link": "https://learn.microsoft.com/azure/storage/blobs/anonymous-read-access-configure?tabs=portal#allow-or-disallow-public-read-access-for-a-storage-account", + "category": "Operations", + "checklist": "Azure AKS Review", + "guid": "4621dd68-c5a5-4be2-bdb1-1726769ef669", + "ha": 1, + "id": "07.04.03", + "link": "https://learn.microsoft.com/azure/azure-monitor/containers/container-insights-analyze", "services": [ - "Storage", - "Entra" + "Monitor", + "AKS" ], - "severity": "High", - "subcategory": "Identity and Access Management", - "text": "Consider whether public blob access is needed, or whether it can be disabled for certain storage accounts. ", - "waf": "Security" + "severity": "Medium", + "simple": -1, + "subcategory": "Monitoring", + "text": "Monitor CPU and memory utilization of the nodes", + "waf": "Operations" }, { - "category": "Azure Billing and Microsoft Entra ID Tenants", - "checklist": "Azure Landing Zone Review", - "guid": "70c15989-c726-42c7-b0d3-24b7375b9201", - "id": "A01.01", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/multi-tenant/considerations-recommendations", + "category": "Operations", + "checklist": "Azure AKS Review", + "guid": "1a4835ac-9422-423e-ae80-b123081a5417", + "ha": 1, + "id": "07.04.04", + "link": "https://learn.microsoft.com/azure/aks/configure-azure-cni", "services": [ - "Entra" + "Monitor", + "AKS" ], "severity": "Medium", - "subcategory": "Microsoft Entra ID Tenants", - "text": "Use one Entra tenant for managing your Azure resources, unless you have a clear regulatory or business requirement for multi-tenants.", + "simple": -1, + "subcategory": "Monitoring", + "text": "If using Azure CNI, monitor % of pod IPs consumed per node", "waf": "Operations" }, { - "category": "Azure Billing and Microsoft Entra ID Tenants", - "checklist": "Azure Landing Zone Review", - "guid": "6309957b-821a-43d1-b9d9-7fcf1802b747", - "id": "A01.02", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/multi-tenant/automation", + "category": "Operations", + "checklist": "Azure AKS Review", + "description": "I/O in the OS disk is a critical resource. If the OS in the nodes gets throttled on I/O, this could lead to unpredictable behavior, typically ending up in node being declared NotReady", + "guid": "415833ea-3ad3-4c2d-b733-165c3acbe04b", + "ha": 1, + "id": "07.04.05", + "link": "https://learn.microsoft.com/azure/virtual-machines/premium-storage-performance", "services": [ - "Entra" + "Monitor", + "Storage", + "ServiceBus", + "AKS", + "EventHubs" ], - "severity": "Low", - "subcategory": "Microsoft Entra ID Tenants", - "text": "Ensure you have a Multi-Tenant Automation approach to managing your Microsoft Entra ID Tenants", + "severity": "Medium", + "simple": -1, + "subcategory": "Monitoring", + "text": "Monitor OS disk queue depth in nodes", "waf": "Operations" }, { - "category": "Azure Billing and Microsoft Entra ID Tenants", - "checklist": "Azure Landing Zone Review", - "guid": "78e11934-499a-45ed-8ef7-aae5578f0ecf", - "id": "A01.03", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/multi-tenant/lighthouse", + "category": "Operations", + "checklist": "Azure AKS Review", + "guid": "be209d39-fda4-4777-a424-d116785c2fa5", + "ha": 1, + "id": "07.04.06", + "link": "https://learn.microsoft.com/azure/aks/load-balancer-standard", "services": [ - "Entra" + "NVA", + "Monitor", + "LoadBalancer", + "AKS" ], - "severity": "Low", - "subcategory": "Microsoft Entra ID Tenants", - "text": "Leverage Azure Lighthouse for Multi-Tenant Management", + "severity": "Medium", + "simple": -1, + "subcategory": "Monitoring", + "text": "If not using egress filtering with AzFW/NVA, monitor standard ALB allocated SNAT ports", "waf": "Operations" }, { - "category": "Azure Billing and Microsoft Entra ID Tenants", - "checklist": "Azure Landing Zone Review", - "guid": "5d82e6df-6f61-42f2-82e2-3132d293be3d", - "id": "A02.01", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", + "category": "Operations", + "checklist": "Azure AKS Review", + "guid": "74c2ee76-569b-4a79-a57e-dedf91b022c9", + "ha": 1, + "id": "07.04.07", + "link": "https://learn.microsoft.com/azure/aks/aks-resource-health", "services": [ - "Entra" + "Monitor", + "AKS" ], "severity": "Medium", - "subcategory": "Cloud Solution Provider", - "text": "Ensure that Azure Lighthouse is used for administering the tenant by partner", - "waf": "Cost" + "subcategory": "Monitoring", + "text": "Subscribe to resource health notifications for your AKS cluster", + "waf": "Operations" }, { - "category": "Azure Billing and Microsoft Entra ID Tenants", - "checklist": "Azure Landing Zone Review", - "guid": "a24d0de3-d4b9-4dfb-8ddd-bbfaf123fa01", - "id": "A02.02", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", + "category": "Operations", + "checklist": "Azure AKS Review", + "guid": "b54eb2eb-03dd-4aa3-9927-18e2edb11726", + "ha": 1, + "id": "07.05.01", + "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-scheduler", "services": [ - "Entra" + "AKS" ], - "severity": "Low", - "subcategory": "Cloud Solution Provider", - "text": "Discuss support request and escalation process with CSP partner", - "waf": "Cost" + "severity": "High", + "simple": -1, + "subcategory": "Resources", + "text": "Configure requests and limits in your pod specs", + "waf": "Operations" }, { - "category": "Azure Billing and Microsoft Entra ID Tenants", - "checklist": "Azure Landing Zone Review", - "guid": "32952499-58c8-4e6f-ada5-972e67893d55", - "id": "A02.03", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", + "category": "Operations", + "checklist": "Azure AKS Review", + "guid": "769ef669-1a48-435a-a942-223ece80b123", + "ha": 1, + "id": "07.05.02", + "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-scheduler", "services": [ - "Entra", - "Cost" + "AKS" ], "severity": "Medium", - "subcategory": "Cloud Solution Provider", - "text": "Setup Cost Reporting and Views with Azure Cost Management", - "waf": "Cost" + "simple": -1, + "subcategory": "Resources", + "text": "Enforce resource quotas for namespaces", + "waf": "Operations" }, { - "category": "Azure Billing and Microsoft Entra ID Tenants", - "checklist": "Azure Landing Zone Review", - "guid": "685cb4f2-ac9c-4b19-9167-993ed0b32415", - "id": "A03.01", - "link": "https://learn.microsoft.com/azure/cost-management-billing/manage/direct-ea-administration#manage-notification-contacts", + "category": "Operations", + "checklist": "Azure AKS Review", + "cost": 1, + "guid": "081a5417-4158-433e-a3ad-3c2de733165c", + "id": "07.05.03", + "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits", "services": [ - "LoadBalancer", - "Entra" + "Subscriptions", + "AKS" ], - "severity": "Medium", - "subcategory": "Enterprise Agreement", - "text": "Configure Notification Contacts to a group mailbox", - "waf": "Cost" + "severity": "High", + "subcategory": "Resources", + "text": "Ensure your subscription has enough quota to scale out your nodepools", + "waf": "Operations" }, { - "category": "Azure Billing and Microsoft Entra ID Tenants", - "checklist": "Azure Landing Zone Review", - "guid": "12cd499f-96e2-4e41-a243-231fb3245a1c", - "id": "A03.02", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-enterprise-agreement#design-considerations", + "category": "Operations", + "checklist": "Azure AKS Review", + "cost": -1, + "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (isnotnull(properties.autoScalerProfile)) | distinct id,compliant", + "guid": "90ce65de-8e13-4f9c-abd4-69266abca264", + "ha": 1, + "id": "07.06.01", + "link": "https://learn.microsoft.com/azure/aks/concepts-scale", "services": [ - "TrafficManager", - "Entra" + "AKS" ], - "severity": "Low", - "subcategory": "Enterprise Agreement", - "text": "Use departments and accounts to map your organization's structure to your enrollment hierarchy which can help with separating billing.", - "waf": "Cost" + "severity": "Medium", + "subcategory": "Scalability", + "text": "Use the Cluster Autoscaler", + "waf": "Performance" }, { - "ammp": true, - "category": "Azure Billing and Microsoft Entra ID Tenants", - "checklist": "Azure Landing Zone Review", - "guid": "29213165-f066-46c4-81fc-4214cc19f3d0", - "id": "A03.03", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-enterprise-agreement#design-considerations", + "category": "Operations", + "checklist": "Azure AKS Review", + "cost": -1, + "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (isnotnull(properties.austoscalerProfile)) | distinct id,compliant", + "guid": "831c2872-c693-4b39-a887-a561bada49bc", + "ha": 1, + "id": "07.06.02", + "link": "https://learn.microsoft.com/azure/aks/custom-node-configuration", "services": [ - "Entra" + "AKS" ], - "severity": "High", - "subcategory": "Enterprise Agreement", - "text": "Ensure that Accounts are configured to be of the type 'Work or School Account", - "waf": "Security" + "severity": "Low", + "subcategory": "Scalability", + "text": "Customize node configuration for AKS node pools", + "waf": "Performance" }, { - "category": "Azure Billing and Microsoft Entra ID Tenants", - "checklist": "Azure Landing Zone Review", - "guid": "ca0fe401-12ad-46fc-8a7e-86293866a9f6", - "id": "A03.04", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-enterprise-agreement#design-considerations", + "category": "Operations", + "checklist": "Azure AKS Review", + "guid": "faa19bfe-9d55-4d04-a3c4-919ca1b2d121", + "id": "07.06.03", + "link": "https://learn.microsoft.com/azure/aks/concepts-scale", + "scale": 1, "services": [ - "Entra", - "Cost" + "AKS" ], "severity": "Medium", - "subcategory": "Enterprise Agreement", - "text": "Enable both DA View Charges and AO View Charges on your EA Enrollments to allow users with the correct perms review Cost and Billing Data.", - "waf": "Security" + "simple": -1, + "subcategory": "Scalability", + "text": "Use the Horizontal Pod Autoscaler when required", + "waf": "Performance" }, { - "category": "Azure Billing and Microsoft Entra ID Tenants", - "checklist": "Azure Landing Zone Review", - "guid": "5cf9f485-2784-49b3-9824-75d9b8bdb57b", - "id": "A03.05", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-enterprise-agreement#design-considerations", + "category": "Operations", + "checklist": "Azure AKS Review", + "cost": 1, + "description": "Larger nodes will bring higher performance and features such as ephemeral disks and accelerated networking, but they will increase the blast radius and decrease the scaling granularity", + "guid": "5ae124ba-34df-4585-bcdc-e9bd3bb0cdb3", + "id": "07.06.04", + "link": "https://blog.cloudtrooper.net/2020/10/23/which-vm-size-should-i-choose-as-aks-node/", "services": [ - "Entra", - "Subscriptions", - "Cost" + "AKS" ], - "severity": "Low", - "subcategory": "Enterprise Agreement", - "text": "Make use of Enterprise Dev/Test Subscriptions to reduce costs for non-production workloads", - "waf": "Cost" + "severity": "High", + "subcategory": "Scalability", + "text": "Consider an appropriate node size, not too large or too small", + "waf": "Performance" }, { - "category": "Azure Billing and Microsoft Entra ID Tenants", - "checklist": "Azure Landing Zone Review", - "guid": "2cf08656-13ea-4f7e-a53a-e2c956b1ff6c", - "id": "A03.06", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-enterprise-agreement#design-considerations", + "category": "Operations", + "checklist": "Azure AKS Review", + "cost": 1, + "guid": "38800e6a-ae01-40a2-9fbc-ae5a06e5462d", + "id": "07.06.05", + "link": "https://learn.microsoft.com/azure/aks/quotas-skus-regions#service-quotas-and-limits", "services": [ - "RBAC", - "Entra" + "AKS" ], - "severity": "Medium", - "subcategory": "Enterprise Agreement", - "text": "Periodically audit the role assignments to review who has access to your Enterprise Agreement Enrollment", - "waf": "Cost" + "severity": "Low", + "subcategory": "Scalability", + "text": "If more than 5000 nodes are required for scalability then consider using an additional AKS cluster", + "waf": "Performance" }, { - "category": "Azure Billing and Microsoft Entra ID Tenants", - "checklist": "Azure Landing Zone Review", - "guid": "6ad5c3dd-e5ea-4ff1-81a4-7886ff87845c", - "id": "A04.01", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", + "category": "Operations", + "checklist": "Azure AKS Review", + "cost": 1, + "guid": "9583c0f6-6083-43f6-aa6b-df7102c901bb", + "id": "07.06.06", + "link": "https://learn.microsoft.com/azure/event-grid/event-schema-aks", "services": [ - "Entra" + "AKS" ], "severity": "Low", - "subcategory": "Microsoft Customer Agreement", - "text": "Configure Agreement billing account notification contact email", - "waf": "Cost" + "subcategory": "Scalability", + "text": "Consider subscribing to EventGrid Events for AKS automation", + "waf": "Performance" }, { - "category": "Azure Billing and Microsoft Entra ID Tenants", - "checklist": "Azure Landing Zone Review", - "guid": "90e87802-602f-4dfb-acea-67c60689f1d7", - "id": "A04.02", - "link": "https://learn.microsoft.com/azure/cost-management-billing/manage/mca-section-invoice", + "category": "Operations", + "checklist": "Azure AKS Review", + "cost": 1, + "guid": "c5016d8c-c6c9-4165-89ae-673ef0fff19d", + "id": "07.06.07", + "link": "https://learn.microsoft.com/azure/aks/manage-abort-operations", "services": [ - "Entra", - "Storage", - "Cost" + "AKS" ], "severity": "Low", - "subcategory": "Microsoft Customer Agreement", - "text": "Use Billing Profiles and Invoice sections to structure your agreements billing for effective cost management", - "waf": "Cost" + "subcategory": "Scalability", + "text": "For long running operation on an AKS cluster consider event termination", + "waf": "Performance" }, { - "category": "Azure Billing and Microsoft Entra ID Tenants", - "checklist": "Azure Landing Zone Review", - "guid": "e81a73f0-84c4-4641-b406-14db3b4d1f50", - "id": "A04.03", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", + "category": "Operations", + "checklist": "Azure AKS Review", + "cost": 1, + "guid": "c4e37133-f186-4ce1-aed9-9f1b32f6e021", + "id": "07.06.08", + "link": "https://learn.microsoft.com/azure/aks/use-azure-dedicated-hosts", "services": [ - "Entra", - "Cost" + "AKS" ], "severity": "Low", - "subcategory": "Microsoft Customer Agreement", - "text": "Make use of Azure Plan to reduce costs for non-production workloads", - "waf": "Cost" + "subcategory": "Scalability", + "text": "If required consider using Azure Dedicated Hosts for AKS nodes", + "waf": "Performance" }, { - "category": "Azure Billing and Microsoft Entra ID Tenants", - "checklist": "Azure Landing Zone Review", - "guid": "ae757485-92a4-482a-8bc9-eefe6f5b5ec3", - "id": "A04.04", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", + "category": "Operations", + "checklist": "Azure AKS Review", + "cost": -1, + "graph": "where type=='microsoft.containerservice/managedclusters' | project id,resourceGroup,name,pools=properties.agentPoolProfiles | mvexpand pools | extend compliant = (pools.osDiskType=='Ephemeral') | project id,name=strcat(name,'-',pools.name), resourceGroup, compliant", + "guid": "24367b33-6971-45b1-952b-eee0b9b588de", + "id": "07.07.01", + "link": "https://learn.microsoft.com/azure/aks/cluster-configuration", + "scale": 1, "services": [ - "RBAC", - "Entra" + "Storage", + "AKS" ], - "severity": "Medium", - "subcategory": "Microsoft Customer Agreement", - "text": "Periodically audit the agreement billing RBAC role assignments to review who has access to your MCA billing account", - "waf": "Cost" + "severity": "High", + "subcategory": "Storage", + "text": "Use ephemeral OS disks", + "waf": "Performance" }, { - "ammp": true, - "category": "Identity and Access Management", - "checklist": "Azure Landing Zone Review", - "guid": "4348bf81-7573-4512-8f46-9061cc198fea", - "id": "B01.01", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/identity-access-landing-zones#identity-and-access-management-in-the-azure-landing-zone-accelerator", + "category": "Operations", + "checklist": "Azure AKS Review", + "cost": -1, + "guid": "fc4972cc-3cd2-45bf-a707-6e9eab4bed32", + "id": "07.07.02", + "link": "https://learn.microsoft.com/azure/virtual-machines/disks-types", + "scale": 1, "services": [ - "Entra" + "Storage", + "AKS" ], "severity": "High", - "subcategory": "Microsoft Entra ID and Hybrid Identity", - "text": "Use managed identities instead of service principals for authentication to Azure services", - "training": "https://learn.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview", - "waf": "Security" + "subcategory": "Storage", + "text": "For non-ephemeral disks, use high IOPS and larger OS disks for the nodes when running many pods/node since it requires high performance for running multiple pods and will generate huge logs with default AKS log rotation thresholds", + "waf": "Performance" }, { - "category": "Identity and Access Management", - "checklist": "Azure Landing Zone Review", - "guid": "cd163e39-84a5-4b39-97b7-6973abd70d94", - "id": "B02.01", - "link": "https://learn.microsoft.com/azure/active-directory/hybrid/how-to-connect-sync-staging-server", + "category": "Operations", + "checklist": "Azure AKS Review", + "cost": -1, + "guid": "39c486ce-d5af-4062-89d5-18bb5fd795db", + "id": "07.07.03", + "link": "https://learn.microsoft.com/azure/aks/use-ultra-disks", + "scale": 1, "services": [ - "ASR", - "Entra" + "Storage", + "AKS" ], - "severity": "Medium", - "subcategory": "Microsoft Entra ID", - "text": "When deploying an AD Connect VM, consider having a staging sever for high availability / Disaster recovery", - "waf": "Reliability" + "severity": "Low", + "subcategory": "Storage", + "text": "For hyper performance storage option use Ultra Disks on AKS", + "waf": "Performance" }, { - "ammp": true, - "category": "Identity and Access Management", - "checklist": "Azure Landing Zone Review", - "guid": "984a859c-773e-47d2-9162-3a765a917e1f", - "id": "B03.01", - "link": "https://learn.microsoft.com/azure/active-directory/roles/security-emergency-access", + "category": "Operations", + "checklist": "Azure AKS Review", + "guid": "9f7547c1-747d-4c56-868a-714435bd19dd", + "ha": 1, + "id": "07.07.04", + "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-multi-region", "services": [ - "Entra" - ], - "severity": "High", - "subcategory": "Identity", - "text": "Implement an emergency access or break-glass accounts to prevent tenant-wide account lockout", - "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/", - "waf": "Security" + "SQL", + "Storage", + "AKS" + ], + "severity": "Medium", + "simple": -1, + "subcategory": "Storage", + "text": "Avoid keeping state in the cluster, and store data outside (AzStorage, AzSQL, Cosmos, etc)", + "waf": "Performance" }, { - "category": "Identity and Access Management", - "checklist": "Azure Landing Zone Review", - "guid": "1cf0b8da-70bd-44d0-94af-8d99cfc89ae1", - "id": "B03.02", - "link": "https://learn.microsoft.com/azure/active-directory/reports-monitoring/concept-activity-logs-azure-monitor", + "category": "Operations", + "checklist": "Azure AKS Review", + "cost": -1, + "guid": "24429eb7-2281-4376-85cc-57b4a4b18142", + "id": "07.07.05", + "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-storage", + "scale": 1, "services": [ - "Monitor", - "Entra" + "Storage", + "AKS" ], "severity": "Medium", - "subcategory": "Identity", - "text": "Integrate Microsoft Entra ID logs with the platform-central Azure Monitor. Azure Monitor allows for a single source of truth around log and monitoring data in Azure, giving organizations a cloud native options to meet requirements around log collection and retention.", - "waf": "Security" + "subcategory": "Storage", + "text": "If using AzFiles Standard, consider AzFiles Premium and/or ANF for performance reasons", + "waf": "Performance" }, { - "ammp": true, - "category": "Identity and Access Management", - "checklist": "Azure Landing Zone Review", - "guid": "348ef254-c27d-442e-abba-c7571559ab91", - "id": "B03.03", - "link": "https://learn.microsoft.com/azure/role-based-access-control/overview", + "category": "Operations", + "checklist": "Azure AKS Review", + "guid": "83958a8c-2689-4b32-ab57-cfc64546135a", + "ha": 1, + "id": "07.07.06", + "link": "https://learn.microsoft.com/azure/aks/availability-zones#azure-disk-availability-zone-support", "services": [ - "ACR", - "RBAC", - "Entra", - "Subscriptions" + "Storage", + "AKS" ], - "severity": "High", - "subcategory": "Identity", - "text": "Enforce a RBAC model that aligns to your cloud operating model. Scope and Assign across Management Groups and Subscriptions.", - "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", - "waf": "Security" + "severity": "Medium", + "simple": -1, + "subcategory": "Storage", + "text": "If using Azure Disks and AZs, consider having nodepools within a zone for LRS disk with VolumeBindingMode:WaitForFirstConsumer for provisioning storage in right zone or use ZRS disk for nodepools spanning multiple zones", + "waf": "Performance" }, { - "category": "Identity and Access Management", - "checklist": "Azure Landing Zone Review", - "guid": "53e8908a-e28c-484c-93b6-b7808b9fe5c4", - "id": "B03.04", - "link": "https://learn.microsoft.com/azure/active-directory/conditional-access/overview", + "category": "Storage", + "checklist": "Azure Stack HCI Review", + "guid": "9f519499-5820-4060-88fe-cab4538c9dd0", + "id": "01.01.01", + "link": "https://learn.microsoft.com/windows-server/storage/storage-spaces/storage-spaces-direct-hardware-requirements", "services": [ - "AzurePolicy", - "Entra" + "Storage" ], - "severity": "Low", - "subcategory": "Identity", - "text": "Enforce Microsoft Entra ID conditional-access policies for any user with rights to Azure environments", - "training": "https://learn.microsoft.com/learn/modules/plan-implement-administer-conditional-access/", - "waf": "Security" + "severity": "Medium", + "subcategory": "Physical", + "text": "All planned storage pools should use direct-attached storage (SATA, SAS, NVMe)", + "waf": "Performance" }, { - "ammp": true, - "category": "Identity and Access Management", - "checklist": "Azure Landing Zone Review", - "guid": "1049d403-a923-4c34-94d0-0018ac6a9e01", - "id": "B03.05", - "link": "https://learn.microsoft.com/azure/active-directory/authentication/concept-mfa-howitworks", + "category": "Storage", + "checklist": "Azure Stack HCI Review", + "guid": "f7c015e0-7d97-4283-b006-567afeb2b5ca", + "id": "01.01.02", + "link": "https://learn.microsoft.com/azure-stack/hci/concepts/drive-symmetry-considerations#understand-capacity-imbalance", "services": [ - "Entra" + "ACR", + "Storage" ], - "severity": "High", - "subcategory": "Identity", - "text": "Enforce multi-factor authentication for any user with rights to the Azure environments", - "training": "https://learn.microsoft.com/learn/modules/secure-aad-users-with-mfa/", - "waf": "Security" + "severity": "Medium", + "subcategory": "Physical", + "text": "Disks are symmetrical across all nodes", + "waf": "Performance" }, { - "category": "Identity and Access Management", - "checklist": "Azure Landing Zone Review", - "guid": "e6a83de5-de32-4c19-a248-1607d5d1e4e6", - "id": "B03.06", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/manage/centralize-operations", + "category": "Storage", + "checklist": "Azure Stack HCI Review", + "guid": "f785b143-2c1e-4466-9baa-dde8ba4c7aaa", + "id": "01.02.01", + "link": "https://learn.microsoft.com/azure-stack/hci/concepts/fault-tolerance#parity", "services": [ - "RBAC", - "Entra" + "Backup", + "Storage" ], "severity": "Medium", - "subcategory": "Identity", - "text": "Enforce centralized and delegated responsibilities to manage resources deployed inside the landing zone, based on role and security requirements", - "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-identities-governance/", - "waf": "Security" + "subcategory": "S2D", + "text": "Parity type disk redundancy should only be used for low I/O volumes (backup/archive)", + "waf": "Performance" }, { - "category": "Identity and Access Management", - "checklist": "Azure Landing Zone Review", - "guid": "14658d35-58fd-4772-99b8-21112df27ee4", - "id": "B03.07", - "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-configure", + "category": "Storage", + "checklist": "Azure Stack HCI Review", + "guid": "8a705965-9840-43cc-93b3-06d089406bb4", + "id": "01.02.02", + "link": "https://learn.microsoft.com/windows-server/storage/storage-spaces/storage-spaces-direct-hardware-requirements#physical-deployments", "services": [ - "Entra" + "Storage" ], "severity": "Medium", - "subcategory": "Identity", - "text": "Enforce Microsoft Entra ID Privileged Identity Management (PIM) to establish zero standing access and least privilege", - "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/", - "waf": "Security" + "subcategory": "S2D", + "text": "Ensure there at least 2 capacity disks with available capacity in the Storage Pool", + "waf": "Reliability" }, { - "ammp": true, - "category": "Identity and Access Management", - "checklist": "Azure Landing Zone Review", - "guid": "12e7f983-f630-4472-8dd6-9c5b5c2622f5", - "id": "B03.08", - "link": "https://learn.microsoft.com/azure/active-directory/roles/security-planning#identify-microsoft-accounts-in-administrative-roles-that-need-to-be-switched-to-work-or-school-accounts", + "category": "Storage", + "checklist": "Azure Stack HCI Review", + "guid": "2a4f629a-d623-4610-a8e3-d6fd66057d8e", + "id": "01.02.03", + "link": "https://learn.microsoft.com/windows-server/storage/storage-spaces/delimit-volume-allocation", "services": [ - "Entra" + "Storage" ], - "severity": "High", - "subcategory": "Identity", - "text": "Only use the authentication type Work or school account for all account types. Avoid using the Microsoft account", - "training": "https://learn.microsoft.com/learn/modules/explore-basic-services-identity-types/", - "waf": "Security" + "severity": "Low", + "subcategory": "S2D", + "text": "'Delimited allocation' has been considered to improve volume resiliency in a multi-node failure", + "waf": "Reliability" }, { - "category": "Identity and Access Management", - "checklist": "Azure Landing Zone Review", - "guid": "4b69bad3-3aad-45e8-a68e-1d76667313b4", - "id": "B03.09", - "link": "https://learn.microsoft.com/azure/active-directory/fundamentals/active-directory-groups-create-azure-portal", + "category": "Storage", + "checklist": "Azure Stack HCI Review", + "guid": "960eb9be-1f0f-4fc1-9b31-fcf1cf9e34e6", + "id": "01.02.04", + "link": "https://learn.microsoft.com/azure-stack/hci/concepts/plan-volumes#choosing-how-many-volumes-to-create", "services": [ - "Entra" + "Storage" ], "severity": "Medium", - "subcategory": "Identity", - "text": "Only use groups to assign permissions. Add on-premises groups to the Azure-AD-only group if a group management system is already in place.", - "training": "https://learn.microsoft.com/learn/paths/manage-identity-and-access/", - "waf": "Security" + "subcategory": "S2D", + "text": "CSVs are created in multiples of node count", + "waf": "Performance" }, { - "category": "Identity and Access Management", - "checklist": "Azure Landing Zone Review", - "guid": "f5664b5e-984a-4859-a773-e7d261623a76", - "id": "B03.10", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/identity-access#prerequisites-for-a-landing-zone---design-recommendations", + "category": "Storage", + "checklist": "Azure Stack HCI Review", + "guid": "859ba2b9-a3a8-4ca1-bb61-165effbf1c03", + "id": "01.02.05", + "link": "https://learn.microsoft.com/azure-stack/hci/concepts/cache", "services": [ - "Entra", - "RBAC", - "Subscriptions" + "Storage" ], "severity": "Medium", - "subcategory": "Identity", - "text": "Consider using Azure custom roles for the following key roles: Azure platform owner, network management, security operations, subscription owner, application owner", - "training": "https://learn.microsoft.com/learn/modules/create-custom-azure-roles-with-rbac/", - "waf": "Security" + "subcategory": "S2D", + "text": "If a cache tier is implemented, the number of capacity drives is a multiple of the number of cache drives", + "waf": "Performance" }, { - "category": "Identity and Access Management", - "checklist": "Azure Landing Zone Review", - "guid": "1559ab91-53e8-4908-ae28-c84c33b6b780", - "id": "B03.11", - "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/identity/adds-extend-domain#vm-recommendations", + "category": "Storage", + "checklist": "Azure Stack HCI Review", + "guid": "d8a65f05-db06-461d-81dc-7899ad3f8f1e", + "id": "01.02.06", + "link": "https://learn.microsoft.com/azure-stack/hci/concepts/plan-volumes#reserve-capacity", "services": [ - "ACR", - "VM", - "Entra" + "Storage" ], "severity": "Medium", - "subcategory": "Identity", - "text": "When deploying Active Directory on Windows Server, use a location with Availability Zones and deploy at least two VMs across these zones. If not available, deploy in an Availability Set", - "training": "https://learn.microsoft.com/learn/modules/azure-active-directory/", + "subcategory": "S2D", + "text": "A minimum of 1 type of each disk type per node has been factored as a reserve disk", "waf": "Reliability" }, { - "category": "Identity and Access Management", - "checklist": "Azure Landing Zone Review", - "guid": "8b9fe5c4-1049-4d40-9a92-3c3474d00018", - "id": "B03.12", - "link": "https://learn.microsoft.com/azure/active-directory-domain-services/overview", + "category": "Storage", + "checklist": "Azure Stack HCI Review", + "description": "VMFleet is a tool that can be used to measure the performance of a storage subsystem, best used to baseline performance prior to workload deployment", + "guid": "9d138f1d-5363-476e-bbd7-acfa500bdc0c", + "id": "01.02.07", + "link": "https://github.com/microsoft/diskspd/wiki/VMFleet", "services": [ - "Entra" + "Storage" + ], + "severity": "Low", + "subcategory": "S2D", + "text": "VMFleet has been run prior to workload deployment to baseline storage performance", + "waf": "Performance" + }, + { + "category": "Storage", + "checklist": "Azure Stack HCI Review", + "guid": "13c12e2a-c938-4dd1-9223-507d5e17f9c5", + "id": "01.03.01", + "services": [ + "Storage" ], "severity": "Medium", - "subcategory": "Identity", - "text": "If AADDS in use, evaluate the compatibility of all workloads", - "training": "https://learn.microsoft.com/learn/modules/implement-hybrid-identity-windows-server/", - "waf": "Security" + "subcategory": "Host OS", + "text": "OS drives use a dedicated storage controller", + "waf": "Reliability" }, { - "category": "Identity and Access Management", - "checklist": "Azure Landing Zone Review", - "guid": "ac6a9e01-e6a8-43de-9de3-2c1992481607", - "id": "B03.13", - "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/identity/adds-extend-domain", + "category": "Storage", + "checklist": "Azure Stack HCI Review", + "guid": "a631e7dc-8879-45bd-b0a7-e5927b805428", + "id": "01.03.02", + "link": "https://learn.microsoft.com/azure-stack/hci/manage/use-csv-cache", "services": [ - "Entra" + "Storage" ], "severity": "Medium", - "subcategory": "Identity", - "text": "If domain controllers are being used, ensure that resources are set to use the correct domain controller.", - "training": "https://learn.microsoft.com/learn/paths/implement-windows-server-iaas-virtual-machine-identity/", - "waf": "Security" + "subcategory": "Host OS", + "text": "CSV in-memory read caching is enabled and properly configured", + "waf": "Performance" }, { - "category": "Identity and Access Management", - "checklist": "Azure Landing Zone Review", - "guid": "d5d1e4e6-1465-48d3-958f-d77249b82111", - "id": "B03.14", - "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy", + "category": "Networking", + "checklist": "Azure Stack HCI Review", + "guid": "c062cd9a-f1db-4f83-aab3-9cb03f56c140", + "id": "02.01.01", + "link": "https://learn.microsoft.com/azure-stack/hci/concepts/host-network-requirements#switch-embedded-teaming-set", "services": [ - "VPN", - "Entra" + "ACR" ], "severity": "Medium", - "subcategory": "Identity", - "text": "Consider using Microsoft Entra ID Application Proxy as a VPN or reverse proxy replacement to give remote users secure and authenticated access to internal applications (hosted in the cloud or on-premises).", - "training": "https://learn.microsoft.com/learn/paths/implement-applications-external-access-azure-ad/", - "waf": "Security" + "subcategory": "Host", + "text": "NICs are symmetrical across nodes", + "waf": "Reliability" }, { - "category": "Identity and Access Management", - "checklist": "Azure Landing Zone Review", - "guid": "35037e68-9349-4c15-b371-228514f4cdff", - "id": "B03.15", - "link": "https://learn.microsoft.com/azure/active-directory/roles/best-practices", + "category": "Networking", + "checklist": "Azure Stack HCI Review", + "guid": "ea8054db-a558-4533-80c8-5d9cf447ba19", + "id": "02.01.02", "services": [ - "RBAC", - "Entra" + "Storage" ], + "severity": "High", + "subcategory": "Host", + "text": "Storage networking is redundant", + "waf": "Reliability" + }, + { + "category": "Networking", + "checklist": "Azure Stack HCI Review", + "guid": "15d976c5-e267-49a1-8b00-62010bfa5188", + "id": "02.01.03", + "link": "https://learn.microsoft.com/azure-stack/hci/deploy/network-atc", + "services": [], "severity": "Medium", - "subcategory": "Identity", - "text": "Avoid using on-premises synced accounts for Microsoft Entra ID role assignments.", - "training": "https://learn.microsoft.com/learn/modules/design-identity-security-strategy/", - "waf": "Security" + "subcategory": "Host", + "text": "Host networking configuration is managed by Network ATC and intents are healthy", + "waf": "Reliability" }, { - "category": "Identity and Access Management", - "checklist": "Azure Landing Zone Review", - "guid": "9cf5418b-1520-4b7b-add7-88eb28f833e8", - "id": "B04.01", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/identity-access-landing-zones#managed-identities", + "category": "Networking", + "checklist": "Azure Stack HCI Review", + "guid": "676c53ad-b29a-4de1-9d03-d7d2674405b8", + "id": "02.01.04", + "link": "https://learn.microsoft.com/azure-stack/hci/concepts/network-hud-overview", + "services": [], + "severity": "Low", + "subcategory": "Host", + "text": "Network HUD has been configured", + "waf": "Reliability" + }, + { + "category": "Networking", + "checklist": "Azure Stack HCI Review", + "guid": "8f6d58d9-6c1a-4ec1-b2d7-b2c6ba8f3949", + "id": "02.01.05", + "link": "https://learn.microsoft.com/azure-stack/hci/concepts/host-network-requirements", "services": [ "VNet", - "Entra" + "Storage" ], "severity": "Medium", - "subcategory": "Landing zones", - "text": "Configure Identity network segmentation through the use of a virtual Network and peer back to the hub. Providing authentication inside application landing zone (legacy).", - "training": "https://learn.microsoft.com/azure/architecture/example-scenario/identity/adds-extend-domain", - "waf": "Security" + "subcategory": "Host", + "text": "Storage NICs are assigned static IP addresses on separate subnets and VLANs", + "waf": "Reliability" }, { - "category": "Identity and Access Management", - "checklist": "Azure Landing Zone Review", - "guid": "d4d1ad54-1abc-4919-b267-3f342d3b49e4", - "id": "B04.02", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/identity-access-landing-zones#rbac-recommendations", + "category": "Networking", + "checklist": "Azure Stack HCI Review", + "guid": "824e53ec-953e-40c2-a6b8-52970b5b0f74", + "id": "02.01.06", + "link": "https://learn.microsoft.com/azure-stack/hci/plan/two-node-switched-converged", + "services": [], + "severity": "Medium", + "subcategory": "Host", + "text": "For switchless designs, dual link full mesh connectivity has been implemented", + "waf": "Reliability" + }, + { + "category": "Networking", + "checklist": "Azure Stack HCI Review", + "guid": "dbc85d0e-0ebd-4589-a789-0fa8ceb1d0f0", + "id": "02.01.07", + "link": "https://learn.microsoft.com/azure-stack/hci/concepts/physical-network-requirements#using-switchless", "services": [ - "ACR", - "RBAC", - "AKV", - "Entra", "Storage" ], "severity": "Medium", - "subcategory": "Landing zones", - "text": "Use Azure RBAC to manage data plane access to resources, if possible. E.G - Data Operations across Key Vault, Storage Account and Database Services. ", - "training": "https://learn.microsoft.com/azure/role-based-access-control/overview", - "waf": "Security" + "subcategory": "Host", + "text": "If the cluster is made up of more than 3 nodes, a switched storage network has been implemented", + "waf": "Reliability" }, { - "category": "Identity and Access Management", - "checklist": "Azure Landing Zone Review", - "guid": "d505ebcb-79b1-4274-9c0d-a27c8bea489c", - "id": "B04.03", - "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-create-roles-and-resource-roles-review", + "category": "Networking", + "checklist": "Azure Stack HCI Review", + "guid": "603c6d71-59d2-419c-a312-8edc6e799c6a", + "id": "02.01.08", "services": [ - "Entra" + "Storage" ], - "severity": "Medium", - "subcategory": "Landing zones", - "text": "Use Microsoft Entra ID PIM access reviews to periodically validate resource entitlements.", - "waf": "Security" + "severity": "High", + "subcategory": "Host", + "text": "RDMA is enabled on the Storage networking", + "waf": "Performance" }, { - "ammp": true, - "category": "Resource Organization", - "checklist": "Azure Landing Zone Review", - "guid": "cacf55bc-e4e4-46be-96bc-57a5f23a269a", - "id": "C01.01", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/resource-naming", + "category": "Networking", + "checklist": "Azure Stack HCI Review", + "guid": "9e260eae-bca1-4827-a259-76ee63fda8d6", + "id": "02.01.09", + "link": "https://github.com/microsoft/SDN/blob/master/Diagnostics/Test-Rdma.ps1", "services": [], - "severity": "High", - "subcategory": "Naming and tagging", - "text": "It is recommended to follow Microsoft Best Practice Naming Standards", - "waf": "Security" + "severity": "Medium", + "subcategory": "Host", + "text": "Test-RDMA.ps1 has been run to validate the RDMA configuration", + "waf": "Performance" }, { - "category": "Resource Organization", - "checklist": "Azure Landing Zone Review", - "graph": "resourcecontainers| where type == 'microsoft.resources/subscriptions'| extend ManagementGroup = tostring(tags),mgmtChain = properties.managementGroupAncestorsChain| extend compliant =( array_length(mgmtChain) <= 4 and array_length(mgmtChain) > 1)", - "guid": "2df27ee4-12e7-4f98-9f63-04722dd69c5b", - "id": "C02.01", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/resource-org-management-groups", + "category": "Networking", + "checklist": "Azure Stack HCI Review", + "description": "This ensures that Management traffic is not exposed to the VM traffic", + "guid": "abc85d0e-0ebd-4589-a777-0fa8ceb1d0f0", + "id": "02.01.10", + "link": "", "services": [ - "Subscriptions" + "VM" ], "severity": "Medium", - "subcategory": "Subscriptions", - "text": "Enforce reasonably flat management group hierarchy with no more than four levels.", - "training": "https://learn.microsoft.com/learn/modules/azure-architecture-fundamentals/", + "subcategory": "Host", + "text": "If a VMSwitch is shared for Compute and Management traffic, require that Management traffic is tagged with a VLAN ID", "waf": "Security" }, { - "category": "Resource Organization", - "checklist": "Azure Landing Zone Review", - "guid": "667313b4-f566-44b5-b984-a859c773e7d2", - "id": "C02.02", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/resource-org-management-groups#management-group-recommendations", + "category": "Networking", + "checklist": "Azure Stack HCI Review", + "description": "This ensures you have at least 3 NCs active at all times during NC upgrades.", + "guid": "eb36f5f4-0fa7-4a2c-85f3-1b1c7c7817c0", + "id": "02.02.01", "services": [ - "Subscriptions" + "VM" ], "severity": "Medium", - "subcategory": "Subscriptions", - "text": "Enforce a sandbox management group to allow users to immediately experiment with Azure", - "training": "https://learn.microsoft.com/learn/paths/enterprise-scale-architecture/", - "waf": "Security" + "subcategory": "SDN", + "text": "There are at least 3 Network Controller VMs deployed", + "waf": "Reliability" }, { - "category": "Resource Organization", - "checklist": "Azure Landing Zone Review", - "guid": "61623a76-5a91-47e1-b348-ef254c27d42e", - "id": "C02.03", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/resource-org-management-groups#management-group-recommendations", + "category": "Networking", + "checklist": "Azure Stack HCI Review", + "guid": "8bc78c85-6028-4a43-af2d-082a0a344909", + "id": "02.02.02", + "link": "https://learn.microsoft.com/windows-server/networking/sdn/manage/update-backup-restore", "services": [ - "AzurePolicy", - "RBAC", - "Subscriptions" + "Backup" + ], + "severity": "High", + "subcategory": "SDN", + "text": "Backups of SDN infrastructure are configured and tested", + "waf": "Operations" + }, + { + "category": "Management and Monitoring", + "checklist": "Azure Stack HCI Review", + "guid": "51eaa4b6-b9a7-43e1-a7dc-634d3107bc6d", + "id": "03.01.01", + "services": [ + "Monitor" ], "severity": "Medium", - "subcategory": "Subscriptions", - "text": "Enforce a platform management group under the root management group to support common platform policy and Azure role assignment", - "training": "https://learn.microsoft.com/learn/paths/enterprise-scale-architecture/", - "waf": "Security" + "subcategory": "Cluster", + "text": "SCOM Managed Instance has been considered for more complex monitoring and alerting scenarios", + "waf": "Operations" + }, + { + "category": "Management and Monitoring", + "checklist": "Azure Stack HCI Review", + "guid": "831f5aca-99ef-41e7-8263-9509f5093b43", + "id": "03.01.02", + "link": "https://learn.microsoft.com/azure-stack/hci/manage/setup-hci-system-alerts", + "services": [ + "Monitor" + ], + "severity": "High", + "subcategory": "Cluster", + "text": "Alerts have been configured for the cluster, either using Azure Monitor, SCOM, or a third-party solution", + "waf": "Operations" }, { - "category": "Resource Organization", - "checklist": "Azure Landing Zone Review", - "guid": "8bbac757-1559-4ab9-853e-8908ae28c84c", - "id": "C02.04", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/resource-org-management-groups#management-group-recommendations", + "category": "Management and Monitoring", + "checklist": "Azure Stack HCI Review", + "guid": "f95d0e7e-9f61-476d-bf65-59f2454d1d39", + "id": "03.01.03", + "link": "https://learn.microsoft.com/azure-stack/hci/manage/monitor-hci-single?tabs=22h2-and-later", "services": [ - "DNS", - "ExpressRoute", - "Subscriptions", - "VWAN" + "Monitor" ], "severity": "Medium", - "subcategory": "Subscriptions", - "text": "Enforce a dedicated connectivity subscription in the Connectivity management group to host an Azure Virtual WAN hub, private Domain Name System (DNS), ExpressRoute circuit, and other networking resources.", - "training": "https://learn.microsoft.com/learn/paths/enterprise-scale-architecture/", - "waf": "Security" + "subcategory": "Cluster", + "text": "Insights has been enabled at the cluster level and all nodes are reporting data", + "waf": "Operations" }, { - "category": "Resource Organization", - "checklist": "Azure Landing Zone Review", - "graph": "resourcecontainers| where type == 'microsoft.resources/subscriptions'| extend ManagementGroup = tostring(tags),mgmtChain = properties.managementGroupAncestorsChain| extend compliant = (array_length(mgmtChain) > 1)", - "guid": "33b6b780-8b9f-4e5c-9104-9d403a923c34", - "id": "C02.05", - "link": "https://learn.microsoft.com/azure/governance/management-groups/how-to/protect-resource-hierarchy#setting---default-management-group", + "category": "Management and Monitoring", + "checklist": "Azure Stack HCI Review", + "guid": "f4250fcb-ff53-40c9-b304-3560464fd90c", + "id": "03.01.04", + "link": "https://learn.microsoft.com/azure-stack/hci/manage/monitor-hci-single?tabs=22h2-and-later", "services": [ - "Subscriptions" + "Monitor" ], "severity": "Medium", - "subcategory": "Subscriptions", - "text": "Enforce no subscriptions are placed under the root management group", - "waf": "Security" + "subcategory": "Cluster", + "text": "Azure Monitoring Agent has been deployed to hosts and an appropriate Data Collection Rule has been configured", + "waf": "Operations" }, { - "category": "Resource Organization", - "checklist": "Azure Landing Zone Review", - "guid": "74d00018-ac6a-49e0-8e6a-83de5de32c19", - "id": "C02.06", - "link": "https://learn.microsoft.com/azure/governance/management-groups/how-to/protect-resource-hierarchy#setting---require-authorization", + "category": "Management and Monitoring", + "checklist": "Azure Stack HCI Review", + "guid": "6143af1d-0d1a-4163-b1c9-662f7459bb98", + "id": "03.02.01", "services": [ - "RBAC", - "Subscriptions" + "Monitor" ], "severity": "Medium", - "subcategory": "Subscriptions", - "text": "Enforce that only privileged users can operate management groups in the tenant by enabling Azure RBAC authorization in the management group hierarchy settings", - "waf": "Security" + "subcategory": "Hardware", + "text": "Relevant hardware monitoring has been configured", + "waf": "Operations" }, { - "category": "Resource Organization", - "checklist": "Azure Landing Zone Review", - "guid": "92481607-d5d1-4e4e-9146-58d3558fd772", - "id": "C02.07", - "link": "https://learn.microsoft.com/azure/governance/management-groups/overview", + "category": "Management and Monitoring", + "checklist": "Azure Stack HCI Review", + "guid": "9cbdf225-549a-41cf-9c97-794766a6f2b0", + "id": "03.02.02", + "link": "https://learn.microsoft.com/azure-stack/hci/manage/health-service-overview", "services": [ - "Subscriptions" + "Monitor" ], "severity": "Medium", - "subcategory": "Subscriptions", - "text": "Enforce management groups under the root-level management group to represent the types of workloads, based on their security, compliance, connectivity, and feature needs.", - "waf": "Security" + "subcategory": "Hardware", + "text": "Relevant hardware alerting has been configured", + "waf": "Operations" }, { - "ammp": true, - "category": "Resource Organization", - "checklist": "Azure Landing Zone Review", - "guid": "49b82111-2df2-47ee-912e-7f983f630472", - "id": "C02.08", - "link": "https://learn.microsoft.com/azure/governance/management-groups/overview", + "category": "Operations", + "checklist": "Azure Stack HCI Review", + "guid": "c0da5bbd-0f0d-4a26-98ec-38c9cc42b323", + "id": "04.01.01", "services": [ - "AzurePolicy", - "Subscriptions", - "RBAC", - "Cost" + "VM" ], - "severity": "High", - "subcategory": "Subscriptions", - "text": "Enforce a process to make resource owners aware of their roles and responsibilities, access review, budget review, policy compliance and remediate when necessary.", - "waf": "Security" + "severity": "Low", + "subcategory": "VM Management - Resource Bridge", + "text": "The Azure CLI has been installed on every node to enable RB management from WAC", + "waf": "Operations" }, { - "category": "Resource Organization", - "checklist": "Azure Landing Zone Review", - "guid": "2dd69c5b-5c26-422f-94b6-9bad33aad5e8", - "id": "C02.09", - "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits", + "category": "Networking", + "checklist": "Azure Stack HCI Review", + "guid": "a8ecf23c-c048-4fa9-b87b-51ebfb409863", + "id": "04.01.02", "services": [ - "Subscriptions" + "VM" ], - "severity": "Medium", - "subcategory": "Subscriptions", - "text": "Ensure that all subscription owners and IT core team are aware of subscription quotas and the impact they have on provision resources for a given subscription.", - "waf": "Security" + "severity": "Low", + "subcategory": "VM Management - Resource Bridge", + "text": "DHCP is available in the cluster to support Guest Configuration at VM deployment from Azure", + "waf": "Operations" }, { - "ammp": true, - "category": "Resource Organization", - "checklist": "Azure Landing Zone Review", - "guid": "c68e1d76-6673-413b-9f56-64b5e984a859", - "id": "C02.10", - "link": "https://learn.microsoft.com/azure/cost-management-billing/reservations/save-compute-costs-reservations", + "category": "Backup and Disaster Recovery", + "checklist": "Azure Stack HCI Review", + "guid": "074541e3-fe08-458a-8062-32d13dcc10c6", + "id": "05.01.01", + "link": "https://learn.microsoft.com/azure/backup/back-up-azure-stack-hyperconverged-infrastructure-virtual-machines", "services": [ "VM", - "Subscriptions", - "Cost", - "AzurePolicy" + "Backup", + "ASR" ], "severity": "High", - "subcategory": "Subscriptions", - "text": "Use Reserved Instances where appropriate to optimize cost and ensure available capacity in target regions. Enforce the use of purchased Reserved Instance VM SKUs via Azure Policy.", - "training": "https://learn.microsoft.com/learn/paths/improve-reliability-modern-operations/", - "waf": "Security" + "subcategory": "VM", + "text": "Backups of HCI VMs have been configured using MABS or a third-party solution", + "waf": "Operations" }, { - "ammp": true, - "category": "Resource Organization", - "checklist": "Azure Landing Zone Review", - "guid": "c773e7d2-6162-43a7-95a9-17e1f348ef25", - "id": "C02.11", - "link": "https://learn.microsoft.com/azure/architecture/framework/scalability/design-capacity", - "services": [ - "Monitor", - "Subscriptions" - ], + "category": "Operations", + "checklist": "Azure Stack HCI Review", + "guid": "48f7ae57-1035-4101-8a38-fbe163d03e8a", + "id": "06.01.01", + "services": [], "severity": "High", - "subcategory": "Subscriptions", - "text": "Enforce a dashboard, workbook, or manual process to monitor used capacity levels", - "training": "https://learn.microsoft.com/learn/paths/monitor-usage-performance-availability-resources-azure-monitor/", - "waf": "Security" + "subcategory": "Cluster Configuration", + "text": "Cluster configuration or a configuration script has been documented and maintained", + "waf": "Operations" }, { - "ammp": true, - "category": "Resource Organization", - "checklist": "Azure Landing Zone Review", - "guid": "ae28c84c-33b6-4b78-88b9-fe5c41049d40", - "id": "C02.12", - "link": "https://learn.microsoft.com/azure/cost-management-billing/cost-management-billing-overview", - "services": [ - "Subscriptions", - "Cost" - ], + "category": "Operations", + "checklist": "Azure Stack HCI Review", + "guid": "f2a6a19a-ffe6-444d-badb-cb336c8e7b50", + "id": "06.01.02", + "link": "https://learn.microsoft.com/azure-stack/hci/manage/witness", + "services": [], "severity": "High", - "subcategory": "Subscriptions", - "text": "Enforce a process for cost management", - "training": "https://learn.microsoft.com/learn/paths/control-spending-manage-bills/", - "waf": "Security" + "subcategory": "Cluster Configuration", + "text": "A cluster witness has been configured for clusters with less than 5 nodes", + "waf": "Reliability" }, { - "category": "Resource Organization", - "checklist": "Azure Landing Zone Review", - "guid": "3a923c34-74d0-4001-aac6-a9e01e6a83de", - "id": "C02.13", - "link": "https://learn.microsoft.com/azure/governance/management-groups/overview", + "category": "Operations", + "checklist": "Azure Stack HCI Review", + "guid": "a47339fe-62c5-44a0-bb83-3d46ef16292f", + "id": "06.01.03", + "link": "https://learn.microsoft.com/azure-stack/hci/manage/update-cluster", + "services": [], + "severity": "Medium", + "subcategory": "Cluster Configuration", + "text": "Cluster-Aware Updating has been configured for Windows and hardware updates (if available)", + "waf": "Operations" + }, + { + "category": "Operations", + "checklist": "Azure Stack HCI Review", + "guid": "7f1d6fe8-3079-44ea-8ea6-14494d1aa470", + "id": "06.01.04", + "link": "https://learn.microsoft.com/azure-stack/hci/deploy/validate", + "services": [], + "severity": "High", + "subcategory": "Cluster Configuration", + "text": "Cluster validation has been run against the configured cluster", + "waf": "Reliability" + }, + { + "category": "Operations", + "checklist": "Azure Stack HCI Review", + "guid": "81693af0-5638-4aa2-a153-1d6189df30a7", + "id": "06.01.05", + "link": "https://learn.microsoft.com/azure-stack/hci/manage/azure-benefits", "services": [ - "Entra", - "Subscriptions" + "VM" ], "severity": "Medium", - "subcategory": "Subscriptions", - "text": "If servers will be used for Identity services, like domain controllers, establish a dedicated identity subscription in the identity management group, to host these services", - "training": "https://learn.microsoft.com/learn/paths/enterprise-scale-architecture/", - "waf": "Security" + "subcategory": "Cluster Configuration", + "text": "Azure Benefits has been enabled at the cluster and VM levels", + "waf": "Cost" }, { - "category": "Resource Organization", - "checklist": "Azure Landing Zone Review", - "graph": "resources | extend compliant = isnotnull(['tags']) | project name, id, subscriptionId, resourceGroup, tags, compliant", - "guid": "5de32c19-9248-4160-9d5d-1e4e614658d3", - "id": "C02.14", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/track-costs", + "category": "Operations", + "checklist": "Azure Stack HCI Review", + "guid": "8c967ee8-8170-4537-a28d-33431cd3632a", + "id": "06.01.06", + "link": "https://learn.microsoft.com/azure-stack/hci/manage/use-environment-checker", + "services": [], + "severity": "Medium", + "subcategory": "Cluster Configuration", + "text": "The Environment Checker module has been run to validate the environment", + "waf": "Reliability" + }, + { + "category": "Operations", + "checklist": "Azure Stack HCI Review", + "guid": "43ffbfab-766e-4950-a102-78b479136e4d", + "id": "06.02.01", + "link": "https://learn.microsoft.com/azure-stack/hci/manage/azure-benefits", "services": [ - "Subscriptions", - "Cost" + "AzurePolicy" ], "severity": "Medium", - "subcategory": "Subscriptions", - "text": "Ensure tags are used for billing and cost management", - "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", - "waf": "Security" + "subcategory": "Cluster Configuration", + "text": "Group Policy inheritance on the HCI cluster and node Active Directory organizational unit has been blocked or applied policies have been evaluated for compatibility issues (usually WinRM and PowerShell execution policy)", + "waf": "Operations" }, { - "category": "Resource Organization", - "checklist": "Azure Landing Zone Review", - "guid": "6cc0ea22-42bb-441e-a345-804ab0a09666", - "id": "C02.15", - "link": "https://github.com/Azure/sovereign-landing-zone/blob/main/docs/02-Architecture.md", + "category": "Operations", + "checklist": "Azure Stack HCI Review", + "guid": "e6a3f3a7-4a7d-49e2-985a-6e39dd284027", + "id": "06.02.02", + "services": [], + "severity": "Medium", + "subcategory": "Cluster Configuration", + "text": "WAC is on the latest release and configured to automatically upgrade extensions", + "waf": "Reliability" + }, + { + "category": "Networking", + "checklist": "Azure Stack HCI Review", + "guid": "d1caa31f-cc26-42b2-b92f-2b667c0e6020", + "id": "07.01.01", + "link": "https://learn.microsoft.com/azure/architecture/hybrid/azure-stack-hci-dr", "services": [ - "Subscriptions" + "Entra" ], "severity": "Medium", - "subcategory": "Subscriptions", - "text": "For Sovereign Landing Zone, have a 'confidential corp' and 'confidential online' management group directly under the 'landing zones' MG.", - "waf": "Security" + "subcategory": "Stretch Clustering", + "text": "There is sub 5ms latency between each site if synchronous replication is being configured AAD", + "waf": "Performance" }, { - "category": "Resource Organization", - "checklist": "Azure Landing Zone Review", - "guid": "250d81ce-8bbe-4f85-9051-6a18a8221e50", - "id": "C03.01", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-setup-guide/regions", + "category": "Networking", + "checklist": "Azure Stack HCI Review", + "guid": "3277558e-3155-4088-b49a-78594cb4ce1a", + "id": "07.01.02", "services": [ - "Cost" + "VNet", + "Storage" ], "severity": "High", - "subcategory": "Regions", - "text": "Select the right Azure region/s for your deployment. Azure is a global-scale cloud platform that provide global coverage through many regions and geographies. Different Azure regions have different characteristics, access and availability models, costs, capacity, and services offered, then it is important to consider all criteria and requirements", - "training": "https://learn.microsoft.com/learn/modules/azure-architecture-fundamentals/", + "subcategory": "Stretch Clustering", + "text": "Management, Replication and Storage networks excluded from stretched VLANs configurations, are routed, and in different subnets", "waf": "Reliability" }, { - "category": "Resource Organization", - "checklist": "Azure Landing Zone Review", - "guid": "19ca3f89-397d-44b1-b5b6-5e18661372ac", - "id": "C03.02", - "link": "https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/azure-setup-guide/regions#operate-in-multiple-geographic-regions", + "category": "Operations", + "checklist": "Azure Stack HCI Review", + "guid": "baed6066-8531-44ba-bd94-38cbabbf4099", + "id": "07.02.01", + "services": [], + "severity": "High", + "subcategory": "Stretch Clustering", + "text": "There is a plan detailed for site failure and recovery", + "waf": "Operations" + }, + { + "category": "Networking", + "checklist": "Azure Stack HCI Review", + "guid": "8e62945f-b9ac-4a5c-a4e4-836f527010b4", + "id": "07.02.02", "services": [ - "ASR" + "ACR" ], "severity": "Medium", - "subcategory": "Regions", - "text": "Consider a multi-region deployment. Depending on customer size, locations, and users presence, operating in multiple regions can be a common choice to deliver services and run applications closer to them. Using a multi-region deployment is also important to provide geo disaster recovery capabilities, to eliminate the dependency from a single region capacity and diminish the risk of a temporary and localized resource capacity constraint", - "training": "https://learn.microsoft.com/learn/modules/azure-architecture-fundamentals/", + "subcategory": "Stretch Clustering", + "text": "Separate vLANs and networks are used for each replication network across both sites", "waf": "Reliability" }, { - "category": "Resource Organization", - "checklist": "Azure Landing Zone Review", - "guid": "4c27d42e-8bba-4c75-9155-9ab9153e8908", - "id": "C03.03", - "link": "https://azure.microsoft.com/explore/global-infrastructure/products-by-region/", + "category": "Operations", + "checklist": "Azure Stack HCI Review", + "guid": "8e62945f-b9ac-4a5c-a4e4-836f527010b5", + "id": "07.02.03", + "link": "https://learn.microsoft.com/azure/architecture/hybrid/azure-stack-hci-dr#cost-optimization", + "services": [ + "Storage" + ], + "severity": "High", + "subcategory": "Stretch Clustering", + "text": "Use either a cloud witness or a file share witness in a third site for cluster quorum for clusters with less than 5 nodes", + "waf": "Reliability" + }, + { + "category": "Operations", + "checklist": "Azure Stack HCI Review", + "guid": "8e62945f-b9ac-4a5c-a4e4-836f527010b6", + "id": "07.02.04", + "link": "https://learn.microsoft.com/azure/architecture/hybrid/azure-stack-hci-dr#cost-optimization", "services": [], - "severity": "Medium", - "subcategory": "Regions", - "text": "Ensure required services and features are available within the chosen deployment regions", - "training": "https://learn.microsoft.com/learn/modules/azure-architecture-fundamentals/", + "severity": "High", + "subcategory": "Stretch Clustering", + "text": "When using data deduplication, only enable it on the primary/source volumes", "waf": "Reliability" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "373f482f-3e39-4d39-8aa4-7e566f6082b6", - "id": "D01.01", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-app-delivery", + "category": "Operations", + "checklist": "Azure Stack HCI Review", + "guid": "ac527887-f6f4-40a3-b883-e04d704f013b", + "id": "07.02.04", + "link": "https://learn.microsoft.com/windows-server/storage/storage-replica/stretch-cluster-replication-using-shared-storage#provision-operating-system-features-roles-storage-and-network", "services": [ - "FrontDoor", - "AppGW" + "Storage" + ], + "severity": "High", + "subcategory": "Stretch Clustering", + "text": "Storage backing log volumes must be faster (ideally) or at least as fast as capacity storage", + "waf": "Reliability" + }, + { + "category": "Backup and Disaster Recovery", + "checklist": "Azure Stack HCI Review", + "guid": "8ea49f70-1038-4283-b0c4-230165d3eabc", + "id": "08.01.01", + "link": "https://learn.microsoft.com/azure-stack/hci/manage/azure-site-recovery", + "services": [ + "ASR", + "Backup" ], "severity": "Medium", - "subcategory": "App delivery", - "text": "Develop a plan for securing the delivery application content from your Workload spokes using Application Gateway and Azure Front door. You can use the Application Delivery checklist to for recommendations.", + "subcategory": "Disaster Recovery", + "text": "Azure Site Recovery has been considered for DR purposes", "waf": "Operations" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "6138a720-0f1c-4e16-bd30-1d6e872e52e3", - "id": "D01.02", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/resource-org-management-groups#management-groups-in-the-azure-landing-zone-accelerator", + "category": "Security", + "checklist": "Azure Stack HCI Review", + "guid": "03e65fdc-2628-4a1a-ba2e-a5174340ba52", + "id": "09.01.01", + "link": "https://learn.microsoft.com/windows/security/operating-system-security/data-protection/bitlocker/protecting-cluster-shared-volumes-and-storage-area-networks-with-bitlocker", "services": [], "severity": "Medium", - "subcategory": "App delivery", - "text": "Perform app delivery within landing zones for both internal-facing (corp) and external-facing apps (online).", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "subcategory": "Host", + "text": "BitLocker has been enabled on CSVs for volume encryption, where appropriate", "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "143b16c3-1d7a-4a9b-9470-4489a8042d88", - "id": "D01.03", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", - "services": [ - "DDoS" - ], + "category": "Security", + "checklist": "Azure Stack HCI Review", + "guid": "9645d2e6-ba28-453c-b6d5-d9ef29fc34be", + "id": "09.01.02", + "link": "https://learn.microsoft.com/windows-server/storage/file-server/smb-security", + "services": [], "severity": "Medium", - "subcategory": "App delivery", - "text": "Use a DDoS Network or IP protection plans for all Public IP addresses in application landing zones.", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "subcategory": "Host", + "text": "SMB encryption has been enabled, where appropriate", "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "de0d5973-cd4c-4d21-a088-137f5e6c4cfd", - "id": "D02.01", - "link": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", + "category": "Security", + "checklist": "Azure Stack HCI Review", + "guid": "8f03437a-5068-4486-9a78-0402ce771298", + "id": "09.01.03", + "link": "https://learn.microsoft.com/microsoft-365/security/defender-endpoint/microsoft-defender-antivirus-on-windows-server", "services": [ - "ExpressRoute" + "Defender" ], "severity": "Medium", - "subcategory": "Encryption", - "text": "When you're using ExpressRoute Direct, configure MACsec in order to encrypt traffic at the layer-two level between the organization's routers and MSEE. The diagram shows this encryption in flow.", + "subcategory": "Host", + "text": "Microsoft Defender Antivirus has been enabled on all nodes", "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "ed301d6e-872e-452e-9611-cc58b5a4b151", - "id": "D02.02", - "link": "https://learn.microsoft.com/azure/expressroute/expressroute-erdirect-about", - "services": [ - "ExpressRoute", - "VPN" - ], - "severity": "Low", - "subcategory": "Encryption", - "text": "For scenarios where MACsec isn't an option (for example, not using ExpressRoute Direct), use a VPN gateway to establish IPsec tunnels over ExpressRoute private peering. ", - "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "category": "Security", + "checklist": "Azure Stack HCI Review", + "guid": "dba6b211-fc02-43b3-b7c8-f163c188332e", + "id": "09.01.04", + "link": "https://learn.microsoft.com/windows/security/identity-protection/credential-guard/credential-guard-manage", + "services": [], + "severity": "Medium", + "subcategory": "Host", + "text": "Credential Guard has been configured, where appropriate", "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "e8bbac75-7155-49ab-a153-e8908ae28c84", - "id": "D03.01", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/enterprise-scale/network-topology-and-connectivity", + "category": "Defender For Cloud", + "checklist": "Azure Security Review Checklist", + "guid": "54174158-33fb-43ae-9c2d-e743165c3acb", + "link": "https://learn.microsoft.com/azure/security-center/security-center-get-started", "services": [ - "VNet" + "Subscriptions", + "Defender" ], - "severity": "Medium", - "subcategory": "Hub and spoke", - "text": "Consider a network design based on the traditional hub-and-spoke network topology for network scenarios that require maximum flexibility.", - "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", - "waf": "Security" + "severity": "High", + "subcategory": "Pricing & Settings", + "text": "Security Center/Defender enable in all subscriptions" }, { - "ammp": true, - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "7dd61623-a364-4a90-9eca-e48ebd54cd7d", - "id": "D03.02", - "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/hybrid-networking/expressroute", + "category": "Defender For Cloud", + "checklist": "Azure Security Review Checklist", + "guid": "349f0364-d28d-442e-abbb-c868255abc91", + "link": "https://learn.microsoft.com/azure/security-center/enable-azure-defender", "services": [ - "VPN", - "DNS", - "ExpressRoute", - "Entra", - "Firewall", - "VNet", - "NVA" + "Monitor", + "Defender" ], "severity": "High", - "subcategory": "Hub and spoke", - "text": "Ensure that shared networking services, including ExpressRoute gateways, VPN gateways, and Azure Firewall or partner NVAs in the central-hub virtual network. If necessary, also deploy DNS servers.", - "waf": "Cost" + "subcategory": "Pricing & Settings", + "text": "Security Center/Defender enabled on all Log Analytics workspaces" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "e2e8abac-3571-4559-ab91-53e89f89dc7b", - "id": "D03.03", - "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/dmz/nva-ha", + "category": "Defender For Cloud", + "checklist": "Azure Security Review Checklist", + "guid": "64e9a19a-e28c-484c-93b6-b7818ca0e6c4", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/enable-data-collection?tabs=autoprovision-feature#what-event-types-are-stored-for-common-and-minimal", "services": [ - "NVA" + "Defender" ], "severity": "Medium", - "subcategory": "Hub and spoke", - "text": "When deploying partner networking technologies or NVAs, follow the partner vendor's guidance", - "waf": "Reliability" + "subcategory": "Pricing & Settings", + "text": "Data collection set to 'Common'" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "ce463dbb-bc8a-4c2a-aebc-92a43da1dae2", - "id": "D03.04", - "link": "https://learn.microsoft.com/azure/expressroute/expressroute-howto-coexist-resource-manager#to-enable-transit-routing-between-expressroute-and-azure-vpn", + "category": "Defender For Cloud", + "checklist": "Azure Security Review Checklist", + "guid": "2149d414-a923-4c35-94d1-1029bd6aaf11", + "link": "https://learn.microsoft.com/azure/security-center/enable-azure-defender", "services": [ - "ExpressRoute", - "VPN", - "ARS" + "Defender" ], - "severity": "Low", - "subcategory": "Hub and spoke", - "text": "If you need transit between ExpressRoute and VPN gateways in hub and spoke scenarios, use Azure Route Server.", - "waf": "Security" + "severity": "High", + "subcategory": "Pricing & Settings", + "text": "Defender for Cloud enhanced security features are all enabled" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant", - "guid": "91b9d7d5-91e1-4dcb-8f1f-fa7e465646cc", - "id": "D03.05", - "link": "https://learn.microsoft.com/azure/route-server/quickstart-configure-route-server-portal#create-a-route-server-1", + "category": "Defender For Cloud", + "checklist": "Azure Security Review Checklist", + "guid": "e6b84ee5-ef43-4d29-a248-1718d5d1f5f7", + "link": "https://learn.microsoft.com/azure/security-center/security-center-enable-data-collection", "services": [ - "VNet", - "ARS" + "AzurePolicy", + "Defender" + ], + "severity": "Medium", + "subcategory": "Pricing & Settings", + "text": "Auto-provisioning enabled as per company policy (policy must exist)" + }, + { + "category": "Defender For Cloud", + "checklist": "Azure Security Review Checklist", + "guid": "25759e35-680e-4782-9ac9-32213d027ff4", + "link": "https://learn.microsoft.com/azure/security-center/security-center-provide-security-contact-details", + "services": [ + "AzurePolicy", + "Defender" ], "severity": "Low", - "subcategory": "Hub and spoke", - "text": "If using Route Server, use a /27 prefix for the Route Server subnet.", - "waf": "Security" + "subcategory": "Pricing & Settings", + "text": "Email notifications enabled as per company policy (policy must exist)" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "cc881471-607c-41cc-a0e6-14658dd558f9", - "id": "D03.06", - "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-faq#can-i-create-a-peering-connection-to-a-vnet-in-a-different-region", + "category": "Defender For Cloud", + "checklist": "Azure Security Review Checklist", + "guid": "12f70993-0631-4583-9ee7-9d6c6d363206", + "link": "https://learn.microsoft.com/azure/security-center/security-center-wdatp?WT.mc_id=Portal-Microsoft_Azure_Security_CloudNativeCompute&tabs=windows", "services": [ - "ACR", - "VNet" + "Defender" ], "severity": "Medium", - "subcategory": "Hub and spoke", - "text": "For network architectures with multiple hub-and-spoke topologies across Azure regions, use global virtual network peerings between the hub VNets to connect the regions to each other. ", - "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-virtual-networks/", - "waf": "Performance" + "subcategory": "Pricing & Settings", + "text": "Enable integrations options are selected " }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "4722d929-c1b1-4cd6-81f5-4b29bade39ad", - "id": "D03.07", - "link": "https://learn.microsoft.com/azure/azure-monitor/insights/network-insights-overview", + "category": "Defender For Cloud", + "checklist": "Azure Security Review Checklist", + "guid": "5b7abae4-4aad-45e8-a79e-2e86667313c5", + "link": "https://learn.microsoft.com/azure/security-center/defender-for-container-registries-cicd", "services": [ - "Monitor" + "Defender" ], "severity": "Medium", - "subcategory": "Hub and spoke", - "text": "Use Azure Monitor for Networks to monitor the end-to-end state of the networks on Azure.", - "training": "https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/", - "waf": "Operations" + "subcategory": "Pricing & Settings", + "text": "CI/CD integration is configured" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "graph": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant", - "guid": "0e7c28ec-9366-4572-83b0-f4664b1d944a", - "id": "D03.08", - "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits", + "category": "Defender For Cloud", + "checklist": "Azure Security Review Checklist", + "guid": "05675c5e-985b-4859-a774-f7e371623b87", + "link": "https://learn.microsoft.com/azure/security-center/continuous-export?tabs=azure-portal", "services": [ - "VNet", - "ExpressRoute", - "Entra" + "EventHubs", + "Defender" ], - "severity": "Medium", - "subcategory": "Hub and spoke", - "text": "When connecting spoke virtual networks to the central hub virtual network, consider VNet peering limits (500), the maximum number of prefixes that can be advertised via ExpressRoute (1000)", - "waf": "Reliability" + "severity": "High", + "subcategory": "Pricing & Settings", + "text": "Continuous export 'Event Hub' is enabled if using 3rd party SIEM" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant", - "guid": "3d457936-e9b7-41eb-bdff-314b26450b12", - "id": "D03.09", - "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits", + "category": "Defender For Cloud", + "checklist": "Azure Security Review Checklist", + "guid": "5a917e1f-349f-4036-9d28-d42e8bbbc868", + "link": "https://learn.microsoft.com/azure/security-center/continuous-export?tabs=azure-portal", "services": [ - "Storage" + "Monitor", + "Sentinel", + "Defender" ], "severity": "Medium", - "subcategory": "Hub and spoke", - "text": "Consider the limit of routes per route table (400).", - "waf": "Reliability" + "subcategory": "Pricing & Settings", + "text": "Continuous export 'Log Analytics Workspace' is enabled if not using Azure Sentinel" }, { - "ammp": true, - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "graph": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True)", - "guid": "c76cb5a2-abe2-11ed-afa1-0242ac120002", - "id": "D03.10", - "link": "https://learn.microsoft.com/azure/virtual-network/virtual-network-manage-peering", + "category": "Defender For Cloud", + "checklist": "Azure Security Review Checklist", + "guid": "255abc91-64e9-4a19-ae28-c84c43b6b781", + "link": "https://learn.microsoft.com/azure/security-center/quickstart-onboard-aws?WT.mc_id=Portal-Microsoft_Azure_Security", "services": [ - "VNet" + "Defender" ], "severity": "High", - "subcategory": "Hub and spoke", - "text": "Use the setting 'Allow traffic to remote virtual network' when configuring VNet peerings", - "waf": "Reliability" + "subcategory": "Pricing & Settings", + "text": "Cloud connector enabled for AWS" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "359c373e-7dd6-4162-9a36-4a907ecae48e", - "id": "D04.01", - "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/hybrid-networking/hub-spoke?tabs=cli", + "category": "Defender For Cloud", + "checklist": "Azure Security Review Checklist", + "guid": "8ca0e6c4-2149-4d41-9a92-3c3574d11029", + "link": "https://learn.microsoft.com/azure/security-center/quickstart-onboard-gcp", "services": [ - "ExpressRoute" + "Defender" ], - "severity": "Medium", - "subcategory": "Hybrid", - "text": "Ensure that you have investigated the possibility to use ExpressRoute as primary connection to Azure.", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", - "waf": "Performance" + "severity": "High", + "subcategory": "Pricing & Settings", + "text": "Cloud connector enabled for GCP" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "description": "You can use AS-path prepending and connection weights to influence traffic from Azure to on-premises, and the full range of BGP attributes in your own routers to influence traffic from on-premises to Azure.", - "guid": "f29812b2-363c-4efe-879b-599de0d5973c", - "id": "D04.02", - "link": "https://learn.microsoft.com/azure/expressroute/expressroute-routing", + "category": "Defender For Cloud", + "checklist": "Azure Security Review Checklist", + "guid": "cce9bdf6-b483-45a0-85ec-c8232b230652", + "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy-integrate-with-microsoft-cloud-application-security", "services": [ - "ExpressRoute" + "Monitor", + "Entra", + "Defender" ], - "severity": "Medium", - "subcategory": "Hybrid", - "text": "When you use multiple ExpressRoute circuits, or multiple on-prem locations, make sure to optimize routing with BGP attributes, if certain paths are preferred.", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", - "waf": "Reliability" + "severity": "Low", + "subcategory": "Pricing & Settings", + "text": "If using Azure AD Application proxy, consider integrating with Microsoft Defender for Cloud Apps to monitor application access in real-time and apply advanced security controls." }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "graph": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant", - "guid": "d4cd21b0-8813-47f5-b6c4-cfd3e504547c", - "id": "D04.03", - "link": "https://learn.microsoft.com/azure/expressroute/expressroute-routing", + "category": "Defender For Cloud", + "checklist": "Azure Security Review Checklist", + "guid": "df9cc234-18db-4611-9126-5f4bb47a393a", + "link": "https://learn.microsoft.com/azure/security-center/secure-score-security-controls", "services": [ - "ExpressRoute", - "VPN" + "Defender" ], "severity": "Medium", - "subcategory": "Hybrid", - "text": "Ensure that you're using the right SKU for the ExpressRoute/VPN gateways based on bandwidth and performance requirements.", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", - "waf": "Performance" + "subcategory": "Recommendations", + "text": "All recommendations remediated or disabled if not required." }, { - "ammp": true, - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant", - "guid": "7025b442-f6e9-4af6-b11f-c9574916016f", - "id": "D04.04", - "link": "https://learn.microsoft.com/azure/expressroute/plan-manage-cost", + "category": "Defender For Cloud", + "checklist": "Azure Security Review Checklist", + "description": "Microsoft minimum target for all customers is 70%", + "guid": "08032729-4798-4b15-98a2-19a46ceb5443", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/secure-score-security-controls", "services": [ - "ExpressRoute", - "Cost" + "Defender" ], "severity": "High", - "subcategory": "Hybrid", - "text": "Ensure that you're using unlimited-data ExpressRoute circuits only if you reach the bandwidth that justifies their cost.", - "waf": "Cost" + "subcategory": "Recommendations", + "text": "Security Score>70%" }, { - "ammp": true, - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id", - "guid": "f4e7926a-ec35-476e-a412-5dd17136bd62", - "id": "D04.05", - "link": "https://learn.microsoft.com/azure/expressroute/expressroute-faqs#expressroute-local", + "category": "Defender For Cloud", + "checklist": "Azure Security Review Checklist", + "guid": "50259226-4429-42bb-9285-37a55119bf8e", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/tutorial-security-incident", "services": [ - "ExpressRoute", - "Cost" + "Monitor", + "Defender" ], - "severity": "High", - "subcategory": "Hybrid", - "text": "Leverage the Local SKU of ExpressRoute to reduce the cost of your circuits, if your circuits' peering location supports your Azure regions for the Local SKU.", - "waf": "Cost" + "severity": "Medium", + "subcategory": "Security Alerts", + "text": "Security Alerts contain only those generated in the past 24 hours (remediate or disable older security alerts)" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "graph": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant", - "guid": "2447ec66-138a-4720-8f1c-e16ed301d6e8", - "id": "D04.06", - "link": "https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways", + "category": "Defender For Cloud", + "checklist": "Azure Security Review Checklist", + "guid": "8f585428-7d9c-4dc1-96cd-072af9b141a8", + "link": "https://learn.microsoft.com/azure/security-center/custom-dashboards-azure-workbooks", "services": [ - "ExpressRoute" + "Defender" ], "severity": "Medium", - "subcategory": "Hybrid", - "text": "Deploy a zone-redundant ExpressRoute gateway in the supported Azure regions.", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", - "waf": "Reliability" + "subcategory": "Workbooks", + "text": "If continuous export is enabled, default workbooks published to custom security dashboard" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "72e52e36-11cc-458b-9a4b-1511e43a58a9", - "id": "D04.07", - "link": "https://learn.microsoft.com/azure/networking/", + "category": "Defender For Cloud", + "checklist": "Azure Security Review Checklist", + "guid": "98a535e7-3789-47e7-8ca7-da7be9962a15", + "link": "https://techcommunity.microsoft.com/t5/microsoft-defender-for-cloud/bd-p/MicrosoftDefenderCloud", "services": [ - "ExpressRoute" + "Defender" ], "severity": "Medium", - "subcategory": "Hybrid", - "text": "For scenarios that require bandwidth higher than 10 Gbps or dedicated 10/100-Gbps ports, use ExpressRoute Direct.", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", - "waf": "Performance" + "subcategory": "Community", + "text": "Customer is aware of the value of the 'Community' page and has a regular cadence set up to review" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "c2299c4d-7b57-4d0c-9555-62f2b3e4563a", - "id": "D04.08", - "link": "https://learn.microsoft.com/azure/expressroute/about-fastpath", + "category": "Defender For Cloud", + "checklist": "Azure Security Review Checklist", + "description": "Customer Operational best practice - Transparency", + "guid": "93846da9-7cc3-4923-856b-22586f4a1641", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/enable-enhanced-security", "services": [ - "ExpressRoute" + "Subscriptions", + "Defender" ], - "severity": "Medium", - "subcategory": "Hybrid", - "text": "When low latency is required, or throughput from on-premises to Azure must be greater than 10 Gbps, enable FastPath to bypass the ExpressRoute gateway from the data path.", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", - "waf": "Performance" + "severity": "High", + "subcategory": "Secure Score", + "text": "All subscriptions protected by Security Center are shown (no subscription filter set)" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant", - "guid": "4d873974-8b66-42d6-b15f-512a65498f6d", - "id": "D04.09", - "link": "https://learn.microsoft.com/azure/vpn-gateway/create-zone-redundant-vnet-gateway", + "category": "Defender For Cloud", + "checklist": "Azure Security Review Checklist", + "guid": "bdddea8a-487c-4deb-9861-bc3bc14aea6e", + "link": "https://learn.microsoft.com/azure/security-center/security-center-compliance-dashboard", "services": [ - "VPN" + "Defender" ], - "severity": "Medium", - "subcategory": "Hybrid", - "text": "Use VPN gateways to connect branches or remote locations to Azure. For higher resilience, deploy zone-redundant gateways (where available).", - "training": "https://learn.microsoft.com/training/modules/intro-to-azure-vpn-gateway/", - "waf": "Reliability" + "severity": "High", + "subcategory": "Regulatory Compliance", + "text": "Compliance controls are green for any required compliance requirements" }, { - "ammp": true, - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "718cb437-b060-2589-8856-2e93a5c6633b", - "id": "D04.10", - "link": "https://learn.microsoft.com/azure/expressroute/expressroute-erdirect-about", + "category": "Defender For Cloud", + "checklist": "Azure Security Review Checklist", + "description": "Customer Operational best practice - verify", + "guid": "65e8d9a3-aec2-418e-9436-b0736db55f57", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/remediate-vulnerability-findings-vm", "services": [ - "ExpressRoute", - "Cost" + "VM", + "Defender" ], "severity": "High", - "subcategory": "Hybrid", - "text": "If using ExpressRoute Direct, consider using ExpressRoute Local circuits to the local Azure regions to save costs", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", - "waf": "Cost" + "subcategory": "Azure Defender", + "text": "High severity VM vulnerabilities is zero (empty)" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "8042d88e-79d1-47b7-9b22-a5a67e7a8ed4", - "id": "D04.11", - "link": "https://learn.microsoft.com/azure/architecture/framework/services/networking/expressroute/reliability", + "category": "Defender For Cloud", + "checklist": "Azure Security Review Checklist", + "guid": "9603334b-df9c-4c23-918d-b61171265f4b", + "link": "https://techcommunity.microsoft.com/t5/azure-network-security/azure-firewall-manager-is-now-integrated-with-azure-security/ba-p/2228679", "services": [ - "ExpressRoute" + "Firewall", + "Defender" ], "severity": "Medium", - "subcategory": "Hybrid", - "text": "When traffic isolation or dedicated bandwidth is required, such as for separating production and nonproduction environments, use different ExpressRoute circuits. It will help you ensure isolated routing domains and alleviate noisy-neighbor risks.", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", - "waf": "Security" + "subcategory": "Firewall Manager", + "text": "Hubs are protected by an Azure Firewall" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "b30e38c3-f298-412b-8363-cefe179b599d", - "id": "D04.12", - "link": "https://learn.microsoft.com/azure/expressroute/expressroute-monitoring-metrics-alerts", + "category": "Defender For Cloud", + "checklist": "Azure Security Review Checklist", + "description": "Customer Operational best practice - verify", + "guid": "b47a393a-0803-4272-a479-8b1578a219a4", + "link": "https://learn.microsoft.com/azure/security/fundamentals/network-best-practices", "services": [ - "ExpressRoute", - "Monitor" + "VNet", + "Firewall", + "Defender" ], "severity": "Medium", - "subcategory": "Hybrid", - "text": "Monitor ExpressRoute availability and utilization using built-in Express Route Insights.", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", - "waf": "Operations" + "subcategory": "Firewall Manager", + "text": "Virtual Networks are protected by a Firewall" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "5bf68dc9-325e-4873-bf88-f8214ef2e5d2", - "id": "D04.13", - "link": "https://learn.microsoft.com/azure/expressroute/how-to-configure-connection-monitor", + "category": "Defender For Cloud", + "checklist": "Azure Security Review Checklist", + "guid": "6ceb5443-5025-4922-9442-92bb628537a5", + "link": "https://azure.microsoft.com/blog/how-azure-security-center-detects-ddos-attack-using-cyber-threat-intelligence/", "services": [ - "ACR", - "Monitor", - "NetworkWatcher" + "Firewall", + "DDoS", + "Defender" ], "severity": "Medium", - "subcategory": "Hybrid", - "text": "Use Connection Monitor for connectivity monitoring across the network, especially between on-premises and Azure.", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", - "waf": "Operations" + "subcategory": "Firewall Manager", + "text": "DDoS Standard enabled" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "e0d5973c-d4cd-421b-8881-37f5e6c4cfd3", - "id": "D04.14", - "link": "https://learn.microsoft.com/azure/expressroute/designing-for-disaster-recovery-with-expressroute-privatepeering#challenges-of-using-multiple-expressroute-circuits", + "category": "Defender For Cloud", + "checklist": "Azure Security Review Checklist", + "guid": "5119bf8e-8f58-4542-a7d9-cdc166cd072a", + "link": "https://learn.microsoft.com/azure/security-center/security-center-get-started?WT.mc_id=Portal-Microsoft_Azure_Security", "services": [ - "ExpressRoute" + "Subscriptions", + "Defender" ], - "severity": "Medium", - "subcategory": "Hybrid", - "text": "Use ExpressRoute circuits from different peering locations for redundancy.", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", - "waf": "Reliability" + "severity": "High", + "subcategory": "Coverage", + "text": "Verify that all subscriptions are covered (see pricing and settings to modify)" }, { - "ammp": true, - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation))", - "guid": "72105cc8-aaea-4ee1-8c7a-ad25977afcaf", - "id": "D04.16", - "link": "https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings#gwsub", + "category": "Azure Networking", + "checklist": "Azure Security Review Checklist", + "guid": "4df585ec-dce9-4793-a7bc-db3b51eb2eb0", + "link": "https://learn.microsoft.com/azure/virtual-network/ip-services/public-ip-addresses", "services": [ - "Storage", + "VM", "VNet" ], "severity": "High", - "subcategory": "Hybrid", - "text": "If you are using a route table in the GatewaySubnet, make sure that gateway routes are propagated.", - "waf": "Reliability" + "subcategory": "Public IPs", + "text": "VM's with public IPs should be protected by NSG " }, { - "ammp": true, - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "d581a947-69a2-4783-942e-9df3664324c8", - "id": "D04.17", - "link": "https://learn.microsoft.com/azure/expressroute/designing-for-high-availability-with-expressroute#active-active-connections", + "category": "Azure Networking", + "checklist": "Azure Security Review Checklist", + "description": "Customer operational best practice - verify", + "guid": "3dda6e59-d7c8-4a2e-bb11-7d6769af669c", + "link": "https://learn.microsoft.com/azure/virtual-network/ip-services/public-ip-addresses", "services": [ - "ACR", - "ExpressRoute" + "VM", + "Firewall", + "EventHubs" ], "severity": "High", - "subcategory": "Hybrid", - "text": "If using ExpressRoute, your on-premises routing should be dynamic: in the event of a connection failure it should converge to the remaining connection of the circuit. Load should be shared across both connections ideally as active/active, although active/passive is supported too.", - "waf": "Reliability" + "subcategory": "Public IPs", + "text": "VMs with public IPs are moved behind Azure Firewall Premium" + }, + { + "category": "Azure Networking", + "checklist": "Azure Security Review Checklist", + "description": "Customer operational best practice - verify", + "guid": "a48e5a85-f222-43ec-b8bb-12308ca5017f", + "link": "https://learn.microsoft.com/azure/virtual-network/ip-services/default-outbound-access", + "services": [ + "VM" + ], + "severity": "High", + "subcategory": "Public IPs", + "text": "VM's that don't need public IPs do not have public IPs (i.e. internal RDP only)" + }, + { + "category": "Azure Networking", + "checklist": "Azure Security Review Checklist", + "guid": "158e3ea3-a93c-42de-9e31-65c3a87a04b7", + "link": "https://learn.microsoft.com/azure/virtual-network/network-security-groups-overview", + "services": [ + "RBAC", + "VNet" + ], + "severity": "Medium", + "subcategory": "NSG", + "text": "NSG RBAC is used to restrict access to network security team" }, { - "ammp": true, - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "558fd772-49b8-4211-82df-27ee412e7f98", - "id": "D05.01", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing", + "category": "Azure Networking", + "checklist": "Azure Security Review Checklist", + "description": "Customer operational best practice - verify", + "guid": "a209939b-da47-4778-b24c-116785c2fa55", + "link": "https://learn.microsoft.com/azure/virtual-network/network-security-groups-overview", "services": [ - "ACR", "VNet" ], "severity": "High", - "subcategory": "IP plan", - "text": "Ensure no overlapping IP address spaces across Azure regions and on-premises locations are used", - "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", - "waf": "Security" + "subcategory": "NSG", + "text": "NSG Inbound security rules do not contain a * (wildcard) in Source field" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "graph": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\\\.|172\\\\.(1[6-9]|2[0-9]|3[01])\\\\.|192\\\\.168\\\\.)') | project id, compliant, cidr", - "guid": "3f630472-2dd6-49c5-a5c2-622f54b69bad", - "id": "D05.02", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing", + "category": "Azure Networking", + "checklist": "Azure Security Review Checklist", + "description": "Customer operational best practice - verify", + "guid": "b56a9480-08be-47d7-b4c4-76b6d8bdcf59", + "link": "https://learn.microsoft.com/azure/virtual-network/network-security-groups-overview", "services": [ "VNet" ], - "severity": "Low", - "subcategory": "IP plan", - "text": "Use IP addresses from the address allocation ranges for private internets (RFC 1918).", - "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", - "waf": "Security" + "severity": "Medium", + "subcategory": "NSG", + "text": "NSG outbound security rules are used to control traffic to specific IP addresses for traffic not routed through a Firewall" }, { - "ammp": true, - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "graph": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant", - "guid": "33aad5e8-c68e-41d7-9667-313b4f5664b5", - "id": "D05.03", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing", + "category": "Azure Networking", + "checklist": "Azure Security Review Checklist", + "description": "Customer operational best practice - verify", + "guid": "bce65de8-a13f-4988-9946-8d66a786d60f", + "link": "https://learn.microsoft.com/azure/virtual-network/network-security-groups-overview", "services": [ "VNet" ], "severity": "High", - "subcategory": "IP plan", - "text": "Ensure that IP address space isn't wasted, don't create unnecessarily large virtual networks (for example /16) ", - "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", - "waf": "Performance" + "subcategory": "NSG", + "text": "NSG do not have Source as a * (wildcard) in place." }, { - "ammp": true, - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "f348ef25-4c27-4d42-b8bb-ac7571559ab9", - "id": "D05.04", - "link": "https://learn.microsoft.com/azure/site-recovery/concepts-on-premises-to-azure-networking#retain-ip-addresses", + "category": "Azure Networking", + "checklist": "Azure Security Review Checklist", + "guid": "a6c97be9-955d-404c-9c49-c986cb2d1215", + "link": "https://learn.microsoft.com/azure/virtual-network/virtual-network-nsg-manage-log", "services": [ - "VNet" + "VNet", + "Sentinel" ], - "severity": "High", - "subcategory": "IP plan", - "text": "Avoid using overlapping IP address ranges for production and DR sites.", - "training": "https://learn.microsoft.com/learn/paths/az-104-manage-virtual-networks/", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "NSG", + "text": "NSG Diagnostics send NetworkSecurityGroupEvent and NetworkSecurityGroupRuleCounter traffic to Sentinel LAW" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "153e8908-ae28-4c84-a33b-6b7808b9fe5c", - "id": "D05.05", - "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-name-resolution-for-vms-and-role-instances", + "category": "Azure Networking", + "checklist": "Azure Security Review Checklist", + "guid": "aa124b6e-4df5-485e-adce-9793b7bcdb3b", + "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview", "services": [ - "DNS", + "RBAC", "VNet" ], "severity": "Medium", - "subcategory": "IP plan", - "text": "For environments where name resolution in Azure is all that's required, use Azure Private DNS for resolution with a delegated zone for name resolution (such as 'azure.contoso.com').", - "training": "https://learn.microsoft.com/learn/paths/az-104-manage-virtual-networks/", - "waf": "Operations" + "subcategory": "UDR", + "text": "UDR RBAC is used to restrict access to the network security team" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "41049d40-3a92-43c3-974d-00018ac6a9e0", - "id": "D05.06", - "link": "https://learn.microsoft.com/azure/dns/dns-private-resolver-overview", + "category": "Azure Networking", + "checklist": "Azure Security Review Checklist", + "guid": "51eb2eb0-3dda-46e5-ad7c-8a2edb117d67", + "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview", "services": [ - "ACR", - "DNS", - "VNet" + "VNet", + "Firewall" ], - "severity": "Medium", - "subcategory": "IP plan", - "text": "For environments where name resolution across Azure and on-premises is required, consider using Azure DNS Private Resolver.", - "training": "https://learn.microsoft.com/training/modules/intro-to-azure-dns-private-resolver/", - "waf": "Security" + "severity": "High", + "subcategory": "UDR", + "text": "If Zero Trust, then UDR's are used to send all traffic to the Azure Firewall Premium" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "1e6a83de-5de3-42c1-a924-81607d5d1e4e", - "id": "D05.07", - "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-name-resolution-for-vms-and-role-instances", + "category": "Azure Networking", + "checklist": "Azure Security Review Checklist", + "description": "Customer operational best practice - verify", + "guid": "69af669c-a48e-45a8-9f22-23ece8bb1230", + "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview", "services": [ - "DNS", "VNet" ], - "severity": "Low", - "subcategory": "IP plan", - "text": "Special workloads that require and deploy their own DNS (such as Red Hat OpenShift) should use their preferred DNS solution.", - "waf": "Operations" + "severity": "Medium", + "subcategory": "UDR", + "text": "UDR's that do not send all traffic to AzureFirewallPremium are known and documented." }, { - "ammp": true, - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "614658d3-558f-4d77-849b-821112df27ee", - "id": "D05.08", - "link": "https://learn.microsoft.com/azure/dns/private-dns-autoregistration", + "category": "Azure Networking", + "checklist": "Azure Security Review Checklist", + "guid": "8ca5017f-158e-43ea-9a93-c2de7e3165c3", + "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview#default", "services": [ - "VM", - "VNet", - "DNS" + "VNet" ], "severity": "High", - "subcategory": "IP plan", - "text": "Enable auto-registration for Azure DNS to automatically manage the lifecycle of the DNS records for the virtual machines deployed within a virtual network.", - "training": "https://learn.microsoft.com/learn/paths/az-104-manage-virtual-networks/", - "waf": "Operations" + "subcategory": "Virtual Networks", + "text": "Customer is familiar with Azure networking defaults / SDN default routing in Azure" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "ee1ac551-c4d5-46cf-b035-d0a3c50d87ad", - "id": "D06.01", - "link": "https://learn.microsoft.com/azure/bastion/bastion-overview", + "category": "Azure Networking", + "checklist": "Azure Security Review Checklist", + "description": "Customer operational best practice - verify", + "guid": "a87a04b7-a209-4939-ada4-7778f24c1167", + "link": "https://github.com/MicrosoftDocs/azure-docs/issues/53672", "services": [ - "Bastion" + "RBAC", + "VNet" ], "severity": "Medium", - "subcategory": "Internet", - "text": "Consider using Azure Bastion to securely connect to your network.", - "waf": "Security" + "subcategory": "Virtual Networks", + "text": "VNet RBAC is used to restrict access to the network security team" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant", - "guid": "6eab9eb6-762b-485e-8ea8-15aa5dba0bd0", - "id": "D06.02", - "link": "https://learn.microsoft.com/azure/bastion/bastion-faq#subnet", + "category": "Azure Networking", + "checklist": "Azure Security Review Checklist", + "guid": "85c2fa55-b56a-4948-808b-e7d7e4c476b6", + "link": "https://learn.microsoft.com/azure/virtual-network/policy-reference", "services": [ - "VNet", - "Bastion" + "VNet" ], - "severity": "Medium", - "subcategory": "Internet", - "text": "Use Azure Bastion in a subnet /26 or larger.", - "waf": "Security" + "severity": "High", + "subcategory": "Virtual Networks", + "text": "VNet Security recommendations are remediated and there are no 'At-risk' VNets " }, { - "ammp": true, - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "e6c4cfd3-e504-4547-a244-7ec66138a720", - "id": "D06.03", - "link": "https://learn.microsoft.com/azure/app-service/networking-features", + "category": "Azure Networking", + "checklist": "Azure Security Review Checklist", + "guid": "d8bdcf59-bce6-45de-aa13-f98879468d66", + "link": "https://learn.microsoft.com/azure/virtual-network/virtual-network-peering-overview", "services": [ - "Firewall" + "VNet" ], "severity": "High", - "subcategory": "Internet", - "text": "Use Azure Firewall to govern Azure outbound traffic to the internet, non-HTTP/S inbound connections, and East/West traffic filtering (if the organization requires it)", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", - "waf": "Security" + "subcategory": "Virtual Networks", + "text": "VNet Peering connections are understood and expected traffic flows are documented" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "5a4b1511-e43a-458a-ac22-99c4d7b57d0c", - "id": "D06.04", - "link": "https://learn.microsoft.com/azure/firewall/", + "category": "Azure Networking", + "checklist": "Azure Security Review Checklist", + "guid": "a786d60f-a6c9-47be-a955-d04c3c49c986", + "link": "https://learn.microsoft.com/azure/virtual-network/virtual-network-service-endpoints-overview", "services": [ - "Firewall", - "ACR", - "RBAC", - "AzurePolicy" + "VNet" ], - "severity": "Medium", - "subcategory": "Internet", - "text": "Create a global Azure Firewall policy to govern security posture across the global network environment and assign it to all Azure Firewall instances. Allow for granular policies to meet requirements of specific regions by delegating incremental firewall policies to local security teams via Azure role-based access control.", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", - "waf": "Security" + "severity": "High", + "subcategory": "Virtual Networks", + "text": "VNet Service Endpoints are in use, no legacy Public Service Endpoints exist" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "655562f2-b3e4-4563-a4d8-739748b662d6", - "id": "D06.05", - "link": "https://learn.microsoft.com/azure/firewall/", + "category": "Azure Networking", + "checklist": "Azure Security Review Checklist", + "guid": "1f625659-ee55-480a-9824-9c931213dbd7", + "link": "https://learn.microsoft.com/azure/private-link/private-endpoint-overview", "services": [ - "Firewall" + "VNet", + "PrivateLink" + ], + "severity": "High", + "subcategory": "Virtual Networks", + "text": "VNet Private Endpoints are in use to allow access from on-premises environments, no legacy public endpoints exist" + }, + { + "category": "Azure Networking", + "checklist": "Azure Security Review Checklist", + "guid": "fb012f70-943f-4630-9722-ea39d2b1ce63", + "link": "https://learn.microsoft.com/azure/virtual-network/monitor-virtual-network", + "services": [ + "Monitor", + "VNet" ], - "severity": "Low", - "subcategory": "Internet", - "text": "Configure supported partner SaaS security providers within Firewall Manager if the organization wants to use such solutions to help protect outbound connections.", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", - "waf": "Security" + "severity": "High", + "subcategory": "Virtual Networks", + "text": "VNet Monitoring enabled" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "1d7aa9b6-4704-4489-a804-2d88e79d17b7", - "id": "D06.06", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/afds-overview", + "category": "Azure Networking", + "checklist": "Azure Security Review Checklist", + "guid": "2055b29b-ade4-4aad-8e8c-39ec94666731", + "link": "https://learn.microsoft.com/azure/virtual-network/kubernetes-network-policies", "services": [ - "ACR", + "VNet", "AzurePolicy", - "FrontDoor", - "WAF" + "AKS" ], - "severity": "Medium", - "subcategory": "Internet", - "text": "Use Azure Front Door and WAF policies to provide global protection across Azure regions for inbound HTTP/S connections to a landing zone.", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", - "waf": "Security" + "severity": "High", + "subcategory": "Virtual Networks", + "text": "Secure traffic between pods using network policies in Azure Kubernetes Service (AKS)" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "3b22a5a6-7e7a-48ed-9b30-e38c3f29812b", - "id": "D06.07", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "category": "Azure Networking", + "checklist": "Azure Security Review Checklist", + "guid": "3c005674-c1e9-445b-959c-373e7ed71623", + "link": "https://learn.microsoft.com/azure/virtual-network/virtual-network-scenario-udr-gw-nva", "services": [ - "AzurePolicy", - "FrontDoor", - "AppGW", - "WAF" + "NVA", + "VNet" ], - "severity": "Low", - "subcategory": "Internet", - "text": "When using Azure Front Door and Azure Application Gateway to help protect HTTP/S apps, use WAF policies in Azure Front Door. Lock down Azure Application Gateway to receive traffic only from Azure Front Door.", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", - "waf": "Security" + "severity": "High", + "subcategory": "Virtual Networks", + "text": "VNet NVA (appliances) customer follows published architecture pattern" }, { - "ammp": true, - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "2363cefe-179b-4599-be0d-5973cd4cd21b", - "id": "D06.08", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "category": "Azure Networking", + "checklist": "Azure Security Review Checklist", + "guid": "b375a917-ecbe-448f-ae64-dd7df2e8bbbc", + "link": "https://learn.microsoft.com/azure/virtual-network/monitor-virtual-network", "services": [ + "Monitor", "VNet", - "WAF" + "Sentinel" ], "severity": "High", - "subcategory": "Internet", - "text": "Deploy WAFs and other reverse proxies are required for inbound HTTP/S connections, deploy them within a landing-zone virtual network and together with the apps that they're protecting and exposing to the internet.", - "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", - "waf": "Security" + "subcategory": "Virtual Networks", + "text": "VNet Diagnostic settings are enabled and sending VMProtectionAlerts to the Azure Sentinel LAW" }, { - "ammp": true, - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "088137f5-e6c4-4cfd-9e50-4547c2447ec6", - "id": "D06.09", - "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-reference-architectures", + "category": "Azure Networking", + "checklist": "Azure Security Review Checklist", + "guid": "468155ab-c916-44e9-a09a-ed8c44cf3b2b", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/connectivity-to-azure", "services": [ - "VNet", - "DDoS" + "ExpressRoute", + "VPN" ], "severity": "High", - "subcategory": "Internet", - "text": "Use Azure DDoS Network or IP Protection plans to help protect Public IP Addresses endpoints within the virtual networks.", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", - "waf": "Security" + "subcategory": "Connectivity", + "text": "Use ExpressRoute or VPN to access Azure resources from on-premises environments" }, { - "ammp": true, - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant", - "guid": "14d99880-2f88-47e8-a134-62a7d85c94af", - "id": "D06.10", - "link": "https://learn.microsoft.com/azure/firewall/fqdn-filtering-network-rules", + "category": "Azure Networking", + "checklist": "Azure Security Review Checklist", + "guid": "bd8ac2aa-ebca-42a4-9da1-dbf3dd992481", + "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-about", "services": [ - "Firewall", - "DNS" + "VWAN", + "RBAC" ], "severity": "High", - "subcategory": "Internet", - "text": "Use FQDN-based network rules and Azure Firewall with DNS proxy to filter egress traffic to the Internet over protocols not supported by application rules.", - "waf": "Security" + "subcategory": "Virtual WAN", + "text": "VWAN RBAC is used to restrict access to the network security team" }, { - "ammp": true, - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant", - "guid": "c10d51ef-f999-455d-bba0-5c90ece07447", - "id": "D06.11", - "link": "https://learn.microsoft.com/azure/firewall/premium-features", + "category": "Azure Networking", + "checklist": "Azure Security Review Checklist", + "guid": "718d1dca-1f62-4565-aee5-580a38249c93", + "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-global-transit-network-architecture", "services": [ - "Firewall" + "VWAN", + "Monitor" ], "severity": "High", - "subcategory": "Internet", - "text": "Use Azure Firewall Premium for additional security and protection.", - "waf": "Security" + "subcategory": "Virtual WAN", + "text": "VWAN Customer is using Secure Hub or external Firewall to route and monitor traffic." }, { - "ammp": true, - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant", - "guid": "e9c8f584-6d5e-473b-8dc5-acc9fbaab4e3", - "id": "D06.12", - "link": "https://learn.microsoft.com/azure/firewall/premium-features", + "category": "Azure Networking", + "checklist": "Azure Security Review Checklist", + "guid": "1213dbd7-fb01-42f7-8943-f6304722ea39", + "link": "https://learn.microsoft.com/azure/web-application-firewall/overview", "services": [ - "Firewall" + "RBAC", + "AppGW" ], "severity": "High", - "subcategory": "Internet", - "text": "Configure Azure Firewall Threat Intelligence mode to Alert and Deny for additional protection.", - "waf": "Security" + "subcategory": "Application Gateway", + "text": "AppGW RBAC is used to restrict access to the network security team" }, { - "ammp": true, - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant", - "guid": "b9d0dff5-bdd4-4cd8-88ed-5811610b2b2c", - "id": "D06.13", - "link": "https://learn.microsoft.com/azure/firewall/premium-features#idps", + "category": "Azure Networking", + "checklist": "Azure Security Review Checklist", + "guid": "d2b1ce63-2055-4b29-aade-4aad1e8c39ec", + "link": "https://learn.microsoft.com/azure/application-gateway/configuration-front-end-ip", "services": [ - "Firewall" + "EventHubs", + "WAF", + "AppGW" ], "severity": "High", - "subcategory": "Internet", - "text": "Configure Azure Firewall IDPS mode to Deny for additional protection.", - "waf": "Security" + "subcategory": "Application Gateway", + "text": "AppGW All external facing web services are behind Application Gateways with WAF enabled " }, { - "ammp": true, - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant", - "guid": "a3784907-9836-4271-aafc-93535f8ec08b", - "id": "D06.14", - "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview", + "category": "Azure Networking", + "checklist": "Azure Security Review Checklist", + "guid": "94666731-3c00-4567-9c1e-945b459c373e", + "link": "https://learn.microsoft.com/azure/application-gateway/configuration-front-end-ip", "services": [ - "VNet", - "VWAN", - "Firewall", - "Storage", - "NVA" + "EventHubs", + "WAF", + "AppGW" ], "severity": "High", - "subcategory": "Internet", - "text": "For subnets in VNets not connected to Virtual WAN, attach a route table so that Internet traffic is redirected to Azure Firewall or a Network Virtual Appliance", - "waf": "Security" + "subcategory": "Application Gateway", + "text": "AppGW All internal facing web services are behind Application Gateways with WAF enabled " }, { - "ammp": true, - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "b034c01e-110b-463a-b36e-e3346e57f225", - "id": "D06.15", - "link": "https://learn.microsoft.com/en-us/azure/virtual-network/ip-services/default-outbound-access", - "services": [], + "category": "Azure Networking", + "checklist": "Azure Security Review Checklist", + "guid": "7ed71623-b375-4a91-9ecb-e48fbe64dd7d", + "link": "https://learn.microsoft.com/azure/application-gateway/ssl-overview", + "services": [ + "AppGW" + ], "severity": "High", - "subcategory": "Internet", - "text": "Assess and review network outbound traffic configuration and strategy before the upcoming breaking change. On September 30, 2025, default outbound access for new deployments will be retired and only explicit access configurations will be allowed", - "waf": "Reliability" + "subcategory": "Application Gateway", + "text": "AppGW - External facing has TLS/SSL enabled and redirects all traffic to 443 (no port 80 traffic)" }, { - "ammp": true, - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "d301d6e8-72e5-42e3-911c-c58b5a4b1511", - "id": "D07.01", - "link": "https://learn.microsoft.com/azure/virtual-network/vnet-integration-for-azure-services", + "category": "Azure Networking", + "checklist": "Azure Security Review Checklist", + "guid": "f2e8bbbc-4681-455a-ac91-64e9909aed8c", + "link": "https://learn.microsoft.com/azure/frontdoor/", "services": [ - "VNet" + "RBAC", + "FrontDoor" ], "severity": "High", - "subcategory": "PaaS", - "text": "Ensure that control-plane communication for Azure PaaS services injected into a virtual network is not broken, for example with a 0.0.0.0/0 route or an NSG rule that blocks control plane traffic.", - "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", - "waf": "Security" + "subcategory": "FrontDoor", + "text": "Front Door RBAC is used to restrict access to the network security team" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "e43a58a9-c229-49c4-b7b5-7d0c655562f2", - "id": "D07.02", - "link": "https://learn.microsoft.com/azure/app-service/networking-features", + "category": "Azure Networking", + "checklist": "Azure Security Review Checklist", + "guid": "44cf3b2b-3818-4baf-a2cf-2149d013a923", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/front-door-security-baseline?toc=/azure/frontdoor/TOC.json", "services": [ - "PrivateLink" + "FrontDoor", + "AzurePolicy", + "WAF" + ], + "severity": "High", + "subcategory": "FrontDoor", + "text": "Front Door is associated with a WAF policy" + }, + { + "category": "Azure Networking", + "checklist": "Azure Security Review Checklist", + "guid": "ce574dcc-bd8a-4c2a-aebc-a2a44da1dbf3", + "link": "https://learn.microsoft.com/azure/frontdoor/front-door-custom-domain-https", + "services": [ + "FrontDoor", + "AzurePolicy" ], - "severity": "Medium", - "subcategory": "PaaS", - "text": "Use Private Link, where available, for shared Azure PaaS services.", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", - "waf": "Security" + "severity": "High", + "subcategory": "FrontDoor", + "text": "Front Door TLS/SSL policy is configured" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "b3e4563a-4d87-4397-98b6-62d6d15f512a", - "id": "D07.03", - "link": "https://learn.microsoft.com/azure/app-service/networking-features", + "category": "Azure Networking", + "checklist": "Azure Security Review Checklist", + "guid": "dd992481-718d-41dc-a1f6-25659ee5580a", + "link": "https://learn.microsoft.com/azure/frontdoor/front-door-url-redirect", "services": [ - "ExpressRoute", - "PrivateLink" + "FrontDoor" ], - "severity": "Medium", - "subcategory": "PaaS", - "text": "Access Azure PaaS services from on-premises via private endpoints and ExpressRoute private peering. This method avoids transiting over the public internet.", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", - "waf": "Security" + "severity": "High", + "subcategory": "FrontDoor", + "text": "Front Door redirect port 80 to port 443 is configured (listeners)" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "graph": "resources | where type =~ 'microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets = properties.subnets | mv-expand subnets | project id = subnets.id, resourceGroup, VNet = name, serviceEndpoints = subnets.properties.serviceEndpoints, compliant = (isnull(subnets.properties.serviceEndpoints) or array_length(subnets.properties.serviceEndpoints) == 0) | order by compliant asc", - "guid": "4704489a-8042-4d88-b79d-17b73b22a5a6", - "id": "D07.04", - "link": "https://learn.microsoft.com/azure/app-service/networking-features", + "category": "Azure Networking", + "checklist": "Azure Security Review Checklist", + "guid": "38249c93-1213-4dbd-9fb0-12f70943f630", + "link": "https://learn.microsoft.com/azure/frontdoor/front-door-diagnostics", "services": [ - "VNet" + "FrontDoor", + "Sentinel" ], - "severity": "Medium", - "subcategory": "PaaS", - "text": "Don't enable virtual network service endpoints by default on all subnets.", - "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", - "waf": "Security" + "severity": "High", + "subcategory": "FrontDoor", + "text": "Front Door diagnostics logs send ApplicationGatewayAccessLog &ApplicationGateway FirewallLog to Sentinel LAW" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "7e7a8ed4-b30e-438c-9f29-812b2363cefe", - "id": "D07.05", - "link": "https://learn.microsoft.com/azure/app-service/networking-features", + "category": "Azure Networking", + "checklist": "Azure Security Review Checklist", + "guid": "4722ea39-d2b1-4ce6-9205-5b29bade4aad", + "link": "https://learn.microsoft.com/azure/security/fundamentals/ddos-best-practices", "services": [ - "Firewall", - "DNS", - "PrivateLink", - "NVA" + "DDoS" ], - "severity": "Medium", - "subcategory": "PaaS", - "text": "Filter egress traffic to Azure PaaS services using FQDNs instead of IP addresses in Azure Firewall or an NVA to prevent data exfiltration. If using Private Link you can block all FQDNs, otherwise allow only the required PaaS services.", - "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", - "waf": "Security" + "severity": "High", + "subcategory": "DDOS Protection", + "text": "Enabled for Firewall public IP's (all public IPs)" }, { - "ammp": true, - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant", - "guid": "22d6419e-b627-4d95-9e7d-019fa759387f", - "id": "D08.01", - "link": "https://learn.microsoft.com/azure/firewall/firewall-faq#why-does-azure-firewall-need-a--26-subnet-size", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "346ad56f-bdb8-44db-8bcd-0a689af63f1e", + "link": "https://learn.microsoft.com/security/compass/identity#a-single-enterprise-directory", "services": [ - "Firewall", - "VNet" + "Entra" ], "severity": "High", - "subcategory": "Segmentation", - "text": "Use a /26 prefix for your Azure Firewall subnets.", - "waf": "Security" + "subcategory": "Tenant", + "text": "Establish a single enterprise directory for managing identities of full-time employees and enterprise resources." }, { - "ammp": true, - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant", - "guid": "f2aad7e3-bb03-4adc-8606-4123d342a917", - "id": "D08.02", - "link": "https://learn.microsoft.com/azure/expressroute/expressroute-howto-add-gateway-resource-manager#add-a-gateway", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "a46108cd-6a76-4749-ae69-b7bf61410010", + "link": "https://learn.microsoft.com/security/compass/identity#synchronized-identity-systems", "services": [ - "VNet", - "ExpressRoute", - "VPN" + "Entra" ], "severity": "High", - "subcategory": "Segmentation", - "text": "Use at least a /27 prefix for your Gateway subnets", - "waf": "Security" + "subcategory": "Tenant", + "text": "Synchronize your cloud identity with your existing identity systems." }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant)", - "guid": "11deb39d-8299-4e47-bbe0-0fb5a36318a8", - "id": "D08.03", - "link": "https://learn.microsoft.com/azure/virtual-network/service-tags-overview#available-service-tags", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "a1ab96ceb-c149-4ce2-bcad-3bd375ebfc7f", + "link": "https://learn.microsoft.com/security/compass/identity#cloud-provider-identity-source-for-third-parties", "services": [ - "VNet" + "Entra" ], - "severity": "Medium", - "subcategory": "Segmentation", - "text": "Don't rely on the NSG inbound default rules using the VirtualNetwork service tag to limit connectivity.", - "waf": "Security" + "severity": "High", + "subcategory": "Tenant", + "text": "Use cloud identity services to host non-employee accounts such as vendors, partners, and customers, rather than rather than including them in your on-premises directory." }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "c2447ec6-6138-4a72-80f1-ce16ed301d6e", - "id": "D08.04", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-landing-zone-network-segmentation", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "343473ec-ed5c-49e1-98f4-cb09524a23cd", + "link": "https://learn.microsoft.com/security/compass/identity#block-legacy-authentication", "services": [ - "VNet" + "Entra" ], - "severity": "Medium", - "subcategory": "Segmentation", - "text": "Delegate subnet creation to the landing zone owner. ", - "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", - "waf": "Security" + "severity": "High", + "subcategory": "Tenant", + "text": "Disable insecure legacy protocols for internet-facing services." }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "872e52e3-611c-4c58-a5a4-b1511e43a58a", - "id": "D08.05", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "70dceb23-50c7-4d8d-bf53-8cc104c7dc44", + "link": "https://learn.microsoft.com/azure/security/fundamentals/identity-management-best-practices#enable-single-sign-on", "services": [ - "ACR", - "VNet" + "Entra" ], - "severity": "Medium", - "subcategory": "Segmentation", - "text": "Use NSGs to help protect traffic across subnets, as well as east/west traffic across the platform (traffic between landing zones).", - "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", - "waf": "Security" + "severity": "High", + "subcategory": "Tenant", + "text": "Enable single sign-on" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "graph": "Resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetName=subnets.name,subnetNsg=subnets.properties.networkSecurityGroup | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend compliant = isnotnull(subnetNsg)", - "guid": "9c2299c4-d7b5-47d0-a655-562f2b3e4563", - "id": "D08.06", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "87791be1-1eb0-48ed-8003-ad9bcf241b99", + "link": "https://learn.microsoft.com/security/compass/identity#no-on-premises-admin-accounts-in-cloud-identity-providers", "services": [ - "VM", - "VNet" + "Entra" ], - "severity": "Medium", - "subcategory": "Segmentation", - "text": "The application team should use application security groups at the subnet-level NSGs to help protect multi-tier VMs within the landing zone.", - "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", - "waf": "Security" + "severity": "High", + "subcategory": "Privileged administration", + "text": "Don’t synchronize accounts with the highest privilege access to on-premises resources as you synchronize your enterprise identity systems with cloud directories." }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "a4d87397-48b6-462d-9d15-f512a65498f6", - "id": "D08.07", - "link": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "9e6efe9d-f28f-463b-9bff-b5080173e9fe", + "link": "https://learn.microsoft.com/azure/active-directory/roles/best-practices#5-limit-the-number-of-global-administrators-to-less-than-5", "services": [ - "VNet", - "NVA", "Entra" ], - "severity": "Medium", - "subcategory": "Segmentation", - "text": "Use NSGs and application security groups to micro-segment traffic within the landing zone and avoid using a central NVA to filter traffic flows.", - "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", - "waf": "Security" + "severity": "High", + "subcategory": "Privileged administration", + "text": "Limit the number of Global Administrators to less than 5" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "dfe237de-143b-416c-91d7-aa9b64704489", - "id": "D08.08", - "link": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "e0d968d3-87f6-41fb-a4f9-d852f1673f4c", + "link": "https://learn.microsoft.com/azure/active-directory/roles/best-practices#6-use-groups-for-azure-ad-role-assignments-and-delegate-the-role-assignment", "services": [ - "VNet", - "NetworkWatcher" + "RBAC", + "Entra" ], - "severity": "Medium", - "subcategory": "Segmentation", - "text": "Enable NSG flow logs and feed them into Traffic Analytics to gain insights into internal and external traffic flows.", - "training": "https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/", - "waf": "Security" + "severity": "High", + "subcategory": "Privileged administration", + "text": "Use groups for Azure AD role assignments and delegate the role assignment" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "412e7f98-3f63-4047-82dd-69c5b5c2622f", - "id": "D09.01", - "link": "https://learn.microsoft.com/azure/virtual-wan/scenario-any-to-any", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "00350863-4df6-4050-9cf1-cbaa6d58283e", + "link": "https://learn.microsoft.com/azure/architecture/framework/security/design-admins#managed-accounts-for-admins", "services": [ - "VWAN" + "AzurePolicy", + "Entra" ], - "severity": "Medium", - "subcategory": "Virtual WAN", - "text": "Consider Virtual WAN for simplified Azure networking management, and make sure your scenario is explicitly described in the list of Virtual WAN routing designs", - "training": "https://learn.microsoft.com/learn/modules/introduction-azure-virtual-wan/", - "waf": "Operations" + "severity": "High", + "subcategory": "Privileged administration", + "text": "Ensure all critical impact admins are managed by enterprise directory to follow organizational policy enforcement." + }, + { + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "eae64d01-0d3a-4ae1-a89d-cc1c2ad3888f", + "link": "https://learn.microsoft.com/azure/active-directory/roles/best-practices#4-configure-recurring-access-reviews-to-revoke-unneeded-permissions-over-time", + "services": [ + "Entra" + ], + "severity": "High", + "subcategory": "Privileged administration", + "text": "Configure recurring access reviews to revoke unneeded permissions over time" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "54b69bad-33aa-4d5e-ac68-e1d76667313b", - "id": "D09.02", - "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-about", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "922ac19f-916d-4697-b8ea-ded26bdd186f", + "link": "https://learn.microsoft.com/azure/architecture/framework/security/design-admins#admin-workstation-security", "services": [ - "ACR", - "VWAN" + "Monitor", + "Entra" ], "severity": "Medium", - "subcategory": "Virtual WAN", - "text": "Use a Virtual WAN hub per Azure region to connect multiple landing zones together across Azure regions via a common global Azure Virtual WAN.", - "waf": "Performance" + "subcategory": "Privileged administration", + "text": "Ensure critical impact admins use a workstation with elevated security protections and monitoring" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "8ac6a9e0-1e6a-483d-b5de-32c199248160", - "id": "D09.03", - "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-about", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "1e8c39ec-9466-4673-83c0-05674c1e945b", + "link": "https://learn.microsoft.com/azure/active-directory/external-identities/compare-with-b2c", "services": [ - "ACR", - "VWAN" + "Entra" ], - "severity": "Low", - "subcategory": "Virtual WAN", - "text": "Follow the principle 'traffic in Azure stays in Azure' so that communication across resources in Azure occurs via the Microsoft backbone network", - "waf": "Performance" + "severity": "High", + "subcategory": "External Identities", + "text": "Identity Providers: Verify external identity providers are known" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/virtualhubs' | extend compliant = isnotnull(properties.azureFirewall.id) | project id, compliant", - "guid": "7d5d1e4e-6146-458d-9558-fd77249b8211", - "id": "D09.04", - "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-about", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "459c373e-7ed7-4162-9b37-5a917ecbe48f", + "link": "https://learn.microsoft.com/azure/active-directory/external-identities/delegate-invitations", "services": [ - "Firewall", - "VWAN" + "Entra" ], - "severity": "Medium", - "subcategory": "Virtual WAN", - "text": "For outbound Internet traffic protection and filtering, deploy Azure Firewall in secured hubs", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", - "waf": "Security" + "severity": "High", + "subcategory": "External Identities", + "text": "External Collaboration Settings: Guest user access set to 'Guest user access is restricted?'" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "6667313b-4f56-464b-9e98-4a859c773e7d", - "id": "D09.05", - "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "be64dd7d-f2e8-4bbb-a468-155abc9164e9", + "link": "https://learn.microsoft.com/azure/active-directory/external-identities/delegate-invitations", "services": [ - "VWAN" + "RBAC", + "Entra" ], - "severity": "Medium", - "subcategory": "Virtual WAN", - "text": "Ensure that the network architecture is within the Azure Virtual WAN limits.", - "waf": "Reliability" + "severity": "High", + "subcategory": "External Identities", + "text": "External Collaboration Settings: Guest invite settings set to 'Only users assigned to specific admin roles'" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "261623a7-65a9-417e-8f34-8ef254c27d42", - "id": "D09.06", - "link": "https://learn.microsoft.com/azure/virtual-wan/azure-monitor-insights", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "909aed8c-44cf-43b2-a381-8bafa2cf2149", + "link": "https://learn.microsoft.com/azure/active-directory/external-identities/delegate-invitations", "services": [ - "Monitor", - "VWAN" + "Entra" ], - "severity": "Medium", - "subcategory": "Virtual WAN", - "text": "Use Azure Monitor Insights for Virtual WAN to monitor the end-to-end topology of the Virtual WAN, status, and key metrics.", - "waf": "Operations" + "severity": "High", + "subcategory": "External Identities", + "text": "External Collaboration Settings: Enable guest self-service sign up via flows set to 'Disabled' " }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "727c77e1-b9aa-4a37-a024-129d042422c1", - "id": "D09.07", - "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-faq#is-branch-to-branch-connectivity-allowed-in-virtual-wan", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "d013a923-ce57-44dc-abd8-ac2aaebca2a4", + "link": "https://learn.microsoft.com/azure/active-directory/external-identities/delegate-invitations", "services": [ - "VWAN" + "Entra" ], - "severity": "Medium", - "subcategory": "Virtual WAN", - "text": "Make sure that your IaC deployments does not disable branch-to-branch traffic in Virtual WAN, unless these flows should be explicitly blocked.", - "waf": "Reliability" + "severity": "High", + "subcategory": "External Identities", + "text": "External Collaboration Settings: Collaboration restrictions set to 'Allow invitations to the specified domains'" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "d49ac006-6670-4bc9-9948-d3e0a3a94f4d", - "id": "D09.08", - "link": "https://learn.microsoft.com/azure/virtual-wan/about-virtual-hub-routing-preference", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "4da1dbf3-dd99-4248-8718-d1dca1f62565", + "link": "https://learn.microsoft.com/azure/active-directory/governance/deploy-access-reviews", "services": [ - "ExpressRoute", - "VPN", - "VWAN" + "Entra" ], "severity": "Medium", - "subcategory": "Virtual WAN", - "text": "Use AS-Path as hub routing preference, since it is more flexible than ExpressRoute or VPN.", - "waf": "Reliability" + "subcategory": "External Identities", + "text": "Access Reviews: Enabled for all groups" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "2586b854-237e-47f1-84a1-d45d4cd2310d", - "id": "D09.09", - "link": "https://learn.microsoft.com/azure/virtual-wan/about-virtual-hub-routing#labels", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "9ee5580a-3824-49c9-9121-3dbd7fb012f7", + "link": "https://learn.microsoft.com/azure/active-directory/manage-apps/configure-user-consent", "services": [ - "VWAN" + "Entra" ], "severity": "Medium", - "subcategory": "Virtual WAN", - "text": "Make sure that your IaC deployments are configuring label-based propagation in Virtual WAN, otherwise connectivity between virtual hubs will be impaired.", - "waf": "Reliability" + "subcategory": "Enterprise Applications", + "text": "Consent & Permissions: Allow user consent for apps from verified publishers" }, { - "ammp": true, - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "9c75dfef-573c-461c-a698-68598595581a", - "id": "D09.10", - "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-faq#what-is-the-recommended-hub-address-space-during-hub-creation", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "0943f630-4722-4ea3-ad2b-1ce632055b29", + "link": "https://learn.microsoft.com/azure/active-directory/manage-apps/configure-user-consent-groups", "services": [ - "VWAN" + "Entra" ], - "severity": "High", - "subcategory": "Virtual WAN", - "text": "Assign enough IP space to virtual hubs, ideally a /23 prefix.", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "Enterprise Applications", + "text": "Consent & Permissions: Allow group owner consent for selected group owners " }, { - "ammp": true, - "category": "Governance", - "checklist": "Azure Landing Zone Review", - "guid": "5c986cb2-9131-456a-8247-6e49f541acdc", - "id": "E01.01", - "link": "https://learn.microsoft.com/azure/governance/policy/overview", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "bade4aad-1e8c-439e-a946-667313c00567", + "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy-configure-custom-domain", "services": [ - "AzurePolicy" + "Entra" ], "severity": "High", - "subcategory": "Governance", - "text": "Leverage Azure Policy strategically, define controls for your environment, using Policy Initiatives to group related policies.", - "waf": "Security" + "subcategory": "Custom Domains", + "text": "Only validated customer domains are registered" }, { - "category": "Governance", - "checklist": "Azure Landing Zone Review", - "guid": "e979377b-cdb3-4751-ab2a-b13ada6e55d7", - "id": "E01.02", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/naming-and-tagging", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "4c1e945b-459c-4373-b7ed-71623b375a91", + "link": "https://learn.microsoft.com/azure/active-directory/authentication/tutorial-enable-sspr", "services": [ - "AzurePolicy" + "AzurePolicy", + "Entra" ], - "severity": "Medium", - "subcategory": "Governance", - "text": "Identify required Azure tags and use the 'append' policy mode to enforce usage via Azure Policy.", - "waf": "Security" + "severity": "High", + "subcategory": "Password Reset", + "text": "Self-service password reset policy requirement verified compliant." }, { - "category": "Governance", - "checklist": "Azure Landing Zone Review", - "guid": "d8a2adb1-17d6-4326-af62-5ca44e5695f2", - "id": "E01.03", - "link": "https://learn.microsoft.com/azure/governance/policy/overview", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "7ecbe48f-be64-4dd7-bf2e-8bbbc468155a", + "link": "https://learn.microsoft.com/azure/active-directory/authentication/howto-sspr-deployment", "services": [ - "AzurePolicy", - "RBAC" + "Entra" ], "severity": "Medium", - "subcategory": "Governance", - "text": "Map regulatory and compliance requirements to Azure Policy definitions and Azure role assignments.", - "waf": "Security" + "subcategory": "Password Reset", + "text": "Set number of days before users are asked to re-confirm authentication information is not set to zero" }, { - "category": "Governance", - "checklist": "Azure Landing Zone Review", - "guid": "223ace8c-b123-408c-a501-7f154e3ab369", - "id": "E01.04", - "link": "https://learn.microsoft.com/azure/governance/policy/overview", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "bc9164e9-909a-4ed8-a44c-f3b2b3818baf", + "link": "https://learn.microsoft.com/azure/active-directory/authentication/howto-sspr-deployment", "services": [ - "AzurePolicy", - "Subscriptions" + "Entra" ], - "severity": "Medium", - "subcategory": "Governance", - "text": "Establish Azure Policy definitions at the intermediate root management group so that they can be assigned at inherited scopes", - "waf": "Security" + "severity": "High", + "subcategory": "Password Reset", + "text": "Set number of methods required to reset password are selected" }, { - "category": "Governance", - "checklist": "Azure Landing Zone Review", - "guid": "3829e7e3-1618-4368-9a04-77a209945bda", - "id": "E01.05", - "link": "https://learn.microsoft.com/azure/governance/policy/overview", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "a2cf2149-d013-4a92-9ce5-74dccbd8ac2a", + "link": "https://learn.microsoft.com/azure/active-directory/roles/delegate-app-roles", "services": [ - "AzurePolicy" + "Entra" ], - "severity": "Medium", - "subcategory": "Governance", - "text": "Manage policy assignments at the highest appropriate level with exclusions at bottom levels, if required.", - "waf": "Security" + "severity": "High", + "subcategory": "User Setting", + "text": "Disable 'Users can register applications'" }, { - "category": "Governance", - "checklist": "Azure Landing Zone Review", - "guid": "43334f24-9116-4341-a2ba-527526944008", - "id": "E01.06", - "link": "https://learn.microsoft.com/security/benchmark/azure/mcsb-asset-management#am-2-use-only-approved-services", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "aebca2a4-4da1-4dbf-9dd9-92481718d1dc", + "link": "https://learn.microsoft.com/azure/active-directory/fundamentals/users-default-permissions", "services": [ - "AzurePolicy", - "Subscriptions" + "Entra" ], - "severity": "Low", - "subcategory": "Governance", - "text": "Use Azure Policy to control which services users can provision at the subscription/management group level", - "waf": "Security" + "severity": "High", + "subcategory": "User Setting", + "text": "Restrict access to Administrative portal (portal.azure.com) to administrators only" }, { - "category": "Governance", - "checklist": "Azure Landing Zone Review", - "guid": "be7d7e48-4327-46d8-adc0-55bcf619e8a1", - "id": "E01.07", - "link": "https://learn.microsoft.com/azure/governance/policy/overview", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "a1f62565-9ee5-4580-a382-49c931213dbd", + "link": "https://learn.microsoft.com/azure/active-directory/enterprise-users/linkedin-integration", "services": [ - "AzurePolicy" + "Entra" ], - "severity": "Medium", - "subcategory": "Governance", - "text": "Use built-in policies where possible to minimize operational overhead.", - "waf": "Security" + "severity": "High", + "subcategory": "User Setting", + "text": "Disable 'LinkedIn account connection'" }, { - "category": "Governance", - "checklist": "Azure Landing Zone Review", - "description": "Assigning the Resource Policy Contributor role to specific scopes allows you to delegate policy management to relevant teams. For instance, a central IT team may oversee management group-level policies, while application teams handle policies for their subscriptions, enabling distributed governance with adherence to organizational standards.", - "guid": "3f988795-25d6-4268-a6d7-0ba6c97be995", - "id": "E01.08", - "link": "https://learn.microsoft.com/azure/governance/policy/overview#azure-rbac-permissions-in-azure-policy", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "7fb012f7-0943-4f63-8472-2ea39d2b1ce6", + "link": "https://learn.microsoft.com/azure/active-directory/reports-monitoring/overview-monitoring", "services": [ - "Entra", - "AzurePolicy", - "RBAC", - "Subscriptions" + "Monitor", + "Sentinel", + "Entra" ], - "severity": "Medium", - "subcategory": "Governance", - "text": "Assign the built-in Resource Policy Contributor role at a particular scope to enable application-level governance.", - "waf": "Security" + "severity": "High", + "subcategory": "Diagnostic Settings", + "text": "Enabled and send to Log Analytics workspace with Sentinel" }, { - "category": "Governance", - "checklist": "Azure Landing Zone Review", - "guid": "19048384-5c98-46cb-8913-156a12476e49", - "id": "E01.09", - "link": "https://learn.microsoft.com/azure/governance/policy/overview", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "21e44a19-a9dd-4399-afd7-b28dc8355562", + "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-deployment-plan", "services": [ - "AzurePolicy", - "Subscriptions" + "Entra" ], - "severity": "Medium", - "subcategory": "Governance", - "text": "Limit the number of Azure Policy assignments made at the root management group scope to avoid managing through exclusions at inherited scopes.", - "waf": "Security" + "severity": "High", + "subcategory": "PIM enabled", + "text": "Privileged Identity Management enabled" }, { - "category": "Governance", - "checklist": "Azure Landing Zone Review", - "guid": "5a917e1f-348e-4f25-9c27-d42e8bbac757", - "id": "E01.10", - "link": "https://azure.microsoft.com/resources/achieving-compliant-data-residency-and-security-with-azure/", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "46f4389a-7f42-4c78-b78c-06a63a21a495", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/just-in-time-access-usage?tabs=jit-config-asc%2Cjit-request-asc", "services": [ - "AzurePolicy" + "Entra" ], - "severity": "Medium", - "subcategory": "Governance", - "text": "If any data sovereignty requirements exist, Azure Policies can be deployed to enforce them", - "training": "https://learn.microsoft.com/learn/paths/secure-your-cloud-data/", - "waf": "Security" + "severity": "High", + "subcategory": "PIM enabled", + "text": "Implement 'just in time' (JIT) access to further lower the exposure time for privileged accounts (reduce standing access)" }, { - "category": "Governance", - "checklist": "Azure Landing Zone Review", - "guid": "78b22132-b41c-460b-a4d3-df8f73a67dc2", - "id": "E01.11", - "link": "https://github.com/Azure/sovereign-landing-zone/blob/main/docs/scenarios/Sovereignty-Policy-Baseline.md", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "6e6a8dc4-a20e-427b-9e29-711b1352beee", + "link": "https://learn.microsoft.com/azure/active-directory/conditional-access/concept-conditional-access-policy-common", "services": [ - "AzurePolicy" + "AzurePolicy", + "Entra" ], - "severity": "Medium", - "subcategory": "Governance", - "text": "For Sovereign Landing Zone, sovereignty policy baseline' policy initiative is deployed and and assigned at correct MG level.", - "waf": "Security" + "severity": "High", + "subcategory": "Conditional Access Policies", + "text": "Configure conditional access policies / Access Controls" }, { - "category": "Governance", - "checklist": "Azure Landing Zone Review", - "guid": "caeea0e9-1024-41df-a52e-d99c3f22a6f4", - "id": "E01.12", - "link": "https://learn.microsoft.com/en-us/industry/sovereignty/policy-portfolio-baseline", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "079b588d-efc4-4972-ac3c-d21bf77036e5", + "link": "https://learn.microsoft.com/azure/active-directory/conditional-access/location-condition", "services": [ - "AzurePolicy" + "AzurePolicy", + "Entra" ], "severity": "Medium", - "subcategory": "Governance", - "text": "For Sovereign Landing Zone, sovereign Control objectives to policy mapping' is documented.", - "waf": "Security" + "subcategory": "Conditional Access Policies", + "text": "Conditions: Restricted Locations" }, { - "category": "Governance", - "checklist": "Azure Landing Zone Review", - "guid": "9b461617-db7b-4399-8ac6-d4eb7153893a", - "id": "E01.13", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "e6b4bed3-d5f3-4547-a134-7dc56028a71f", + "link": "https://learn.microsoft.com/azure/active-directory/authentication/tutorial-enable-azure-mfa", "services": [ - "AzurePolicy" + "AzurePolicy", + "Entra" ], - "severity": "Medium", - "subcategory": "Governance", - "text": "For Sovereign Landing Zone, process is in place for CRUD of 'Sovereign Control objectives to policy mapping'.", - "waf": "Security" + "severity": "High", + "subcategory": "Conditional Access Policies", + "text": "Access Controls: MFA enabled for all users" }, { - "category": "Governance", - "checklist": "Azure Landing Zone Review", - "guid": "9b5e2a28-9823-4faf-ab7e-afa5f6c57221", - "id": "E02.01", - "link": "https://learn.microsoft.com/azure/automation/automation-solution-vm-management-config", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "fe1bd15d-d2f0-4d5e-972d-41e3611cc57b", + "link": "https://learn.microsoft.com/azure/active-directory/conditional-access/howto-conditional-access-policy-admin-mfa", "services": [ - "VM", - "TrafficManager", - "Cost" + "AzurePolicy", + "Entra" ], - "severity": "Low", - "subcategory": "Optimize your cloud investment", - "text": "Consider using automation tags to start/stop VM's in your environment to save on cost.", - "waf": "Security" + "severity": "Medium", + "subcategory": "Conditional Access Policies", + "text": "Access Controls: Require MFA for Administrators" }, { - "category": "Management ", - "checklist": "Azure Landing Zone Review", - "guid": "ecdc7506-6f37-4ea9-be87-fc5d3df08a64", - "id": "E02.01", - "link": "https://learn.microsoft.com/azure/virtual-machine-scale-sets/overview", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "4a4b1410-d439-4589-ac22-89b3d6b57cfc", + "link": "https://learn.microsoft.com/azure/active-directory/conditional-access/howto-conditional-access-policy-azure-management", "services": [ - "VM" + "AzurePolicy", + "Entra" ], - "severity": "Medium", - "subcategory": "Scalability", - "text": "Leverage Azure Virtual Machine Scale sets to scale in and out based on the load.", - "waf": "Reliability" + "severity": "High", + "subcategory": "Conditional Access Policies", + "text": "Access Controls: Require MFA for Azure Management " }, { - "category": "Governance", - "checklist": "Azure Landing Zone Review", - "guid": "29fd366b-a180-452b-9bd7-954b7700c667", - "id": "E02.02", - "link": "https://learn.microsoft.com/azure/cost-management-billing/costs/tutorial-acm-create-budgets?bc=%2Fazure%2Fcloud-adoption-framework%2F_bread%2Ftoc.json&toc=%2Fazure%2Fcloud-adoption-framework%2Ftoc.json", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "645461e1-a3e3-4453-a3c8-639637a552d6", + "link": "https://learn.microsoft.com/azure/active-directory/conditional-access/howto-conditional-access-policy-block-legacy", "services": [ - "TrafficManager", - "Monitor", - "Cost" + "AzurePolicy", + "Entra" ], - "severity": "Medium", - "subcategory": "Optimize your cloud investment", - "text": "Configure 'Actual' and 'Forecasted' Budget Alerts.", - "waf": "Cost" + "severity": "High", + "subcategory": "Conditional Access Policies", + "text": "Access Controls: Block Legacy Protocols" }, { - "ammp": true, - "category": "Management", - "checklist": "Azure Landing Zone Review", - "guid": "89cc5e11-aa4d-4c3b-893d-feb99215266a", - "id": "F01.01", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#add-diagnostic-settings-to-save-your-wafs-logs", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "7ae9eab4-0fd3-4290-998b-c178bdc5a06c", + "link": "https://learn.microsoft.com/azure/active-directory/conditional-access/require-managed-devices", "services": [ - "FrontDoor", - "AppGW", - "WAF" + "AzurePolicy", + "Entra" ], "severity": "High", - "subcategory": "App delivery", - "text": "Add diagnostic settings to save WAF logs from application delivery services like Azure Front Door and Azure Application Gateway. Regularly review the logs to check for attacks and for false positive detections.", - "waf": "Operations" + "subcategory": "Conditional Access Policies", + "text": "Access Controls: Require devices to be marked as compliant" }, { - "category": "Management", - "checklist": "Azure Landing Zone Review", - "guid": "7f408960-c626-44cb-a018-347c8d790cdf", - "id": "F01.02", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#send-logs-to-microsoft-sentinel", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "description": "Customer documented policy", + "guid": "a7144351-e19d-4d34-929e-b7228137a151", + "link": "https://devblogs.microsoft.com/premier-developer/azure-active-directory-automating-guest-user-management/", "services": [ - "FrontDoor", - "Sentinel", - "AppGW", - "WAF" + "AzurePolicy", + "Entra" ], "severity": "Medium", - "subcategory": "App delivery", - "text": "Send WAF logs from your application delivery services like Azure Front Door and Azure Application Gateway to Microsoft Sentinel. Detect attacks and integrate WAF telemetry into your overall Azure environment.", - "waf": "Operations" - }, - { - "category": "Management", - "checklist": "Azure Landing Zone Review", - "guid": "7ea02e1c-7166-45a3-bdf5-098891367fcb", - "id": "F02.01", - "link": "https://learn.microsoft.com/azure/reliability/cross-region-replication-azure", - "services": [], - "severity": "Medium", - "subcategory": "Data Protection", - "text": "Consider cross-region replication in Azure for BCDR with paired regions", - "waf": "Reliability" + "subcategory": "Guest users", + "text": "Is there a policy to track guest user accounts (i.e. usage/delete/disable)?" }, { - "category": "Management", - "checklist": "Azure Landing Zone Review", - "guid": "eba8cf22-45c6-4dc1-9b57-2cceb3b97ce5", - "id": "F02.02", - "link": "https://learn.microsoft.com/azure/storage/common/storage-redundancy", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "c5bb4e4f-1814-4287-b5ca-8c26c9b32ab5", + "link": "https://learn.microsoft.com/azure/active-directory/fundamentals/identity-secure-score", "services": [ - "Backup" + "Entra" ], - "severity": "Medium", - "subcategory": "Data Protection", - "text": "When using Azure Backup, consider the different backup types (GRS, ZRS & LRS) as the default setting is GRS", - "waf": "Reliability" + "severity": "High", + "subcategory": "Identity Secure Score", + "text": "Implement Identity Secure Score based on best practices in your industry" }, { - "category": "Management", - "checklist": "Azure Landing Zone Review", - "guid": "67e7a8ed-4b30-4e38-a3f2-9812b2363cef", - "id": "F03.01", - "link": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", + "category": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "bcfc6998-a135-4e33-9897-e31c67d68cb6", + "link": "https://learn.microsoft.com/azure/active-directory/roles/security-emergency-access", "services": [ "AzurePolicy", - "RBAC", - "Monitor", "Entra" ], "severity": "Medium", - "subcategory": "Monitoring", - "text": "Use a single monitor logs workspace to manage platforms centrally except where Azure role-based access control (Azure RBAC), data sovereignty requirements, or data retention policies mandate separate workspaces.", - "training": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", - "waf": "Operations" + "subcategory": "Break Glass Accounts", + "text": "At least two break glass accounts have been created and policy around their use exists" }, { - "category": "Management", - "checklist": "Azure Landing Zone Review", - "guid": "e179b599-de0d-4597-9cd4-cd21b088137f", - "id": "F03.02", + "category": "VM Security Checks", + "checklist": "Azure Security Review Checklist", + "guid": "0ac252b9-99a6-48af-a7c9-a8f821b8eb8c", + "link": "https://learn.microsoft.com/azure/governance/policy/overview", "services": [ - "Monitor" + "VM", + "AzurePolicy" + ], + "severity": "High", + "subcategory": "Access Control", + "text": "Control VM Access leveraging Azure Policy" + }, + { + "category": "VM Security Checks", + "checklist": "Azure Security Review Checklist", + "guid": "0aa77e26-e4d5-4aea-a8dc-4e2436bc336d", + "link": "https://learn.microsoft.com/azure/azure-resource-manager/templates/syntax", + "services": [ + "VM" ], "severity": "Medium", - "subcategory": "Monitoring", - "text": "Is the landing zone documented?", - "waf": "Operations" + "subcategory": "Access Control", + "text": "Reduce variability in your setup and deployment of VMs by leveraging templates" }, { - "category": "Management", - "checklist": "Azure Landing Zone Review", - "guid": "5e6c4cfd-3e50-4454-9c24-47ec66138a72", - "id": "F03.03", - "link": "https://learn.microsoft.com/azure/azure-monitor/logs/data-retention-archive?tabs=portal-1%2Cportal-2#how-retention-and-archiving-work", + "category": "VM Security Checks", + "checklist": "Azure Security Review Checklist", + "guid": "b5945bda-4333-44fd-b91c-234182b65275", + "link": "https://learn.microsoft.com/windows-server/identity/ad-ds/plan/security-best-practices/implementing-least-privilege-administrative-models", "services": [ - "Monitor", - "ARS" + "VM" ], "severity": "Medium", - "subcategory": "Monitoring", - "text": "Use Azure Monitor Logs when log retention requirements exceed two years. You can currently keep data in archived state for up to 7 years.", - "training": "https://learn.microsoft.com/learn/paths/architect-infrastructure-operations/", - "waf": "Operations" + "subcategory": "Access Control", + "text": "Secure privileged access to deploy VMS by reducing who has access to Resources through Governance" }, { - "category": "Management", - "checklist": "Azure Landing Zone Review", - "guid": "00f1ce16-ed30-41d6-b872-e52e3611cc58", - "id": "F03.04", - "link": "https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/govern/policy-compliance/regulatory-compliance", + "category": "VM Security Checks", + "checklist": "Azure Security Review Checklist", + "guid": "269440b4-be3d-43e0-a432-76d4bdc015bc", + "link": "https://learn.microsoft.com/azure/architecture/checklist/resiliency-per-service", "services": [ - "AzurePolicy", - "Monitor" + "VM" ], "severity": "Medium", - "subcategory": "Monitoring", - "text": "Use Azure Policy for access control and compliance reporting. Azure Policy provides the ability to enforce organization-wide settings to ensure consistent policy adherence and fast violation detection. ", - "training": "https://learn.microsoft.com/en-us/azure/governance/policy/concepts/effects", - "waf": "Operations" + "subcategory": "High Availability ", + "text": "Use multiple VMs for your workloads for better availability " }, { - "category": "Management", - "checklist": "Azure Landing Zone Review", - "guid": "e7d7e484-3276-4d8b-bc05-5bcf619e8a13", - "id": "F03.05", - "link": "https://learn.microsoft.com/azure/governance/policy/how-to/guest-configuration-create", + "category": "VM Security Checks", + "checklist": "Azure Security Review Checklist", + "guid": "f219e4a1-eb58-4879-935d-227886d30b66", + "link": "https://learn.microsoft.com/azure/backup/backup-azure-vms-first-look-arm", "services": [ "VM", - "Monitor", - "AzurePolicy" + "ASR" ], "severity": "Medium", - "subcategory": "Monitoring", - "text": "Monitor in-guest virtual machine (VM) configuration drift using Azure Policy. Enabling guest configuration audit capabilities through policy helps application team workloads to immediately consume feature capabilities with little effort.", - "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", - "waf": "Operations" + "subcategory": "High Availability ", + "text": "Deploy and test a disaster recovery solution " }, { - "category": "Management", - "checklist": "Azure Landing Zone Review", - "guid": "f9887952-5d62-4688-9d70-ba6c97be9951", - "id": "F03.06", - "link": "https://learn.microsoft.com/azure/automation/update-management/overview", + "category": "VM Security Checks", + "checklist": "Azure Security Review Checklist", + "guid": "c57be595-1900-4838-95c5-86cb291ec16a", + "link": "https://learn.microsoft.com/azure/virtual-machines/availability-set-overview", "services": [ - "VM", - "Monitor" + "VM" ], "severity": "Medium", - "subcategory": "Monitoring", - "text": "Use Update Management in Azure Automation as a long-term patching mechanism for both Windows and Linux VMs. ", - "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-compute-resources/", - "waf": "Operations" + "subcategory": "High Availability ", + "text": "Availability sets" }, { - "category": "Management", - "checklist": "Azure Landing Zone Review", - "guid": "90483845-c986-4cb2-a131-56a12476e49f", - "id": "F03.07", - "link": "https://learn.microsoft.com/azure/network-watcher/network-watcher-monitoring-overview", + "category": "VM Security Checks", + "checklist": "Azure Security Review Checklist", + "guid": "1d076ef9-f141-4acd-ae57-9377bcdb3751", + "link": "https://learn.microsoft.com/azure/availability-zones/az-overview?context=/azure/virtual-machines/context/context", "services": [ - "Monitor", - "NetworkWatcher" + "VM" ], "severity": "Medium", - "subcategory": "Monitoring", - "text": "Use Network Watcher to proactively monitor traffic flows", - "training": "https://learn.microsoft.com/learn/modules/configure-network-watcher/", - "waf": "Operations" + "subcategory": "High Availability ", + "text": "Availability Zones" }, { - "category": "Management", - "checklist": "Azure Landing Zone Review", - "guid": "541acdce-9793-477b-adb3-751ab2ab13ad", - "id": "F03.08", - "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/lock-resources?tabs=json", + "category": "VM Security Checks", + "checklist": "Azure Security Review Checklist", + "guid": "ab2ac1fa-d66e-415d-9d5a-2adb2c3e2326", + "link": "https://learn.microsoft.com/azure/architecture/resiliency/recovery-loss-azure-region", "services": [ - "Monitor" + "VM" ], "severity": "Medium", - "subcategory": "Monitoring", - "text": "Use resource locks to prevent accidental deletion of critical shared services.", - "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", - "waf": "Operations" + "subcategory": "High Availability ", + "text": "Regional fault tolerance " }, { - "category": "Management", - "checklist": "Azure Landing Zone Review", - "guid": "a6e55d7d-8a2a-4db1-87d6-326af625ca44", - "id": "F03.09", - "link": "https://learn.microsoft.com/azure/governance/policy/overview", + "category": "VM Security Checks", + "checklist": "Azure Security Review Checklist", + "guid": "af225ca4-4e16-496f-bdde-ace4cb1deb4c", + "link": "https://learn.microsoft.com/azure/security/fundamentals/antimalware", "services": [ - "AzurePolicy", - "RBAC", - "Monitor" + "VM" ], - "severity": "Low", - "subcategory": "Monitoring", - "text": "Use deny policies to supplement Azure role assignments. The combination of deny policies and Azure role assignments ensures the appropriate guardrails are in place to enforce who can deploy and configure resources and what resources they can deploy and configure.", - "waf": "Operations" + "severity": "High", + "subcategory": "Protect against malware", + "text": "Install antimalware solutions" }, { - "category": "Management", - "checklist": "Azure Landing Zone Review", - "guid": "e5695f22-23ac-4e8c-a123-08ca5017f154", - "id": "F03.10", - "link": "https://learn.microsoft.com/azure/service-health/alerts-activity-log-service-notifications-portal", + "category": "VM Security Checks", + "checklist": "Azure Security Review Checklist", + "guid": "650c3fc1-4eeb-4b36-a382-9e3eec218368", + "link": "https://learn.microsoft.com/azure/security-center/security-center-partner-integration", "services": [ - "Monitor" + "VM", + "Defender" ], - "severity": "Medium", - "subcategory": "Monitoring", - "text": "Include service and resource health events as part of the overall platform monitoring solution. Tracking service and resource health from the platform perspective is an important component of resource management in Azure.", - "waf": "Operations" + "severity": "High", + "subcategory": "Protect against malware", + "text": "Integrate antimalware solution with Security Center" }, { - "category": "Management", - "checklist": "Azure Landing Zone Review", - "guid": "d5f345bf-97ab-41a7-819c-6104baa7d48c", - "id": "F03.11", - "link": "https://learn.microsoft.com/azure/azure-monitor/alerts/action-groups", + "category": "VM Security Checks", + "checklist": "Azure Security Review Checklist", + "guid": "7a0177a2-b594-45bd-a433-34fdf91c2341", + "link": "https://learn.microsoft.com/azure/automation/update-management/overview", "services": [ - "Monitor" + "VM" ], - "severity": "Medium", - "subcategory": "Monitoring", - "text": "Include alerts and action groups as part of the Azure Service Health platform to ensure that alerts or issues can be actioned", - "waf": "Operations" + "severity": "High", + "subcategory": "Manage VM Updates", + "text": "Keep VMs up to date using Update Management with Azure Automation" }, { - "category": "Management", - "checklist": "Azure Landing Zone Review", - "guid": "e3ab3693-829e-47e3-8618-3687a0477a20", - "id": "F03.12", - "link": "https://learn.microsoft.com/azure/sentinel/quickstart-onboard", + "category": "VM Security Checks", + "checklist": "Azure Security Review Checklist", + "guid": "c6fa96b9-6ad8-4840-af37-2734c876ba28", + "link": "https://learn.microsoft.com/azure/virtual-machines/automatic-vm-guest-patching", "services": [ - "Monitor" + "VM" ], "severity": "Medium", - "subcategory": "Monitoring", - "text": "Don't send raw log entries back to on-premises monitoring systems. Instead, adopt a principle that data born in Azure stays in Azure. If on-premises SIEM integration is required, then send critical alerts instead of logs.", - "waf": "Operations" + "subcategory": "Manage VM Updates", + "text": "Ensure Windows images for deployment have the most recent level of updates " }, { - "category": "Management", - "checklist": "Azure Landing Zone Review", - "guid": "9945bda4-3334-4f24-a116-34182ba52752", - "id": "F03.13", - "link": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", + "category": "VM Security Checks", + "checklist": "Azure Security Review Checklist", + "guid": "02145901-465d-438e-9309-ccbd979266bc", + "link": "https://learn.microsoft.com/azure/security-center/asset-inventory", "services": [ - "RBAC", - "Monitor", - "Entra" + "VM", + "Defender" ], - "severity": "Medium", - "subcategory": "Monitoring", - "text": "Use a centralized Azure Monitor Log Analytics workspace to collect logs and metrics from IaaS and PaaS application resources and control log access with Azure RBAC.", - "waf": "Operations" + "severity": "High", + "subcategory": "Manage VM Updates", + "text": "Rapidly apply security updates to VMs using Microsoft Defender for Cloud" }, { - "category": "Management", - "checklist": "Azure Landing Zone Review", - "guid": "6944008b-e7d7-4e48-9327-6d8bdc055bcf", - "id": "F03.14", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-setup-guide/monitoring-reporting?tabs=AzureMonitor", + "category": "VM Security Checks", + "checklist": "Azure Security Review Checklist", + "guid": "ca274faa-19bf-439d-a5d4-4c7c8919ca1f", + "link": "https://learn.microsoft.com/azure/virtual-machines/disk-encryption-overview", "services": [ - "Monitor" + "VM" ], - "severity": "Medium", - "subcategory": "Monitoring", - "text": "Use Azure Monitor Logs for insights and reporting.", - "waf": "Operations" + "severity": "High", + "subcategory": "Encrypt your VHDs", + "text": "Enable encryption on your VMs" }, { - "category": "Management", - "checklist": "Azure Landing Zone Review", - "guid": "619e8a13-f988-4795-85d6-26886d70ba6c", - "id": "F03.15", - "link": "https://learn.microsoft.com/azure/azure-monitor/agents/diagnostics-extension-overview", + "category": "VM Security Checks", + "checklist": "Azure Security Review Checklist", + "guid": "6d5315ae-524b-4a34-b458-5e12139bd7bb", + "link": "https://learn.microsoft.com/azure/virtual-machines/windows/disk-encryption-key-vault#set-up-a-key-encryption-key-kek", "services": [ - "Storage", - "Monitor" + "VM" ], - "severity": "Medium", - "subcategory": "Monitoring", - "text": "When necessary, use shared storage accounts within the landing zone for Azure diagnostic extension log storage.", - "waf": "Operations" + "severity": "High", + "subcategory": "Encrypt your VHDs", + "text": "Add Key Encryption Key (KEK) for added layer of security for encryption " }, { - "category": "Management", - "checklist": "Azure Landing Zone Review", - "guid": "97be9951-9048-4384-9c98-6cb2913156a1", - "id": "F03.16", - "link": "https://learn.microsoft.com/azure/azure-monitor/alerts/alerts-overview", + "category": "VM Security Checks", + "checklist": "Azure Security Review Checklist", + "guid": "012f7b95-e06e-4154-b2aa-3592828e6e20", + "link": "https://learn.microsoft.com/azure/virtual-machines/windows/snapshot-copy-managed-disk", "services": [ - "Monitor" + "VM", + "LoadBalancer" ], "severity": "Medium", - "subcategory": "Monitoring", - "text": "Use Azure Monitor alerts for the generation of operational alerts.", - "waf": "Operations" + "subcategory": "Encrypt your VHDs", + "text": "Take a snapshot of disks before encryption for rollback purposes" }, { - "category": "Management", - "checklist": "Azure Landing Zone Review", - "guid": "859c3900-4514-41eb-b010-475d695abd74", - "id": "F03.17", - "link": "https://learn.microsoft.com/azure/architecture/best-practices/monitoring", + "category": "VM Security Checks", + "checklist": "Azure Security Review Checklist", + "guid": "5173676a-e466-491e-a835-ad942223e138", + "link": "https://learn.microsoft.com/azure/role-based-access-control/built-in-roles", "services": [ - "Monitor" + "VM", + "Entra" ], - "severity": "Medium", - "subcategory": "Monitoring", - "text": "Ensure that monitoring requirements have been assessed and that appropriate data collection and alerting configurations are applied", - "waf": "Operations" + "severity": "High", + "subcategory": "Restrict direct internet connection ", + "text": "Ensure only the central networking group has permissions to networking resources " }, { - "category": "Management", - "checklist": "Azure Landing Zone Review", - "guid": "fed3c55f-a67e-4875-aadd-3aba3f9fde31", - "id": "F03.18", - "link": "https://learn.microsoft.com/azure/automation/how-to/region-mappings", + "category": "VM Security Checks", + "checklist": "Azure Security Review Checklist", + "guid": "10523081-a941-4741-9833-ff7ad7c6d373", + "link": "https://learn.microsoft.com/azure/security-center/security-center-partner-integration", "services": [ - "Monitor" + "VM", + "Entra" ], - "severity": "Medium", - "subcategory": "Monitoring", - "text": "Consider supported regions for linked Log Analytics workspace and automation accounts", - "waf": "Operations" + "severity": "High", + "subcategory": "Restrict direct internet connection ", + "text": "Identity and remediate exposed VMs that allow access from 'ANY' source IP address" }, { - "category": "Management", - "checklist": "Azure Landing Zone Review", - "guid": "f541acdc-e979-4377-acdb-3751ab2ab13a", - "id": "F04.01", - "link": "https://learn.microsoft.com/azure/governance/policy/concepts/guest-configuration", + "category": "VM Security Checks", + "checklist": "Azure Security Review Checklist", + "guid": "75a91be1-f388-4f03-a4d2-cd463cbbbc86", + "link": "https://learn.microsoft.com/azure/security-center/security-center-just-in-time", "services": [ - "VM", - "AzurePolicy" + "VM" ], - "severity": "Medium", - "subcategory": "Operational compliance", - "text": "Use Azure policies to automatically deploy software configurations through VM extensions and enforce a compliant baseline VM configuration.", - "waf": "Security" + "severity": "High", + "subcategory": "Restrict direct internet connection ", + "text": "Restrict management ports (RDP, SSH) using Just-in-Time Access" }, { - "category": "Management", - "checklist": "Azure Landing Zone Review", - "description": "Azure Policy's guest configuration features can audit and remediate machine settings (e.g., OS, application, environment) to ensure resources align with expected configurations, and Update Management can enforce patch management for VMs.", - "guid": "da6e55d7-d8a2-4adb-817d-6326af625ca4", - "id": "F04.02", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/management-operational-compliance#monitoring-for-configuration-drift", + "category": "VM Security Checks", + "checklist": "Azure Security Review Checklist", + "guid": "8295abc9-1a4e-4da0-bae2-cc84c47b6b78", + "link": "http://learn.microsoft.com/answers/questions/171195/how-to-create-jump-server-in-azure-not-bastion-paa.html", "services": [ - "VM", - "Monitor", - "AzurePolicy" + "VM" ], - "severity": "Medium", - "subcategory": "Operational compliance", - "text": "Monitor VM security configuration drift via Azure Policy.", - "waf": "Security" + "severity": "High", + "subcategory": "Restrict direct internet connection ", + "text": "Remove internet access and implement jump servers for RDP" }, { - "category": "Management", - "checklist": "Azure Landing Zone Review", - "guid": "2476e49f-541a-4cdc-b979-377bcdb3751a", - "id": "F05.01", - "link": "https://learn.microsoft.com/azure/site-recovery/site-recovery-overview", + "category": "VM Security Checks", + "checklist": "Azure Security Review Checklist", + "guid": "1cbafe6c-4658-49d4-98a9-27c3974d1102", + "link": "https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-forced-tunneling", "services": [ - "ACR", "VM", - "ASR" + "VPN" ], - "severity": "Medium", - "subcategory": "Protect and Recover", - "text": "Use Azure Site Recovery for Azure-to-Azure Virtual Machines disaster recovery scenarios. This enables you to replicate workloads across regions.", - "waf": "Operations" + "severity": "High", + "subcategory": "Restrict direct internet connection ", + "text": "Remove direct logging into servers using RDP/SSH from internet and implement VPN or express route" }, { - "category": "Management", - "checklist": "Azure Landing Zone Review", - "guid": "b2ab13ad-a6e5-45d7-b8a2-adb117d6326a", - "id": "F05.02", - "link": "https://learn.microsoft.com/azure/architecture/framework/resiliency/backup-and-recovery", + "category": "VM Security Checks", + "checklist": "Azure Security Review Checklist", + "guid": "dad6aae1-1e6b-484e-b5df-47d2d92881b1", + "link": "https://learn.microsoft.com/azure/bastion/bastion-overview", "services": [ - "ASR" + "Bastion", + "VM" ], - "severity": "Medium", - "subcategory": "Protect and Recover", - "text": "Ensure to use and test native PaaS service disaster recovery capabilities.", - "waf": "Operations" + "severity": "High", + "subcategory": "Restrict direct internet connection ", + "text": "Leverage Azure Bastion as your RDP/SSH broker for added security and reduction in footprint" }, { - "category": "Management", - "checklist": "Azure Landing Zone Review", - "guid": "f625ca44-e569-45f2-823a-ce8cb12308ca", - "id": "F05.03", - "link": "https://learn.microsoft.com/azure/backup/backup-center-overview", + "category": "Sentinel", + "checklist": "Azure Security Review Checklist", + "guid": "cd5d1e54-a297-459e-9968-0e78289c9356", + "link": "https://learn.microsoft.com/azure/sentinel/quickstart-onboard", "services": [ - "Backup" + "Monitor", + "Sentinel" ], - "severity": "Medium", - "subcategory": "Protect and Recover", - "text": "Use Azure-native backup capabilities, or an Azure-compatible, 3rd-party backup solution.", - "waf": "Operations" + "severity": "High", + "subcategory": "Architecture ", + "text": "All tenants contain have Sentinel enabled on at least one Log Analytics workspace" }, { - "ammp": true, - "category": "Management ", - "checklist": "Azure Landing Zone Review", - "guid": "826c5c45-bb79-4951-a812-e3bfbfd7326b", - "id": "F06.01", - "link": "https://learn.microsoft.com/azure/reliability/availability-zones-overview", + "category": "Sentinel", + "checklist": "Azure Security Review Checklist", + "guid": "57d02bff-4564-4b0d-a34a-359836ee79d6", + "link": "https://learn.microsoft.com/azure/sentinel/best-practices-workspace-architecture", "services": [ - "VM" + "Sentinel" ], "severity": "High", - "subcategory": "Fault Tolerance", - "text": "Leverage Availability Zones for your VMs in regions where they are supported.", - "waf": "Reliability" + "subcategory": "Architecture ", + "text": "Customer understands Sentinel architecture" }, { - "ammp": true, - "category": "Management ", - "checklist": "Azure Landing Zone Review", - "guid": "7ccb7c06-5511-42df-8177-d97f08d0337d", - "id": "F06.02", - "link": "https://learn.microsoft.com/azure/virtual-machines/availability", + "category": "Sentinel", + "checklist": "Azure Security Review Checklist", + "guid": "e8f5c586-c7d9-4cdc-86ac-c075ef9b141a", + "link": "https://learn.microsoft.com/azure/sentinel/multiple-workspace-view", "services": [ - "VM" + "ACR", + "Monitor", + "Sentinel" + ], + "severity": "Medium", + "subcategory": "Architecture ", + "text": "Customer knows how to monitor Incidents across multiple Sentinel instances" + }, + { + "category": "Sentinel", + "checklist": "Azure Security Review Checklist", + "guid": "8989579e-76b8-497e-910a-7da7be9966e1", + "link": "https://learn.microsoft.com/azure/sentinel/manage-soc-with-incident-metrics", + "services": [ + "Sentinel" ], - "severity": "High", - "subcategory": "Fault Tolerance", - "text": "Avoid running a production workload on a single VM.", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "Overview", + "text": "No Incidents open more than 24 hours" }, { - "category": "Management ", - "checklist": "Azure Landing Zone Review", - "guid": "84101f59-1941-4195-a270-e28034290e3a", - "id": "F06.03", - "link": "https://learn.microsoft.com/azure/load-balancer/load-balancer-overview", + "category": "Sentinel", + "checklist": "Azure Security Review Checklist", + "guid": "5d3c4ada-97cb-43d1-925a-b225c6f4e068", + "link": "https://learn.microsoft.com/azure/sentinel/whats-new", "services": [ - "ACR", - "LoadBalancer", - "AppGW" + "Sentinel" ], - "severity": "Medium", - "subcategory": "Fault Tolerance", - "text": "Azure Load Balancer and Application Gateway distribute incoming network traffic across multiple resources.", - "waf": "Reliability" + "severity": "Low", + "subcategory": "News & Guides", + "text": "Customer have been shown the News & Guides tab" }, { - "category": "Security", - "checklist": "Azure Landing Zone Review", - "guid": "b86ad884-08e3-4727-94b8-75ba18f20459", - "id": "G01.01", - "link": "https://learn.microsoft.com/security/benchmark/azure/security-control-incident-response", - "services": [], + "category": "Sentinel", + "checklist": "Azure Security Review Checklist", + "guid": "5edddea8-a4b7-4cde-a4c6-1fc3fc14eea6", + "link": "https://learn.microsoft.com/azure/sentinel/enable-entity-behavior-analytics", + "services": [ + "Sentinel" + ], "severity": "Medium", - "subcategory": "Access control", - "text": "Determine the incident response plan for Azure services before allowing it into production.", - "waf": "Security" + "subcategory": "UEBA ", + "text": "UEBA Configured (Sentinel/Settings/Settings/Configure UEBA)" }, { - "category": "Security", - "checklist": "Azure Landing Zone Review", - "guid": "01365d38-e43f-49cc-ad86-8266abca264f", - "id": "G01.02", - "link": "https://www.microsoft.com/security/business/zero-trust", - "services": [], - "severity": "Medium", - "subcategory": "Access control", - "text": "Implement a zero-trust approach for access to the Azure platform, where appropriate.", - "waf": "Security" + "category": "Sentinel", + "checklist": "Azure Security Review Checklist", + "guid": "e69d8d9a-3eec-4218-b687-ab077adb49e5", + "link": "https://learn.microsoft.com/azure/sentinel/connect-azure-active-directory", + "services": [ + "Sentinel", + "Entra" + ], + "severity": "High", + "subcategory": "Data Connectors", + "text": "Azure Active Directory in configured and 'Last Log Received' shows today" }, { - "ammp": true, - "category": "Security", - "checklist": "Azure Landing Zone Review", - "guid": "5017f154-e3ab-4369-9829-e7e316183687", - "id": "G02.01", - "link": "https://learn.microsoft.com/azure/key-vault/general/overview", + "category": "Sentinel", + "checklist": "Azure Security Review Checklist", + "guid": "b9603334-fdf8-4cc2-9318-db61171269f4", + "link": "https://learn.microsoft.com/azure/sentinel/data-connectors-reference#azure-active-directory-identity-protection", "services": [ - "AKV" + "Sentinel", + "Entra" ], "severity": "High", - "subcategory": "Encryption and keys", - "text": "Use Azure Key Vault to store your secrets and credentials", - "waf": "Security" + "subcategory": "Data Connectors", + "text": "Azure Active Directory Identity Protection is configured and 'Last Log Received' shows today" }, { - "category": "Security", - "checklist": "Azure Landing Zone Review", - "graph": "ResourceContainers | where type=='microsoft.resources/subscriptions'| parse id with '/subscriptions/' SubscriptionID| project subscriptionId, SubscriptionName = name| join kind=leftouter (Resources| where type == 'microsoft.keyvault/vaults'| project id, name, subscriptionId) on subscriptionId| join kind= leftouter (Resources| where type == 'microsoft.keyvault/vaults'| summarize ResourceCount = count() by subscriptionId) on subscriptionId| extend RCount = iff(isnull(ResourceCount), 0, ResourceCount)| project-away ResourceCount| extend compliant = (RCount <> 1)", - "guid": "a0477a20-9945-4bda-9333-4f2491163418", - "id": "G02.02", - "link": "https://learn.microsoft.com/azure/key-vault/general/overview-throttling", + "category": "Sentinel", + "checklist": "Azure Security Review Checklist", + "guid": "0b4aa3d3-e070-4327-9d4b-98b15b8a219a", + "link": "https://learn.microsoft.com/azure/sentinel/data-connectors-reference#azure-activity", "services": [ - "AKV" + "Sentinel" ], - "severity": "Medium", - "subcategory": "Encryption and keys", - "text": "Use different Azure Key Vaults for different applications and regions to avoid transaction scale limits and restrict access to secrets.", - "waf": "Security" + "severity": "High", + "subcategory": "Data Connectors", + "text": "Azure Activity is configured is configured and 'Last Log Received' shows today" }, { - "category": "Security", - "checklist": "Azure Landing Zone Review", - "guid": "2ba52752-6944-4008-ae7d-7e4843276d8b", - "id": "G02.03", - "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", + "category": "Sentinel", + "checklist": "Azure Security Review Checklist", + "guid": "8e13f9cc-bd46-4826-9abc-a264f9a19bfe", + "link": "https://learn.microsoft.com/azure/sentinel/connect-defender-for-cloud", "services": [ - "AzurePolicy", - "AKV" + "Sentinel", + "Defender" ], - "severity": "Medium", - "subcategory": "Encryption and keys", - "text": "Provision Azure Key Vault with the soft delete and purge policies enabled to allow retention protection for deleted objects.", - "waf": "Security" + "severity": "High", + "subcategory": "Data Connectors", + "text": "Microsoft Defender for Cloud is configured and 'Last Log Received' shows today" }, { - "category": "Security", - "checklist": "Azure Landing Zone Review", - "guid": "dc055bcf-619e-48a1-9f98-879525d62688", - "id": "G02.04", - "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", + "category": "Sentinel", + "checklist": "Azure Security Review Checklist", + "guid": "9d55d04c-3c49-419c-a1b2-d1215ae114b9", + "link": "https://learn.microsoft.com/azure/sentinel/data-connectors-reference#azure-firewall", "services": [ - "RBAC", - "AKV", - "Entra" + "Firewall", + "Sentinel" ], - "severity": "Medium", - "subcategory": "Encryption and keys", - "text": "Follow a least privilege model by limiting authorization to permanently delete keys, secrets, and certificates to specialized custom Microsoft Entra ID roles.", - "waf": "Security" + "severity": "High", + "subcategory": "Data Connectors", + "text": "Azure Firewall is configured and 'Last Log Received' shows today" }, { - "category": "Security", - "checklist": "Azure Landing Zone Review", - "guid": "6d70ba6c-97be-4995-8904-83845c986cb2", - "id": "G02.05", - "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", + "category": "Sentinel", + "checklist": "Azure Security Review Checklist", + "guid": "34df585e-cccd-49bd-9ba0-cdb3b54eb2eb", + "link": "https://learn.microsoft.com/azure/sentinel/data-connectors-reference#windows-firewall", "services": [ - "AKV" + "Sentinel" ], - "severity": "Medium", - "subcategory": "Encryption and keys", - "text": "Automate the certificate management and renewal process with public certificate authorities to ease administration.", - "waf": "Security" + "severity": "High", + "subcategory": "Data Connectors", + "text": "Windows Firewall is configured and 'Last Log Received' shows today" }, { - "category": "Security", - "checklist": "Azure Landing Zone Review", - "guid": "913156a1-2476-4e49-b541-acdce979377b", - "id": "G02.06", - "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", + "category": "Sentinel", + "checklist": "Azure Security Review Checklist", + "guid": "03ddaa25-9271-48d2-bdb1-0725769ef669", + "link": "https://learn.microsoft.com/azure/sentinel/data-connectors-reference#windows-security-events-via-ama", "services": [ - "AKV" + "Sentinel" ], - "severity": "Medium", - "subcategory": "Encryption and keys", - "text": "Establish an automated process for key and certificate rotation.", - "waf": "Security" + "severity": "High", + "subcategory": "Data Connectors", + "text": "Security Events is configured with AMA and 'Last Log Received' shows today" }, { - "category": "Security", - "checklist": "Azure Landing Zone Review", - "guid": "cdb3751a-b2ab-413a-ba6e-55d7d8a2adb1", - "id": "G02.07", - "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", + "category": "Sentinel", + "checklist": "Azure Security Review Checklist", + "guid": "1a4834ac-9322-423e-ae80-b123081a5417", + "link": "https://learn.microsoft.com/azure/sentinel/data-connectors-reference", "services": [ - "VNet", - "PrivateLink", - "AKV" + "Sentinel" ], - "severity": "Medium", - "subcategory": "Encryption and keys", - "text": "Enable firewall and virtual network service endpoint or private endpoint on the vault to control access to the key vault.", - "waf": "Security" + "severity": "High", + "subcategory": "Data Connectors", + "text": "Security Events - verify Azure computers are connected and sending data to the workspace" }, { - "category": "Security", - "checklist": "Azure Landing Zone Review", - "guid": "17d6326a-f625-4ca4-9e56-95f2223ace8c", - "id": "G02.08", - "link": "https://learn.microsoft.com/azure/key-vault/general/monitor-key-vault", + "category": "Sentinel", + "checklist": "Azure Security Review Checklist", + "guid": "859c773e-7e26-4162-9b77-5a917e1f348e", + "link": "https://learn.microsoft.com/azure/sentinel/data-connectors-reference", "services": [ - "Monitor", - "AKV", - "Entra" + "Sentinel" ], - "severity": "Medium", - "subcategory": "Encryption and keys", - "text": "Use the platform-central Azure Monitor Log Analytics workspace to audit key, certificate, and secret usage within each instance of Key Vault.", - "waf": "Security" + "severity": "High", + "subcategory": "Data Connectors", + "text": "Security Events - verify non-Azure computers are connected and sending data to the workspace" }, { - "category": "Security", - "checklist": "Azure Landing Zone Review", - "guid": "b12308ca-5017-4f15-9e3a-b3693829e7e3", - "id": "G02.09", - "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", + "category": "Sentinel", + "checklist": "Azure Security Review Checklist", + "guid": "f354c27d-42e8-4bba-a868-155abb9163e9", + "link": "https://learn.microsoft.com/azure/sentinel/connect-aws?tabs=s3", "services": [ - "AzurePolicy", - "AKV" + "Sentinel" ], - "severity": "Medium", - "subcategory": "Encryption and keys", - "text": "Delegate Key Vault instantiation and privileged access and use Azure Policy to enforce a consistent compliant configuration.", - "waf": "Security" + "severity": "High", + "subcategory": "Data Connectors", + "text": "Connector for AWS" }, { - "category": "Security", - "checklist": "Azure Landing Zone Review", - "guid": "16183687-a047-47a2-8994-5bda43334f24", - "id": "G02.10", - "link": "https://learn.microsoft.com/azure/security/fundamentals/encryption-atrest", + "category": "Sentinel", + "checklist": "Azure Security Review Checklist", + "guid": "909ae28c-84c3-43b6-a780-8bafe6c42149", + "link": "https://learn.microsoft.com/azure/sentinel/data-connectors-reference", + "services": [ + "Sentinel" + ], + "severity": "High", + "subcategory": "Data Connectors", + "text": "Connector for GCP" + }, + { + "category": "Sentinel", + "checklist": "Azure Security Review Checklist", + "guid": "d413a923-c357-44d1-8028-ac6aae01e6a8", + "link": "https://learn.microsoft.com/azure/sentinel/detect-threats-built-in", "services": [ - "AKV" + "Sentinel" ], - "severity": "Medium", - "subcategory": "Encryption and keys", - "text": "Default to Microsoft-managed keys for principal encryption functionality and use customer-managed keys when required.", - "waf": "Security" + "severity": "High", + "subcategory": "Analytics Rules", + "text": "Customer has enabled Analytics rules and configured Incidents " }, { - "category": "Security", - "checklist": "Azure Landing Zone Review", - "guid": "91163418-2ba5-4275-8694-4008be7d7e48", - "id": "G02.11", - "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", + "category": "Sentinel", + "checklist": "Azure Security Review Checklist", + "guid": "4de5df43-d299-4248-8718-d5d1e5f62565", + "link": "https://azure.microsoft.com/updates/controlling-data-volume-and-retention-in-log-analytics-2/", "services": [ - "AKV" + "Sentinel" ], "severity": "Medium", - "subcategory": "Encryption and keys", - "text": "Use an Azure Key Vault per application per environment per region.", - "waf": "Security" + "subcategory": "Settings", + "text": "Customer does not have a daily cap enabled" }, { - "category": "Security", - "checklist": "Azure Landing Zone Review", - "guid": "25d62688-6d70-4ba6-a97b-e99519048384", - "id": "G02.12", - "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", + "category": "Azure Firewall", + "checklist": "Azure Security Review Checklist", + "guid": "9e3558fd-7724-49c9-9111-2d027fe412f7", + "link": "https://learn.microsoft.com/azure/firewall/premium-features", "services": [ - "ACR", - "ASR", - "AKV" + "Firewall" ], - "severity": "Medium", - "subcategory": "Encryption and keys", - "text": "If you want to bring your own keys, this might not be supported across all considered services. Implement relevant mitigation so that inconsistencies don't hinder desired outcomes. Choose appropriate region pairs and disaster recovery regions that minimize latency.", - "waf": "Security" + "severity": "High", + "subcategory": "Configuration", + "text": "Azure Firewall Premium deployed" }, { - "category": "Security", - "checklist": "Azure Landing Zone Review", - "guid": "4ac6b67c-b3a4-4ff9-8e87-b07a7ce7bbdb", - "id": "G02.13", - "link": "https://learn.microsoft.com/en-us/industry/sovereignty/key-management", + "category": "Azure Firewall", + "checklist": "Azure Security Review Checklist", + "guid": "4dc74a74-8b66-433a-b2a0-916a764980ad", + "link": "https://learn.microsoft.com/azure/firewall/tutorial-firewall-deploy-portal#create-a-default-route", "services": [ - "AKV" + "Firewall" ], - "severity": "Medium", - "subcategory": "Encryption and keys", - "text": "For Sovereign Landing Zone, use Azure Key Vault managed HSM to store your secrets and credentials.", - "waf": "Security" + "severity": "High", + "subcategory": "Configuration", + "text": "Quad zero/force tunning enabled through Azure Firewall" }, { - "category": "Security", - "checklist": "Azure Landing Zone Review", - "guid": "4e5695f2-223a-4ce8-ab12-308ca5017f15", - "id": "G03.01", - "link": "https://learn.microsoft.com/azure/active-directory/reports-monitoring/overview-reports", + "category": "Azure Firewall", + "checklist": "Azure Security Review Checklist", + "guid": "0e278ee2-93c1-4bc3-92ba-aab7571849ab", + "link": "https://techcommunity.microsoft.com/t5/azure-network-security/role-based-access-control-for-azure-firewall/ba-p/2245598", "services": [ - "Entra" + "RBAC", + "Firewall" ], "severity": "Medium", - "subcategory": "Operations", - "text": "Use Microsoft Entra ID reporting capabilities to generate access control audit reports.", - "waf": "Security" + "subcategory": "Access Control", + "text": "RBAC set to enable only authorized users" }, { - "category": "Security", - "checklist": "Azure Landing Zone Review", - "guid": "4e3ab369-3829-4e7e-9161-83687a0477a2", - "id": "G03.02", - "link": "https://learn.microsoft.com/azure/azure-monitor/logs/logs-data-export?tabs=portal", + "category": "Azure Firewall", + "checklist": "Azure Security Review Checklist", + "guid": "8093dc9f-c9d1-4bb7-9b36-a5a67fbb9ed5", + "link": "https://learn.microsoft.com/azure/firewall/firewall-diagnostics", "services": [ - "Storage", "Monitor", - "ARS" + "Firewall" ], "severity": "Medium", - "subcategory": "Operations", - "text": "Export Azure activity logs to Azure Monitor Logs for long-term data retention. Export to Azure Storage for long-term storage beyond two years, if necessary.", - "waf": "Security" + "subcategory": "Diagnostic Settings", + "text": "Diagnostics enabled and sending metrics to a Log Analytics workspace " }, { - "ammp": true, - "category": "Security", - "checklist": "Azure Landing Zone Review", - "guid": "09945bda-4333-44f2-9911-634182ba5275", - "id": "G03.03", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/concept-cloud-security-posture-management", + "category": "Azure Firewall", + "checklist": "Azure Security Review Checklist", + "guid": "b35478c3-4798-416b-8863-cffe1cac599e", + "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview", "services": [ - "Defender", - "Subscriptions" + "VNet", + "Firewall" ], "severity": "High", - "subcategory": "Operations", - "text": "Enable Defender Cloud Security Posture Management for all subscriptions.", - "waf": "Security" + "subcategory": "Firewall Manager", + "text": "Hubs and virtual networks are protected or connected through Firewall Premium" }, { - "ammp": true, - "category": "Security", - "checklist": "Azure Landing Zone Review", - "guid": "36a72a48-fffe-4c40-9747-0ab5064355ba", - "id": "G03.04", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/plan-defender-for-servers-select-plan", + "category": "Azure Firewall", + "checklist": "Azure Security Review Checklist", + "guid": "f0d5a73d-d4de-436c-8c81-770afbc4c0e4", + "link": "https://techcommunity.microsoft.com/t5/azure-network-security/role-based-access-control-for-azure-firewall/ba-p/2245598", "services": [ - "Defender", - "Subscriptions" + "RBAC", + "Firewall", + "AzurePolicy" ], "severity": "High", - "subcategory": "Operations", - "text": "Enable a Defender Cloud Workload Protection Plan for Servers on all subscriptions.", - "waf": "Security" + "subcategory": "Firewall Manager", + "text": "Policy: Access controls are configured (RBAC)" }, { - "ammp": true, - "category": "Security", - "checklist": "Azure Landing Zone Review", - "guid": "77425f48-ecba-43a0-aeac-a3ac733ccc6a", - "id": "G03.05", - "link": "https://www.microsoft.com/en-gb/security/business/solutions/cloud-workload-protection", + "category": "Azure Firewall", + "checklist": "Azure Security Review Checklist", + "guid": "5c3a87af-4a79-41f8-a39b-da47768e14c1", + "link": "https://learn.microsoft.com/azure/firewall-manager/policy-overview", "services": [ - "Defender", - "Subscriptions" + "Firewall", + "AzurePolicy" ], "severity": "High", - "subcategory": "Operations", - "text": "Enable Defender Cloud Workload Protection Plans for Azure Resources on all subscriptions.", - "waf": "Security" + "subcategory": "Firewall Manager", + "text": "Policy: Parent policy is configured " }, { - "ammp": true, - "category": "Security", - "checklist": "Azure Landing Zone Review", - "guid": "24d96b30-61ee-4436-a1cc-d6ef08bc574b", - "id": "G03.06", - "link": "https://learn.microsoft.com/mem/configmgr/protect/deploy-use/endpoint-protection", - "services": [], + "category": "Azure Firewall", + "checklist": "Azure Security Review Checklist", + "guid": "15675c1e-a55b-446a-a48f-f8ae7d7e4b47", + "link": "https://learn.microsoft.com/azure/firewall/rule-processing", + "services": [ + "Firewall", + "AzurePolicy" + ], "severity": "High", - "subcategory": "Operations", - "text": "Enable Endpoint Protection on IaaS Servers.", - "waf": "Security" + "subcategory": "Firewall Manager", + "text": "Policy: Rule collections are defined" }, { - "category": "Security", - "checklist": "Azure Landing Zone Review", - "guid": "15833ee7-ad6c-46d3-9331-65c7acbe44ab", - "id": "G03.07", - "link": "https://learn.microsoft.com/azure/security-center/", + "category": "Azure Firewall", + "checklist": "Azure Security Review Checklist", + "guid": "5b6c8bcb-f59b-4ce6-9de8-a03f97879468", + "link": "https://learn.microsoft.com/azure/firewall/rule-processing", "services": [ - "Defender", - "Monitor" + "Firewall", + "AzurePolicy" ], - "severity": "Medium", - "subcategory": "Operations", - "text": "Monitor base operating system patching drift via Azure Monitor Logs and Defender for Cloud.", - "waf": "Security" + "severity": "High", + "subcategory": "Firewall Manager", + "text": "Policy: DNAT policies are defined" }, { - "category": "Security", - "checklist": "Azure Landing Zone Review", - "guid": "e5f8d79f-2e87-4768-924c-516775c6ea95", - "id": "G03.08", - "link": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", + "category": "Azure Firewall", + "checklist": "Azure Security Review Checklist", + "guid": "d66a786d-60e9-46c9-9ad8-855d04c2b39c", + "link": "https://learn.microsoft.com/azure/firewall/rule-processing", "services": [ - "Monitor", - "Entra" + "Firewall", + "AzurePolicy" ], - "severity": "Medium", - "subcategory": "Operations", - "text": "Connect default resource configurations to a centralized Azure Monitor Log Analytics workspace.", - "waf": "Security" + "severity": "High", + "subcategory": "Firewall Manager", + "text": "Policy: Network rules are defined" }, { - "category": "Security", - "checklist": "Azure Landing Zone Review", - "guid": "1761e147-f65e-4d09-bbc2-f464f23e2eba", - "id": "G03.09", - "link": "https://learn.microsoft.com/en-us/industry/sovereignty/transparency-logs", + "category": "Azure Firewall", + "checklist": "Azure Security Review Checklist", + "guid": "986bb2c1-2149-4a11-9b5e-3df574ecccd9", + "link": "https://learn.microsoft.com/azure/firewall/features", "services": [ - "Entra" + "Firewall", + "AzurePolicy" ], - "severity": "Medium", - "subcategory": "Operations", - "text": "For Sovereign Landing Zone, transparancy logs is enabled on the Entra ID tenant.", - "waf": "Security" + "severity": "High", + "subcategory": "Firewall Manager", + "text": "Policy: Application rules are defined" }, { - "category": "Security", - "checklist": "Azure Landing Zone Review", - "guid": "d21a922d-5ca7-427a-82a6-35f7b21f1bfc", - "id": "G03.10", - "link": "https://learn.microsoft.com/en-us/azure/security/fundamentals/customer-lockbox-overview", + "category": "Azure Firewall", + "checklist": "Azure Security Review Checklist", + "guid": "793a6bcd-a3b5-40eb-8eb0-3dd95d58d7c8", + "link": "https://learn.microsoft.com/azure/firewall/dns-details", "services": [ - "Entra" + "Firewall", + "DNS" ], "severity": "Medium", - "subcategory": "Operations", - "text": "For Sovereign Landing Zone, customer Lockbox is enabled on the Entra ID tenant.", - "waf": "Security" + "subcategory": "Firewall Manager", + "text": "DNS: Feature understood and applied or not applied" }, { - "ammp": true, - "category": "Security", - "checklist": "Azure Landing Zone Review", - "guid": "b03ed428-4617-4067-a787-85468b9ccf3f", - "id": "G04.01", - "link": "https://learn.microsoft.com/azure/storage/common/storage-require-secure-transfer", + "category": "Azure Firewall", + "checklist": "Azure Security Review Checklist", + "guid": "d622f54b-29ba-4de3-aad1-e8c28ec93666", + "link": "https://learn.microsoft.com/azure/firewall-manager/threat-intelligence-settings", "services": [ - "Storage" + "Firewall" ], "severity": "High", - "subcategory": "Overview", - "text": "Secure transfer to storage accounts should be enabled", - "waf": "Security" + "subcategory": "Firewall Manager", + "text": "Threat Intelligence: Set to Alert & Deny" }, { - "ammp": true, - "category": "Security", - "checklist": "Azure Landing Zone Review", - "guid": "159aac9f-863f-4f48-82cf-00c28fa97a0e", - "id": "G04.02", - "link": "https://learn.microsoft.com/azure/storage/blobs/data-protection-overview#recommendations-for-basic-data-protection", + "category": "Azure Firewall", + "checklist": "Azure Security Review Checklist", + "guid": "7313b005-674b-41e9-94a4-59c373e7ed61", + "link": "https://learn.microsoft.com/azure/firewall-manager/threat-intelligence-settings#allowlist-addresses", "services": [ - "Storage" + "Firewall" ], "severity": "High", - "subcategory": "Overview", - "text": "Enable container soft delete for the storage account to recover a deleted container and its contents.", - "waf": "Security" + "subcategory": "Firewall Manager", + "text": "Threat Intelligence: Allowed list (justify if they are being used - ie performance)" }, { - "ammp": true, - "category": "Security", - "checklist": "Azure Landing Zone Review", - "guid": "6f704104-85c1-441f-96d3-c9819911645e", - "id": "G05.01", - "link": "https://learn.microsoft.com/azure/active-directory/roles/security-planning", + "category": "Azure Firewall", + "checklist": "Azure Security Review Checklist", + "guid": "623b365a-917e-4cbe-98eb-d54cd7df2e8b", + "link": "https://learn.microsoft.com/azure/firewall/premium-certificates", "services": [ - "Entra" + "Firewall" ], "severity": "High", - "subcategory": "Secure privileged access", - "text": "Separate privileged admin accounts for Azure administrative tasks.", - "waf": "Security" - }, - { - "category": "Security", - "checklist": "Azure Landing Zone Review", - "guid": "9a19bf39-c95d-444c-9c89-19ca1f6d5215", - "id": "G06.01", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/service-enablement-framework", - "services": [], - "severity": "Medium", - "subcategory": "Service enablement framework", - "text": "Plan how new azure services will be implemented", - "waf": "Security" - }, - { - "category": "Security", - "checklist": "Azure Landing Zone Review", - "guid": "ae514b93-3d45-485e-8112-9bd7ba012f7b", - "id": "G06.02", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/service-enablement-framework", - "services": [], - "severity": "Medium", - "subcategory": "Service enablement framework", - "text": "Plan how service request will be fulfilled for Azure services", - "waf": "Security" + "subcategory": "Firewall Manager", + "text": "TLS enabled" }, { - "ammp": true, - "category": "Platform Automation and DevOps", - "checklist": "Azure Landing Zone Review", - "guid": "e85f4226-bf06-4e35-8a8b-7aee4d2d633a", - "id": "H01.01", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/platform-automation-devops", - "services": [], + "category": "Azure Firewall", + "checklist": "Azure Security Review Checklist", + "guid": "bac35715-59ab-4915-9e99-08aed8c44ce3", + "link": "https://learn.microsoft.com/azure/firewall/rule-processing", + "services": [ + "Firewall" + ], "severity": "High", - "subcategory": "DevOps Team Topologies", - "text": "Ensure you have a cross functional DevOps Platform Team to build, manage and maintain your Azure Landing Zone architecture.", - "waf": "Operations" - }, - { - "category": "Platform Automation and DevOps", - "checklist": "Azure Landing Zone Review", - "guid": "634146bf-7085-4419-a7b5-f96d2726f6da", - "id": "H01.02", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/devops-teams-topologies#design-recommendations", - "services": [], - "severity": "Low", - "subcategory": "DevOps Team Topologies", - "text": "Aim to define functions for Azure Landing Zone Platform team.", - "waf": "Operations" + "subcategory": "Firewall Manager", + "text": "IDPS enabled" }, { - "category": "Platform Automation and DevOps", - "checklist": "Azure Landing Zone Review", - "guid": "a9e65070-c59e-4112-8bf6-c11364d4a2a5", - "id": "H01.03", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/devops-teams-topologies#design-recommendations", + "category": "Azure Firewall", + "checklist": "Azure Security Review Checklist", + "guid": "b2b3808b-9fa1-4cf1-849d-003a923ce474", + "link": "https://learn.microsoft.com/azure/firewall/snat-private-range", "services": [ - "RBAC" + "Firewall" ], - "severity": "Low", - "subcategory": "DevOps Team Topologies", - "text": "Aim to define functions for application workload teams to be self-sufficient and not require DevOps Platform Team support. Achieve this through the use of custom RBAC role.", - "waf": "Operations" - }, - { - "ammp": true, - "category": "Platform Automation and DevOps", - "checklist": "Azure Landing Zone Review", - "guid": "165eb5e9-b434-448a-9e24-178632186212", - "id": "H01.04", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/infrastructure-as-code", - "services": [], "severity": "High", - "subcategory": "DevOps Team Topologies", - "text": "Use a CI/CD pipeline to deploy IaC artifacts and ensure the quality of your deployment and Azure environments.", - "waf": "Operations" + "subcategory": "Firewall Manager", + "text": "SNAT: Configured " }, { - "category": "Platform Automation and DevOps", - "checklist": "Azure Landing Zone Review", - "guid": "0cadb8c7-8fa5-4fbf-8f39-d1fadb3b0460", - "id": "H01.05", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/development-strategy-development-lifecycle#automated-builds", - "services": [], + "category": "Azure Firewall", + "checklist": "Azure Security Review Checklist", + "guid": "dbcbd8ac-2aae-4bca-8a43-da1dae2cc992", + "link": "https://learn.microsoft.com/azure/security/fundamentals/ddos-best-practices", + "services": [ + "DDoS", + "Firewall" + ], "severity": "Medium", - "subcategory": "DevOps Team Topologies", - "text": "Include unit tests for IaC and application code as part of your build process.", - "waf": "Operations" + "subcategory": "DDOS Protection", + "text": "Enabled for Firewall public IP's" }, { - "ammp": true, - "category": "Platform Automation and DevOps", - "checklist": "Azure Landing Zone Review", - "guid": "108d5099-a11d-4445-bd8b-e12a5e95412e", - "id": "H01.06", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/development-strategy-development-lifecycle#automated-builds", + "category": "Foundation", + "checklist": "Azure Arc Review", + "description": "Define a resource group structure for placement of Azure Arc-enabled servers resources", + "guid": "585e1112-9bd7-4ba0-82f7-b94ef6e043d2", "services": [ - "VM", - "AKV" + "Arc" ], "severity": "High", - "subcategory": "DevOps Team Topologies", - "text": "Use Key Vault secrets to avoid hard-coding sensitive information such as credentials (virtual machines user passwords), certificates or keys.", + "subcategory": "Capacity Planning", + "text": "One or more resource groups is required for onboarding servers into Azure", "waf": "Operations" }, { - "category": "Platform Automation and DevOps", - "checklist": "Azure Landing Zone Review", - "guid": "a52e0c98-76b9-4a09-a1c9-6b2babf22ac4", - "id": "H01.07", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/subscription-vending", + "category": "Foundation", + "checklist": "Azure Arc Review", + "guid": "aa359271-8e6e-4205-8725-769e46691e88", + "link": "https://learn.microsoft.com/azure/azure-arc/servers/prerequisites#azure-subscription-and-service-limits", "services": [ - "Storage" + "Entra", + "Arc" ], - "severity": "Low", - "subcategory": "DevOps Team Topologies", - "text": "Implement automation for File > New > Landing Zone for applications and workloads.", - "waf": "Operations" + "severity": "Medium", + "subcategory": "Capacity Planning", + "text": "Take Azure Active Directory object limitations into account", + "waf": "Performance" }, { - "ammp": true, - "category": "Platform Automation and DevOps", - "checklist": "Azure Landing Zone Review", - "guid": "cfe363b5-f579-4284-bc56-a42153e4c10b", - "id": "H02.01", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/infrastructure-as-code", - "services": [], + "category": "Foundation", + "checklist": "Azure Arc Review", + "description": "The following resource providers needs to be registered: Microsoft.HybridCompute, Microsoft.GuestConfiguration, Microsoft.HybridConnectivity", + "guid": "deace4bb-1deb-44c6-9fc3-fc14eeaa3692", + "link": "https://learn.microsoft.com/azure/azure-arc/servers/prerequisites#azure-resource-providers", + "services": [ + "Subscriptions", + "Arc" + ], "severity": "High", - "subcategory": "Development Lifecycle", - "text": "Ensure a version control system is used for source code of applications and IaC developed. Microsoft recommends Git.", + "subcategory": "General", + "text": "Has the Resource providers required been registered in all subscriptions", "waf": "Operations" }, { - "category": "Platform Automation and DevOps", - "checklist": "Azure Landing Zone Review", - "guid": "c7245dd4-af8a-403a-8bb7-890c1a7cfa9d", - "id": "H02.02", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/development-strategy-development-lifecycle", - "services": [], + "category": "Foundation", + "checklist": "Azure Arc Review", + "description": "Aligning with an existing or creating an Azure tagging strategy is recommended. Resource tags allow you to quickly locate it, automate operational tasks amd more. ", + "guid": "c6d37331-65c7-4acb-b44b-be609d79f2e8", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/decision-guides/resource-tagging/", + "services": [ + "Arc" + ], "severity": "Low", - "subcategory": "Development Lifecycle", - "text": "Follow a branching strategy to allow teams to collaborate better and efficiently manage version control of IaC and application Code. Review options such as Github Flow.", - "waf": "Operations" - }, - { - "category": "Platform Automation and DevOps", - "checklist": "Azure Landing Zone Review", - "guid": "12aeea20-9165-4b3e-bdf2-6795fcd3cdbe", - "id": "H02.03", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/development-strategy-development-lifecycle", - "services": [], - "severity": "Medium", - "subcategory": "Development Lifecycle", - "text": "Adopt a pull request strategy to help keep control of code changes merged into branches.", - "waf": "Operations" + "subcategory": "General", + "text": "Has a tagging strategy for Azure Arc-enabled servers been defined", + "waf": "Cost" }, { - "ammp": true, - "category": "Platform Automation and DevOps", - "checklist": "Azure Landing Zone Review", - "guid": "2cdc9d99-dbcc-4ad4-97f5-e7d358bdfa73", - "id": "H03.01", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/infrastructure-as-code", - "services": [], + "category": "Foundation", + "checklist": "Azure Arc Review", + "description": "Installation of the connected machine agent is supported on most newer Windows and Linux operative systems, review the link to se the latest list", + "guid": "7778424c-5167-475c-9fa9-5b96ad88408e", + "link": "https://learn.microsoft.com/azure/azure-arc/servers/prerequisites#supported-operating-systems", + "services": [ + "Arc" + ], "severity": "High", - "subcategory": "Development Strategy", - "text": "Leverage Declarative Infrastructure as Code Tools such as Azure Bicep, ARM Templates or Terraform to build and maintain your Azure Landing Zone architecture. Both from a Platform and Application workload perspective.", + "subcategory": "General", + "text": "What operating systems need to be Azure Arc-enabled", "waf": "Operations" }, { - "ammp": true, - "category": "Platform Automation and DevOps", - "checklist": "Azure Landing Zone Review", - "guid": "cc87a3bc-c572-4ad2-92ed-8cabab66160f", - "id": "H04.01", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/landing-zone-security#secure", - "services": [], + "category": "Foundation", + "checklist": "Azure Arc Review", + "description": "There are software requirements to the agent installation. Some might require a system reboot after installation, review to link", + "guid": "372734b8-76ba-428f-8145-901365d38e53", + "link": "https://learn.microsoft.com/azure/azure-arc/servers/prerequisites#software-requirements", + "services": [ + "Arc" + ], "severity": "High", - "subcategory": "Security", - "text": "Integrate security into the already combined process of development and operations in DevOps to mitigate risks in the innovation process.", + "subcategory": "General", + "text": "Are required software installed on Windows and Linux servers to support the installation", "waf": "Operations" }, { - "category": "Management", - "checklist": "Azure API Management Review", - "guid": "06862505-2d9a-4874-9491-2837b00a3475", - "link": "https://learn.microsoft.com/azure/api-management/backends", + "category": "Foundation", + "checklist": "Azure Arc Review", + "guid": "d44c7c89-19ca-41f6-b521-5ae514ba34d4", + "link": "https://azure.microsoft.com/explore/global-infrastructure/products-by-region/?products=azure-arc®ions=all", "services": [ - "APIM" + "Arc" ], - "severity": "Medium", - "subcategory": "Best practices", - "text": "Use Backends feature to eliminate redundant API backend configurations" + "severity": "High", + "subcategory": "General", + "text": "Make sure to use a supported Azure region", + "waf": "Reliability" }, { - "category": "Management", - "checklist": "Azure API Management Review", - "guid": "03b125d5-b69b-4739-b7fd-84b86da4933e", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-properties?tabs=azure-portal", + "category": "Foundation", + "checklist": "Azure Arc Review", + "description": "The scope include organization into management groups, subscriptions, and resource groups.", + "guid": "f9ccbd86-8266-4abc-a264-f9a19bf39d95", + "link": "https://learn.microsoft.com/azure/azure-arc/servers/organize-inventory-servers#organize-resources-with-built-in-azure-hierarchies", "services": [ - "AzurePolicy", - "APIM" + "Subscriptions", + "Arc" ], - "severity": "Medium", - "subcategory": "Best practices", - "text": "Use Named Values to store common values that can be used in policies" + "severity": "Low", + "subcategory": "Organization", + "text": "Define the structure for Azure management of resources", + "waf": "Performance" }, { - "category": "Management", - "checklist": "Azure API Management Review", - "guid": "beae759e-4ddb-4326-bf26-47f87d3454b6", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-deploy-multi-region", + "category": "Identity", + "checklist": "Azure Arc Review", + "description": "Define RBAC rules to the servers / resource groups as required for servers management, the 'Azure Connected Machine Resource Administrator' or 'Hybrid Server Resource Administrator' role would be sufficient for management of the Azure Arc-enabled servers resources in Azure", + "guid": "9bf39d95-d44c-47c8-a19c-a1f6d5215ae5", + "link": "https://learn.microsoft.com/azure/azure-arc/servers/security-overview#identity-and-access-control", "services": [ - "ASR", - "APIM" + "RBAC", + "Entra", + "Arc" ], "severity": "Medium", - "subcategory": "Business continuity and disaster recovery", - "text": "Deploy to multiple Azure regions" + "subcategory": "Access", + "text": "Assign RBAC rights to Azure AD user/group access for managing Azure Arc-enabled servers", + "waf": "Security" }, { - "category": "Management", - "checklist": "Azure API Management Review", - "guid": "9c8d1664-dd9a-49d4-bd83-950af0af4044", - "link": "https://learn.microsoft.com/azure/api-management/high-availability", + "category": "Identity", + "checklist": "Azure Arc Review", + "guid": "14ba34d4-585e-4111-89bd-7ba012f7b94e", + "link": "https://learn.microsoft.com/azure/active-directory/managed-identities-azure-resources/tutorial-windows-vm-access-nonaad", "services": [ - "ASR", - "APIM" + "Entra", + "AKV", + "Arc" ], - "severity": "Medium", - "subcategory": "Business continuity and disaster recovery", - "text": "Deploy at least two scale units spread over two availability zones per region for best availability and performance" + "severity": "Low", + "subcategory": "Access", + "text": "Consider using managed identities for applications to access Azure resources like Key Vault example in link", + "waf": "Security" }, { - "category": "Management", - "checklist": "Azure API Management Review", - "guid": "8d2db6e8-85c6-4118-a52c-ae76a4f27934", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#service-native-backup-capability", + "category": "Identity", + "checklist": "Azure Arc Review", + "description": "An Azure subscription must be parented to the same Azure AD tenant", + "guid": "35ac9322-23e1-4380-8523-081a94174158", + "link": "https://learn.microsoft.com/azure/azure-arc/servers/prerequisites#azure-subscription-and-service-limits", "services": [ - "Backup", - "ASR", - "APIM" + "Entra", + "Subscriptions", + "Arc" ], "severity": "High", - "subcategory": "Business continuity and disaster recovery", - "text": "Ensure there is an automated backup routine" + "subcategory": "Requirements", + "text": "An Azure Active Directory tenant must be available with at least one subscription", + "waf": "Operations" }, { - "category": "Management", - "checklist": "Azure API Management Review", - "guid": "f96ddac5-77ec-4fa9-8833-4327f052059e", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-cache-external", + "category": "Identity", + "checklist": "Azure Arc Review", + "description": "Users (or SPs) need the 'Azure Connected Machine Onboarding' or 'Contributor' role to onboarding of servers", + "guid": "33ee7ad6-c6d3-4733-865c-7acbe44bbe60", + "link": "https://learn.microsoft.com/azure/azure-arc/servers/prerequisites#required-permissions", "services": [ - "AzurePolicy", - "APIM" + "RBAC", + "Entra", + "Arc" ], "severity": "Medium", - "subcategory": "Performance and scalability", - "text": "Consider using a external cache policy for APIs that can benefit from caching", - "training": "https://learn.microsoft.com/training/modules/improve-api-performance-with-apim-caching-policy/" + "subcategory": "Requirements", + "text": "Define which users (AAD user/groups) has access to onboard Azure Arc-enabled servers", + "waf": "Security" }, { - "category": "Management", - "checklist": "Azure API Management Review", - "guid": "8210699f-8d43-45c2-8f19-57e54134bd8f", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-log-event-hubs", + "category": "Identity", + "checklist": "Azure Arc Review", + "description": "Ensure to only add the rights to users or groups that is required to perform their role", + "guid": "9d79f2e8-7778-4424-a516-775c6fa95b96", + "link": "https://learn.microsoft.com/azure/azure-arc/servers/onboard-service-principal#create-a-service-principal-for-onboarding-at-scale", "services": [ - "AzurePolicy", - "APIM", - "EventHubs" + "RBAC", + "Entra", + "Arc" ], - "severity": "Low", - "subcategory": "Performance and scalability", - "text": "If you need to log at high performance levels, consider Event Hubs policy" + "severity": "Medium", + "subcategory": "Security", + "text": "Use the principle of least privileged", + "waf": "Security" }, { - "category": "Management", - "checklist": "Azure API Management Review", - "guid": "121bfc39-fa7b-4096-b93b-ab56c1bc0bed", - "link": "https://learn.microsoft.com/azure/api-management/api-management-sample-flexible-throttling", + "category": "Identity", + "checklist": "Azure Arc Review", + "description": "A service principle with the 'Azure Connected Machine Onboarding' role is required for at-scale onboarding of servers, consider more SP's if onboarding is done by different teams/decentralized management", + "guid": "ad88408e-3727-434b-a76b-a28f21459013", + "link": "https://learn.microsoft.com/azure/azure-arc/servers/onboard-service-principal#create-a-service-principal-for-onboarding-at-scale", "services": [ - "AzurePolicy", - "APIM" + "RBAC", + "Entra", + "Arc" ], "severity": "Medium", - "subcategory": "Performance and scalability", - "text": "Apply throttling policies to control the number of requests per second", - "training": "https://learn.microsoft.com/training/modules/protect-apis-on-api-management/" + "subcategory": "Security", + "text": "How many Service Principals are needed for onboarding Arc-enabled servers into Azure", + "waf": "Security" }, { - "category": "Management", - "checklist": "Azure API Management Review", - "guid": "bb5f356b-3daf-47a2-a9ee-867a8100bbd5", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-autoscale", + "category": "Identity", + "checklist": "Azure Arc Review", + "description": "Consider assigning the rights for the 'Azure Connected Machine Onboarding' role at the resource group level, to control the resource creation", + "guid": "65d38e53-f9cc-4bd8-9826-6abca264f9a1", + "link": "https://learn.microsoft.com/azure/azure-arc/servers/prerequisites#required-permissions", "services": [ - "APIM" + "RBAC", + "Entra", + "Arc" ], "severity": "Medium", - "subcategory": "Performance and scalability", - "text": "Configure autoscaling to scale out the number of instances when the load increases" + "subcategory": "Security", + "text": "Limit the rights to onboard Azure Arc-enabled servers to the desired resource groups", + "waf": "Security" }, { - "category": "Management", - "checklist": "Azure API Management Review", - "guid": "84b94abb-59b6-4b9d-8587-3413669468e8", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-provision-self-hosted-gateway", + "category": "Management and Monitoring", + "checklist": "Azure Arc Review", + "description": "Plan for agent deployments at scale", + "guid": "6ee79d6b-5c2a-4364-a4b6-9bad38aad53c", + "link": "https://learn.microsoft.com/azure/azure-arc/servers/plan-at-scale-deployment", + "services": [ + "Monitor", + "Arc" + ], + "severity": "Medium", + "subcategory": "Management", + "text": "Define a strategy for agent provisioning", + "waf": "Operations" + }, + { + "category": "Management and Monitoring", + "checklist": "Azure Arc Review", + "description": "Use Microsoft Update to ensure that the connected machine agent is always up-to-date", + "guid": "c78e1d76-6673-457c-9496-74c5ed85b859", + "link": "https://learn.microsoft.com/azure/azure-arc/servers/manage-agent#upgrade-the-agent", + "services": [ + "Monitor", + "Arc" + ], + "severity": "High", + "subcategory": "Management", + "text": "Define a strategy for agent updates", + "waf": "Operations" + }, + { + "category": "Management and Monitoring", + "checklist": "Azure Arc Review", + "description": "Recommendation is to use Azure Policy, or another automation tool like Azure DevOps - important is to avoid configuration drift.", + "guid": "c7733be2-a1a2-47b7-95a9-1be1f388ff39", + "link": "https://learn.microsoft.com/azure/azure-arc/servers/manage-vm-extensions", + "services": [ + "Monitor", + "AzurePolicy", + "Arc" + ], + "severity": "Medium", + "subcategory": "Management", + "text": "Define a strategy for extension installation", + "waf": "Operations" + }, + { + "category": "Management and Monitoring", + "checklist": "Azure Arc Review", + "description": "Use automatic upgrades where available and define an update strategy for all extensions not supporting automatic upgrades.", + "guid": "4c2bd463-cbbb-4c86-a195-abb91a4ed90d", + "link": "https://learn.microsoft.com/azure/azure-arc/servers/manage-automatic-vm-extension-upgrade?tabs=azure-portal", "services": [ - "APIM" + "Monitor", + "Arc" ], - "severity": "Medium", - "subcategory": "Performance and scalability", - "text": "Deploy self-hosted gateways where Azure doesn't have a region close to the backend APIs." + "severity": "High", + "subcategory": "Management", + "text": "Define a strategy for extension updates", + "waf": "Operations" }, { - "category": "Governance", - "checklist": "Azure API Management Review", - "guid": "d7941d4a-7b6f-458f-8714-2f8f8c059ad4", - "link": "https://learn.microsoft.com/azure/api-management/api-management-error-handling-policies", + "category": "Management and Monitoring", + "checklist": "Azure Arc Review", + "description": "Azure Automanage help implement Microsoft best-practices for servers management in Azure", + "guid": "7a927c39-74d1-4102-aac6-aae01e6a84de", + "link": "https://learn.microsoft.com/azure/automanage/automanage-arc", "services": [ - "AzurePolicy", - "APIM" + "Monitor", + "Arc" ], "severity": "Medium", - "subcategory": "Development best practices", - "text": "Implement an error handling policy at the global level" + "subcategory": "Management", + "text": "Consider using Azure Automanage to control settings and avoid configuration drift on servers", + "waf": "Operations" }, { - "category": "Governance", - "checklist": "Azure API Management Review", - "guid": "0b0c0765-ff37-4369-90bd-3eb23ce71b08", - "link": "https://learn.microsoft.com/azure/api-management/set-edit-policies?tabs=form#use-base-element-to-set-policy-evaluation-order", + "category": "Management and Monitoring", + "checklist": "Azure Arc Review", + "guid": "37b6b780-cbaf-4e6c-9658-9d457a927c39", + "link": "https://learn.microsoft.com/azure/azure-arc/servers/plan-at-scale-deployment#phase-3-manage-and-operate", "services": [ - "AzurePolicy", - "APIM" + "Monitor", + "Arc" ], - "severity": "Medium", - "subcategory": "Development best practices", - "text": "Ensure all APIs policies include a element." + "severity": "High", + "subcategory": "Monitoring", + "text": "Monitor for unresponsive agents", + "waf": "Operations" }, { - "category": "Governance", - "checklist": "Azure API Management Review", - "guid": "a5c45b03-93b6-42fe-b16b-8fccb6a79902", - "link": "https://learn.microsoft.com/azure/api-management/policy-fragments", + "category": "Management and Monitoring", + "checklist": "Azure Arc Review", + "guid": "74d1102c-ac6a-4ae0-8e6a-84de5df47d2d", + "link": "https://learn.microsoft.com/azure/azure-monitor/agents/log-analytics-agent#data-collected", "services": [ - "ACR", - "AzurePolicy", - "APIM" + "Monitor", + "Arc" ], "severity": "Medium", - "subcategory": "Development best practices", - "text": "Use Policy Fragments to avoid repeating same policies definitions across multiple APIs" + "subcategory": "Monitoring", + "text": "Design a monitoring strategy to send metrics and logs to an Log Analytics workspace", + "waf": "Operations" }, { - "category": "Governance", - "checklist": "Azure API Management Review", - "guid": "c3818a95-6ff3-4474-88dc-e809b46dad6a", - "link": "https://learn.microsoft.com/azure/api-management/monetization-support", + "category": "Management and Monitoring", + "checklist": "Azure Arc Review", + "guid": "92881b1c-d5d1-4e54-a296-59e3958fd782", + "link": "https://learn.microsoft.com/azure/service-health/resource-health-alert-monitor-guide", "services": [ - "APIM" + "Monitor", + "Arc" ], "severity": "Medium", - "subcategory": "Monetization", - "text": "If you are planning to monetize your APIs, review the 'monetization support' article for best practices" + "subcategory": "Monitoring", + "text": "Use notification in Activity logs to receive notification on unexpected changes to the resources", + "waf": "Operations" }, { - "category": "Governance", - "checklist": "Azure API Management Review", - "guid": "a7d0840a-c8c4-4e83-adec-5ca578eb4049", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-use-azure-monitor#resource-logs", + "category": "Management and Monitoring", + "checklist": "Azure Arc Review", + "guid": "89c93555-6d02-4bfe-9564-b0d834a34872", + "link": "https://learn.microsoft.com/azure/azure-arc/servers/learn/tutorial-enable-vm-insights", "services": [ - "APIM", - "Monitor" + "Monitor", + "Arc" ], - "severity": "High", + "severity": "Medium", "subcategory": "Monitoring", - "text": "Enable Diagnostics Settings to export logs to Azure Monitor" + "text": "Use Azure Monitor for compliance and operational monitoring", + "waf": "Operations" }, { - "category": "Governance", - "checklist": "Azure API Management Review", - "guid": "8691fa38-45ed-4299-a247-fecd98d35deb", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-app-insights", + "category": "Management and Monitoring", + "checklist": "Azure Arc Review", + "guid": "5df47d2d-9288-41b1-ad5d-1e54a29659e3", + "link": "https://learn.microsoft.com/azure/azure-arc/servers/plan-at-scale-deployment#phase-3-manage-and-operate", "services": [ - "APIM", - "Monitor" + "Monitor", + "Arc" ], "severity": "Medium", "subcategory": "Monitoring", - "text": "Enable Application Insights for more detailed telemetry" + "text": "Create an alert to identify Azure Arc-enabled servers that aren't using the latest version of the Azure connected machine agent", + "waf": "Operations" }, { - "category": "Governance", - "checklist": "Azure API Management Review", - "guid": "55fd27bb-76ac-4a91-bc37-049e885be6b7", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-use-azure-monitor", + "category": "Management and Monitoring", + "checklist": "Azure Arc Review", + "description": "Use Update Management in Azure Automation or the new Update Management Center (preview) functionality to ensure update management of servers", + "guid": "ae2cc84c-37b6-4b78-8cba-fe6c46589d45", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/manage/hybrid/server/best-practices/arc-update-management", "services": [ - "APIM", - "Monitor" + "Monitor", + "Arc" ], - "severity": "High", - "subcategory": "Monitoring", - "text": "Configure alerts on the most critical metrics" + "severity": "Low", + "subcategory": "Security", + "text": "Use Azure Arc-enabled servers to control software updates deployments to servers", + "waf": "Operations" }, { - "category": "Identity and Access Management", - "checklist": "Azure API Management Review", - "guid": "39460bdb-156f-4dc2-a87f-1e8c11ab0998", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#certificate-management-in-azure-key-vault", + "category": "Networking", + "checklist": "Azure Arc Review", + "description": "The Connected Machine Agent will by default communicate with Azure services over public Internet connectivity using HTTPS (TCP port 443)", + "guid": "f6e043d2-aa35-4927-88e6-e2050725769e", + "link": "https://learn.microsoft.com/azure/azure-arc/servers/network-requirements?tabs=azure-cloud#details", "services": [ - "APIM", - "AKV", - "Entra" + "Arc" ], "severity": "High", - "subcategory": "Data protection", - "text": "Ensure that custom SSL certificates are stored an Azure Key Vault so they can be securely accessed and updated" + "subcategory": "Networking", + "text": "Define a connectivity method from the server to Azure", + "waf": "Operations" }, { - "category": "Identity and Access Management", - "checklist": "Azure API Management Review", - "guid": "e9217997-5f6c-479d-8576-8f2adf706ec8", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#azure-ad-authentication-required-for-data-plane-access", + "category": "Networking", + "checklist": "Azure Arc Review", + "description": "The Connected Machine Agent can be configured to use a proxy server, it is recommended to define the proxy server address using 'azcmagent config set proxy.url' command on the local system.", + "guid": "46691e88-35ac-4932-823e-13800523081a", + "link": "https://learn.microsoft.com/azure/azure-arc/servers/manage-agent#update-or-remove-proxy-settings", "services": [ - "APIM", - "Entra" + "Arc" ], - "severity": "High", - "subcategory": "Identity", - "text": "Protect incoming requests to APIs (data plane) with Azure AD" + "severity": "Medium", + "subcategory": "Networking", + "text": "Is a proxy server a required for communication over the Public Internet", + "waf": "Operations" }, { - "category": "Identity and Access Management", - "checklist": "Azure API Management Review", - "guid": "5e5f64ba-c90e-480e-8888-398d96cf0bfb", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-aad", + "category": "Networking", + "checklist": "Azure Arc Review", + "description": "The Connected Machine Agent can use a Private Link for communication with Azure Services over an existing ExpressRoute or VPN connection", + "guid": "94174158-33ee-47ad-9c6d-3733165c7acb", + "link": "https://learn.microsoft.com/azure/azure-arc/servers/private-link-security", "services": [ - "APIM", - "Entra" + "ExpressRoute", + "PrivateLink", + "VPN", + "Arc" ], "severity": "Medium", - "subcategory": "Identity", - "text": "Use Azure AD to authenticate users in the Developer Portal" + "subcategory": "Networking", + "text": "Is a private (not public Internet) connection required?", + "waf": "Operations" }, { - "category": "Identity and Access Management", - "checklist": "Azure API Management Review", - "guid": "f8e574ce-280f-49c8-b2ef-68279b081cf3", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-create-groups", + "category": "Networking", + "checklist": "Azure Arc Review", + "description": "Firewall configuration might be required for the agent to communicate with Azure, use the link to see ServiceTags and/or URL's required", + "guid": "e44bbe60-9d79-4f2e-a777-8424c516775c", + "link": "https://learn.microsoft.com/azure/azure-arc/servers/network-requirements?tabs=azure-cloud#service-tags", "services": [ - "APIM", - "Entra" + "Arc" ], - "severity": "Medium", - "subcategory": "Privileged access", - "text": "Create appropriate groups to control the visibility of the products" + "severity": "High", + "subcategory": "Networking", + "text": "Will Firewall configurations be needed in order to ensure communication with Azure Services?", + "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure API Management Review", - "guid": "cd45c90e-7690-4753-930b-bf290c69c074", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#virtual-network-integration", + "category": "Networking", + "checklist": "Azure Arc Review", + "description": "Use available automation tool for the system in question to regularly update the Azure endpoints", + "guid": "6fa95b96-ad88-4408-b372-734b876ba28f", + "link": "https://www.microsoft.com/download/details.aspx?id=56519", "services": [ - "VNet", - "APIM" + "Arc" ], - "severity": "Medium", - "subcategory": "Security", - "text": "Deploy the service within a Virtual Network (VNET)" + "severity": "Low", + "subcategory": "Networking", + "text": "Can the Firewall or Proxy rules be automated updated if Service Tags or IP addresses change", + "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure API Management Review", - "guid": "02661582-b3d1-48d1-9d7b-c6a918a0ca33", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#network-security-group-support", + "category": "Networking", + "checklist": "Azure Arc Review", + "description": "Configure Servers to use Transport Layer Security (TLS) version 1.2", + "guid": "21459013-65d3-48e5-9f9c-cbd868266abc", + "link": "https://learn.microsoft.com/azure/azure-arc/servers/network-requirements?tabs=azure-cloud#transport-layer-security-12-protocol", "services": [ - "VNet", - "APIM", - "Monitor" + "Arc" ], - "severity": "Medium", - "subcategory": "Security", - "text": "Deploy network security groups (NSG) to your subnets to restrict or monitor traffic" + "severity": "High", + "subcategory": "Networking", + "text": "Always use secure communication for Azure where possible", + "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure API Management Review", - "guid": "67437a28-2721-4a2c-becd-caa54c8237a5", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#azure-private-link", + "category": "Networking", + "checklist": "Azure Arc Review", + "description": "All extensions (like log analytics etc.) have separate network requirements, be sure to include all in the network design.", + "guid": "a264f9a1-9bf3-49d9-9d44-c7c8919ca1f6", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/hybrid/arc-enabled-servers/eslz-arc-servers-connectivity#define-extensions-connectivity-method", "services": [ + "Monitor", "PrivateLink", - "VNet", - "APIM" + "Arc" ], - "severity": "Medium", - "subcategory": "Security", - "text": "Deploy Private Endpoints to filter incoming traffic when VNET is not used" + "severity": "Low", + "subcategory": "Networking", + "text": "Include communication for Azure Arc-enabled Servers extensions in the design (firewall/proxy/private link)", + "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure API Management Review", - "guid": "d698adbd-3288-44cb-b10a-9b572da395ae", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#disable-public-network-access", + "category": "Security, Governance and Compliance", + "checklist": "Azure Arc Review", + "guid": "ac6aae01-e6a8-44de-9df4-7d2d92881b1c", + "link": "https://learn.microsoft.com/azure/governance/policy/", "services": [ - "APIM" + "AzurePolicy", + "Arc" ], - "severity": "High", - "subcategory": "Security", - "text": "Disable Public Network Access" + "severity": "Medium", + "subcategory": "Management", + "text": "Use Azure Policy to implement a governance model for hybrid connected servers", + "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure API Management Review", - "guid": "7519e385-a88b-4d34-966b-6269d686e890", - "link": "https://learn.microsoft.com/azure/api-management/front-door-api-management", + "category": "Security, Governance and Compliance", + "checklist": "Azure Arc Review", + "guid": "5c2a3649-4b69-4bad-98aa-d53cc78e1d76", + "link": "https://learn.microsoft.com/azure/governance/machine-configuration/overview", "services": [ - "FrontDoor", - "APIM" + "Arc" ], "severity": "Medium", - "subcategory": "Connectivity", - "text": "Use Azure Front Door for multi-region deployment" + "subcategory": "Management", + "text": "Consider using Machine configurations for in guest OS configurations", + "waf": "Operations" }, { - "category": "Platform automation and DevOps", - "checklist": "Azure API Management Review", - "guid": "0674d750-0c6f-4ac0-8717-ceec04d0bdbd", - "link": "https://learn.microsoft.com/azure/api-management/automation-manage-api-management", + "category": "Security, Governance and Compliance", + "checklist": "Azure Arc Review", + "guid": "667357c4-4967-44c5-bd85-b859c7733be2", + "link": "https://learn.microsoft.com/azure/governance/machine-configuration/machine-configuration-create", "services": [ - "APIM" + "AzurePolicy", + "Arc" ], "severity": "Medium", - "subcategory": "Automation", - "text": "Simplify management with PowerShell automation scripts" + "subcategory": "Management", + "text": "Evaluate the need for custom Guest Configuration policies", + "waf": "Operations" }, { - "category": "Platform automation and DevOps", - "checklist": "Azure API Management Review", - "guid": "c385bfcd-49fd-4786-81ba-cedbb4c57345", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/app-platform/api-management/platform-automation-and-devops#design-recommendations", + "category": "Security, Governance and Compliance", + "checklist": "Azure Arc Review", + "guid": "49674c5e-d85b-4859-a773-3be2a1a27b77", + "link": "https://learn.microsoft.com/azure/automation/change-tracking/overview", "services": [ - "APIM", - "Entra" + "Monitor", + "Arc" ], "severity": "Medium", - "subcategory": "Best practices", - "text": "Review DevOps best practices from the Cloud Adaption Framework APIM Landing Zone Accelerator" + "subcategory": "Monitoring", + "text": "Consider using change tracking for tracking changes made on the servers", + "waf": "Operations" }, { - "category": "Platform automation and DevOps", - "checklist": "Azure API Management Review", - "guid": "6c3a27c0-197f-426c-9ffa-86fed51d9ab6", - "link": "https://learn.microsoft.com/azure/api-management/visual-studio-code-tutorial", + "category": "Security, Governance and Compliance", + "checklist": "Azure Arc Review", + "guid": "d5d1e54a-2965-49e3-a58f-d78289c93555", + "link": "https://learn.microsoft.com/azure/azure-arc/servers/data-residency", "services": [ - "APIM", - "Entra" + "Arc" ], "severity": "Medium", - "subcategory": "Best practices", - "text": "Promote usage of Visual Studio Code APIM extension for faster API development" + "subcategory": "Requirements", + "text": "Make sure to use an Azure region for storing the metadata approved by the organization", + "waf": "Security" }, { - "category": "Platform automation and DevOps", - "checklist": "Azure API Management Review", - "guid": "354f1c03-8112-4965-85ad-c0074bddf231", - "link": "https://learn.microsoft.com/azure/api-management/devops-api-development-templates", + "category": "Security, Governance and Compliance", + "checklist": "Azure Arc Review", + "guid": "195abb91-a4ed-490d-ae2c-c84c37b6b780", + "link": "https://learn.microsoft.com/azure/key-vault/general/basic-concepts", "services": [ - "APIM" + "AKV", + "Arc" ], "severity": "Medium", - "subcategory": "DevOps", - "text": "Implement DevOps and CI/CD in your workflow" + "subcategory": "Secrets", + "text": "Use Azure Key Vault for certificate management on servers", + "waf": "Security" }, { - "category": "Security", - "checklist": "Azure API Management Review", - "guid": "b6439493-426a-45f3-9697-cf65baee208d", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-mutual-certificates-for-clients", + "category": "Security, Governance and Compliance", + "checklist": "Azure Arc Review", + "description": "Consider using a short-lived Azure AD service principal client secrets.", + "guid": "6d02bfe4-564b-40d8-94a3-48726ee79d6b", + "link": "https://learn.microsoft.com/azure/active-directory/develop/howto-create-service-principal-portal#option-2-create-a-new-application-secret", "services": [ - "APIM" + "Entra", + "Storage", + "AKV", + "Arc" ], - "severity": "Medium", - "subcategory": "APIs", - "text": "Secure APIs using client certificate authentication" + "severity": "High", + "subcategory": "Secrets", + "text": "What is the acceptable life time of the secret used by SP's", + "waf": "Security" }, { - "category": "Security", - "checklist": "Azure API Management Review", - "guid": "2a67d143-1033-4c0a-8732-680896478f08", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-mutual-certificates", + "category": "Security, Governance and Compliance", + "checklist": "Azure Arc Review", + "description": "A private key is saved to the disk, ensure this is protected using disk encryption", + "guid": "a1a27b77-5a91-4be1-b388-ff394c2bd463", + "link": "https://learn.microsoft.com/azure/azure-arc/servers/security-overview#using-disk-encryption", "services": [ - "APIM" + "AKV", + "Arc" ], "severity": "Medium", - "subcategory": "APIs", - "text": "Secure backend services using client certificate authentication" + "subcategory": "Secrets", + "text": "Secure the public key for Azure Arc-enabled Servers", + "waf": "Security" }, { - "category": "Security", - "checklist": "Azure API Management Review", - "guid": "074435f5-4a46-41ac-b521-d6114cb5d845", - "link": "https://learn.microsoft.com/azure/api-management/mitigate-owasp-api-threats", + "category": "Security, Governance and Compliance", + "checklist": "Azure Arc Review", + "description": "Local administrator is required to install the Connected Machine Agent on Windows and Linux systems", + "guid": "29659e39-58fd-4782-a9c9-35556d02bfe4", + "link": "https://learn.microsoft.com/azure/azure-arc/servers/onboard-portal#install-manually", "services": [ - "APIM" + "Arc" ], - "severity": "Medium", - "subcategory": "APIs", - "text": "Review 'Recommendations to mitigate OWASP API Security Top 10 threats' article and check what is applicable to your APIs" + "severity": "High", + "subcategory": "Security", + "text": "Ensure there is local administrator access for executing the agent installation", + "waf": "Security" }, { - "category": "Security", - "checklist": "Azure API Management Review", - "guid": "5507c4b8-a7f8-41d6-9661-418c987100c9", - "link": "https://learn.microsoft.com/azure/api-management/authorizations-overview", + "category": "Security, Governance and Compliance", + "checklist": "Azure Arc Review", + "description": "Members of the local administrator group on Windows and users with root privileges on Linux, have permissions to manage the agent via command line.", + "guid": "564b0d83-4a34-4872-9ee7-9d6b5c2a3649", + "link": "https://learn.microsoft.com/azure/azure-arc/servers/security-overview#agent-security-and-permissions", "services": [ - "APIM" + "Arc" ], "severity": "Medium", - "subcategory": "APIs", - "text": "Use Authorizations feature to simplify management of OAuth 2.0 token for your backend APIs" + "subcategory": "Security", + "text": "Limit the amount of users with local administrator rights to the servers", + "waf": "Security" }, { - "category": "Security", - "checklist": "Azure API Management Review", - "guid": "2deee033-b906-4bc2-9f26-c8d3699fe091", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-manage-protocols-ciphers", + "category": "Security, Governance and Compliance", + "checklist": "Azure Arc Review", + "guid": "4b69bad3-8aad-453c-a78e-1d76667357c4", + "link": "https://learn.microsoft.com/azure/azure-arc/servers/managed-identity-authentication", "services": [ - "APIM" + "Entra", + "Arc" ], - "severity": "High", - "subcategory": "Ciphers", - "text": "Use the latest TLS version when encrypting information in transit. Disable outdated and unnecessary protocols and ciphers when possible." + "severity": "Medium", + "subcategory": "Security", + "text": "Consider using and restricting access to managed identities for applications.", + "waf": "Security" }, { - "category": "Security", - "checklist": "Azure API Management Review", - "guid": "f8af3d94-1d2b-4070-846f-849197524258", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#im-8-restrict-the-exposure-of-credential-and-secrets", + "category": "Security, Governance and Compliance", + "checklist": "Azure Arc Review", + "description": "Use Defender for Endpoint or another AV and EDR solution to protect endpoints", + "guid": "5a91be1f-388f-4f39-9c2b-d463cbbbc868", + "link": "https://learn.microsoft.com/azure/security-center/security-center-get-started", "services": [ - "APIM", - "AKV" + "Defender", + "Arc" ], - "severity": "High", - "subcategory": "Data protection", - "text": "Ensure that secrets (Named values) are stored an Azure Key Vault so they can be securely accessed and updated" + "severity": "Medium", + "subcategory": "Security", + "text": "Enable Defender for Servers for all servers to secure hybrid workloads from threats", + "waf": "Security" }, { - "category": "Security", - "checklist": "Azure API Management Review", - "guid": "791abd8b-7706-4e31-9569-afefde724be3", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#managed-identities", + "category": "Security, Governance and Compliance", + "checklist": "Azure Arc Review", + "guid": "cbafe6c4-6589-4d45-9a92-7c3974d1102c", "services": [ - "APIM", - "Entra" + "Arc" ], "severity": "Medium", - "subcategory": "Identities", - "text": "Use managed identities to authenticate to other Azure resources whenever possible" + "subcategory": "Security", + "text": "Define controls to detect security misconfigurations and track compliance", + "waf": "Security" }, { - "category": "Security", - "checklist": "Azure API Management Review", - "guid": "220c4ca6-6688-476b-b2b5-425a78e6fb87", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#ns-6-deploy-web-application-firewall", + "category": "Security, Governance and Compliance", + "checklist": "Azure Arc Review", + "guid": "cbbbc868-195a-4bb9-8a4e-d90dae2cc84c", + "link": "https://learn.microsoft.com/azure/azure-arc/servers/security-overview#extension-allowlists-and-blocklists", "services": [ - "APIM", - "AppGW", - "Entra", - "WAF" + "Arc" ], - "severity": "High", - "subcategory": "Network", - "text": "Use web application firewall (WAF) by deploying Application Gateway in front of APIM" + "severity": "Medium", + "subcategory": "Security", + "text": "Use allow- or block-lists to control what extensions can be installed on the Azure Arc-enabled servers", + "waf": "Security" } ], "metadata": { "name": "Master checklist", - "timestamp": "December 14, 2023" + "timestamp": "December 15, 2023" }, "severities": [ { diff --git a/spreadsheet/macrofree/aro_checklist.en.xlsx b/spreadsheet/macrofree/aro_checklist.en.xlsx index cc093850bef26ab5d72c47d63deb7e1a27aeec79..72307deb1093dbe6bdba5ccc0cce7494dad3c344 100644 GIT binary patch literal 24997 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 literal 25221 zcmcGW2{@F|`}ZrAqAbxO%Oqt<_C1WE$ev{13E7vy*hQ99$i9;-lU;V%k}by0*oSOm zAM03#;hmvH_51&NumAPF*Trd$=gc|x`P|?8zR&Z>Jd(ycNq+3uu`|a$*m9|etJj?K z!uCF5ze%v)Ppu3d*;-kH*z~NeSsg9RWdmgizp#_s-~B6@Y*wwK1M~RSLEK53B#spmir0#Dr&CDWylSFKbGOauHQ9i1 z-HklTMm*h%GF)x3yVMIscc!T-c*dD#GfRA;;_M<#IT*Jh&DH{a`YHg$R@-`~szcGI z9{pzTyzTi3g5y|2PaHc&demM6D_cXH!9KwX(zWd5K3IcYV$$HR2(Y+E<7b#yw^Ozw?n7 zeNT*N;AdeMf=8&+R@Ys67Lj%e_FVKV`TCg~4)hIVkDDk=sN47vu6HGb763{jO$MN#L#hddl@guOFEbxYvQnSn&T;0Yd4H#HQC5;| z-Bx{{`T46a7XtAK=eH&+rip`E6*Ub_8Xh)3EH+oIS-Yt->_(%evS$2_Hv?X{PYMdj zIita2Uc=R(W^+&Icm}6t4jIk7WT}Xz$8;}E(Y%3*$nW54E|XM+oIZA};o7ldWLR*H z=4^J)3@r=~TMit$MYUF|Azt!o;{N?>Gf1i8n;s|a2{ej#!nyBFILrh`n7rn=dG$tk z9V5ZHMU%+mc%SqlkC!j9pJUED!R#;qAbVHeiy?IhslFd;8p_LZ=QfdUXwQ=H-qy&( z#A`>?pya~tSC)ee#JhIphES`1{*m&Vye0I9cqhwdcHN zq4-8Zc@5yt(!-9&#Gnyz)Afq@I6>^UGYRJ@h=aXZ0cv=Gf%mK)W`|g)WRV1a<-Sht zHCQ?JcB_Bp=B?I6pH(8C+=s88eunIRmN#yZO6jjDjoN*gzRbuMNMaGi-u|3=bJ?H! z{3~y7{PW#%B56f#Fm(cjXu8K>99vy-^f%8vdq%o<{d$O94!F0P@ z(r!%0wt-oNA3D`ooZ6^jkGIBLg)f?xYd%?~z)YQY?UvmmcXjds^De`4O7itibDMpl zbSzP_DpJBA33LWNt1KD~rQg~jCx3JyfUl!igURJJjFnbQ-0Inwec!CIG-!*!(D1z( zJ)o&Vm9Ud`LhD#c+k=q%zHxHPB-_u|NN&2xy`knLxVB8ssDHwDF$7)&U5?)sFkwb9 z4t`;z6Q*3PZ+P^jkp##smz7vv^`!wJ24Fj@(^)bom^kZT`S|8vV8X}EZhat z&9}e1oVv1UB~s;%&Zc3@-%_b|Ma>0?jHYPcDy(wZnAHt8>ydRf;80X$`u zOd6QS9b#<$=A-z+aoSf}VE^`LT`?1(YvP2Y*^1H^^_5 z2_9uoO|a4!eQ_>@`0b=*i@nAPE_)HVSrWbYReIv^g~7@Dl+@XdDc&1I4dm3x#~T_d zWA6yXvJ1~@9Df>4scIan@h||E0?<2d`1o<(Gb(BC3;Fntb+%gza(x%t$sf>;JH;%$ zfxVsm%mk55b?E^xr-v;+?Vgid@F$6voOgd7mM4W41>`Ey#Djx8TgC*xegi@8>WdUu zIKR|)`@Bv>nTnID+k)N?GqRivuvYj7MmSxCl79FGv&1$~Pyc59yyMU-# zrMMtPJQ+4l9efFRVq@T`CO_xLg%J06u<)aItS;p|Y z$rnrX(@i}-P0npVj0Mc#O^*C^RV@^1_G1Gw{u{F{UZF&=~st-WEZO^+kuU0mwsggTj1-v=3fA{O7%-QsCRL^Q#AmQyZoZU*c z3(CzXgiFHdc?C1Wx#q$Wo6J_UAIY}G2W5j>^$Sz|XTwHE#(}mGXS+HdI0yubw@B8y zJ}Z}PWG>UL$tjEXQgm1lZMBFXlV=JJ08j~Lv)Z`0fn4qeCk8g|0CIAOGUZ_wPL2iTxyZudg^iLah5gcf zNBh!Im8nnKGY&3>IyyTlB~u7wd7?*_2V^4@W~s%}JTwPca_6d!HXRhEDv2$Zniw0~ zC?583Q?UT+xT7u6T5GR$_y8i*^E#TC-3hntkLc_>dyCp^?>s8*Fr#a zS%L(Bs$7O03nr(kV*_?mY1A;hkyA;p9ESD>vw{-W0T|2t9Lr|E#g!GX-cGp=SSNo@ zNPCYmcaJL*zVT>(e-b)7rHDbpYR5{;h1skc&|9zyc}(t5D}1(k3efsa=eF69)xzgk z=c>i?Id#C?I%Mt*yHUpiGh=kiorSeKaoDfDJ5-ykJ(cd3Tro^)bGbx!(f#NE6JSa=Lt-9jjR{b%`||x>OS*Z%npt7Zc!xWvz}u`rQ|%&1unzr> zGerR?AHx@9l@2$Ub(?Okn8|jBjd5q7`(gz_&$kv!`zkt_h4*$h0K_|{7u+(GtF8F_ zCW2HXFqhA3Ww)6*_NmpvXN4(Vwz1EPx%$2%K3l_fGX0ne8dLJ(TcK4?x{is+Kn(a~ zu-K6NGSo?_Po8(J!dpIeHbI{!UaM}-?n#EoDa^O%aHmBqS$pob=HmRsF4E}n+zX5`h+Ri`Q;px^ z)y`AKu}zL$pa5pXo%1v6dG;(u7xYeBsR+?~mFndtzb)!r;2q4~tTCSZ{%Z*hB9Cjh z%Mm+^5j%NP%R68FSo}sIc?sv-MMN+o8#~LMy7wNDFdn~?%q6(AQ^98d2_2#2!@HB| zF;;7be%D^WV1=43S>N_>?;NFxD15rU8?s2`m@lAQ@?~{p4cZ9PD;gc{Gj855&fM3q z+}Bc-=UgVbRVm$1RZSqh$C)?zQ3y!oJ=Nt2t}2HO_!bs4ogOdj#?NVmx5}xmW7b~p zHEK6Hf;JUYIYn3m?DabBbVfX4c9;B2*#bIs{37;-c2rf(-PK#t>fJMy(Tps&xAb&t zo-rUBE{l1zrx<;)t?#gn9dfa`$CIbKQC$AWI0t{)0J4vW?vDGmj-R%SKaz_wmhs48 zn1Va6IuvCP`8D~i${BxN9&_Qd_33&7Q04A&d1;VJTB-+?My~7aD-t(LHq;Wes5(^tCi+#{_cbT5(C!l?Sh;f2v^>~>GXDIh{;u8K zO9^p#yWzU-r=6|l)u!4sjZIs3m2}IXs4jKqkuG(mJ?<>8)xol}sb@#k7N&bX5~Lb2g=~fRk+Ho`)t8`XT4`CzpPmwp%uj zeYn$4@7 z4z5~w7?pWe7k`;Ie72owU7RHvKjzohRdLp2goOO0)bq9qjt9|W{s!8pPh7?eS5wou z3e7d)GovyDn9i+MSMGHVv(0@aX1AwZ1tz(QO&BBlxLq{T;%T5!BHz%Qf&HBrY6tqh ztk>m3T4nBW&)Q}4kqFJU{G{`#CcKsIV?wpEO>La~-M!_o^adUI4CnW={`NhPcd(I9 zeaQv{`zpxTbdb`>s8y?+WMUN{Cx*6)(*Qz@?u~3+35D%$v_d8pm1ADRTR+9UY1MGL zLrLirv%n*2)pb7Z^NMoP#Vu&+)ZkbTL0W=wcz3$s+AW5P6-^VML!XNPtpWl0O-Znv zoJ4EWY-W2?uo?OERkYD&7NlvSG_Bww0 z;5=8ynx9ENmxz!cErg#Izj#%wXhi5C#Uh)c`crGEu7;<^PB5lz$BcKzQ?S~amO4zn z=E}*qaopF9Xg*P^*-x6;%JbGnK5Z?13?Z3CN_V*0Ke0wSlvOx`iOK zDD#Wn5!7?LZSmUeb|KUK5h}`6i`i0r*^@7l13;k%=1-?_nOfe-1@hs{kHv$=JeB7$ zem^f+ZWE;Ol;|xzbx%3^&a9xkhTAh&As?;8z|_@YJ8MfK^C2!!XwJ&HHrc_bh1;X- zeDd*^drgRt8#=i(evN~1jVOJjHr&cGn-@gRkn|$7qek)}rKKJ;48y@$?_6Q@**(5&h}W$ zO46_#vd!u~>+qM_48ff0^S``J5zhUI*U zP(>4qAbIwTsat-B%?)XhPfVQ3ho(OhpRDY#1=bO&na(_&X%!G-z z_vRv=JMZKPTV}bTI%Q_&a-Z#6{fTp(9^Nl@}T*GF< zgAfljL}EMOp<7%yuuUq&iB2`cJ~#J8evBGoFxfB%IA`#oI^S!`*=fQ_8Z@hLIO@Rk z@B)Pb+YRHEX3ub-AhTaYW%Lt|;U$^v4k|{JUF=MgfswW_&kotf4!YljlLdsjpW9Lq zjyNwA-QOB*<3|3R0C~=M>~n+&7ojm*yiXy=fSUG4hHr%>1%oG!vTmh?T4u9DRePN}JAKd&%^`9I#5o3fNzeB;X60HG0{FW<5h0PXElHMf z)AWdrd_Ks0FlxFk?B%+Hg|bep*)0f2OL&tPjJTqjm@l`^t%0OznQC1FB+RU@B8&>U zxIPN)&Figx>|(G=74U=kLA6KFnC)Xi>2lM}vKd2J`rG!8bqq-^s8>#??oMksxf_(U zcN`Pqs@54?c|jQ}t5Z1*DMOpb`zpq@_4jerH_(J_+r2A-n26=I6e&RME5emd?{%qT zb9RDrLK*ihIpc-JdrXhQZop@SGOCU5bo8#~&kE%|wg)c6uZr3{CN4S~5Z7ZrI7nkO znkiYP-4~jl&L^xb>Xtd;A)=26kX@fYa1tLa$e>&$RR8yd67Q}Flgq)v9YkyIX9Wto#;}cVBYBZp->$2#3y_<)vCc@bU2=BzRxP?>p{#Xnxf1ww zPQL$>7*Z(2&BNRZ!h zro)#QZ?TvRUf#x#4w`7$lV_!cy zC~6sjrmXq+R}I&LjXYSZhk-5wcDt|Y(gpJDZ22P~8IJ_Y;Bbq;^2%tH%^fYRWa0Se zgjZrvzt)XsIa9;R=*z^;G(Z}b>GB{zD>F)O-G;uZS}<-9&|^_#Edy&=Ygkc z;%O^B=Pp+ZFkz$o4!pKeKC~3AISg3OmF<2Wfp(>H_PAIdT5GxU$jZOX1EB1@X&d#S z)y;4ZF?I`1B@bN$TJ@rj<$}IB=v-f-&Eqnikrf6FyPFu3Tgn&(ExbW9klPGg#=0oGUQh)4oIo$qu5+Tu9*;b4KJmMWIHF?Cbv_{D9E;N zHcccg1qev;D^H2JQ%M%l(Noe2Cuk*99=hP1WU&CfI(Q}~gKZJ|g{5i1 z3JLWRRX2&p|3CwE;?pL+b=39LQ!I)>T@z3pO{{BX`RZnFS?K$V~;KA^Zi`D*aXyuQV=%S zxNFe8RR+v^pM-53Z6T4`!foH0Mga~IZob*=aYH*Y^-OPAw8T7CqM3HPB3KX7OBbq3 z&`v(telG|pN7Gs$kmXX)VY2Q>V=x^V5U;}sa(TCAHZ|18Jnft+Z=cz08(Bcfd^_{A zx}WrPn)-mlBmeXCybkV3`IUM*%`EoT+UsX%>x_IAHUgr(s>}R?g z#4LLy-Su3d>OI77gj`|xTSIH`Uc}X%$<=6z>8G{iOTZXkJJ8@Gz@xcbt$sM>8qdnG za@rDloq;H=(->qNPq@>ngTX$p0FUW*!#jrF!+qAeA_TE+*hWN@d!$uPb4T@>u%}}1 zs%lpTBv5`MJhLq75%?HL%xjMzrRs^k9jPkdk}e3)JWTNnNhs>EC=*#VmD>`!8)1m) z$m>wo!dJ4M$gb2a4sjqP;@vz%Z>jeLl(?qe>L$i~b&%zp{U)4xjKN3Ww%7;U1xV+pn~Fo@uo|sF;GP^2I0#3j|`{aWY2RWh(%kRJzp+}i4071xI7;M zrt9D2RUzOEOE&VkaqQ~{6p>-V^0nEm_-*6nSl&%gXLHUa!RwEo9BjE5nMQn zh1#wxYT#UCo>|SMYH{nn{ByNxJhAF&3U`e!)kq}{g`wZPk8w5wFGd58+w^&{xF41( zGYZ%^c5kmov3ql1!F$aYlw17_Uppdm6o8yBvr@k|4>}IgNGrRlAab&_N*EF|9Ge^4 zIZX+6Hd-tuE`gv$wLWF_U2AtV@1z`jT-7^MQ7BE!M-QqhlP1>ikbAKfInoX>!%t+6 z=UBLnSzWuP;a9%8w`_v1R#&ol0f|D^3*BtqeS}en$%|;PZV$StgidlwcU-?>AvzbI?$_ov1F`BMNLs;-KrNh$W8uI@Ra%5VY-X| z@_|=mx@d6MSDCv|@k-~kaf~k#<)^Eo5>v(3M=`g1Pku!y-3<&frQ?)Wa;+wgo_Wd%RYy??CjIdK^Z)Hp5 zMO=#O9@w&QTg6!Oi%{(jll7F_@9i|wCplk=oOW??*x9&e4GHyJW7!z?=x`H@pA}qI zHbGYvZXXJ08+*_*H_+$d7~7s7+pXsn!XC_2v%qOp)wU76rfOOmIVIff*`-9;MHHxS`?)=29M-unVsGUcj~l$EUKlv^uRni=al2D? zLS@oLOkbJKgSeM3C~aI_<2+LKl-u)$<{V1)2f1tIfssS_AWIF!?Z%0D=CzqLS^E;S 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 Z$0=$KW}*Le007{i?{Re3qCmH<{s(klGX?+v diff --git a/spreadsheet/macrofree/aro_checklist.es.xlsx b/spreadsheet/macrofree/aro_checklist.es.xlsx index 1428810af92d4cb165b0501bddd951b16fb733f3..ed6799702053abc82e2999f3e380e194d7b04993 100644 GIT binary patch literal 25605 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 VsYtF50013nk0E6(Pp5;cKLI9dGAjT8 literal 25786 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%0AZb6XzSuB1jQNL@c5mwCZG9B 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 H{BiU@&0FRG diff --git a/spreadsheet/macrofree/aro_checklist.pt.xlsx b/spreadsheet/macrofree/aro_checklist.pt.xlsx index da30026a27c1753f02b6d9be633f7d994d4b24c1..8ae1787a2639578698cdb447331334f3f7acb122 100644 GIT binary patch literal 25631 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 JF^)f;{s$|fY?}Z8 literal 25842 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%0Dv1Bwq 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 V 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ⅅ?(X{69s;u-s8nPMUR3his*riR75 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 z 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

    b6WuXyE=CwH3t(j~wHLuGmS?h{*0p9iC zsjGl5AuY4E%jb}16LHS@swXUe99||!&oZm)r;hsGpq<@g?br5*;r+pSYniy$=IEv` zsRv#`Mo5Y?9S}XmihnM8+b5t-jxfL`$q@a2Onq};oZItvlg4PAjcwa#+}LbvtFe>D zwr$(CZ8k<@8}HuU-?#Vu?>yOOvj=l#<}*x;J^S2@s&C!@H0@4;LNG!Z_6@&N`4K3th0)yd_ z5&&ZX7^j+WCIbHer^x|Z64OHaQCN4`)T}`^nnF8`kyDGV#4)2fgM)c$? zY=?1G1(@*IbZx0)_j1Z*Xxka<|3Ef96@P&X4YO>twQh9k#@K<-pxAw1cHO{iM}s%y zglAcS0{<08paZ>cR-2u)zZ&f?m!o#lExYWkMgv4O?Ldn$ zMe1rt6uO@Ph*Rm8^*h%rOElEq?w$=EsFSp#_Xl&%rt2EiVOJew)GPW{n&i7*I{s`u zd>CcfCCw;Rf4p)qWm$AiISjjV7}KqPS?^b{S;+t?Nzzv(bYe7sw!&&uA~d7XU(J51 z8h4bcoxx~eU>DxKws z%A|e-;lim=5;3!SrFt5VF*Z6r@Qh*qO{NSNow}VN3^^gD`-sKR0+BMULiRq+%0AEVFjt8GHWA4w=ODqikpB=^xlV8_&#Cdu{o? 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 pBjqu<)jx_VT8NYU_r{kX>Kl<;*);Ol9E zV0{@#dMEI*4XP=Z-}mE-0$pVLRLH)uzX3{|06r^*jiBV)myJcI`Dxniu7RruMg8hr?#CAX-R?b^-i4);c=6Y#Oi80-~ zbzFodyyexFrKA7C-NL3-AQJN@pE9X|&jWMYR*sh6)du~zAR)|fWaeMRL7V%&#S|H4 zDH3j%ojrTK-#AB<4=TCTpMqr2l5rmI@G@~?*5Vax*FU5{&ZZD74xZ-qav?@$>CN>( z6Z0SM?UZHw-m$x$cVF0-?c^FCoFC7N;XDXOYqfjvka2NhBlqC=jo3uLJ(4wn()?e zXr~_KMrRb}g3j=|ZfbQrDJu?Y!>Qd)UH&tk+SJE!_SoLiLZJf%1obk`XM_ZXjDZ4W zZd|fWk0I%D1HsYT^FFX`4C!<^*&?;w2! zXUY%L`?9J+2lIQwrjzHrz#>L!z_8|I3k{3{on(sevZ_hO;_*24yvB3M$hmrQ@djmo zz2A?WjEFuFI_laitiHovfjk0+Z�MaqU6PXw8>rjcq++ajjSVSL?CVqYVt2o*UW? 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

    i#1H^H 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ɟ(r1H2O`(0`5`s9NZN2hwNVZ1PY7F%?HjJ^1!; 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 diff --git a/workbooks/alz_checklist.en_network_counters.json b/workbooks/alz_checklist.en_network_counters.json index 8328d5eaa..13d5a3af1 100644 --- a/workbooks/alz_checklist.en_network_counters.json +++ b/workbooks/alz_checklist.en_network_counters.json @@ -749,7 +749,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query10Stats:$.Success}+{Query11Stats:$.Success}" + "resultVal": "{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}+{Query22Stats:$.Success}" } } ] @@ -768,7 +768,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query10Stats:$.Total}+{Query11Stats:$.Total}" + "resultVal": "{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}+{Query22Stats:$.Total}" } } ] @@ -863,7 +863,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}" + "resultVal": "{Query18Stats:$.Success}" } } ] @@ -882,7 +882,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}" + "resultVal": "{Query18Stats:$.Total}" } } ] @@ -920,7 +920,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query23Stats:$.Success}" + "resultVal": "{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query16Stats:$.Success}+{Query17Stats:$.Success}" } } ] @@ -939,7 +939,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query23Stats:$.Total}" + "resultVal": "{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query16Stats:$.Total}+{Query17Stats:$.Total}" } } ] @@ -977,7 +977,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}+{Query22Stats:$.Success}" + "resultVal": "{Query23Stats:$.Success}" } } ] @@ -996,7 +996,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}+{Query22Stats:$.Total}" + "resultVal": "{Query23Stats:$.Total}" } } ] @@ -1034,7 +1034,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query16Stats:$.Success}+{Query17Stats:$.Success}" + "resultVal": "{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}" } } ] @@ -1053,7 +1053,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query16Stats:$.Total}+{Query17Stats:$.Total}" + "resultVal": "{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}" } } ] @@ -1091,7 +1091,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query18Stats:$.Success}" + "resultVal": "{Query10Stats:$.Success}+{Query11Stats:$.Success}" } } ] @@ -1110,7 +1110,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query18Stats:$.Total}" + "resultVal": "{Query10Stats:$.Total}+{Query11Stats:$.Total}" } } ] @@ -1148,7 +1148,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query10Stats:$.Total}+{Query11Stats:$.Total}+{Query4Stats:$.Total}+{Query5Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}+{Query9Stats:$.Total}+{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}+{Query23Stats:$.Total}+{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}+{Query22Stats:$.Total}+{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query16Stats:$.Total}+{Query17Stats:$.Total}+{Query18Stats:$.Total}" + "resultVal": "{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}+{Query22Stats:$.Total}+{Query4Stats:$.Total}+{Query5Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}+{Query9Stats:$.Total}+{Query18Stats:$.Total}+{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query16Stats:$.Total}+{Query17Stats:$.Total}+{Query23Stats:$.Total}+{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}+{Query10Stats:$.Total}+{Query11Stats:$.Total}" } } ] @@ -1167,7 +1167,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query10Stats:$.Success}+{Query11Stats:$.Success}+{Query4Stats:$.Success}+{Query5Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}+{Query9Stats:$.Success}+{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}+{Query23Stats:$.Success}+{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}+{Query22Stats:$.Success}+{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query16Stats:$.Success}+{Query17Stats:$.Success}+{Query18Stats:$.Success}" + "resultVal": "{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}+{Query22Stats:$.Success}+{Query4Stats:$.Success}+{Query5Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}+{Query9Stats:$.Success}+{Query18Stats:$.Success}+{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query16Stats:$.Success}+{Query17Stats:$.Success}+{Query23Stats:$.Success}+{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}+{Query10Stats:$.Success}+{Query11Stats:$.Success}" } } ] @@ -1241,16 +1241,16 @@ "style": "tabs", "links": [ { - "id": "a36ca971-5e80-40d5-b309-a779dc2a9237", + "id": "c0934dc4-5ad6-41b1-89dc-699f07cb195d", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "IP plan ({Tab0Success:value}/{Tab0Total:value})", + "linkLabel": "Segmentation ({Tab0Success:value}/{Tab0Total:value})", "subTarget": "tab0", - "preText": "IP plan", + "preText": "Segmentation", "style": "primary" }, { - "id": "4f77502a-7314-43a6-8007-13cf1c597b26", + "id": "d5396adf-0a18-4c62-9ea3-c8f004c2a567", "cellValue": "VisibleTab", "linkTarget": "parameter", "linkLabel": "Hybrid ({Tab1Success:value}/{Tab1Total:value})", @@ -1259,48 +1259,48 @@ "style": "primary" }, { - "id": "1aeba34c-b616-4f72-a54c-8d14ae8061ba", + "id": "fdbd0965-c467-4d22-b6c0-2981fc2804dd", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Hub and spoke ({Tab2Success:value}/{Tab2Total:value})", + "linkLabel": "PaaS ({Tab2Success:value}/{Tab2Total:value})", "subTarget": "tab2", - "preText": "Hub and spoke", + "preText": "PaaS", "style": "primary" }, { - "id": "324a39ca-244e-4580-a78c-9e2205a0dd77", + "id": "cc8940ff-5b3e-4add-99b3-ee6b4787485b", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Virtual WAN ({Tab3Success:value}/{Tab3Total:value})", + "linkLabel": "Internet ({Tab3Success:value}/{Tab3Total:value})", "subTarget": "tab3", - "preText": "Virtual WAN", + "preText": "Internet", "style": "primary" }, { - "id": "d0b119bf-df65-4661-aca6-6578f497e755", + "id": "981697c4-1ee5-45cc-b167-feda2f44b9b4", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Segmentation ({Tab4Success:value}/{Tab4Total:value})", + "linkLabel": "Virtual WAN ({Tab4Success:value}/{Tab4Total:value})", "subTarget": "tab4", - "preText": "Segmentation", + "preText": "Virtual WAN", "style": "primary" }, { - "id": "be536a5c-d5cc-4ac1-bdc7-800240abde34", + "id": "da02aab8-6d46-4000-9fc4-b0bd68e61980", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Internet ({Tab5Success:value}/{Tab5Total:value})", + "linkLabel": "Hub and spoke ({Tab5Success:value}/{Tab5Total:value})", "subTarget": "tab5", - "preText": "Internet", + "preText": "Hub and spoke", "style": "primary" }, { - "id": "e3ccd69a-b165-4617-b5fb-64ae42053785", + "id": "f557f192-4071-46a5-bd0d-036598a0d5b3", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "PaaS ({Tab6Success:value}/{Tab6Total:value})", + "linkLabel": "IP plan ({Tab6Success:value}/{Tab6Total:value})", "subTarget": "tab6", - "preText": "PaaS", + "preText": "IP plan", "style": "primary" } ] @@ -1316,22 +1316,22 @@ { "type": 1, "content": { - "json": "## IP plan" + "json": "## Segmentation" }, "name": "tab0title" }, { "type": 1, "content": { - "json": "Use IP addresses from the address allocation ranges for private internets (RFC 1918). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this." + "json": "Use a /26 prefix for your Azure Firewall subnets. Check [this link](https://learn.microsoft.com/azure/firewall/firewall-faq#why-does-azure-firewall-need-a--26-subnet-size) for further information." }, - "name": "querytext10" + "name": "querytext19" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\.|172\\.(1[6-9]|2[0-9]|3[01])\\.|192\\.168\\.)') | project id, compliant, cidr | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1380,20 +1380,20 @@ ] } }, - "name": "query10" + "name": "query19" }, { "type": 1, "content": { - "json": "Ensure that IP address space isn't wasted, don't create unnecessarily large virtual networks (for example /16). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this." + "json": "Use at least a /27 prefix for your Gateway subnets. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-howto-add-gateway-resource-manager#add-a-gateway) for further information." }, - "name": "querytext11" + "name": "querytext20" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1442,42 +1442,20 @@ ] } }, - "name": "query11" - } - ] - }, - "conditionalVisibility": { - "parameterName": "VisibleTab", - "comparison": "isEqualTo", - "value": "tab0" - }, - "name": "tab0" - }, - { - "type": 12, - "content": { - "version": "NotebookGroup/1.0", - "groupType": "editable", - "items": [ - { - "type": 1, - "content": { - "json": "## Hybrid" - }, - "name": "tab1title" + "name": "query20" }, { "type": 1, "content": { - "json": "Ensure that you're using the right SKU for the ExpressRoute/VPN gateways based on bandwidth and performance requirements. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-routing) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this." + "json": "Don't rely on the NSG inbound default rules using the VirtualNetwork service tag to limit connectivity. Check [this link](https://learn.microsoft.com/azure/virtual-network/service-tags-overview#available-service-tags) for further information." }, - "name": "querytext4" + "name": "querytext21" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1526,20 +1504,20 @@ ] } }, - "name": "query4" + "name": "query21" }, { "type": 1, "content": { - "json": "Ensure that you're using unlimited-data ExpressRoute circuits only if you reach the bandwidth that justifies their cost. Check [this link](https://learn.microsoft.com/azure/expressroute/plan-manage-cost) for further information." + "json": "The application team should use application security groups at the subnet-level NSGs to help protect multi-tier VMs within the landing zone. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/) can help to educate yourself on this." }, - "name": "querytext5" + "name": "querytext22" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "Resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetName=subnets.name,subnetNsg=subnets.properties.networkSecurityGroup | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend compliant = isnotnull(subnetNsg) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1588,20 +1566,42 @@ ] } }, - "name": "query5" + "name": "query22" + } + ] + }, + "conditionalVisibility": { + "parameterName": "VisibleTab", + "comparison": "isEqualTo", + "value": "tab0" + }, + "name": "tab0" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## Hybrid" + }, + "name": "tab1title" }, { "type": 1, "content": { - "json": "Leverage the Local SKU of ExpressRoute to reduce the cost of your circuits, if your circuits' peering location supports your Azure regions for the Local SKU. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-faqs#expressroute-local) for further information." + "json": "Ensure that you're using the right SKU for the ExpressRoute/VPN gateways based on bandwidth and performance requirements. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-routing) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this." }, - "name": "querytext6" + "name": "querytext4" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1650,20 +1650,20 @@ ] } }, - "name": "query6" + "name": "query4" }, { "type": 1, "content": { - "json": "Deploy a zone-redundant ExpressRoute gateway in the supported Azure regions. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this." + "json": "Ensure that you're using unlimited-data ExpressRoute circuits only if you reach the bandwidth that justifies their cost. Check [this link](https://learn.microsoft.com/azure/expressroute/plan-manage-cost) for further information." }, - "name": "querytext7" + "name": "querytext5" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1712,20 +1712,20 @@ ] } }, - "name": "query7" + "name": "query5" }, { "type": 1, "content": { - "json": "Use VPN gateways to connect branches or remote locations to Azure. For higher resilience, deploy zone-redundant gateways (where available). Check [this link](https://learn.microsoft.com/azure/vpn-gateway/create-zone-redundant-vnet-gateway) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-vpn-gateway/) can help to educate yourself on this." + "json": "Leverage the Local SKU of ExpressRoute to reduce the cost of your circuits, if your circuits' peering location supports your Azure regions for the Local SKU. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-faqs#expressroute-local) for further information." }, - "name": "querytext8" + "name": "querytext6" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1774,20 +1774,20 @@ ] } }, - "name": "query8" + "name": "query6" }, { "type": 1, "content": { - "json": "If you are using a route table in the GatewaySubnet, make sure that gateway routes are propagated. Check [this link](https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings#gwsub) for further information." + "json": "Deploy a zone-redundant ExpressRoute gateway in the supported Azure regions. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this." }, - "name": "querytext9" + "name": "querytext7" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation)) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1836,42 +1836,20 @@ ] } }, - "name": "query9" - } - ] - }, - "conditionalVisibility": { - "parameterName": "VisibleTab", - "comparison": "isEqualTo", - "value": "tab1" - }, - "name": "tab1" - }, - { - "type": 12, - "content": { - "version": "NotebookGroup/1.0", - "groupType": "editable", - "items": [ - { - "type": 1, - "content": { - "json": "## Hub and spoke" - }, - "name": "tab2title" + "name": "query7" }, { "type": 1, "content": { - "json": "If using Route Server, use a /27 prefix for the Route Server subnet. Check [this link](https://learn.microsoft.com/azure/route-server/quickstart-configure-route-server-portal#create-a-route-server-1) for further information." + "json": "Use VPN gateways to connect branches or remote locations to Azure. For higher resilience, deploy zone-redundant gateways (where available). Check [this link](https://learn.microsoft.com/azure/vpn-gateway/create-zone-redundant-vnet-gateway) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-vpn-gateway/) can help to educate yourself on this." }, - "name": "querytext0" + "name": "querytext8" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1920,20 +1898,20 @@ ] } }, - "name": "query0" + "name": "query8" }, { "type": 1, "content": { - "json": "When connecting spoke virtual networks to the central hub virtual network, consider VNet peering limits (500), the maximum number of prefixes that can be advertised via ExpressRoute (1000). Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information." + "json": "If you are using a route table in the GatewaySubnet, make sure that gateway routes are propagated. Check [this link](https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings#gwsub) for further information." }, - "name": "querytext1" + "name": "querytext9" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation)) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1982,20 +1960,42 @@ ] } }, - "name": "query1" + "name": "query9" + } + ] + }, + "conditionalVisibility": { + "parameterName": "VisibleTab", + "comparison": "isEqualTo", + "value": "tab1" + }, + "name": "tab1" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## PaaS" + }, + "name": "tab2title" }, { "type": 1, "content": { - "json": "Consider the limit of routes per route table (400). Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information." + "json": "Don't enable virtual network service endpoints by default on all subnets. Check [this link](https://learn.microsoft.com/azure/app-service/networking-features) for further information.. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn) can help to educate yourself on this." }, - "name": "querytext2" + "name": "querytext18" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type =~ 'microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets = properties.subnets | mv-expand subnets | project id = subnets.id, resourceGroup, VNet = name, serviceEndpoints = subnets.properties.serviceEndpoints, compliant = (isnull(subnets.properties.serviceEndpoints) or array_length(subnets.properties.serviceEndpoints) == 0) | order by compliant asc | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2044,20 +2044,42 @@ ] } }, - "name": "query2" + "name": "query18" + } + ] + }, + "conditionalVisibility": { + "parameterName": "VisibleTab", + "comparison": "isEqualTo", + "value": "tab2" + }, + "name": "tab2" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## Internet" + }, + "name": "tab3title" }, { "type": 1, "content": { - "json": "Use the setting 'Allow traffic to remote virtual network' when configuring VNet peerings. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-network-manage-peering) for further information." + "json": "Use Azure Bastion in a subnet /26 or larger. Check [this link](https://learn.microsoft.com/azure/bastion/bastion-faq#subnet) for further information." }, - "name": "querytext3" + "name": "querytext12" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2106,42 +2128,20 @@ ] } }, - "name": "query3" - } - ] - }, - "conditionalVisibility": { - "parameterName": "VisibleTab", - "comparison": "isEqualTo", - "value": "tab2" - }, - "name": "tab2" - }, - { - "type": 12, - "content": { - "version": "NotebookGroup/1.0", - "groupType": "editable", - "items": [ - { - "type": 1, - "content": { - "json": "## Virtual WAN" - }, - "name": "tab3title" + "name": "query12" }, { "type": 1, "content": { - "json": "For outbound Internet traffic protection and filtering, deploy Azure Firewall in secured hubs. Check [this link](https://learn.microsoft.com/azure/virtual-wan/virtual-wan-about) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/) can help to educate yourself on this." + "json": "Use FQDN-based network rules and Azure Firewall with DNS proxy to filter egress traffic to the Internet over protocols not supported by application rules. Check [this link](https://learn.microsoft.com/azure/firewall/fqdn-filtering-network-rules) for further information." }, - "name": "querytext23" + "name": "querytext13" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualhubs' | extend compliant = isnotnull(properties.azureFirewall.id) | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2190,42 +2190,20 @@ ] } }, - "name": "query23" - } - ] - }, - "conditionalVisibility": { - "parameterName": "VisibleTab", - "comparison": "isEqualTo", - "value": "tab3" - }, - "name": "tab3" - }, - { - "type": 12, - "content": { - "version": "NotebookGroup/1.0", - "groupType": "editable", - "items": [ - { - "type": 1, - "content": { - "json": "## Segmentation" - }, - "name": "tab4title" + "name": "query13" }, { "type": 1, "content": { - "json": "Use a /26 prefix for your Azure Firewall subnets. Check [this link](https://learn.microsoft.com/azure/firewall/firewall-faq#why-does-azure-firewall-need-a--26-subnet-size) for further information." + "json": "Use Azure Firewall Premium for additional security and protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information." }, - "name": "querytext19" + "name": "querytext14" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2274,20 +2252,20 @@ ] } }, - "name": "query19" + "name": "query14" }, { "type": 1, "content": { - "json": "Use at least a /27 prefix for your Gateway subnets. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-howto-add-gateway-resource-manager#add-a-gateway) for further information." + "json": "Configure Azure Firewall Threat Intelligence mode to Alert and Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information." }, - "name": "querytext20" + "name": "querytext15" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2336,20 +2314,20 @@ ] } }, - "name": "query20" + "name": "query15" }, { "type": 1, "content": { - "json": "Don't rely on the NSG inbound default rules using the VirtualNetwork service tag to limit connectivity. Check [this link](https://learn.microsoft.com/azure/virtual-network/service-tags-overview#available-service-tags) for further information." + "json": "Configure Azure Firewall IDPS mode to Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features#idps) for further information." }, - "name": "querytext21" + "name": "querytext16" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2398,20 +2376,20 @@ ] } }, - "name": "query21" + "name": "query16" }, { "type": 1, "content": { - "json": "The application team should use application security groups at the subnet-level NSGs to help protect multi-tier VMs within the landing zone. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/) can help to educate yourself on this." + "json": "For subnets in VNets not connected to Virtual WAN, attach a route table so that Internet traffic is redirected to Azure Firewall or a Network Virtual Appliance. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview) for further information." }, - "name": "querytext22" + "name": "querytext17" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "Resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetName=subnets.name,subnetNsg=subnets.properties.networkSecurityGroup | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend compliant = isnotnull(subnetNsg) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2460,16 +2438,16 @@ ] } }, - "name": "query22" + "name": "query17" } ] }, "conditionalVisibility": { "parameterName": "VisibleTab", "comparison": "isEqualTo", - "value": "tab4" + "value": "tab3" }, - "name": "tab4" + "name": "tab3" }, { "type": 12, @@ -2480,22 +2458,22 @@ { "type": 1, "content": { - "json": "## Internet" + "json": "## Virtual WAN" }, - "name": "tab5title" + "name": "tab4title" }, { "type": 1, "content": { - "json": "Use Azure Bastion in a subnet /26 or larger. Check [this link](https://learn.microsoft.com/azure/bastion/bastion-faq#subnet) for further information." + "json": "For outbound Internet traffic protection and filtering, deploy Azure Firewall in secured hubs. Check [this link](https://learn.microsoft.com/azure/virtual-wan/virtual-wan-about) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/) can help to educate yourself on this." }, - "name": "querytext12" + "name": "querytext23" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualhubs' | extend compliant = isnotnull(properties.azureFirewall.id) | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2544,20 +2522,42 @@ ] } }, - "name": "query12" + "name": "query23" + } + ] + }, + "conditionalVisibility": { + "parameterName": "VisibleTab", + "comparison": "isEqualTo", + "value": "tab4" + }, + "name": "tab4" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## Hub and spoke" + }, + "name": "tab5title" }, { "type": 1, "content": { - "json": "Use FQDN-based network rules and Azure Firewall with DNS proxy to filter egress traffic to the Internet over protocols not supported by application rules. Check [this link](https://learn.microsoft.com/azure/firewall/fqdn-filtering-network-rules) for further information." + "json": "If using Route Server, use a /27 prefix for the Route Server subnet. Check [this link](https://learn.microsoft.com/azure/route-server/quickstart-configure-route-server-portal#create-a-route-server-1) for further information." }, - "name": "querytext13" + "name": "querytext0" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2606,20 +2606,20 @@ ] } }, - "name": "query13" + "name": "query0" }, { "type": 1, "content": { - "json": "Use Azure Firewall Premium for additional security and protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information." + "json": "When connecting spoke virtual networks to the central hub virtual network, consider VNet peering limits (500), the maximum number of prefixes that can be advertised via ExpressRoute (1000). Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information." }, - "name": "querytext14" + "name": "querytext1" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2668,20 +2668,20 @@ ] } }, - "name": "query14" + "name": "query1" }, { "type": 1, "content": { - "json": "Configure Azure Firewall Threat Intelligence mode to Alert and Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information." + "json": "Consider the limit of routes per route table (400). Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information." }, - "name": "querytext15" + "name": "querytext2" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2730,20 +2730,20 @@ ] } }, - "name": "query15" + "name": "query2" }, { "type": 1, "content": { - "json": "Configure Azure Firewall IDPS mode to Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features#idps) for further information." + "json": "Use the setting 'Allow traffic to remote virtual network' when configuring VNet peerings. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-network-manage-peering) for further information." }, - "name": "querytext16" + "name": "querytext3" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2792,20 +2792,42 @@ ] } }, - "name": "query16" + "name": "query3" + } + ] + }, + "conditionalVisibility": { + "parameterName": "VisibleTab", + "comparison": "isEqualTo", + "value": "tab5" + }, + "name": "tab5" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## IP plan" + }, + "name": "tab6title" }, { "type": 1, "content": { - "json": "For subnets in VNets not connected to Virtual WAN, attach a route table so that Internet traffic is redirected to Azure Firewall or a Network Virtual Appliance. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview) for further information." + "json": "Use IP addresses from the address allocation ranges for private internets (RFC 1918). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this." }, - "name": "querytext17" + "name": "querytext10" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\.|172\\.(1[6-9]|2[0-9]|3[01])\\.|192\\.168\\.)') | project id, compliant, cidr | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2854,42 +2876,20 @@ ] } }, - "name": "query17" - } - ] - }, - "conditionalVisibility": { - "parameterName": "VisibleTab", - "comparison": "isEqualTo", - "value": "tab5" - }, - "name": "tab5" - }, - { - "type": 12, - "content": { - "version": "NotebookGroup/1.0", - "groupType": "editable", - "items": [ - { - "type": 1, - "content": { - "json": "## PaaS" - }, - "name": "tab6title" + "name": "query10" }, { "type": 1, "content": { - "json": "Don't enable virtual network service endpoints by default on all subnets. Check [this link](https://learn.microsoft.com/azure/app-service/networking-features) for further information.. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn) can help to educate yourself on this." + "json": "Ensure that IP address space isn't wasted, don't create unnecessarily large virtual networks (for example /16). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this." }, - "name": "querytext18" + "name": "querytext11" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type =~ 'microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets = properties.subnets | mv-expand subnets | project id = subnets.id, resourceGroup, VNet = name, serviceEndpoints = subnets.properties.serviceEndpoints, compliant = (isnull(subnets.properties.serviceEndpoints) or array_length(subnets.properties.serviceEndpoints) == 0) | order by compliant asc | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2938,7 +2938,7 @@ ] } }, - "name": "query18" + "name": "query11" } ] }, diff --git a/workbooks/alz_checklist.en_network_counters_template.json b/workbooks/alz_checklist.en_network_counters_template.json index 8373fc832..568cb6e7f 100644 --- a/workbooks/alz_checklist.en_network_counters_template.json +++ b/workbooks/alz_checklist.en_network_counters_template.json @@ -41,7 +41,7 @@ "dependsOn": [], "properties": { "displayName": "[parameters('workbookDisplayName')]", - "serializedData": "{\n \"version\": \"Notebook/1.0\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"parameters\": [\n {\n \"id\": \"497a107e-dde8-433e-b263-35ac8e8f7834\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Subscription\",\n \"type\": 6,\n \"multiSelect\": true,\n \"quote\": \"'\",\n \"delimiter\": \",\",\n \"typeSettings\": {\n \"additionalResourceOptions\": [\n \"value::all\"\n ],\n \"includeAll\": true,\n \"showDefault\": false\n },\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"value\": [\n \"value::all\"\n ]\n },\n {\n \"id\": \"844e4f4e-df51-4e3c-8eaf-0dc78b92c721\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"OnlyFailed\",\n \"label\": \"Only show failed\",\n \"type\": 2,\n \"typeSettings\": {\n \"additionalResourceOptions\": [],\n \"showDefault\": false\n },\n \"jsonData\": \"[\\r\\n { \\\"value\\\":true, \\\"label\\\":\\\"True\\\" },\\r\\n { \\\"value\\\":false, \\\"label\\\":\\\"False\\\", \\\"selected\\\":true }\\r\\n]\"\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 0,\n \"resourceType\": \"microsoft.operationalinsights/workspaces\"\n },\n \"name\": \"WorkbookSelectors\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If you set \\\"Only show failed\\\" to \\\"Yes\\\", the different queries will only show items that have failed their compliance checks.\",\n \"style\": \"info\"\n },\n \"name\": \"InfoBox\"\n },\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"crossComponentResources\": [\n \"value::all\"\n ],\n \"parameters\": [\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query0Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query0FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query0Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query1Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query1FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query1Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query2Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query2FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query2Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query3Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query3FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query3Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query4Stats\",\n \"type\": 1,\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query4FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query4Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query5Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query5FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query5Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query6Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query6FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query6Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query7Stats\",\n \"type\": 1,\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query7FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query7Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query8Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query8FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query8Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query9Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation))| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query9FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query9Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query10Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\\\.|172\\\\.(1[6-9]|2[0-9]|3[01])\\\\.|192\\\\.168\\\\.)') | project id, compliant, cidr| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query10FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query10Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query11Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query11FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query11Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query12Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query12FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query12Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query13Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query13FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query13Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query14Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query14FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query14Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query15Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query15FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query15Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query16Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query16FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query16Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query17Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query17FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query17Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query18Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets = properties.subnets | mv-expand subnets | project id = subnets.id, resourceGroup, VNet = name, serviceEndpoints = subnets.properties.serviceEndpoints, compliant = (isnull(subnets.properties.serviceEndpoints) or array_length(subnets.properties.serviceEndpoints) == 0) | order by compliant asc| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query18FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query18Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query19Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query19FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query19Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query20Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query20FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query20Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query21Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query21FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query21Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query22Stats\",\n \"type\": 1,\n \"query\": \"Resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetName=subnets.name,subnetNsg=subnets.properties.networkSecurityGroup | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend compliant = isnotnull(subnetNsg)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query22FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query22Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query23Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualhubs' | extend compliant = isnotnull(properties.azureFirewall.id) | project id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query23FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query23Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab0Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query10Stats:$.Success}+{Query11Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab0Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query10Stats:$.Total}+{Query11Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab0Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab0Success}/{Tab0Total})\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab1Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query4Stats:$.Success}+{Query5Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}+{Query9Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab1Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query4Stats:$.Total}+{Query5Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}+{Query9Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab1Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab1Success}/{Tab1Total})\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab2Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab2Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab2Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab2Success}/{Tab2Total})\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab3Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query23Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab3Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query23Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab3Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab3Success}/{Tab3Total})\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab4Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}+{Query22Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab4Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}+{Query22Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab4Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab4Success}/{Tab4Total})\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab5Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query16Stats:$.Success}+{Query17Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab5Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query16Stats:$.Total}+{Query17Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab5Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab5Success}/{Tab5Total})\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab6Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query18Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab6Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query18Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab6Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab6Success}/{Tab6Total})\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"WorkbookTotal\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query10Stats:$.Total}+{Query11Stats:$.Total}+{Query4Stats:$.Total}+{Query5Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}+{Query9Stats:$.Total}+{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}+{Query23Stats:$.Total}+{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}+{Query22Stats:$.Total}+{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query16Stats:$.Total}+{Query17Stats:$.Total}+{Query18Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"WorkbookSuccess\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query10Stats:$.Success}+{Query11Stats:$.Success}+{Query4Stats:$.Success}+{Query5Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}+{Query9Stats:$.Success}+{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}+{Query23Stats:$.Success}+{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}+{Query22Stats:$.Success}+{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query16Stats:$.Success}+{Query17Stats:$.Success}+{Query18Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"WorkbookPercent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{WorkbookSuccess}/{WorkbookTotal})\"\n }\n }\n ]\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n \"name\": \"InvisibleParameters\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Azure Landing Zone Review - Network\\n\\n---\\n\\nThis workbook has been automatically generated out of the checklists in the [Azure Review Checklists repo](https://github.com/Azure/review-checklists). This repo contains best practices and recommendations around generic Landing Zones as well as specific services such as Azure Virtual Desktop, Azure Kubernetes Service or Azure VMware Solution, to name a few. This repository of best practices is curated by Azure engineers, but open to anybody to contribute.\\n\\nIf you see a problem in the queries that are part of this workbook, please open a Github issue [here](https://github.com/Azure/review-checklists/issues/new).\"\n },\n \"customWidth\": \"50\",\n \"name\": \"MarkdownHeader\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"WorkbookPercent\\\\\\\": \\\\\\\"{WorkbookPercent}\\\\\\\", \\\\\\\"SubTitle\\\\\\\": \\\\\\\"Percent of successful checks\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"size\": 4,\n \"queryType\": 8,\n \"visualization\": \"tiles\",\n \"tileSettings\": {\n \"titleContent\": {\n \"columnMatch\": \"WorkbookPercent\",\n \"formatter\": 4,\n \"formatOptions\": {\n \"min\": 0,\n \"max\": 100,\n \"palette\": \"redGreen\"\n }\n },\n \"subtitleContent\": {\n \"columnMatch\": \"SubTitle\",\n \"formatter\": 1\n },\n \"showBorder\": true\n }\n },\n \"customWidth\": \"50\",\n \"name\": \"ProgressTile\"\n },\n {\n \"type\": 11,\n \"content\": {\n \"version\": \"LinkItem/1.0\",\n \"style\": \"tabs\",\n \"links\": [\n {\n \"id\": \"a36ca971-5e80-40d5-b309-a779dc2a9237\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"IP plan ({Tab0Success:value}/{Tab0Total:value})\",\n \"subTarget\": \"tab0\",\n \"preText\": \"IP plan\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"4f77502a-7314-43a6-8007-13cf1c597b26\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Hybrid ({Tab1Success:value}/{Tab1Total:value})\",\n \"subTarget\": \"tab1\",\n \"preText\": \"Hybrid\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"1aeba34c-b616-4f72-a54c-8d14ae8061ba\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Hub and spoke ({Tab2Success:value}/{Tab2Total:value})\",\n \"subTarget\": \"tab2\",\n \"preText\": \"Hub and spoke\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"324a39ca-244e-4580-a78c-9e2205a0dd77\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Virtual WAN ({Tab3Success:value}/{Tab3Total:value})\",\n \"subTarget\": \"tab3\",\n \"preText\": \"Virtual WAN\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"d0b119bf-df65-4661-aca6-6578f497e755\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Segmentation ({Tab4Success:value}/{Tab4Total:value})\",\n \"subTarget\": \"tab4\",\n \"preText\": \"Segmentation\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"be536a5c-d5cc-4ac1-bdc7-800240abde34\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Internet ({Tab5Success:value}/{Tab5Total:value})\",\n \"subTarget\": \"tab5\",\n \"preText\": \"Internet\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"e3ccd69a-b165-4617-b5fb-64ae42053785\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"PaaS ({Tab6Success:value}/{Tab6Total:value})\",\n \"subTarget\": \"tab6\",\n \"preText\": \"PaaS\",\n \"style\": \"primary\"\n }\n ]\n },\n \"name\": \"Tabs\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## IP plan\"\n },\n \"name\": \"tab0title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use IP addresses from the address allocation ranges for private internets (RFC 1918). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext10\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\\\.|172\\\\.(1[6-9]|2[0-9]|3[01])\\\\.|192\\\\.168\\\\.)') | project id, compliant, cidr | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query10\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure that IP address space isn't wasted, don't create unnecessarily large virtual networks (for example /16). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext11\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query11\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab0\"\n },\n \"name\": \"tab0\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Hybrid\"\n },\n \"name\": \"tab1title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure that you're using the right SKU for the ExpressRoute/VPN gateways based on bandwidth and performance requirements. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-routing) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext4\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query4\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure that you're using unlimited-data ExpressRoute circuits only if you reach the bandwidth that justifies their cost. Check [this link](https://learn.microsoft.com/azure/expressroute/plan-manage-cost) for further information.\"\n },\n \"name\": \"querytext5\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query5\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Leverage the Local SKU of ExpressRoute to reduce the cost of your circuits, if your circuits' peering location supports your Azure regions for the Local SKU. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-faqs#expressroute-local) for further information.\"\n },\n \"name\": \"querytext6\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query6\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Deploy a zone-redundant ExpressRoute gateway in the supported Azure regions. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext7\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query7\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use VPN gateways to connect branches or remote locations to Azure. For higher resilience, deploy zone-redundant gateways (where available). Check [this link](https://learn.microsoft.com/azure/vpn-gateway/create-zone-redundant-vnet-gateway) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-vpn-gateway/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext8\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query8\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If you are using a route table in the GatewaySubnet, make sure that gateway routes are propagated. Check [this link](https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings#gwsub) for further information.\"\n },\n \"name\": \"querytext9\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation)) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query9\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab1\"\n },\n \"name\": \"tab1\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Hub and spoke\"\n },\n \"name\": \"tab2title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If using Route Server, use a /27 prefix for the Route Server subnet. Check [this link](https://learn.microsoft.com/azure/route-server/quickstart-configure-route-server-portal#create-a-route-server-1) for further information.\"\n },\n \"name\": \"querytext0\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query0\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"When connecting spoke virtual networks to the central hub virtual network, consider VNet peering limits (500), the maximum number of prefixes that can be advertised via ExpressRoute (1000). Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information.\"\n },\n \"name\": \"querytext1\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query1\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Consider the limit of routes per route table (400). Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information.\"\n },\n \"name\": \"querytext2\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query2\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use the setting 'Allow traffic to remote virtual network' when configuring VNet peerings. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-network-manage-peering) for further information.\"\n },\n \"name\": \"querytext3\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query3\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab2\"\n },\n \"name\": \"tab2\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Virtual WAN\"\n },\n \"name\": \"tab3title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"For outbound Internet traffic protection and filtering, deploy Azure Firewall in secured hubs. Check [this link](https://learn.microsoft.com/azure/virtual-wan/virtual-wan-about) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext23\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualhubs' | extend compliant = isnotnull(properties.azureFirewall.id) | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query23\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab3\"\n },\n \"name\": \"tab3\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Segmentation\"\n },\n \"name\": \"tab4title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use a /26 prefix for your Azure Firewall subnets. Check [this link](https://learn.microsoft.com/azure/firewall/firewall-faq#why-does-azure-firewall-need-a--26-subnet-size) for further information.\"\n },\n \"name\": \"querytext19\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query19\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use at least a /27 prefix for your Gateway subnets. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-howto-add-gateway-resource-manager#add-a-gateway) for further information.\"\n },\n \"name\": \"querytext20\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query20\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Don't rely on the NSG inbound default rules using the VirtualNetwork service tag to limit connectivity. Check [this link](https://learn.microsoft.com/azure/virtual-network/service-tags-overview#available-service-tags) for further information.\"\n },\n \"name\": \"querytext21\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query21\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"The application team should use application security groups at the subnet-level NSGs to help protect multi-tier VMs within the landing zone. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext22\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"Resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetName=subnets.name,subnetNsg=subnets.properties.networkSecurityGroup | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend compliant = isnotnull(subnetNsg) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query22\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab4\"\n },\n \"name\": \"tab4\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Internet\"\n },\n \"name\": \"tab5title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Azure Bastion in a subnet /26 or larger. Check [this link](https://learn.microsoft.com/azure/bastion/bastion-faq#subnet) for further information.\"\n },\n \"name\": \"querytext12\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query12\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use FQDN-based network rules and Azure Firewall with DNS proxy to filter egress traffic to the Internet over protocols not supported by application rules. Check [this link](https://learn.microsoft.com/azure/firewall/fqdn-filtering-network-rules) for further information.\"\n },\n \"name\": \"querytext13\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query13\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Azure Firewall Premium for additional security and protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information.\"\n },\n \"name\": \"querytext14\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query14\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Configure Azure Firewall Threat Intelligence mode to Alert and Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information.\"\n },\n \"name\": \"querytext15\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query15\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Configure Azure Firewall IDPS mode to Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features#idps) for further information.\"\n },\n \"name\": \"querytext16\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query16\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"For subnets in VNets not connected to Virtual WAN, attach a route table so that Internet traffic is redirected to Azure Firewall or a Network Virtual Appliance. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview) for further information.\"\n },\n \"name\": \"querytext17\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query17\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab5\"\n },\n \"name\": \"tab5\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## PaaS\"\n },\n \"name\": \"tab6title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Don't enable virtual network service endpoints by default on all subnets. Check [this link](https://learn.microsoft.com/azure/app-service/networking-features) for further information.. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn) can help to educate yourself on this.\"\n },\n \"name\": \"querytext18\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets = properties.subnets | mv-expand subnets | project id = subnets.id, resourceGroup, VNet = name, serviceEndpoints = subnets.properties.serviceEndpoints, compliant = (isnull(subnets.properties.serviceEndpoints) or array_length(subnets.properties.serviceEndpoints) == 0) | order by compliant asc | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query18\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab6\"\n },\n \"name\": \"tab6\"\n }\n ],\n \"$schema\": \"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"\n}", + "serializedData": "{\n \"version\": \"Notebook/1.0\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"parameters\": [\n {\n \"id\": \"497a107e-dde8-433e-b263-35ac8e8f7834\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Subscription\",\n \"type\": 6,\n \"multiSelect\": true,\n \"quote\": \"'\",\n \"delimiter\": \",\",\n \"typeSettings\": {\n \"additionalResourceOptions\": [\n \"value::all\"\n ],\n \"includeAll\": true,\n \"showDefault\": false\n },\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"value\": [\n \"value::all\"\n ]\n },\n {\n \"id\": \"844e4f4e-df51-4e3c-8eaf-0dc78b92c721\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"OnlyFailed\",\n \"label\": \"Only show failed\",\n \"type\": 2,\n \"typeSettings\": {\n \"additionalResourceOptions\": [],\n \"showDefault\": false\n },\n \"jsonData\": \"[\\r\\n { \\\"value\\\":true, \\\"label\\\":\\\"True\\\" },\\r\\n { \\\"value\\\":false, \\\"label\\\":\\\"False\\\", \\\"selected\\\":true }\\r\\n]\"\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 0,\n \"resourceType\": \"microsoft.operationalinsights/workspaces\"\n },\n \"name\": \"WorkbookSelectors\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If you set \\\"Only show failed\\\" to \\\"Yes\\\", the different queries will only show items that have failed their compliance checks.\",\n \"style\": \"info\"\n },\n \"name\": \"InfoBox\"\n },\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"crossComponentResources\": [\n \"value::all\"\n ],\n \"parameters\": [\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query0Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query0FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query0Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query1Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query1FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query1Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query2Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query2FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query2Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query3Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query3FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query3Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query4Stats\",\n \"type\": 1,\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query4FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query4Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query5Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query5FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query5Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query6Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query6FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query6Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query7Stats\",\n \"type\": 1,\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query7FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query7Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query8Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query8FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query8Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query9Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation))| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query9FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query9Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query10Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\\\.|172\\\\.(1[6-9]|2[0-9]|3[01])\\\\.|192\\\\.168\\\\.)') | project id, compliant, cidr| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query10FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query10Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query11Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query11FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query11Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query12Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query12FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query12Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query13Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query13FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query13Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query14Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query14FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query14Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query15Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query15FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query15Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query16Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query16FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query16Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query17Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query17FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query17Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query18Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets = properties.subnets | mv-expand subnets | project id = subnets.id, resourceGroup, VNet = name, serviceEndpoints = subnets.properties.serviceEndpoints, compliant = (isnull(subnets.properties.serviceEndpoints) or array_length(subnets.properties.serviceEndpoints) == 0) | order by compliant asc| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query18FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query18Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query19Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query19FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query19Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query20Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query20FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query20Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query21Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query21FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query21Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query22Stats\",\n \"type\": 1,\n \"query\": \"Resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetName=subnets.name,subnetNsg=subnets.properties.networkSecurityGroup | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend compliant = isnotnull(subnetNsg)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query22FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query22Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query23Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualhubs' | extend compliant = isnotnull(properties.azureFirewall.id) | project id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query23FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query23Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab0Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}+{Query22Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab0Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}+{Query22Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab0Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab0Success}/{Tab0Total})\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab1Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query4Stats:$.Success}+{Query5Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}+{Query9Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab1Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query4Stats:$.Total}+{Query5Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}+{Query9Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab1Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab1Success}/{Tab1Total})\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab2Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query18Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab2Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query18Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab2Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab2Success}/{Tab2Total})\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab3Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query16Stats:$.Success}+{Query17Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab3Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query16Stats:$.Total}+{Query17Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab3Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab3Success}/{Tab3Total})\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab4Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query23Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab4Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query23Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab4Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab4Success}/{Tab4Total})\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab5Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab5Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab5Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab5Success}/{Tab5Total})\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab6Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query10Stats:$.Success}+{Query11Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab6Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query10Stats:$.Total}+{Query11Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab6Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab6Success}/{Tab6Total})\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"WorkbookTotal\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}+{Query22Stats:$.Total}+{Query4Stats:$.Total}+{Query5Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}+{Query9Stats:$.Total}+{Query18Stats:$.Total}+{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query16Stats:$.Total}+{Query17Stats:$.Total}+{Query23Stats:$.Total}+{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}+{Query10Stats:$.Total}+{Query11Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"WorkbookSuccess\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}+{Query22Stats:$.Success}+{Query4Stats:$.Success}+{Query5Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}+{Query9Stats:$.Success}+{Query18Stats:$.Success}+{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query16Stats:$.Success}+{Query17Stats:$.Success}+{Query23Stats:$.Success}+{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}+{Query10Stats:$.Success}+{Query11Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"WorkbookPercent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{WorkbookSuccess}/{WorkbookTotal})\"\n }\n }\n ]\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n \"name\": \"InvisibleParameters\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Azure Landing Zone Review - Network\\n\\n---\\n\\nThis workbook has been automatically generated out of the checklists in the [Azure Review Checklists repo](https://github.com/Azure/review-checklists). This repo contains best practices and recommendations around generic Landing Zones as well as specific services such as Azure Virtual Desktop, Azure Kubernetes Service or Azure VMware Solution, to name a few. This repository of best practices is curated by Azure engineers, but open to anybody to contribute.\\n\\nIf you see a problem in the queries that are part of this workbook, please open a Github issue [here](https://github.com/Azure/review-checklists/issues/new).\"\n },\n \"customWidth\": \"50\",\n \"name\": \"MarkdownHeader\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"WorkbookPercent\\\\\\\": \\\\\\\"{WorkbookPercent}\\\\\\\", \\\\\\\"SubTitle\\\\\\\": \\\\\\\"Percent of successful checks\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"size\": 4,\n \"queryType\": 8,\n \"visualization\": \"tiles\",\n \"tileSettings\": {\n \"titleContent\": {\n \"columnMatch\": \"WorkbookPercent\",\n \"formatter\": 4,\n \"formatOptions\": {\n \"min\": 0,\n \"max\": 100,\n \"palette\": \"redGreen\"\n }\n },\n \"subtitleContent\": {\n \"columnMatch\": \"SubTitle\",\n \"formatter\": 1\n },\n \"showBorder\": true\n }\n },\n \"customWidth\": \"50\",\n \"name\": \"ProgressTile\"\n },\n {\n \"type\": 11,\n \"content\": {\n \"version\": \"LinkItem/1.0\",\n \"style\": \"tabs\",\n \"links\": [\n {\n \"id\": \"c0934dc4-5ad6-41b1-89dc-699f07cb195d\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Segmentation ({Tab0Success:value}/{Tab0Total:value})\",\n \"subTarget\": \"tab0\",\n \"preText\": \"Segmentation\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"d5396adf-0a18-4c62-9ea3-c8f004c2a567\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Hybrid ({Tab1Success:value}/{Tab1Total:value})\",\n \"subTarget\": \"tab1\",\n \"preText\": \"Hybrid\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"fdbd0965-c467-4d22-b6c0-2981fc2804dd\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"PaaS ({Tab2Success:value}/{Tab2Total:value})\",\n \"subTarget\": \"tab2\",\n \"preText\": \"PaaS\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"cc8940ff-5b3e-4add-99b3-ee6b4787485b\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Internet ({Tab3Success:value}/{Tab3Total:value})\",\n \"subTarget\": \"tab3\",\n \"preText\": \"Internet\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"981697c4-1ee5-45cc-b167-feda2f44b9b4\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Virtual WAN ({Tab4Success:value}/{Tab4Total:value})\",\n \"subTarget\": \"tab4\",\n \"preText\": \"Virtual WAN\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"da02aab8-6d46-4000-9fc4-b0bd68e61980\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Hub and spoke ({Tab5Success:value}/{Tab5Total:value})\",\n \"subTarget\": \"tab5\",\n \"preText\": \"Hub and spoke\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"f557f192-4071-46a5-bd0d-036598a0d5b3\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"IP plan ({Tab6Success:value}/{Tab6Total:value})\",\n \"subTarget\": \"tab6\",\n \"preText\": \"IP plan\",\n \"style\": \"primary\"\n }\n ]\n },\n \"name\": \"Tabs\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Segmentation\"\n },\n \"name\": \"tab0title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use a /26 prefix for your Azure Firewall subnets. Check [this link](https://learn.microsoft.com/azure/firewall/firewall-faq#why-does-azure-firewall-need-a--26-subnet-size) for further information.\"\n },\n \"name\": \"querytext19\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query19\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use at least a /27 prefix for your Gateway subnets. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-howto-add-gateway-resource-manager#add-a-gateway) for further information.\"\n },\n \"name\": \"querytext20\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query20\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Don't rely on the NSG inbound default rules using the VirtualNetwork service tag to limit connectivity. Check [this link](https://learn.microsoft.com/azure/virtual-network/service-tags-overview#available-service-tags) for further information.\"\n },\n \"name\": \"querytext21\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query21\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"The application team should use application security groups at the subnet-level NSGs to help protect multi-tier VMs within the landing zone. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext22\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"Resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetName=subnets.name,subnetNsg=subnets.properties.networkSecurityGroup | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend compliant = isnotnull(subnetNsg) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query22\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab0\"\n },\n \"name\": \"tab0\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Hybrid\"\n },\n \"name\": \"tab1title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure that you're using the right SKU for the ExpressRoute/VPN gateways based on bandwidth and performance requirements. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-routing) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext4\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query4\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure that you're using unlimited-data ExpressRoute circuits only if you reach the bandwidth that justifies their cost. Check [this link](https://learn.microsoft.com/azure/expressroute/plan-manage-cost) for further information.\"\n },\n \"name\": \"querytext5\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query5\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Leverage the Local SKU of ExpressRoute to reduce the cost of your circuits, if your circuits' peering location supports your Azure regions for the Local SKU. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-faqs#expressroute-local) for further information.\"\n },\n \"name\": \"querytext6\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query6\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Deploy a zone-redundant ExpressRoute gateway in the supported Azure regions. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext7\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query7\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use VPN gateways to connect branches or remote locations to Azure. For higher resilience, deploy zone-redundant gateways (where available). Check [this link](https://learn.microsoft.com/azure/vpn-gateway/create-zone-redundant-vnet-gateway) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-vpn-gateway/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext8\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query8\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If you are using a route table in the GatewaySubnet, make sure that gateway routes are propagated. Check [this link](https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings#gwsub) for further information.\"\n },\n \"name\": \"querytext9\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation)) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query9\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab1\"\n },\n \"name\": \"tab1\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## PaaS\"\n },\n \"name\": \"tab2title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Don't enable virtual network service endpoints by default on all subnets. Check [this link](https://learn.microsoft.com/azure/app-service/networking-features) for further information.. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn) can help to educate yourself on this.\"\n },\n \"name\": \"querytext18\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets = properties.subnets | mv-expand subnets | project id = subnets.id, resourceGroup, VNet = name, serviceEndpoints = subnets.properties.serviceEndpoints, compliant = (isnull(subnets.properties.serviceEndpoints) or array_length(subnets.properties.serviceEndpoints) == 0) | order by compliant asc | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query18\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab2\"\n },\n \"name\": \"tab2\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Internet\"\n },\n \"name\": \"tab3title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Azure Bastion in a subnet /26 or larger. Check [this link](https://learn.microsoft.com/azure/bastion/bastion-faq#subnet) for further information.\"\n },\n \"name\": \"querytext12\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query12\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use FQDN-based network rules and Azure Firewall with DNS proxy to filter egress traffic to the Internet over protocols not supported by application rules. Check [this link](https://learn.microsoft.com/azure/firewall/fqdn-filtering-network-rules) for further information.\"\n },\n \"name\": \"querytext13\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query13\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Azure Firewall Premium for additional security and protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information.\"\n },\n \"name\": \"querytext14\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query14\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Configure Azure Firewall Threat Intelligence mode to Alert and Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information.\"\n },\n \"name\": \"querytext15\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query15\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Configure Azure Firewall IDPS mode to Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features#idps) for further information.\"\n },\n \"name\": \"querytext16\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query16\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"For subnets in VNets not connected to Virtual WAN, attach a route table so that Internet traffic is redirected to Azure Firewall or a Network Virtual Appliance. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview) for further information.\"\n },\n \"name\": \"querytext17\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query17\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab3\"\n },\n \"name\": \"tab3\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Virtual WAN\"\n },\n \"name\": \"tab4title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"For outbound Internet traffic protection and filtering, deploy Azure Firewall in secured hubs. Check [this link](https://learn.microsoft.com/azure/virtual-wan/virtual-wan-about) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext23\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualhubs' | extend compliant = isnotnull(properties.azureFirewall.id) | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query23\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab4\"\n },\n \"name\": \"tab4\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Hub and spoke\"\n },\n \"name\": \"tab5title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If using Route Server, use a /27 prefix for the Route Server subnet. Check [this link](https://learn.microsoft.com/azure/route-server/quickstart-configure-route-server-portal#create-a-route-server-1) for further information.\"\n },\n \"name\": \"querytext0\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query0\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"When connecting spoke virtual networks to the central hub virtual network, consider VNet peering limits (500), the maximum number of prefixes that can be advertised via ExpressRoute (1000). Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information.\"\n },\n \"name\": \"querytext1\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query1\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Consider the limit of routes per route table (400). Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information.\"\n },\n \"name\": \"querytext2\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query2\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use the setting 'Allow traffic to remote virtual network' when configuring VNet peerings. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-network-manage-peering) for further information.\"\n },\n \"name\": \"querytext3\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query3\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab5\"\n },\n \"name\": \"tab5\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## IP plan\"\n },\n \"name\": \"tab6title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use IP addresses from the address allocation ranges for private internets (RFC 1918). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext10\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\\\.|172\\\\.(1[6-9]|2[0-9]|3[01])\\\\.|192\\\\.168\\\\.)') | project id, compliant, cidr | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query10\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure that IP address space isn't wasted, don't create unnecessarily large virtual networks (for example /16). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext11\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query11\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab6\"\n },\n \"name\": \"tab6\"\n }\n ],\n \"$schema\": \"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"\n}", "version": "1.0", "sourceId": "[parameters('workbookSourceId')]", "category": "[parameters('workbookType')]" diff --git a/workbooks/alz_checklist.en_network_tabcounters.json b/workbooks/alz_checklist.en_network_tabcounters.json index 57574ccb0..d5db8c3df 100644 --- a/workbooks/alz_checklist.en_network_tabcounters.json +++ b/workbooks/alz_checklist.en_network_tabcounters.json @@ -70,25 +70,25 @@ "style": "tabs", "links": [ { - "id": "488ee46d-9198-4a98-bec2-404e4019bb0d", + "id": "a6a03215-5e70-40e8-960f-b5255b7c5c3c", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Hybrid", + "linkLabel": "Hub and spoke", "subTarget": "tab0", - "preText": "Hybrid", + "preText": "Hub and spoke", "style": "primary" }, { - "id": "d102af5a-dcbe-4e0f-9601-bf3fd2caa01f", + "id": "94e5143a-993d-4473-b90b-e1f3dd7ead27", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "PaaS", + "linkLabel": "Segmentation", "subTarget": "tab1", - "preText": "PaaS", + "preText": "Segmentation", "style": "primary" }, { - "id": "220bf218-c977-4b69-a9bf-0be6b6c33e36", + "id": "8f888b07-9f89-49da-8784-48397da4a67b", "cellValue": "VisibleTab", "linkTarget": "parameter", "linkLabel": "Virtual WAN", @@ -97,39 +97,39 @@ "style": "primary" }, { - "id": "96e69059-1f19-4065-9933-b18d0b3991a2", + "id": "1148bb75-6faf-4908-ab1a-486dbc95e5de", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Segmentation", + "linkLabel": "Internet", "subTarget": "tab3", - "preText": "Segmentation", + "preText": "Internet", "style": "primary" }, { - "id": "31a18141-9bae-425d-8e56-9211cedd70ff", + "id": "4efbff5e-a90c-47de-a332-ff039329358a", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "IP plan", + "linkLabel": "Hybrid", "subTarget": "tab4", - "preText": "IP plan", + "preText": "Hybrid", "style": "primary" }, { - "id": "a305ce1d-42df-47d9-b0d7-4750212b0b63", + "id": "36408e59-845e-4361-921c-98326bd81068", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Internet", + "linkLabel": "IP plan", "subTarget": "tab5", - "preText": "Internet", + "preText": "IP plan", "style": "primary" }, { - "id": "8dcfbbed-8f0f-46ec-938a-3bf0a02d6192", + "id": "39a752db-e60e-4ab6-ba96-6f872a7ad64b", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Hub and spoke", + "linkLabel": "PaaS", "subTarget": "tab6", - "preText": "Hub and spoke", + "preText": "PaaS", "style": "primary" } ] @@ -153,65 +153,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query4Stats", - "type": 1, - "query": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", - "crossComponentResources": [ - "{Subscription}" - ], - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources" - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query4FullyCompliant", - "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query4Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 8 - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query5Stats", - "type": 1, - "query": "resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", - "crossComponentResources": [ - "{Subscription}" - ], - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources" - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query5FullyCompliant", - "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query5Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 8 - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query6Stats", + "name": "Query0Stats", "type": 1, - "query": "resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -225,9 +169,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query6FullyCompliant", + "name": "Query0FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query6Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query0Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -237,9 +181,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query7Stats", + "name": "Query1Stats", "type": 1, - "query": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -253,9 +197,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query7FullyCompliant", + "name": "Query1FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query7Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query1Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -265,9 +209,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query8Stats", + "name": "Query2Stats", "type": 1, - "query": "resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -281,9 +225,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query8FullyCompliant", + "name": "Query2FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query8Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query2Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -293,9 +237,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query9Stats", + "name": "Query3Stats", "type": 1, - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation))| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -309,9 +253,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query9FullyCompliant", + "name": "Query3FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query9Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query3Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -332,7 +276,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query4Stats:$.Success}+{Query5Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}+{Query9Stats:$.Success}" + "resultVal": "{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}" } } ] @@ -351,7 +295,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query4Stats:$.Total}+{Query5Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}+{Query9Stats:$.Total}" + "resultVal": "{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}" } } ] @@ -385,7 +329,7 @@ { "type": 1, "content": { - "json": "## Hybrid" + "json": "## Hub and spoke" }, "customWidth": "50", "name": "tab0title" @@ -426,15 +370,15 @@ { "type": 1, "content": { - "json": "Ensure that you're using the right SKU for the ExpressRoute/VPN gateways based on bandwidth and performance requirements. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-routing) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this." + "json": "If using Route Server, use a /27 prefix for the Route Server subnet. Check [this link](https://learn.microsoft.com/azure/route-server/quickstart-configure-route-server-portal#create-a-route-server-1) for further information." }, - "name": "querytext4" + "name": "querytext0" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -483,20 +427,20 @@ ] } }, - "name": "query4" + "name": "query0" }, { "type": 1, "content": { - "json": "Ensure that you're using unlimited-data ExpressRoute circuits only if you reach the bandwidth that justifies their cost. Check [this link](https://learn.microsoft.com/azure/expressroute/plan-manage-cost) for further information." + "json": "When connecting spoke virtual networks to the central hub virtual network, consider VNet peering limits (500), the maximum number of prefixes that can be advertised via ExpressRoute (1000). Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information." }, - "name": "querytext5" + "name": "querytext1" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -545,20 +489,20 @@ ] } }, - "name": "query5" + "name": "query1" }, { "type": 1, "content": { - "json": "Leverage the Local SKU of ExpressRoute to reduce the cost of your circuits, if your circuits' peering location supports your Azure regions for the Local SKU. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-faqs#expressroute-local) for further information." + "json": "Consider the limit of routes per route table (400). Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information." }, - "name": "querytext6" + "name": "querytext2" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -607,20 +551,20 @@ ] } }, - "name": "query6" + "name": "query2" }, { "type": 1, "content": { - "json": "Deploy a zone-redundant ExpressRoute gateway in the supported Azure regions. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this." + "json": "Use the setting 'Allow traffic to remote virtual network' when configuring VNet peerings. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-network-manage-peering) for further information." }, - "name": "querytext7" + "name": "querytext3" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -669,161 +613,65 @@ ] } }, - "name": "query7" - }, - { - "type": 1, - "content": { - "json": "Use VPN gateways to connect branches or remote locations to Azure. For higher resilience, deploy zone-redundant gateways (where available). Check [this link](https://learn.microsoft.com/azure/vpn-gateway/create-zone-redundant-vnet-gateway) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-vpn-gateway/) can help to educate yourself on this." - }, - "name": "querytext8" - }, + "name": "query3" + } + ] + }, + "conditionalVisibility": { + "parameterName": "VisibleTab", + "comparison": "isEqualTo", + "value": "tab0" + }, + "name": "tab0" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ { - "type": 3, + "type": 9, "content": { - "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", - "size": 4, - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources", + "version": "KqlParameterItem/1.0", "crossComponentResources": [ "{Subscription}" ], - "gridSettings": { - "formatters": [ - { - "columnMatch": "id", - "formatter": 0, - "numberFormat": { - "unit": 0, - "options": { - "style": "decimal" - } - } + "parameters": [ + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query19Stats", + "type": 1, + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "crossComponentResources": [ + "{Subscription}" + ], + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 }, - { - "columnMatch": "compliant", - "formatter": 18, - "formatOptions": { - "thresholdsOptions": "icons", - "thresholdsGrid": [ - { - "operator": "==", - "thresholdValue": "1", - "representation": "success", - "text": "Success" - }, - { - "operator": "==", - "thresholdValue": "0", - "representation": "failed", - "text": "Failed" - }, - { - "operator": "Default", - "thresholdValue": null, - "representation": "unknown", - "text": "Unknown" - } - ] - } - } - ] - } - }, - "name": "query8" - }, - { - "type": 1, - "content": { - "json": "If you are using a route table in the GatewaySubnet, make sure that gateway routes are propagated. Check [this link](https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings#gwsub) for further information." - }, - "name": "querytext9" - }, - { - "type": 3, - "content": { - "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation)) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", - "size": 4, - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources", - "crossComponentResources": [ - "{Subscription}" - ], - "gridSettings": { - "formatters": [ - { - "columnMatch": "id", - "formatter": 0, - "numberFormat": { - "unit": 0, - "options": { - "style": "decimal" - } - } + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query19FullyCompliant", + "type": 1, + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query19Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 }, - { - "columnMatch": "compliant", - "formatter": 18, - "formatOptions": { - "thresholdsOptions": "icons", - "thresholdsGrid": [ - { - "operator": "==", - "thresholdValue": "1", - "representation": "success", - "text": "Success" - }, - { - "operator": "==", - "thresholdValue": "0", - "representation": "failed", - "text": "Failed" - }, - { - "operator": "Default", - "thresholdValue": null, - "representation": "unknown", - "text": "Unknown" - } - ] - } - } - ] - } - }, - "name": "query9" - } - ] - }, - "conditionalVisibility": { - "parameterName": "VisibleTab", - "comparison": "isEqualTo", - "value": "tab0" - }, - "name": "tab0" - }, - { - "type": 12, - "content": { - "version": "NotebookGroup/1.0", - "groupType": "editable", - "items": [ - { - "type": 9, - "content": { - "version": "KqlParameterItem/1.0", - "crossComponentResources": [ - "{Subscription}" - ], - "parameters": [ + "queryType": 8 + }, { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query18Stats", + "name": "Query20Stats", "type": 1, - "query": "resources | where type =~ 'microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets = properties.subnets | mv-expand subnets | project id = subnets.id, resourceGroup, VNet = name, serviceEndpoints = subnets.properties.serviceEndpoints, compliant = (isnull(subnets.properties.serviceEndpoints) or array_length(subnets.properties.serviceEndpoints) == 0) | order by compliant asc| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -837,9 +685,65 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query18FullyCompliant", + "name": "Query20FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query18Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query20Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 8 + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query21Stats", + "type": 1, + "query": "resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "crossComponentResources": [ + "{Subscription}" + ], + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query21FullyCompliant", + "type": 1, + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query21Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 8 + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query22Stats", + "type": 1, + "query": "Resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetName=subnets.name,subnetNsg=subnets.properties.networkSecurityGroup | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend compliant = isnotnull(subnetNsg)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "crossComponentResources": [ + "{Subscription}" + ], + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query22FullyCompliant", + "type": 1, + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query22Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -860,7 +764,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query18Stats:$.Success}" + "resultVal": "{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}+{Query22Stats:$.Success}" } } ] @@ -879,7 +783,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query18Stats:$.Total}" + "resultVal": "{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}+{Query22Stats:$.Total}" } } ] @@ -913,7 +817,7 @@ { "type": 1, "content": { - "json": "## PaaS" + "json": "## Segmentation" }, "customWidth": "50", "name": "tab1title" @@ -954,15 +858,15 @@ { "type": 1, "content": { - "json": "Don't enable virtual network service endpoints by default on all subnets. Check [this link](https://learn.microsoft.com/azure/app-service/networking-features) for further information.. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn) can help to educate yourself on this." + "json": "Use a /26 prefix for your Azure Firewall subnets. Check [this link](https://learn.microsoft.com/azure/firewall/firewall-faq#why-does-azure-firewall-need-a--26-subnet-size) for further information." }, - "name": "querytext18" + "name": "querytext19" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type =~ 'microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets = properties.subnets | mv-expand subnets | project id = subnets.id, resourceGroup, VNet = name, serviceEndpoints = subnets.properties.serviceEndpoints, compliant = (isnull(subnets.properties.serviceEndpoints) or array_length(subnets.properties.serviceEndpoints) == 0) | order by compliant asc | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1011,7 +915,193 @@ ] } }, - "name": "query18" + "name": "query19" + }, + { + "type": 1, + "content": { + "json": "Use at least a /27 prefix for your Gateway subnets. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-howto-add-gateway-resource-manager#add-a-gateway) for further information." + }, + "name": "querytext20" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "size": 4, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "id", + "formatter": 0, + "numberFormat": { + "unit": 0, + "options": { + "style": "decimal" + } + } + }, + { + "columnMatch": "compliant", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "1", + "representation": "success", + "text": "Success" + }, + { + "operator": "==", + "thresholdValue": "0", + "representation": "failed", + "text": "Failed" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "Unknown" + } + ] + } + } + ] + } + }, + "name": "query20" + }, + { + "type": 1, + "content": { + "json": "Don't rely on the NSG inbound default rules using the VirtualNetwork service tag to limit connectivity. Check [this link](https://learn.microsoft.com/azure/virtual-network/service-tags-overview#available-service-tags) for further information." + }, + "name": "querytext21" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "size": 4, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "id", + "formatter": 0, + "numberFormat": { + "unit": 0, + "options": { + "style": "decimal" + } + } + }, + { + "columnMatch": "compliant", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "1", + "representation": "success", + "text": "Success" + }, + { + "operator": "==", + "thresholdValue": "0", + "representation": "failed", + "text": "Failed" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "Unknown" + } + ] + } + } + ] + } + }, + "name": "query21" + }, + { + "type": 1, + "content": { + "json": "The application team should use application security groups at the subnet-level NSGs to help protect multi-tier VMs within the landing zone. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/) can help to educate yourself on this." + }, + "name": "querytext22" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "Resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetName=subnets.name,subnetNsg=subnets.properties.networkSecurityGroup | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend compliant = isnotnull(subnetNsg) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "size": 4, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "id", + "formatter": 0, + "numberFormat": { + "unit": 0, + "options": { + "style": "decimal" + } + } + }, + { + "columnMatch": "compliant", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "1", + "representation": "success", + "text": "Success" + }, + { + "operator": "==", + "thresholdValue": "0", + "representation": "failed", + "text": "Failed" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "Unknown" + } + ] + } + } + ] + } + }, + "name": "query22" } ] }, @@ -1257,9 +1347,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query19Stats", + "name": "Query12Stats", "type": 1, - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -1273,9 +1363,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query19FullyCompliant", + "name": "Query12FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query19Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query12Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -1285,9 +1375,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query20Stats", + "name": "Query13Stats", "type": 1, - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -1301,9 +1391,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query20FullyCompliant", + "name": "Query13FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query20Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query13Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -1313,9 +1403,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query21Stats", + "name": "Query14Stats", "type": 1, - "query": "resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -1329,9 +1419,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query21FullyCompliant", + "name": "Query14FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query21Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query14Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -1341,9 +1431,65 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query22Stats", + "name": "Query15Stats", + "type": 1, + "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "crossComponentResources": [ + "{Subscription}" + ], + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query15FullyCompliant", + "type": 1, + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query15Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 8 + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query16Stats", + "type": 1, + "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "crossComponentResources": [ + "{Subscription}" + ], + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query16FullyCompliant", + "type": 1, + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query16Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 8 + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query17Stats", "type": 1, - "query": "Resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetName=subnets.name,subnetNsg=subnets.properties.networkSecurityGroup | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend compliant = isnotnull(subnetNsg)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -1357,9 +1503,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query22FullyCompliant", + "name": "Query17FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query22Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query17Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -1380,7 +1526,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}+{Query22Stats:$.Success}" + "resultVal": "{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query16Stats:$.Success}+{Query17Stats:$.Success}" } } ] @@ -1399,7 +1545,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}+{Query22Stats:$.Total}" + "resultVal": "{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query16Stats:$.Total}+{Query17Stats:$.Total}" } } ] @@ -1433,7 +1579,7 @@ { "type": 1, "content": { - "json": "## Segmentation" + "json": "## Internet" }, "customWidth": "50", "name": "tab3title" @@ -1474,15 +1620,15 @@ { "type": 1, "content": { - "json": "Use a /26 prefix for your Azure Firewall subnets. Check [this link](https://learn.microsoft.com/azure/firewall/firewall-faq#why-does-azure-firewall-need-a--26-subnet-size) for further information." + "json": "Use Azure Bastion in a subnet /26 or larger. Check [this link](https://learn.microsoft.com/azure/bastion/bastion-faq#subnet) for further information." }, - "name": "querytext19" + "name": "querytext12" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1531,20 +1677,20 @@ ] } }, - "name": "query19" + "name": "query12" }, { "type": 1, "content": { - "json": "Use at least a /27 prefix for your Gateway subnets. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-howto-add-gateway-resource-manager#add-a-gateway) for further information." + "json": "Use FQDN-based network rules and Azure Firewall with DNS proxy to filter egress traffic to the Internet over protocols not supported by application rules. Check [this link](https://learn.microsoft.com/azure/firewall/fqdn-filtering-network-rules) for further information." }, - "name": "querytext20" + "name": "querytext13" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1593,20 +1739,20 @@ ] } }, - "name": "query20" + "name": "query13" }, { "type": 1, "content": { - "json": "Don't rely on the NSG inbound default rules using the VirtualNetwork service tag to limit connectivity. Check [this link](https://learn.microsoft.com/azure/virtual-network/service-tags-overview#available-service-tags) for further information." + "json": "Use Azure Firewall Premium for additional security and protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information." }, - "name": "querytext21" + "name": "querytext14" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1655,266 +1801,82 @@ ] } }, - "name": "query21" + "name": "query14" }, { "type": 1, "content": { - "json": "The application team should use application security groups at the subnet-level NSGs to help protect multi-tier VMs within the landing zone. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/) can help to educate yourself on this." + "json": "Configure Azure Firewall Threat Intelligence mode to Alert and Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information." }, - "name": "querytext22" + "name": "querytext15" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "Resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetName=subnets.name,subnetNsg=subnets.properties.networkSecurityGroup | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend compliant = isnotnull(subnetNsg) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", - "crossComponentResources": [ - "{Subscription}" - ], - "gridSettings": { - "formatters": [ - { - "columnMatch": "id", - "formatter": 0, - "numberFormat": { - "unit": 0, - "options": { - "style": "decimal" - } - } - }, - { - "columnMatch": "compliant", - "formatter": 18, - "formatOptions": { - "thresholdsOptions": "icons", - "thresholdsGrid": [ - { - "operator": "==", - "thresholdValue": "1", - "representation": "success", - "text": "Success" - }, - { - "operator": "==", - "thresholdValue": "0", - "representation": "failed", - "text": "Failed" - }, - { - "operator": "Default", - "thresholdValue": null, - "representation": "unknown", - "text": "Unknown" - } - ] - } - } - ] - } - }, - "name": "query22" - } - ] - }, - "conditionalVisibility": { - "parameterName": "VisibleTab", - "comparison": "isEqualTo", - "value": "tab3" - }, - "name": "tab3" - }, - { - "type": 12, - "content": { - "version": "NotebookGroup/1.0", - "groupType": "editable", - "items": [ - { - "type": 9, - "content": { - "version": "KqlParameterItem/1.0", - "crossComponentResources": [ - "{Subscription}" - ], - "parameters": [ - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query10Stats", - "type": 1, - "query": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\.|172\\.(1[6-9]|2[0-9]|3[01])\\.|192\\.168\\.)') | project id, compliant, cidr| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", - "crossComponentResources": [ - "{Subscription}" - ], - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources" - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query10FullyCompliant", - "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query10Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 8 - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query11Stats", - "type": 1, - "query": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", - "crossComponentResources": [ - "{Subscription}" - ], - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources" - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query11FullyCompliant", - "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query11Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 8 - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Tab4Success", - "type": 1, - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "criteriaData": [ - { - "criteriaContext": { - "operator": "Default", - "resultValType": "expression", - "resultVal": "{Query10Stats:$.Success}+{Query11Stats:$.Success}" - } - } - ] - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Tab4Total", - "type": 1, - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "criteriaData": [ - { - "criteriaContext": { - "operator": "Default", - "resultValType": "expression", - "resultVal": "{Query10Stats:$.Total}+{Query11Stats:$.Total}" - } - } - ] - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Tab4Percent", - "type": 1, - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "criteriaData": [ - { - "criteriaContext": { - "operator": "Default", - "resultValType": "expression", - "resultVal": "round(100*{Tab4Success}/{Tab4Total})" - } - } - ] - } - ], - "style": "pills", - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources" - }, - "name": "TabInvisibleParameters" - }, - { - "type": 1, - "content": { - "json": "## IP plan" - }, - "customWidth": "50", - "name": "tab4title" - }, - { - "type": 3, - "content": { - "version": "KqlItem/1.0", - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"Column1\\\": \\\"{Tab4Percent}\\\", \\\"Column2\\\": \\\"Percent of successful checks\\\"}\",\"transformers\":null}", - "size": 3, - "queryType": 8, - "visualization": "tiles", - "tileSettings": { - "titleContent": { - "columnMatch": "Column1", - "formatter": 4, - "formatOptions": { - "min": 0, - "max": 100, - "palette": "redGreen" + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "id", + "formatter": 0, + "numberFormat": { + "unit": 0, + "options": { + "style": "decimal" + } + } }, - "numberFormat": { - "unit": 0, - "options": { - "style": "decimal" + { + "columnMatch": "compliant", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "1", + "representation": "success", + "text": "Success" + }, + { + "operator": "==", + "thresholdValue": "0", + "representation": "failed", + "text": "Failed" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "Unknown" + } + ] } } - }, - "subtitleContent": { - "columnMatch": "Column2" - }, - "showBorder": true + ] } }, - "customWidth": "50", - "name": "TabPercentTile" + "name": "query15" }, { "type": 1, "content": { - "json": "Use IP addresses from the address allocation ranges for private internets (RFC 1918). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this." + "json": "Configure Azure Firewall IDPS mode to Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features#idps) for further information." }, - "name": "querytext10" + "name": "querytext16" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\.|172\\.(1[6-9]|2[0-9]|3[01])\\.|192\\.168\\.)') | project id, compliant, cidr | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1963,20 +1925,20 @@ ] } }, - "name": "query10" + "name": "query16" }, { "type": 1, "content": { - "json": "Ensure that IP address space isn't wasted, don't create unnecessarily large virtual networks (for example /16). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this." + "json": "For subnets in VNets not connected to Virtual WAN, attach a route table so that Internet traffic is redirected to Azure Firewall or a Network Virtual Appliance. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview) for further information." }, - "name": "querytext11" + "name": "querytext17" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2025,16 +1987,16 @@ ] } }, - "name": "query11" + "name": "query17" } ] }, "conditionalVisibility": { "parameterName": "VisibleTab", "comparison": "isEqualTo", - "value": "tab4" + "value": "tab3" }, - "name": "tab4" + "name": "tab3" }, { "type": 12, @@ -2053,9 +2015,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query12Stats", + "name": "Query4Stats", "type": 1, - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -2069,9 +2031,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query12FullyCompliant", + "name": "Query4FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query12Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query4Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -2081,9 +2043,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query13Stats", + "name": "Query5Stats", "type": 1, - "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -2097,9 +2059,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query13FullyCompliant", + "name": "Query5FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query13Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query5Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -2109,9 +2071,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query14Stats", + "name": "Query6Stats", "type": 1, - "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -2125,9 +2087,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query14FullyCompliant", + "name": "Query6FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query14Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query6Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -2137,9 +2099,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query15Stats", + "name": "Query7Stats", "type": 1, - "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -2153,9 +2115,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query15FullyCompliant", + "name": "Query7FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query15Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query7Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -2165,9 +2127,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query16Stats", + "name": "Query8Stats", "type": 1, - "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -2181,9 +2143,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query16FullyCompliant", + "name": "Query8FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query16Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query8Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -2193,9 +2155,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query17Stats", + "name": "Query9Stats", "type": 1, - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation))| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -2209,9 +2171,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query17FullyCompliant", + "name": "Query9FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query17Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query9Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -2221,7 +2183,7 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Tab5Success", + "name": "Tab4Success", "type": 1, "isHiddenWhenLocked": true, "timeContext": { @@ -2232,7 +2194,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query16Stats:$.Success}+{Query17Stats:$.Success}" + "resultVal": "{Query4Stats:$.Success}+{Query5Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}+{Query9Stats:$.Success}" } } ] @@ -2240,7 +2202,7 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Tab5Total", + "name": "Tab4Total", "type": 1, "isHiddenWhenLocked": true, "timeContext": { @@ -2251,7 +2213,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query16Stats:$.Total}+{Query17Stats:$.Total}" + "resultVal": "{Query4Stats:$.Total}+{Query5Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}+{Query9Stats:$.Total}" } } ] @@ -2259,7 +2221,7 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Tab5Percent", + "name": "Tab4Percent", "type": 1, "isHiddenWhenLocked": true, "timeContext": { @@ -2270,7 +2232,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "round(100*{Tab5Success}/{Tab5Total})" + "resultVal": "round(100*{Tab4Success}/{Tab4Total})" } } ] @@ -2285,16 +2247,16 @@ { "type": 1, "content": { - "json": "## Internet" + "json": "## Hybrid" }, "customWidth": "50", - "name": "tab5title" + "name": "tab4title" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"Column1\\\": \\\"{Tab5Percent}\\\", \\\"Column2\\\": \\\"Percent of successful checks\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"Column1\\\": \\\"{Tab4Percent}\\\", \\\"Column2\\\": \\\"Percent of successful checks\\\"}\",\"transformers\":null}", "size": 3, "queryType": 8, "visualization": "tiles", @@ -2326,15 +2288,15 @@ { "type": 1, "content": { - "json": "Use Azure Bastion in a subnet /26 or larger. Check [this link](https://learn.microsoft.com/azure/bastion/bastion-faq#subnet) for further information." + "json": "Ensure that you're using the right SKU for the ExpressRoute/VPN gateways based on bandwidth and performance requirements. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-routing) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this." }, - "name": "querytext12" + "name": "querytext4" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2383,20 +2345,20 @@ ] } }, - "name": "query12" + "name": "query4" }, { "type": 1, "content": { - "json": "Use FQDN-based network rules and Azure Firewall with DNS proxy to filter egress traffic to the Internet over protocols not supported by application rules. Check [this link](https://learn.microsoft.com/azure/firewall/fqdn-filtering-network-rules) for further information." + "json": "Ensure that you're using unlimited-data ExpressRoute circuits only if you reach the bandwidth that justifies their cost. Check [this link](https://learn.microsoft.com/azure/expressroute/plan-manage-cost) for further information." }, - "name": "querytext13" + "name": "querytext5" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2445,20 +2407,20 @@ ] } }, - "name": "query13" + "name": "query5" }, { "type": 1, "content": { - "json": "Use Azure Firewall Premium for additional security and protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information." + "json": "Leverage the Local SKU of ExpressRoute to reduce the cost of your circuits, if your circuits' peering location supports your Azure regions for the Local SKU. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-faqs#expressroute-local) for further information." }, - "name": "querytext14" + "name": "querytext6" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2507,20 +2469,20 @@ ] } }, - "name": "query14" + "name": "query6" }, { "type": 1, "content": { - "json": "Configure Azure Firewall Threat Intelligence mode to Alert and Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information." + "json": "Deploy a zone-redundant ExpressRoute gateway in the supported Azure regions. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this." }, - "name": "querytext15" + "name": "querytext7" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2569,20 +2531,20 @@ ] } }, - "name": "query15" + "name": "query7" }, { "type": 1, "content": { - "json": "Configure Azure Firewall IDPS mode to Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features#idps) for further information." + "json": "Use VPN gateways to connect branches or remote locations to Azure. For higher resilience, deploy zone-redundant gateways (where available). Check [this link](https://learn.microsoft.com/azure/vpn-gateway/create-zone-redundant-vnet-gateway) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-vpn-gateway/) can help to educate yourself on this." }, - "name": "querytext16" + "name": "querytext8" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2631,20 +2593,20 @@ ] } }, - "name": "query16" + "name": "query8" }, { "type": 1, "content": { - "json": "For subnets in VNets not connected to Virtual WAN, attach a route table so that Internet traffic is redirected to Azure Firewall or a Network Virtual Appliance. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview) for further information." + "json": "If you are using a route table in the GatewaySubnet, make sure that gateway routes are propagated. Check [this link](https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings#gwsub) for further information." }, - "name": "querytext17" + "name": "querytext9" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation)) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2693,93 +2655,37 @@ ] } }, - "name": "query17" + "name": "query9" } ] }, "conditionalVisibility": { "parameterName": "VisibleTab", "comparison": "isEqualTo", - "value": "tab5" + "value": "tab4" }, - "name": "tab5" + "name": "tab4" }, { "type": 12, "content": { "version": "NotebookGroup/1.0", - "groupType": "editable", - "items": [ - { - "type": 9, - "content": { - "version": "KqlParameterItem/1.0", - "crossComponentResources": [ - "{Subscription}" - ], - "parameters": [ - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query0Stats", - "type": 1, - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", - "crossComponentResources": [ - "{Subscription}" - ], - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources" - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query0FullyCompliant", - "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query0Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 8 - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query1Stats", - "type": 1, - "query": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", - "crossComponentResources": [ - "{Subscription}" - ], - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources" - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query1FullyCompliant", - "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query1Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 8 - }, + "groupType": "editable", + "items": [ + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [ + "{Subscription}" + ], + "parameters": [ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query2Stats", + "name": "Query10Stats", "type": 1, - "query": "resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\.|172\\.(1[6-9]|2[0-9]|3[01])\\.|192\\.168\\.)') | project id, compliant, cidr| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -2793,9 +2699,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query2FullyCompliant", + "name": "Query10FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query2Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query10Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -2805,9 +2711,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query3Stats", + "name": "Query11Stats", "type": 1, - "query": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -2821,9 +2727,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query3FullyCompliant", + "name": "Query11FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query3Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query11Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -2833,7 +2739,7 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Tab6Success", + "name": "Tab5Success", "type": 1, "isHiddenWhenLocked": true, "timeContext": { @@ -2844,7 +2750,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}" + "resultVal": "{Query10Stats:$.Success}+{Query11Stats:$.Success}" } } ] @@ -2852,7 +2758,7 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Tab6Total", + "name": "Tab5Total", "type": 1, "isHiddenWhenLocked": true, "timeContext": { @@ -2863,7 +2769,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}" + "resultVal": "{Query10Stats:$.Total}+{Query11Stats:$.Total}" } } ] @@ -2871,7 +2777,7 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Tab6Percent", + "name": "Tab5Percent", "type": 1, "isHiddenWhenLocked": true, "timeContext": { @@ -2882,7 +2788,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "round(100*{Tab6Success}/{Tab6Total})" + "resultVal": "round(100*{Tab5Success}/{Tab5Total})" } } ] @@ -2897,16 +2803,16 @@ { "type": 1, "content": { - "json": "## Hub and spoke" + "json": "## IP plan" }, "customWidth": "50", - "name": "tab6title" + "name": "tab5title" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"Column1\\\": \\\"{Tab6Percent}\\\", \\\"Column2\\\": \\\"Percent of successful checks\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"Column1\\\": \\\"{Tab5Percent}\\\", \\\"Column2\\\": \\\"Percent of successful checks\\\"}\",\"transformers\":null}", "size": 3, "queryType": 8, "visualization": "tiles", @@ -2938,15 +2844,15 @@ { "type": 1, "content": { - "json": "If using Route Server, use a /27 prefix for the Route Server subnet. Check [this link](https://learn.microsoft.com/azure/route-server/quickstart-configure-route-server-portal#create-a-route-server-1) for further information." + "json": "Use IP addresses from the address allocation ranges for private internets (RFC 1918). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this." }, - "name": "querytext0" + "name": "querytext10" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\.|172\\.(1[6-9]|2[0-9]|3[01])\\.|192\\.168\\.)') | project id, compliant, cidr | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2995,20 +2901,20 @@ ] } }, - "name": "query0" + "name": "query10" }, { "type": 1, "content": { - "json": "When connecting spoke virtual networks to the central hub virtual network, consider VNet peering limits (500), the maximum number of prefixes that can be advertised via ExpressRoute (1000). Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information." + "json": "Ensure that IP address space isn't wasted, don't create unnecessarily large virtual networks (for example /16). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this." }, - "name": "querytext1" + "name": "querytext11" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -3057,82 +2963,176 @@ ] } }, - "name": "query1" + "name": "query11" + } + ] + }, + "conditionalVisibility": { + "parameterName": "VisibleTab", + "comparison": "isEqualTo", + "value": "tab5" + }, + "name": "tab5" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [ + "{Subscription}" + ], + "parameters": [ + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query18Stats", + "type": 1, + "query": "resources | where type =~ 'microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets = properties.subnets | mv-expand subnets | project id = subnets.id, resourceGroup, VNet = name, serviceEndpoints = subnets.properties.serviceEndpoints, compliant = (isnull(subnets.properties.serviceEndpoints) or array_length(subnets.properties.serviceEndpoints) == 0) | order by compliant asc| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "crossComponentResources": [ + "{Subscription}" + ], + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query18FullyCompliant", + "type": 1, + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query18Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 8 + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Tab6Success", + "type": 1, + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "criteriaData": [ + { + "criteriaContext": { + "operator": "Default", + "resultValType": "expression", + "resultVal": "{Query18Stats:$.Success}" + } + } + ] + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Tab6Total", + "type": 1, + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "criteriaData": [ + { + "criteriaContext": { + "operator": "Default", + "resultValType": "expression", + "resultVal": "{Query18Stats:$.Total}" + } + } + ] + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Tab6Percent", + "type": 1, + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "criteriaData": [ + { + "criteriaContext": { + "operator": "Default", + "resultValType": "expression", + "resultVal": "round(100*{Tab6Success}/{Tab6Total})" + } + } + ] + } + ], + "style": "pills", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + "name": "TabInvisibleParameters" }, { "type": 1, "content": { - "json": "Consider the limit of routes per route table (400). Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information." + "json": "## PaaS" }, - "name": "querytext2" + "customWidth": "50", + "name": "tab6title" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", - "size": 4, - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources", - "crossComponentResources": [ - "{Subscription}" - ], - "gridSettings": { - "formatters": [ - { - "columnMatch": "id", - "formatter": 0, - "numberFormat": { - "unit": 0, - "options": { - "style": "decimal" - } - } + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"Column1\\\": \\\"{Tab6Percent}\\\", \\\"Column2\\\": \\\"Percent of successful checks\\\"}\",\"transformers\":null}", + "size": 3, + "queryType": 8, + "visualization": "tiles", + "tileSettings": { + "titleContent": { + "columnMatch": "Column1", + "formatter": 4, + "formatOptions": { + "min": 0, + "max": 100, + "palette": "redGreen" }, - { - "columnMatch": "compliant", - "formatter": 18, - "formatOptions": { - "thresholdsOptions": "icons", - "thresholdsGrid": [ - { - "operator": "==", - "thresholdValue": "1", - "representation": "success", - "text": "Success" - }, - { - "operator": "==", - "thresholdValue": "0", - "representation": "failed", - "text": "Failed" - }, - { - "operator": "Default", - "thresholdValue": null, - "representation": "unknown", - "text": "Unknown" - } - ] + "numberFormat": { + "unit": 0, + "options": { + "style": "decimal" } } - ] + }, + "subtitleContent": { + "columnMatch": "Column2" + }, + "showBorder": true } }, - "name": "query2" + "customWidth": "50", + "name": "TabPercentTile" }, { "type": 1, "content": { - "json": "Use the setting 'Allow traffic to remote virtual network' when configuring VNet peerings. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-network-manage-peering) for further information." + "json": "Don't enable virtual network service endpoints by default on all subnets. Check [this link](https://learn.microsoft.com/azure/app-service/networking-features) for further information.. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn) can help to educate yourself on this." }, - "name": "querytext3" + "name": "querytext18" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type =~ 'microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets = properties.subnets | mv-expand subnets | project id = subnets.id, resourceGroup, VNet = name, serviceEndpoints = subnets.properties.serviceEndpoints, compliant = (isnull(subnets.properties.serviceEndpoints) or array_length(subnets.properties.serviceEndpoints) == 0) | order by compliant asc | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -3181,7 +3181,7 @@ ] } }, - "name": "query3" + "name": "query18" } ] }, diff --git a/workbooks/alz_checklist.en_network_tabcounters_template.json b/workbooks/alz_checklist.en_network_tabcounters_template.json index d0653fa75..54868930c 100644 --- a/workbooks/alz_checklist.en_network_tabcounters_template.json +++ b/workbooks/alz_checklist.en_network_tabcounters_template.json @@ -41,7 +41,7 @@ "dependsOn": [], "properties": { "displayName": "[parameters('workbookDisplayName')]", - "serializedData": "{\n \"version\": \"Notebook/1.0\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"parameters\": [\n {\n \"id\": \"497a107e-dde8-433e-b263-35ac8e8f7834\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Subscription\",\n \"type\": 6,\n \"multiSelect\": true,\n \"quote\": \"'\",\n \"delimiter\": \",\",\n \"typeSettings\": {\n \"additionalResourceOptions\": [\n \"value::all\"\n ],\n \"includeAll\": true,\n \"showDefault\": false\n },\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"value\": [\n \"value::all\"\n ]\n },\n {\n \"id\": \"844e4f4e-df51-4e3c-8eaf-0dc78b92c721\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"OnlyFailed\",\n \"label\": \"Only show failed\",\n \"type\": 2,\n \"typeSettings\": {\n \"additionalResourceOptions\": [],\n \"showDefault\": false\n },\n \"jsonData\": \"[\\r\\n { \\\"value\\\":true, \\\"label\\\":\\\"True\\\" },\\r\\n { \\\"value\\\":false, \\\"label\\\":\\\"False\\\", \\\"selected\\\":true }\\r\\n]\"\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 0,\n \"resourceType\": \"microsoft.operationalinsights/workspaces\"\n },\n \"name\": \"WorkbookSelectors\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If you set \\\"Only show failed\\\" to \\\"Yes\\\", the different queries will only show items that have failed their compliance checks.\",\n \"style\": \"info\"\n },\n \"name\": \"InfoBox\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Azure Landing Zone Review - Network\\n\\n---\\n\\nThis workbook has been automatically generated out of the checklists in the [Azure Review Checklists repo](https://github.com/Azure/review-checklists). This repo contains best practices and recommendations around generic Landing Zones as well as specific services such as Azure Virtual Desktop, Azure Kubernetes Service or Azure VMware Solution, to name a few. This repository of best practices is curated by Azure engineers, but open to anybody to contribute.\\n\\nIf you see a problem in the queries that are part of this workbook, please open a Github issue [here](https://github.com/Azure/review-checklists/issues/new).\"\n },\n \"customWidth\": \"100\",\n \"name\": \"MarkdownHeader\"\n },\n {\n \"type\": 11,\n \"content\": {\n \"version\": \"LinkItem/1.0\",\n \"style\": \"tabs\",\n \"links\": [\n {\n \"id\": \"488ee46d-9198-4a98-bec2-404e4019bb0d\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Hybrid\",\n \"subTarget\": \"tab0\",\n \"preText\": \"Hybrid\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"d102af5a-dcbe-4e0f-9601-bf3fd2caa01f\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"PaaS\",\n \"subTarget\": \"tab1\",\n \"preText\": \"PaaS\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"220bf218-c977-4b69-a9bf-0be6b6c33e36\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Virtual WAN\",\n \"subTarget\": \"tab2\",\n \"preText\": \"Virtual WAN\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"96e69059-1f19-4065-9933-b18d0b3991a2\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Segmentation\",\n \"subTarget\": \"tab3\",\n \"preText\": \"Segmentation\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"31a18141-9bae-425d-8e56-9211cedd70ff\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"IP plan\",\n \"subTarget\": \"tab4\",\n \"preText\": \"IP plan\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"a305ce1d-42df-47d9-b0d7-4750212b0b63\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Internet\",\n \"subTarget\": \"tab5\",\n \"preText\": \"Internet\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"8dcfbbed-8f0f-46ec-938a-3bf0a02d6192\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Hub and spoke\",\n \"subTarget\": \"tab6\",\n \"preText\": \"Hub and spoke\",\n \"style\": \"primary\"\n }\n ]\n },\n \"name\": \"Tabs\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"parameters\": [\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query4Stats\",\n \"type\": 1,\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query4FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query4Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query5Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query5FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query5Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query6Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query6FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query6Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query7Stats\",\n \"type\": 1,\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query7FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query7Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query8Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query8FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query8Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query9Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation))| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query9FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query9Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab0Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query4Stats:$.Success}+{Query5Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}+{Query9Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab0Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query4Stats:$.Total}+{Query5Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}+{Query9Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab0Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab0Success}/{Tab0Total})\"\n }\n }\n ]\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n \"name\": \"TabInvisibleParameters\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Hybrid\"\n },\n \"customWidth\": \"50\",\n \"name\": \"tab0title\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"Column1\\\\\\\": \\\\\\\"{Tab0Percent}\\\\\\\", \\\\\\\"Column2\\\\\\\": \\\\\\\"Percent of successful checks\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"size\": 3,\n \"queryType\": 8,\n \"visualization\": \"tiles\",\n \"tileSettings\": {\n \"titleContent\": {\n \"columnMatch\": \"Column1\",\n \"formatter\": 4,\n \"formatOptions\": {\n \"min\": 0,\n \"max\": 100,\n \"palette\": \"redGreen\"\n },\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n \"subtitleContent\": {\n \"columnMatch\": \"Column2\"\n },\n \"showBorder\": true\n }\n },\n \"customWidth\": \"50\",\n \"name\": \"TabPercentTile\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure that you're using the right SKU for the ExpressRoute/VPN gateways based on bandwidth and performance requirements. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-routing) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext4\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query4\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure that you're using unlimited-data ExpressRoute circuits only if you reach the bandwidth that justifies their cost. Check [this link](https://learn.microsoft.com/azure/expressroute/plan-manage-cost) for further information.\"\n },\n \"name\": \"querytext5\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query5\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Leverage the Local SKU of ExpressRoute to reduce the cost of your circuits, if your circuits' peering location supports your Azure regions for the Local SKU. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-faqs#expressroute-local) for further information.\"\n },\n \"name\": \"querytext6\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query6\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Deploy a zone-redundant ExpressRoute gateway in the supported Azure regions. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext7\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query7\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use VPN gateways to connect branches or remote locations to Azure. For higher resilience, deploy zone-redundant gateways (where available). Check [this link](https://learn.microsoft.com/azure/vpn-gateway/create-zone-redundant-vnet-gateway) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-vpn-gateway/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext8\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query8\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If you are using a route table in the GatewaySubnet, make sure that gateway routes are propagated. Check [this link](https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings#gwsub) for further information.\"\n },\n \"name\": \"querytext9\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation)) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query9\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab0\"\n },\n \"name\": \"tab0\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"parameters\": [\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query18Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets = properties.subnets | mv-expand subnets | project id = subnets.id, resourceGroup, VNet = name, serviceEndpoints = subnets.properties.serviceEndpoints, compliant = (isnull(subnets.properties.serviceEndpoints) or array_length(subnets.properties.serviceEndpoints) == 0) | order by compliant asc| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query18FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query18Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab1Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query18Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab1Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query18Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab1Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab1Success}/{Tab1Total})\"\n }\n }\n ]\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n \"name\": \"TabInvisibleParameters\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## PaaS\"\n },\n \"customWidth\": \"50\",\n \"name\": \"tab1title\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"Column1\\\\\\\": \\\\\\\"{Tab1Percent}\\\\\\\", \\\\\\\"Column2\\\\\\\": \\\\\\\"Percent of successful checks\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"size\": 3,\n \"queryType\": 8,\n \"visualization\": \"tiles\",\n \"tileSettings\": {\n \"titleContent\": {\n \"columnMatch\": \"Column1\",\n \"formatter\": 4,\n \"formatOptions\": {\n \"min\": 0,\n \"max\": 100,\n \"palette\": \"redGreen\"\n },\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n \"subtitleContent\": {\n \"columnMatch\": \"Column2\"\n },\n \"showBorder\": true\n }\n },\n \"customWidth\": \"50\",\n \"name\": \"TabPercentTile\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Don't enable virtual network service endpoints by default on all subnets. Check [this link](https://learn.microsoft.com/azure/app-service/networking-features) for further information.. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn) can help to educate yourself on this.\"\n },\n \"name\": \"querytext18\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets = properties.subnets | mv-expand subnets | project id = subnets.id, resourceGroup, VNet = name, serviceEndpoints = subnets.properties.serviceEndpoints, compliant = (isnull(subnets.properties.serviceEndpoints) or array_length(subnets.properties.serviceEndpoints) == 0) | order by compliant asc | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query18\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab1\"\n },\n \"name\": \"tab1\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"parameters\": [\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query23Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualhubs' | extend compliant = isnotnull(properties.azureFirewall.id) | project id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query23FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query23Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab2Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query23Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab2Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query23Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab2Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab2Success}/{Tab2Total})\"\n }\n }\n ]\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n \"name\": \"TabInvisibleParameters\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Virtual WAN\"\n },\n \"customWidth\": \"50\",\n \"name\": \"tab2title\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"Column1\\\\\\\": \\\\\\\"{Tab2Percent}\\\\\\\", \\\\\\\"Column2\\\\\\\": \\\\\\\"Percent of successful checks\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"size\": 3,\n \"queryType\": 8,\n \"visualization\": \"tiles\",\n \"tileSettings\": {\n \"titleContent\": {\n \"columnMatch\": \"Column1\",\n \"formatter\": 4,\n \"formatOptions\": {\n \"min\": 0,\n \"max\": 100,\n \"palette\": \"redGreen\"\n },\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n \"subtitleContent\": {\n \"columnMatch\": \"Column2\"\n },\n \"showBorder\": true\n }\n },\n \"customWidth\": \"50\",\n \"name\": \"TabPercentTile\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"For outbound Internet traffic protection and filtering, deploy Azure Firewall in secured hubs. Check [this link](https://learn.microsoft.com/azure/virtual-wan/virtual-wan-about) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext23\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualhubs' | extend compliant = isnotnull(properties.azureFirewall.id) | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query23\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab2\"\n },\n \"name\": \"tab2\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"parameters\": [\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query19Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query19FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query19Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query20Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query20FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query20Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query21Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query21FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query21Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query22Stats\",\n \"type\": 1,\n \"query\": \"Resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetName=subnets.name,subnetNsg=subnets.properties.networkSecurityGroup | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend compliant = isnotnull(subnetNsg)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query22FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query22Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab3Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}+{Query22Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab3Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}+{Query22Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab3Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab3Success}/{Tab3Total})\"\n }\n }\n ]\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n \"name\": \"TabInvisibleParameters\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Segmentation\"\n },\n \"customWidth\": \"50\",\n \"name\": \"tab3title\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"Column1\\\\\\\": \\\\\\\"{Tab3Percent}\\\\\\\", \\\\\\\"Column2\\\\\\\": \\\\\\\"Percent of successful checks\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"size\": 3,\n \"queryType\": 8,\n \"visualization\": \"tiles\",\n \"tileSettings\": {\n \"titleContent\": {\n \"columnMatch\": \"Column1\",\n \"formatter\": 4,\n \"formatOptions\": {\n \"min\": 0,\n \"max\": 100,\n \"palette\": \"redGreen\"\n },\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n \"subtitleContent\": {\n \"columnMatch\": \"Column2\"\n },\n \"showBorder\": true\n }\n },\n \"customWidth\": \"50\",\n \"name\": \"TabPercentTile\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use a /26 prefix for your Azure Firewall subnets. Check [this link](https://learn.microsoft.com/azure/firewall/firewall-faq#why-does-azure-firewall-need-a--26-subnet-size) for further information.\"\n },\n \"name\": \"querytext19\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query19\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use at least a /27 prefix for your Gateway subnets. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-howto-add-gateway-resource-manager#add-a-gateway) for further information.\"\n },\n \"name\": \"querytext20\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query20\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Don't rely on the NSG inbound default rules using the VirtualNetwork service tag to limit connectivity. Check [this link](https://learn.microsoft.com/azure/virtual-network/service-tags-overview#available-service-tags) for further information.\"\n },\n \"name\": \"querytext21\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query21\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"The application team should use application security groups at the subnet-level NSGs to help protect multi-tier VMs within the landing zone. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext22\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"Resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetName=subnets.name,subnetNsg=subnets.properties.networkSecurityGroup | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend compliant = isnotnull(subnetNsg) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query22\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab3\"\n },\n \"name\": \"tab3\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"parameters\": [\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query10Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\\\.|172\\\\.(1[6-9]|2[0-9]|3[01])\\\\.|192\\\\.168\\\\.)') | project id, compliant, cidr| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query10FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query10Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query11Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query11FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query11Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab4Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query10Stats:$.Success}+{Query11Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab4Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query10Stats:$.Total}+{Query11Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab4Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab4Success}/{Tab4Total})\"\n }\n }\n ]\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n \"name\": \"TabInvisibleParameters\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## IP plan\"\n },\n \"customWidth\": \"50\",\n \"name\": \"tab4title\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"Column1\\\\\\\": \\\\\\\"{Tab4Percent}\\\\\\\", \\\\\\\"Column2\\\\\\\": \\\\\\\"Percent of successful checks\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"size\": 3,\n \"queryType\": 8,\n \"visualization\": \"tiles\",\n \"tileSettings\": {\n \"titleContent\": {\n \"columnMatch\": \"Column1\",\n \"formatter\": 4,\n \"formatOptions\": {\n \"min\": 0,\n \"max\": 100,\n \"palette\": \"redGreen\"\n },\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n \"subtitleContent\": {\n \"columnMatch\": \"Column2\"\n },\n \"showBorder\": true\n }\n },\n \"customWidth\": \"50\",\n \"name\": \"TabPercentTile\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use IP addresses from the address allocation ranges for private internets (RFC 1918). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext10\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\\\.|172\\\\.(1[6-9]|2[0-9]|3[01])\\\\.|192\\\\.168\\\\.)') | project id, compliant, cidr | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query10\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure that IP address space isn't wasted, don't create unnecessarily large virtual networks (for example /16). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext11\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query11\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab4\"\n },\n \"name\": \"tab4\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"parameters\": [\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query12Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query12FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query12Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query13Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query13FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query13Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query14Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query14FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query14Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query15Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query15FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query15Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query16Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query16FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query16Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query17Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query17FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query17Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab5Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query16Stats:$.Success}+{Query17Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab5Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query16Stats:$.Total}+{Query17Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab5Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab5Success}/{Tab5Total})\"\n }\n }\n ]\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n \"name\": \"TabInvisibleParameters\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Internet\"\n },\n \"customWidth\": \"50\",\n \"name\": \"tab5title\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"Column1\\\\\\\": \\\\\\\"{Tab5Percent}\\\\\\\", \\\\\\\"Column2\\\\\\\": \\\\\\\"Percent of successful checks\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"size\": 3,\n \"queryType\": 8,\n \"visualization\": \"tiles\",\n \"tileSettings\": {\n \"titleContent\": {\n \"columnMatch\": \"Column1\",\n \"formatter\": 4,\n \"formatOptions\": {\n \"min\": 0,\n \"max\": 100,\n \"palette\": \"redGreen\"\n },\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n \"subtitleContent\": {\n \"columnMatch\": \"Column2\"\n },\n \"showBorder\": true\n }\n },\n \"customWidth\": \"50\",\n \"name\": \"TabPercentTile\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Azure Bastion in a subnet /26 or larger. Check [this link](https://learn.microsoft.com/azure/bastion/bastion-faq#subnet) for further information.\"\n },\n \"name\": \"querytext12\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query12\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use FQDN-based network rules and Azure Firewall with DNS proxy to filter egress traffic to the Internet over protocols not supported by application rules. Check [this link](https://learn.microsoft.com/azure/firewall/fqdn-filtering-network-rules) for further information.\"\n },\n \"name\": \"querytext13\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query13\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Azure Firewall Premium for additional security and protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information.\"\n },\n \"name\": \"querytext14\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query14\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Configure Azure Firewall Threat Intelligence mode to Alert and Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information.\"\n },\n \"name\": \"querytext15\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query15\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Configure Azure Firewall IDPS mode to Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features#idps) for further information.\"\n },\n \"name\": \"querytext16\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query16\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"For subnets in VNets not connected to Virtual WAN, attach a route table so that Internet traffic is redirected to Azure Firewall or a Network Virtual Appliance. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview) for further information.\"\n },\n \"name\": \"querytext17\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query17\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab5\"\n },\n \"name\": \"tab5\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"parameters\": [\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query0Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query0FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query0Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query1Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query1FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query1Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query2Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query2FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query2Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query3Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query3FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query3Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab6Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab6Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab6Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab6Success}/{Tab6Total})\"\n }\n }\n ]\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n \"name\": \"TabInvisibleParameters\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Hub and spoke\"\n },\n \"customWidth\": \"50\",\n \"name\": \"tab6title\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"Column1\\\\\\\": \\\\\\\"{Tab6Percent}\\\\\\\", \\\\\\\"Column2\\\\\\\": \\\\\\\"Percent of successful checks\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"size\": 3,\n \"queryType\": 8,\n \"visualization\": \"tiles\",\n \"tileSettings\": {\n \"titleContent\": {\n \"columnMatch\": \"Column1\",\n \"formatter\": 4,\n \"formatOptions\": {\n \"min\": 0,\n \"max\": 100,\n \"palette\": \"redGreen\"\n },\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n \"subtitleContent\": {\n \"columnMatch\": \"Column2\"\n },\n \"showBorder\": true\n }\n },\n \"customWidth\": \"50\",\n \"name\": \"TabPercentTile\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If using Route Server, use a /27 prefix for the Route Server subnet. Check [this link](https://learn.microsoft.com/azure/route-server/quickstart-configure-route-server-portal#create-a-route-server-1) for further information.\"\n },\n \"name\": \"querytext0\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query0\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"When connecting spoke virtual networks to the central hub virtual network, consider VNet peering limits (500), the maximum number of prefixes that can be advertised via ExpressRoute (1000). Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information.\"\n },\n \"name\": \"querytext1\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query1\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Consider the limit of routes per route table (400). Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information.\"\n },\n \"name\": \"querytext2\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query2\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use the setting 'Allow traffic to remote virtual network' when configuring VNet peerings. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-network-manage-peering) for further information.\"\n },\n \"name\": \"querytext3\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query3\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab6\"\n },\n \"name\": \"tab6\"\n }\n ],\n \"$schema\": \"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"\n}", + "serializedData": "{\n \"version\": \"Notebook/1.0\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"parameters\": [\n {\n \"id\": \"497a107e-dde8-433e-b263-35ac8e8f7834\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Subscription\",\n \"type\": 6,\n \"multiSelect\": true,\n \"quote\": \"'\",\n \"delimiter\": \",\",\n \"typeSettings\": {\n \"additionalResourceOptions\": [\n \"value::all\"\n ],\n \"includeAll\": true,\n \"showDefault\": false\n },\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"value\": [\n \"value::all\"\n ]\n },\n {\n \"id\": \"844e4f4e-df51-4e3c-8eaf-0dc78b92c721\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"OnlyFailed\",\n \"label\": \"Only show failed\",\n \"type\": 2,\n \"typeSettings\": {\n \"additionalResourceOptions\": [],\n \"showDefault\": false\n },\n \"jsonData\": \"[\\r\\n { \\\"value\\\":true, \\\"label\\\":\\\"True\\\" },\\r\\n { \\\"value\\\":false, \\\"label\\\":\\\"False\\\", \\\"selected\\\":true }\\r\\n]\"\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 0,\n \"resourceType\": \"microsoft.operationalinsights/workspaces\"\n },\n \"name\": \"WorkbookSelectors\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If you set \\\"Only show failed\\\" to \\\"Yes\\\", the different queries will only show items that have failed their compliance checks.\",\n \"style\": \"info\"\n },\n \"name\": \"InfoBox\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Azure Landing Zone Review - Network\\n\\n---\\n\\nThis workbook has been automatically generated out of the checklists in the [Azure Review Checklists repo](https://github.com/Azure/review-checklists). This repo contains best practices and recommendations around generic Landing Zones as well as specific services such as Azure Virtual Desktop, Azure Kubernetes Service or Azure VMware Solution, to name a few. This repository of best practices is curated by Azure engineers, but open to anybody to contribute.\\n\\nIf you see a problem in the queries that are part of this workbook, please open a Github issue [here](https://github.com/Azure/review-checklists/issues/new).\"\n },\n \"customWidth\": \"100\",\n \"name\": \"MarkdownHeader\"\n },\n {\n \"type\": 11,\n \"content\": {\n \"version\": \"LinkItem/1.0\",\n \"style\": \"tabs\",\n \"links\": [\n {\n \"id\": \"a6a03215-5e70-40e8-960f-b5255b7c5c3c\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Hub and spoke\",\n \"subTarget\": \"tab0\",\n \"preText\": \"Hub and spoke\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"94e5143a-993d-4473-b90b-e1f3dd7ead27\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Segmentation\",\n \"subTarget\": \"tab1\",\n \"preText\": \"Segmentation\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"8f888b07-9f89-49da-8784-48397da4a67b\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Virtual WAN\",\n \"subTarget\": \"tab2\",\n \"preText\": \"Virtual WAN\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"1148bb75-6faf-4908-ab1a-486dbc95e5de\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Internet\",\n \"subTarget\": \"tab3\",\n \"preText\": \"Internet\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"4efbff5e-a90c-47de-a332-ff039329358a\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Hybrid\",\n \"subTarget\": \"tab4\",\n \"preText\": \"Hybrid\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"36408e59-845e-4361-921c-98326bd81068\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"IP plan\",\n \"subTarget\": \"tab5\",\n \"preText\": \"IP plan\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"39a752db-e60e-4ab6-ba96-6f872a7ad64b\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"PaaS\",\n \"subTarget\": \"tab6\",\n \"preText\": \"PaaS\",\n \"style\": \"primary\"\n }\n ]\n },\n \"name\": \"Tabs\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"parameters\": [\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query0Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query0FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query0Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query1Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query1FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query1Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query2Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query2FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query2Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query3Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query3FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query3Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab0Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab0Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab0Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab0Success}/{Tab0Total})\"\n }\n }\n ]\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n \"name\": \"TabInvisibleParameters\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Hub and spoke\"\n },\n \"customWidth\": \"50\",\n \"name\": \"tab0title\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"Column1\\\\\\\": \\\\\\\"{Tab0Percent}\\\\\\\", \\\\\\\"Column2\\\\\\\": \\\\\\\"Percent of successful checks\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"size\": 3,\n \"queryType\": 8,\n \"visualization\": \"tiles\",\n \"tileSettings\": {\n \"titleContent\": {\n \"columnMatch\": \"Column1\",\n \"formatter\": 4,\n \"formatOptions\": {\n \"min\": 0,\n \"max\": 100,\n \"palette\": \"redGreen\"\n },\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n \"subtitleContent\": {\n \"columnMatch\": \"Column2\"\n },\n \"showBorder\": true\n }\n },\n \"customWidth\": \"50\",\n \"name\": \"TabPercentTile\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If using Route Server, use a /27 prefix for the Route Server subnet. Check [this link](https://learn.microsoft.com/azure/route-server/quickstart-configure-route-server-portal#create-a-route-server-1) for further information.\"\n },\n \"name\": \"querytext0\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query0\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"When connecting spoke virtual networks to the central hub virtual network, consider VNet peering limits (500), the maximum number of prefixes that can be advertised via ExpressRoute (1000). Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information.\"\n },\n \"name\": \"querytext1\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query1\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Consider the limit of routes per route table (400). Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information.\"\n },\n \"name\": \"querytext2\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query2\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use the setting 'Allow traffic to remote virtual network' when configuring VNet peerings. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-network-manage-peering) for further information.\"\n },\n \"name\": \"querytext3\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query3\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab0\"\n },\n \"name\": \"tab0\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"parameters\": [\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query19Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query19FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query19Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query20Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query20FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query20Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query21Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query21FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query21Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query22Stats\",\n \"type\": 1,\n \"query\": \"Resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetName=subnets.name,subnetNsg=subnets.properties.networkSecurityGroup | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend compliant = isnotnull(subnetNsg)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query22FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query22Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab1Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}+{Query22Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab1Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}+{Query22Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab1Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab1Success}/{Tab1Total})\"\n }\n }\n ]\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n \"name\": \"TabInvisibleParameters\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Segmentation\"\n },\n \"customWidth\": \"50\",\n \"name\": \"tab1title\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"Column1\\\\\\\": \\\\\\\"{Tab1Percent}\\\\\\\", \\\\\\\"Column2\\\\\\\": \\\\\\\"Percent of successful checks\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"size\": 3,\n \"queryType\": 8,\n \"visualization\": \"tiles\",\n \"tileSettings\": {\n \"titleContent\": {\n \"columnMatch\": \"Column1\",\n \"formatter\": 4,\n \"formatOptions\": {\n \"min\": 0,\n \"max\": 100,\n \"palette\": \"redGreen\"\n },\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n \"subtitleContent\": {\n \"columnMatch\": \"Column2\"\n },\n \"showBorder\": true\n }\n },\n \"customWidth\": \"50\",\n \"name\": \"TabPercentTile\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use a /26 prefix for your Azure Firewall subnets. Check [this link](https://learn.microsoft.com/azure/firewall/firewall-faq#why-does-azure-firewall-need-a--26-subnet-size) for further information.\"\n },\n \"name\": \"querytext19\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query19\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use at least a /27 prefix for your Gateway subnets. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-howto-add-gateway-resource-manager#add-a-gateway) for further information.\"\n },\n \"name\": \"querytext20\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query20\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Don't rely on the NSG inbound default rules using the VirtualNetwork service tag to limit connectivity. Check [this link](https://learn.microsoft.com/azure/virtual-network/service-tags-overview#available-service-tags) for further information.\"\n },\n \"name\": \"querytext21\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query21\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"The application team should use application security groups at the subnet-level NSGs to help protect multi-tier VMs within the landing zone. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext22\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"Resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetName=subnets.name,subnetNsg=subnets.properties.networkSecurityGroup | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend compliant = isnotnull(subnetNsg) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query22\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab1\"\n },\n \"name\": \"tab1\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"parameters\": [\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query23Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualhubs' | extend compliant = isnotnull(properties.azureFirewall.id) | project id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query23FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query23Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab2Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query23Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab2Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query23Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab2Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab2Success}/{Tab2Total})\"\n }\n }\n ]\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n \"name\": \"TabInvisibleParameters\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Virtual WAN\"\n },\n \"customWidth\": \"50\",\n \"name\": \"tab2title\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"Column1\\\\\\\": \\\\\\\"{Tab2Percent}\\\\\\\", \\\\\\\"Column2\\\\\\\": \\\\\\\"Percent of successful checks\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"size\": 3,\n \"queryType\": 8,\n \"visualization\": \"tiles\",\n \"tileSettings\": {\n \"titleContent\": {\n \"columnMatch\": \"Column1\",\n \"formatter\": 4,\n \"formatOptions\": {\n \"min\": 0,\n \"max\": 100,\n \"palette\": \"redGreen\"\n },\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n \"subtitleContent\": {\n \"columnMatch\": \"Column2\"\n },\n \"showBorder\": true\n }\n },\n \"customWidth\": \"50\",\n \"name\": \"TabPercentTile\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"For outbound Internet traffic protection and filtering, deploy Azure Firewall in secured hubs. Check [this link](https://learn.microsoft.com/azure/virtual-wan/virtual-wan-about) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext23\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualhubs' | extend compliant = isnotnull(properties.azureFirewall.id) | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query23\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab2\"\n },\n \"name\": \"tab2\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"parameters\": [\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query12Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query12FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query12Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query13Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query13FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query13Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query14Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query14FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query14Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query15Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query15FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query15Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query16Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query16FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query16Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query17Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query17FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query17Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab3Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query16Stats:$.Success}+{Query17Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab3Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query16Stats:$.Total}+{Query17Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab3Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab3Success}/{Tab3Total})\"\n }\n }\n ]\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n \"name\": \"TabInvisibleParameters\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Internet\"\n },\n \"customWidth\": \"50\",\n \"name\": \"tab3title\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"Column1\\\\\\\": \\\\\\\"{Tab3Percent}\\\\\\\", \\\\\\\"Column2\\\\\\\": \\\\\\\"Percent of successful checks\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"size\": 3,\n \"queryType\": 8,\n \"visualization\": \"tiles\",\n \"tileSettings\": {\n \"titleContent\": {\n \"columnMatch\": \"Column1\",\n \"formatter\": 4,\n \"formatOptions\": {\n \"min\": 0,\n \"max\": 100,\n \"palette\": \"redGreen\"\n },\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n \"subtitleContent\": {\n \"columnMatch\": \"Column2\"\n },\n \"showBorder\": true\n }\n },\n \"customWidth\": \"50\",\n \"name\": \"TabPercentTile\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Azure Bastion in a subnet /26 or larger. Check [this link](https://learn.microsoft.com/azure/bastion/bastion-faq#subnet) for further information.\"\n },\n \"name\": \"querytext12\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query12\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use FQDN-based network rules and Azure Firewall with DNS proxy to filter egress traffic to the Internet over protocols not supported by application rules. Check [this link](https://learn.microsoft.com/azure/firewall/fqdn-filtering-network-rules) for further information.\"\n },\n \"name\": \"querytext13\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query13\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Azure Firewall Premium for additional security and protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information.\"\n },\n \"name\": \"querytext14\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query14\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Configure Azure Firewall Threat Intelligence mode to Alert and Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information.\"\n },\n \"name\": \"querytext15\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query15\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Configure Azure Firewall IDPS mode to Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features#idps) for further information.\"\n },\n \"name\": \"querytext16\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query16\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"For subnets in VNets not connected to Virtual WAN, attach a route table so that Internet traffic is redirected to Azure Firewall or a Network Virtual Appliance. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview) for further information.\"\n },\n \"name\": \"querytext17\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query17\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab3\"\n },\n \"name\": \"tab3\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"parameters\": [\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query4Stats\",\n \"type\": 1,\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query4FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query4Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query5Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query5FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query5Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query6Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query6FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query6Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query7Stats\",\n \"type\": 1,\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query7FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query7Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query8Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query8FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query8Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query9Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation))| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query9FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query9Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab4Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query4Stats:$.Success}+{Query5Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}+{Query9Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab4Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query4Stats:$.Total}+{Query5Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}+{Query9Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab4Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab4Success}/{Tab4Total})\"\n }\n }\n ]\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n \"name\": \"TabInvisibleParameters\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Hybrid\"\n },\n \"customWidth\": \"50\",\n \"name\": \"tab4title\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"Column1\\\\\\\": \\\\\\\"{Tab4Percent}\\\\\\\", \\\\\\\"Column2\\\\\\\": \\\\\\\"Percent of successful checks\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"size\": 3,\n \"queryType\": 8,\n \"visualization\": \"tiles\",\n \"tileSettings\": {\n \"titleContent\": {\n \"columnMatch\": \"Column1\",\n \"formatter\": 4,\n \"formatOptions\": {\n \"min\": 0,\n \"max\": 100,\n \"palette\": \"redGreen\"\n },\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n \"subtitleContent\": {\n \"columnMatch\": \"Column2\"\n },\n \"showBorder\": true\n }\n },\n \"customWidth\": \"50\",\n \"name\": \"TabPercentTile\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure that you're using the right SKU for the ExpressRoute/VPN gateways based on bandwidth and performance requirements. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-routing) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext4\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query4\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure that you're using unlimited-data ExpressRoute circuits only if you reach the bandwidth that justifies their cost. Check [this link](https://learn.microsoft.com/azure/expressroute/plan-manage-cost) for further information.\"\n },\n \"name\": \"querytext5\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query5\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Leverage the Local SKU of ExpressRoute to reduce the cost of your circuits, if your circuits' peering location supports your Azure regions for the Local SKU. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-faqs#expressroute-local) for further information.\"\n },\n \"name\": \"querytext6\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query6\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Deploy a zone-redundant ExpressRoute gateway in the supported Azure regions. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext7\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query7\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use VPN gateways to connect branches or remote locations to Azure. For higher resilience, deploy zone-redundant gateways (where available). Check [this link](https://learn.microsoft.com/azure/vpn-gateway/create-zone-redundant-vnet-gateway) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-vpn-gateway/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext8\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query8\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If you are using a route table in the GatewaySubnet, make sure that gateway routes are propagated. Check [this link](https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings#gwsub) for further information.\"\n },\n \"name\": \"querytext9\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation)) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query9\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab4\"\n },\n \"name\": \"tab4\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"parameters\": [\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query10Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\\\.|172\\\\.(1[6-9]|2[0-9]|3[01])\\\\.|192\\\\.168\\\\.)') | project id, compliant, cidr| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query10FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query10Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query11Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query11FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query11Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab5Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query10Stats:$.Success}+{Query11Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab5Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query10Stats:$.Total}+{Query11Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab5Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab5Success}/{Tab5Total})\"\n }\n }\n ]\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n \"name\": \"TabInvisibleParameters\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## IP plan\"\n },\n \"customWidth\": \"50\",\n \"name\": \"tab5title\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"Column1\\\\\\\": \\\\\\\"{Tab5Percent}\\\\\\\", \\\\\\\"Column2\\\\\\\": \\\\\\\"Percent of successful checks\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"size\": 3,\n \"queryType\": 8,\n \"visualization\": \"tiles\",\n \"tileSettings\": {\n \"titleContent\": {\n \"columnMatch\": \"Column1\",\n \"formatter\": 4,\n \"formatOptions\": {\n \"min\": 0,\n \"max\": 100,\n \"palette\": \"redGreen\"\n },\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n \"subtitleContent\": {\n \"columnMatch\": \"Column2\"\n },\n \"showBorder\": true\n }\n },\n \"customWidth\": \"50\",\n \"name\": \"TabPercentTile\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use IP addresses from the address allocation ranges for private internets (RFC 1918). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext10\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\\\.|172\\\\.(1[6-9]|2[0-9]|3[01])\\\\.|192\\\\.168\\\\.)') | project id, compliant, cidr | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query10\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure that IP address space isn't wasted, don't create unnecessarily large virtual networks (for example /16). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext11\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query11\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab5\"\n },\n \"name\": \"tab5\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"parameters\": [\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query18Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets = properties.subnets | mv-expand subnets | project id = subnets.id, resourceGroup, VNet = name, serviceEndpoints = subnets.properties.serviceEndpoints, compliant = (isnull(subnets.properties.serviceEndpoints) or array_length(subnets.properties.serviceEndpoints) == 0) | order by compliant asc| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query18FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query18Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab6Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query18Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab6Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query18Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab6Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab6Success}/{Tab6Total})\"\n }\n }\n ]\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n \"name\": \"TabInvisibleParameters\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## PaaS\"\n },\n \"customWidth\": \"50\",\n \"name\": \"tab6title\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"Column1\\\\\\\": \\\\\\\"{Tab6Percent}\\\\\\\", \\\\\\\"Column2\\\\\\\": \\\\\\\"Percent of successful checks\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"size\": 3,\n \"queryType\": 8,\n \"visualization\": \"tiles\",\n \"tileSettings\": {\n \"titleContent\": {\n \"columnMatch\": \"Column1\",\n \"formatter\": 4,\n \"formatOptions\": {\n \"min\": 0,\n \"max\": 100,\n \"palette\": \"redGreen\"\n },\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n \"subtitleContent\": {\n \"columnMatch\": \"Column2\"\n },\n \"showBorder\": true\n }\n },\n \"customWidth\": \"50\",\n \"name\": \"TabPercentTile\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Don't enable virtual network service endpoints by default on all subnets. Check [this link](https://learn.microsoft.com/azure/app-service/networking-features) for further information.. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn) can help to educate yourself on this.\"\n },\n \"name\": \"querytext18\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets = properties.subnets | mv-expand subnets | project id = subnets.id, resourceGroup, VNet = name, serviceEndpoints = subnets.properties.serviceEndpoints, compliant = (isnull(subnets.properties.serviceEndpoints) or array_length(subnets.properties.serviceEndpoints) == 0) | order by compliant asc | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query18\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab6\"\n },\n \"name\": \"tab6\"\n }\n ],\n \"$schema\": \"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"\n}", "version": "1.0", "sourceId": "[parameters('workbookSourceId')]", "category": "[parameters('workbookType')]" diff --git a/workbooks/alz_checklist.en_network_workbook.json b/workbooks/alz_checklist.en_network_workbook.json index fc816bf97..cfcf6751b 100644 --- a/workbooks/alz_checklist.en_network_workbook.json +++ b/workbooks/alz_checklist.en_network_workbook.json @@ -70,7 +70,7 @@ "style": "tabs", "links": [ { - "id": "2b07f785-bad6-4756-ac57-eb259363cdec", + "id": "049e3ea0-e2f8-42f8-95a5-dbd14154ec1f", "cellValue": "VisibleTab", "linkTarget": "parameter", "linkLabel": "Hub and spoke", @@ -79,52 +79,52 @@ "style": "primary" }, { - "id": "2b171841-bb94-4bd2-88f8-97d0934c1a19", + "id": "ffd88e33-c3c4-4f70-b18b-dbfcdef2ab4e", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Virtual WAN", + "linkLabel": "Internet", "subTarget": "tab1", - "preText": "Virtual WAN", + "preText": "Internet", "style": "primary" }, { - "id": "9b645c2b-95c5-431f-8db3-54a978d02473", + "id": "5b40515f-2780-49d8-a782-56ab0254b188", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Hybrid", + "linkLabel": "Virtual WAN", "subTarget": "tab2", - "preText": "Hybrid", + "preText": "Virtual WAN", "style": "primary" }, { - "id": "98012932-d716-4c19-b058-3fbd6e9af20e", + "id": "78e14aa3-7b2d-4fd5-85b7-c4493bd9b027", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "PaaS", + "linkLabel": "Segmentation", "subTarget": "tab3", - "preText": "PaaS", + "preText": "Segmentation", "style": "primary" }, { - "id": "35f39d55-34c3-40a7-bee9-f492c58c0960", + "id": "65949e1b-75bf-4105-8c11-97ca5316164e", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Internet", + "linkLabel": "Hybrid", "subTarget": "tab4", - "preText": "Internet", + "preText": "Hybrid", "style": "primary" }, { - "id": "ee7e24fd-7785-413b-a7da-605f2a1ef5ad", + "id": "35576815-b6c5-4d09-96c5-3a4d6a96eba1", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Segmentation", + "linkLabel": "PaaS", "subTarget": "tab5", - "preText": "Segmentation", + "preText": "PaaS", "style": "primary" }, { - "id": "0061c1c2-7992-4dfe-9ca1-515b75a172b8", + "id": "00c76246-584f-4067-834c-88ad8ecd06e3", "cellValue": "VisibleTab", "linkTarget": "parameter", "linkLabel": "IP plan", @@ -415,22 +415,22 @@ { "type": 1, "content": { - "json": "## Virtual WAN" + "json": "## Internet" }, "name": "tab1title" }, { "type": 1, "content": { - "json": "For outbound Internet traffic protection and filtering, deploy Azure Firewall in secured hubs. Check [this link](https://learn.microsoft.com/azure/virtual-wan/virtual-wan-about) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/) can help to educate yourself on this." + "json": "Use Azure Bastion in a subnet /26 or larger. Check [this link](https://learn.microsoft.com/azure/bastion/bastion-faq#subnet) for further information." }, - "name": "querytext23" + "name": "querytext12" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualhubs' | extend compliant = isnotnull(properties.azureFirewall.id) | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -479,42 +479,20 @@ ] } }, - "name": "query23" - } - ] - }, - "conditionalVisibility": { - "parameterName": "VisibleTab", - "comparison": "isEqualTo", - "value": "tab1" - }, - "name": "tab1" - }, - { - "type": 12, - "content": { - "version": "NotebookGroup/1.0", - "groupType": "editable", - "items": [ - { - "type": 1, - "content": { - "json": "## Hybrid" - }, - "name": "tab2title" + "name": "query12" }, { "type": 1, "content": { - "json": "Ensure that you're using the right SKU for the ExpressRoute/VPN gateways based on bandwidth and performance requirements. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-routing) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this." + "json": "Use FQDN-based network rules and Azure Firewall with DNS proxy to filter egress traffic to the Internet over protocols not supported by application rules. Check [this link](https://learn.microsoft.com/azure/firewall/fqdn-filtering-network-rules) for further information." }, - "name": "querytext4" + "name": "querytext13" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -563,20 +541,20 @@ ] } }, - "name": "query4" + "name": "query13" }, { "type": 1, "content": { - "json": "Ensure that you're using unlimited-data ExpressRoute circuits only if you reach the bandwidth that justifies their cost. Check [this link](https://learn.microsoft.com/azure/expressroute/plan-manage-cost) for further information." + "json": "Use Azure Firewall Premium for additional security and protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information." }, - "name": "querytext5" + "name": "querytext14" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -625,20 +603,20 @@ ] } }, - "name": "query5" + "name": "query14" }, { "type": 1, "content": { - "json": "Leverage the Local SKU of ExpressRoute to reduce the cost of your circuits, if your circuits' peering location supports your Azure regions for the Local SKU. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-faqs#expressroute-local) for further information." + "json": "Configure Azure Firewall Threat Intelligence mode to Alert and Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information." }, - "name": "querytext6" + "name": "querytext15" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -687,20 +665,20 @@ ] } }, - "name": "query6" + "name": "query15" }, { "type": 1, "content": { - "json": "Deploy a zone-redundant ExpressRoute gateway in the supported Azure regions. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this." + "json": "Configure Azure Firewall IDPS mode to Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features#idps) for further information." }, - "name": "querytext7" + "name": "querytext16" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -749,20 +727,20 @@ ] } }, - "name": "query7" + "name": "query16" }, { "type": 1, "content": { - "json": "Use VPN gateways to connect branches or remote locations to Azure. For higher resilience, deploy zone-redundant gateways (where available). Check [this link](https://learn.microsoft.com/azure/vpn-gateway/create-zone-redundant-vnet-gateway) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-vpn-gateway/) can help to educate yourself on this." + "json": "For subnets in VNets not connected to Virtual WAN, attach a route table so that Internet traffic is redirected to Azure Firewall or a Network Virtual Appliance. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview) for further information." }, - "name": "querytext8" + "name": "querytext17" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -811,20 +789,42 @@ ] } }, - "name": "query8" + "name": "query17" + } + ] + }, + "conditionalVisibility": { + "parameterName": "VisibleTab", + "comparison": "isEqualTo", + "value": "tab1" + }, + "name": "tab1" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## Virtual WAN" + }, + "name": "tab2title" }, { "type": 1, "content": { - "json": "If you are using a route table in the GatewaySubnet, make sure that gateway routes are propagated. Check [this link](https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings#gwsub) for further information." + "json": "For outbound Internet traffic protection and filtering, deploy Azure Firewall in secured hubs. Check [this link](https://learn.microsoft.com/azure/virtual-wan/virtual-wan-about) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/) can help to educate yourself on this." }, - "name": "querytext9" + "name": "querytext23" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation)) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualhubs' | extend compliant = isnotnull(properties.azureFirewall.id) | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -873,7 +873,7 @@ ] } }, - "name": "query9" + "name": "query23" } ] }, @@ -893,22 +893,22 @@ { "type": 1, "content": { - "json": "## PaaS" + "json": "## Segmentation" }, "name": "tab3title" }, { "type": 1, "content": { - "json": "Don't enable virtual network service endpoints by default on all subnets. Check [this link](https://learn.microsoft.com/azure/app-service/networking-features) for further information.. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn) can help to educate yourself on this." + "json": "Use a /26 prefix for your Azure Firewall subnets. Check [this link](https://learn.microsoft.com/azure/firewall/firewall-faq#why-does-azure-firewall-need-a--26-subnet-size) for further information." }, - "name": "querytext18" + "name": "querytext19" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type =~ 'microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets = properties.subnets | mv-expand subnets | project id = subnets.id, resourceGroup, VNet = name, serviceEndpoints = subnets.properties.serviceEndpoints, compliant = (isnull(subnets.properties.serviceEndpoints) or array_length(subnets.properties.serviceEndpoints) == 0) | order by compliant asc | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -957,42 +957,20 @@ ] } }, - "name": "query18" - } - ] - }, - "conditionalVisibility": { - "parameterName": "VisibleTab", - "comparison": "isEqualTo", - "value": "tab3" - }, - "name": "tab3" - }, - { - "type": 12, - "content": { - "version": "NotebookGroup/1.0", - "groupType": "editable", - "items": [ - { - "type": 1, - "content": { - "json": "## Internet" - }, - "name": "tab4title" + "name": "query19" }, { "type": 1, "content": { - "json": "Use Azure Bastion in a subnet /26 or larger. Check [this link](https://learn.microsoft.com/azure/bastion/bastion-faq#subnet) for further information." + "json": "Use at least a /27 prefix for your Gateway subnets. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-howto-add-gateway-resource-manager#add-a-gateway) for further information." }, - "name": "querytext12" + "name": "querytext20" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1041,20 +1019,20 @@ ] } }, - "name": "query12" + "name": "query20" }, { "type": 1, "content": { - "json": "Use FQDN-based network rules and Azure Firewall with DNS proxy to filter egress traffic to the Internet over protocols not supported by application rules. Check [this link](https://learn.microsoft.com/azure/firewall/fqdn-filtering-network-rules) for further information." + "json": "Don't rely on the NSG inbound default rules using the VirtualNetwork service tag to limit connectivity. Check [this link](https://learn.microsoft.com/azure/virtual-network/service-tags-overview#available-service-tags) for further information." }, - "name": "querytext13" + "name": "querytext21" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1103,20 +1081,20 @@ ] } }, - "name": "query13" + "name": "query21" }, { "type": 1, "content": { - "json": "Use Azure Firewall Premium for additional security and protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information." + "json": "The application team should use application security groups at the subnet-level NSGs to help protect multi-tier VMs within the landing zone. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/) can help to educate yourself on this." }, - "name": "querytext14" + "name": "querytext22" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "Resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetName=subnets.name,subnetNsg=subnets.properties.networkSecurityGroup | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend compliant = isnotnull(subnetNsg) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1165,20 +1143,42 @@ ] } }, - "name": "query14" + "name": "query22" + } + ] + }, + "conditionalVisibility": { + "parameterName": "VisibleTab", + "comparison": "isEqualTo", + "value": "tab3" + }, + "name": "tab3" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## Hybrid" + }, + "name": "tab4title" }, { "type": 1, "content": { - "json": "Configure Azure Firewall Threat Intelligence mode to Alert and Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information." + "json": "Ensure that you're using the right SKU for the ExpressRoute/VPN gateways based on bandwidth and performance requirements. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-routing) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this." }, - "name": "querytext15" + "name": "querytext4" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1227,20 +1227,20 @@ ] } }, - "name": "query15" + "name": "query4" }, { "type": 1, "content": { - "json": "Configure Azure Firewall IDPS mode to Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features#idps) for further information." + "json": "Ensure that you're using unlimited-data ExpressRoute circuits only if you reach the bandwidth that justifies their cost. Check [this link](https://learn.microsoft.com/azure/expressroute/plan-manage-cost) for further information." }, - "name": "querytext16" + "name": "querytext5" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1289,20 +1289,20 @@ ] } }, - "name": "query16" + "name": "query5" }, { "type": 1, "content": { - "json": "For subnets in VNets not connected to Virtual WAN, attach a route table so that Internet traffic is redirected to Azure Firewall or a Network Virtual Appliance. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview) for further information." + "json": "Leverage the Local SKU of ExpressRoute to reduce the cost of your circuits, if your circuits' peering location supports your Azure regions for the Local SKU. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-faqs#expressroute-local) for further information." }, - "name": "querytext17" + "name": "querytext6" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1351,42 +1351,20 @@ ] } }, - "name": "query17" - } - ] - }, - "conditionalVisibility": { - "parameterName": "VisibleTab", - "comparison": "isEqualTo", - "value": "tab4" - }, - "name": "tab4" - }, - { - "type": 12, - "content": { - "version": "NotebookGroup/1.0", - "groupType": "editable", - "items": [ - { - "type": 1, - "content": { - "json": "## Segmentation" - }, - "name": "tab5title" + "name": "query6" }, { "type": 1, "content": { - "json": "Use a /26 prefix for your Azure Firewall subnets. Check [this link](https://learn.microsoft.com/azure/firewall/firewall-faq#why-does-azure-firewall-need-a--26-subnet-size) for further information." + "json": "Deploy a zone-redundant ExpressRoute gateway in the supported Azure regions. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this." }, - "name": "querytext19" + "name": "querytext7" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1435,20 +1413,20 @@ ] } }, - "name": "query19" + "name": "query7" }, { "type": 1, "content": { - "json": "Use at least a /27 prefix for your Gateway subnets. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-howto-add-gateway-resource-manager#add-a-gateway) for further information." + "json": "Use VPN gateways to connect branches or remote locations to Azure. For higher resilience, deploy zone-redundant gateways (where available). Check [this link](https://learn.microsoft.com/azure/vpn-gateway/create-zone-redundant-vnet-gateway) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-vpn-gateway/) can help to educate yourself on this." }, - "name": "querytext20" + "name": "querytext8" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1497,20 +1475,20 @@ ] } }, - "name": "query20" + "name": "query8" }, { "type": 1, "content": { - "json": "Don't rely on the NSG inbound default rules using the VirtualNetwork service tag to limit connectivity. Check [this link](https://learn.microsoft.com/azure/virtual-network/service-tags-overview#available-service-tags) for further information." + "json": "If you are using a route table in the GatewaySubnet, make sure that gateway routes are propagated. Check [this link](https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings#gwsub) for further information." }, - "name": "querytext21" + "name": "querytext9" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation)) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1559,20 +1537,42 @@ ] } }, - "name": "query21" + "name": "query9" + } + ] + }, + "conditionalVisibility": { + "parameterName": "VisibleTab", + "comparison": "isEqualTo", + "value": "tab4" + }, + "name": "tab4" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## PaaS" + }, + "name": "tab5title" }, { "type": 1, "content": { - "json": "The application team should use application security groups at the subnet-level NSGs to help protect multi-tier VMs within the landing zone. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/) can help to educate yourself on this." + "json": "Don't enable virtual network service endpoints by default on all subnets. Check [this link](https://learn.microsoft.com/azure/app-service/networking-features) for further information.. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn) can help to educate yourself on this." }, - "name": "querytext22" + "name": "querytext18" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "Resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetName=subnets.name,subnetNsg=subnets.properties.networkSecurityGroup | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend compliant = isnotnull(subnetNsg) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type =~ 'microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets = properties.subnets | mv-expand subnets | project id = subnets.id, resourceGroup, VNet = name, serviceEndpoints = subnets.properties.serviceEndpoints, compliant = (isnull(subnets.properties.serviceEndpoints) or array_length(subnets.properties.serviceEndpoints) == 0) | order by compliant asc | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1621,7 +1621,7 @@ ] } }, - "name": "query22" + "name": "query18" } ] }, diff --git a/workbooks/alz_checklist.en_network_workbook_template.json b/workbooks/alz_checklist.en_network_workbook_template.json index 3bd67cac3..ce9a9ed62 100644 --- a/workbooks/alz_checklist.en_network_workbook_template.json +++ b/workbooks/alz_checklist.en_network_workbook_template.json @@ -41,7 +41,7 @@ "dependsOn": [], "properties": { "displayName": "[parameters('workbookDisplayName')]", - "serializedData": "{\n \"version\": \"Notebook/1.0\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"parameters\": [\n {\n \"id\": \"497a107e-dde8-433e-b263-35ac8e8f7834\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Subscription\",\n \"type\": 6,\n \"multiSelect\": true,\n \"quote\": \"'\",\n \"delimiter\": \",\",\n \"typeSettings\": {\n \"additionalResourceOptions\": [\n \"value::all\"\n ],\n \"includeAll\": true,\n \"showDefault\": false\n },\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"value\": [\n \"value::all\"\n ]\n },\n {\n \"id\": \"844e4f4e-df51-4e3c-8eaf-0dc78b92c721\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"OnlyFailed\",\n \"label\": \"Only show failed\",\n \"type\": 2,\n \"typeSettings\": {\n \"additionalResourceOptions\": [],\n \"showDefault\": false\n },\n \"jsonData\": \"[\\r\\n { \\\"value\\\":true, \\\"label\\\":\\\"True\\\" },\\r\\n { \\\"value\\\":false, \\\"label\\\":\\\"False\\\", \\\"selected\\\":true }\\r\\n]\"\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 0,\n \"resourceType\": \"microsoft.operationalinsights/workspaces\"\n },\n \"name\": \"WorkbookSelectors\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If you set \\\"Only show failed\\\" to \\\"Yes\\\", the different queries will only show items that have failed their compliance checks.\",\n \"style\": \"info\"\n },\n \"name\": \"InfoBox\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Azure Landing Zone Review - Network\\n\\n---\\n\\nThis workbook has been automatically generated out of the checklists in the [Azure Review Checklists repo](https://github.com/Azure/review-checklists). This repo contains best practices and recommendations around generic Landing Zones as well as specific services such as Azure Virtual Desktop, Azure Kubernetes Service or Azure VMware Solution, to name a few. This repository of best practices is curated by Azure engineers, but open to anybody to contribute.\\n\\nIf you see a problem in the queries that are part of this workbook, please open a Github issue [here](https://github.com/Azure/review-checklists/issues/new).\"\n },\n \"customWidth\": \"100\",\n \"name\": \"MarkdownHeader\"\n },\n {\n \"type\": 11,\n \"content\": {\n \"version\": \"LinkItem/1.0\",\n \"style\": \"tabs\",\n \"links\": [\n {\n \"id\": \"2b07f785-bad6-4756-ac57-eb259363cdec\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Hub and spoke\",\n \"subTarget\": \"tab0\",\n \"preText\": \"Hub and spoke\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"2b171841-bb94-4bd2-88f8-97d0934c1a19\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Virtual WAN\",\n \"subTarget\": \"tab1\",\n \"preText\": \"Virtual WAN\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"9b645c2b-95c5-431f-8db3-54a978d02473\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Hybrid\",\n \"subTarget\": \"tab2\",\n \"preText\": \"Hybrid\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"98012932-d716-4c19-b058-3fbd6e9af20e\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"PaaS\",\n \"subTarget\": \"tab3\",\n \"preText\": \"PaaS\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"35f39d55-34c3-40a7-bee9-f492c58c0960\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Internet\",\n \"subTarget\": \"tab4\",\n \"preText\": \"Internet\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"ee7e24fd-7785-413b-a7da-605f2a1ef5ad\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Segmentation\",\n \"subTarget\": \"tab5\",\n \"preText\": \"Segmentation\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"0061c1c2-7992-4dfe-9ca1-515b75a172b8\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"IP plan\",\n \"subTarget\": \"tab6\",\n \"preText\": \"IP plan\",\n \"style\": \"primary\"\n }\n ]\n },\n \"name\": \"Tabs\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Hub and spoke\"\n },\n \"name\": \"tab0title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If using Route Server, use a /27 prefix for the Route Server subnet. Check [this link](https://learn.microsoft.com/azure/route-server/quickstart-configure-route-server-portal#create-a-route-server-1) for further information.\"\n },\n \"name\": \"querytext0\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query0\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"When connecting spoke virtual networks to the central hub virtual network, consider VNet peering limits (500), the maximum number of prefixes that can be advertised via ExpressRoute (1000). Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information.\"\n },\n \"name\": \"querytext1\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query1\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Consider the limit of routes per route table (400). Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information.\"\n },\n \"name\": \"querytext2\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query2\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use the setting 'Allow traffic to remote virtual network' when configuring VNet peerings. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-network-manage-peering) for further information.\"\n },\n \"name\": \"querytext3\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query3\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab0\"\n },\n \"name\": \"tab0\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Virtual WAN\"\n },\n \"name\": \"tab1title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"For outbound Internet traffic protection and filtering, deploy Azure Firewall in secured hubs. Check [this link](https://learn.microsoft.com/azure/virtual-wan/virtual-wan-about) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext23\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualhubs' | extend compliant = isnotnull(properties.azureFirewall.id) | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query23\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab1\"\n },\n \"name\": \"tab1\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Hybrid\"\n },\n \"name\": \"tab2title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure that you're using the right SKU for the ExpressRoute/VPN gateways based on bandwidth and performance requirements. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-routing) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext4\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query4\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure that you're using unlimited-data ExpressRoute circuits only if you reach the bandwidth that justifies their cost. Check [this link](https://learn.microsoft.com/azure/expressroute/plan-manage-cost) for further information.\"\n },\n \"name\": \"querytext5\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query5\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Leverage the Local SKU of ExpressRoute to reduce the cost of your circuits, if your circuits' peering location supports your Azure regions for the Local SKU. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-faqs#expressroute-local) for further information.\"\n },\n \"name\": \"querytext6\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query6\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Deploy a zone-redundant ExpressRoute gateway in the supported Azure regions. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext7\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query7\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use VPN gateways to connect branches or remote locations to Azure. For higher resilience, deploy zone-redundant gateways (where available). Check [this link](https://learn.microsoft.com/azure/vpn-gateway/create-zone-redundant-vnet-gateway) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-vpn-gateway/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext8\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query8\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If you are using a route table in the GatewaySubnet, make sure that gateway routes are propagated. Check [this link](https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings#gwsub) for further information.\"\n },\n \"name\": \"querytext9\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation)) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query9\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab2\"\n },\n \"name\": \"tab2\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## PaaS\"\n },\n \"name\": \"tab3title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Don't enable virtual network service endpoints by default on all subnets. Check [this link](https://learn.microsoft.com/azure/app-service/networking-features) for further information.. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn) can help to educate yourself on this.\"\n },\n \"name\": \"querytext18\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets = properties.subnets | mv-expand subnets | project id = subnets.id, resourceGroup, VNet = name, serviceEndpoints = subnets.properties.serviceEndpoints, compliant = (isnull(subnets.properties.serviceEndpoints) or array_length(subnets.properties.serviceEndpoints) == 0) | order by compliant asc | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query18\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab3\"\n },\n \"name\": \"tab3\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Internet\"\n },\n \"name\": \"tab4title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Azure Bastion in a subnet /26 or larger. Check [this link](https://learn.microsoft.com/azure/bastion/bastion-faq#subnet) for further information.\"\n },\n \"name\": \"querytext12\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query12\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use FQDN-based network rules and Azure Firewall with DNS proxy to filter egress traffic to the Internet over protocols not supported by application rules. Check [this link](https://learn.microsoft.com/azure/firewall/fqdn-filtering-network-rules) for further information.\"\n },\n \"name\": \"querytext13\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query13\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Azure Firewall Premium for additional security and protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information.\"\n },\n \"name\": \"querytext14\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query14\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Configure Azure Firewall Threat Intelligence mode to Alert and Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information.\"\n },\n \"name\": \"querytext15\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query15\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Configure Azure Firewall IDPS mode to Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features#idps) for further information.\"\n },\n \"name\": \"querytext16\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query16\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"For subnets in VNets not connected to Virtual WAN, attach a route table so that Internet traffic is redirected to Azure Firewall or a Network Virtual Appliance. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview) for further information.\"\n },\n \"name\": \"querytext17\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query17\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab4\"\n },\n \"name\": \"tab4\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Segmentation\"\n },\n \"name\": \"tab5title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use a /26 prefix for your Azure Firewall subnets. Check [this link](https://learn.microsoft.com/azure/firewall/firewall-faq#why-does-azure-firewall-need-a--26-subnet-size) for further information.\"\n },\n \"name\": \"querytext19\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query19\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use at least a /27 prefix for your Gateway subnets. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-howto-add-gateway-resource-manager#add-a-gateway) for further information.\"\n },\n \"name\": \"querytext20\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query20\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Don't rely on the NSG inbound default rules using the VirtualNetwork service tag to limit connectivity. Check [this link](https://learn.microsoft.com/azure/virtual-network/service-tags-overview#available-service-tags) for further information.\"\n },\n \"name\": \"querytext21\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query21\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"The application team should use application security groups at the subnet-level NSGs to help protect multi-tier VMs within the landing zone. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext22\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"Resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetName=subnets.name,subnetNsg=subnets.properties.networkSecurityGroup | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend compliant = isnotnull(subnetNsg) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query22\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab5\"\n },\n \"name\": \"tab5\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## IP plan\"\n },\n \"name\": \"tab6title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use IP addresses from the address allocation ranges for private internets (RFC 1918). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext10\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\\\.|172\\\\.(1[6-9]|2[0-9]|3[01])\\\\.|192\\\\.168\\\\.)') | project id, compliant, cidr | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query10\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure that IP address space isn't wasted, don't create unnecessarily large virtual networks (for example /16). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext11\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query11\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab6\"\n },\n \"name\": \"tab6\"\n }\n ],\n \"$schema\": \"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"\n}", + "serializedData": "{\n \"version\": \"Notebook/1.0\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"parameters\": [\n {\n \"id\": \"497a107e-dde8-433e-b263-35ac8e8f7834\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Subscription\",\n \"type\": 6,\n \"multiSelect\": true,\n \"quote\": \"'\",\n \"delimiter\": \",\",\n \"typeSettings\": {\n \"additionalResourceOptions\": [\n \"value::all\"\n ],\n \"includeAll\": true,\n \"showDefault\": false\n },\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"value\": [\n \"value::all\"\n ]\n },\n {\n \"id\": \"844e4f4e-df51-4e3c-8eaf-0dc78b92c721\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"OnlyFailed\",\n \"label\": \"Only show failed\",\n \"type\": 2,\n \"typeSettings\": {\n \"additionalResourceOptions\": [],\n \"showDefault\": false\n },\n \"jsonData\": \"[\\r\\n { \\\"value\\\":true, \\\"label\\\":\\\"True\\\" },\\r\\n { \\\"value\\\":false, \\\"label\\\":\\\"False\\\", \\\"selected\\\":true }\\r\\n]\"\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 0,\n \"resourceType\": \"microsoft.operationalinsights/workspaces\"\n },\n \"name\": \"WorkbookSelectors\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If you set \\\"Only show failed\\\" to \\\"Yes\\\", the different queries will only show items that have failed their compliance checks.\",\n \"style\": \"info\"\n },\n \"name\": \"InfoBox\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Azure Landing Zone Review - Network\\n\\n---\\n\\nThis workbook has been automatically generated out of the checklists in the [Azure Review Checklists repo](https://github.com/Azure/review-checklists). This repo contains best practices and recommendations around generic Landing Zones as well as specific services such as Azure Virtual Desktop, Azure Kubernetes Service or Azure VMware Solution, to name a few. This repository of best practices is curated by Azure engineers, but open to anybody to contribute.\\n\\nIf you see a problem in the queries that are part of this workbook, please open a Github issue [here](https://github.com/Azure/review-checklists/issues/new).\"\n },\n \"customWidth\": \"100\",\n \"name\": \"MarkdownHeader\"\n },\n {\n \"type\": 11,\n \"content\": {\n \"version\": \"LinkItem/1.0\",\n \"style\": \"tabs\",\n \"links\": [\n {\n \"id\": \"049e3ea0-e2f8-42f8-95a5-dbd14154ec1f\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Hub and spoke\",\n \"subTarget\": \"tab0\",\n \"preText\": \"Hub and spoke\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"ffd88e33-c3c4-4f70-b18b-dbfcdef2ab4e\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Internet\",\n \"subTarget\": \"tab1\",\n \"preText\": \"Internet\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"5b40515f-2780-49d8-a782-56ab0254b188\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Virtual WAN\",\n \"subTarget\": \"tab2\",\n \"preText\": \"Virtual WAN\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"78e14aa3-7b2d-4fd5-85b7-c4493bd9b027\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Segmentation\",\n \"subTarget\": \"tab3\",\n \"preText\": \"Segmentation\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"65949e1b-75bf-4105-8c11-97ca5316164e\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Hybrid\",\n \"subTarget\": \"tab4\",\n \"preText\": \"Hybrid\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"35576815-b6c5-4d09-96c5-3a4d6a96eba1\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"PaaS\",\n \"subTarget\": \"tab5\",\n \"preText\": \"PaaS\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"00c76246-584f-4067-834c-88ad8ecd06e3\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"IP plan\",\n \"subTarget\": \"tab6\",\n \"preText\": \"IP plan\",\n \"style\": \"primary\"\n }\n ]\n },\n \"name\": \"Tabs\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Hub and spoke\"\n },\n \"name\": \"tab0title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If using Route Server, use a /27 prefix for the Route Server subnet. Check [this link](https://learn.microsoft.com/azure/route-server/quickstart-configure-route-server-portal#create-a-route-server-1) for further information.\"\n },\n \"name\": \"querytext0\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query0\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"When connecting spoke virtual networks to the central hub virtual network, consider VNet peering limits (500), the maximum number of prefixes that can be advertised via ExpressRoute (1000). Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information.\"\n },\n \"name\": \"querytext1\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query1\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Consider the limit of routes per route table (400). Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information.\"\n },\n \"name\": \"querytext2\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query2\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use the setting 'Allow traffic to remote virtual network' when configuring VNet peerings. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-network-manage-peering) for further information.\"\n },\n \"name\": \"querytext3\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query3\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab0\"\n },\n \"name\": \"tab0\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Internet\"\n },\n \"name\": \"tab1title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Azure Bastion in a subnet /26 or larger. Check [this link](https://learn.microsoft.com/azure/bastion/bastion-faq#subnet) for further information.\"\n },\n \"name\": \"querytext12\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query12\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use FQDN-based network rules and Azure Firewall with DNS proxy to filter egress traffic to the Internet over protocols not supported by application rules. Check [this link](https://learn.microsoft.com/azure/firewall/fqdn-filtering-network-rules) for further information.\"\n },\n \"name\": \"querytext13\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query13\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Azure Firewall Premium for additional security and protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information.\"\n },\n \"name\": \"querytext14\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query14\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Configure Azure Firewall Threat Intelligence mode to Alert and Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information.\"\n },\n \"name\": \"querytext15\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query15\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Configure Azure Firewall IDPS mode to Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features#idps) for further information.\"\n },\n \"name\": \"querytext16\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query16\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"For subnets in VNets not connected to Virtual WAN, attach a route table so that Internet traffic is redirected to Azure Firewall or a Network Virtual Appliance. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview) for further information.\"\n },\n \"name\": \"querytext17\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query17\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab1\"\n },\n \"name\": \"tab1\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Virtual WAN\"\n },\n \"name\": \"tab2title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"For outbound Internet traffic protection and filtering, deploy Azure Firewall in secured hubs. Check [this link](https://learn.microsoft.com/azure/virtual-wan/virtual-wan-about) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext23\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualhubs' | extend compliant = isnotnull(properties.azureFirewall.id) | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query23\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab2\"\n },\n \"name\": \"tab2\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Segmentation\"\n },\n \"name\": \"tab3title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use a /26 prefix for your Azure Firewall subnets. Check [this link](https://learn.microsoft.com/azure/firewall/firewall-faq#why-does-azure-firewall-need-a--26-subnet-size) for further information.\"\n },\n \"name\": \"querytext19\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query19\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use at least a /27 prefix for your Gateway subnets. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-howto-add-gateway-resource-manager#add-a-gateway) for further information.\"\n },\n \"name\": \"querytext20\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query20\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Don't rely on the NSG inbound default rules using the VirtualNetwork service tag to limit connectivity. Check [this link](https://learn.microsoft.com/azure/virtual-network/service-tags-overview#available-service-tags) for further information.\"\n },\n \"name\": \"querytext21\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query21\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"The application team should use application security groups at the subnet-level NSGs to help protect multi-tier VMs within the landing zone. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext22\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"Resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetName=subnets.name,subnetNsg=subnets.properties.networkSecurityGroup | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend compliant = isnotnull(subnetNsg) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query22\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab3\"\n },\n \"name\": \"tab3\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Hybrid\"\n },\n \"name\": \"tab4title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure that you're using the right SKU for the ExpressRoute/VPN gateways based on bandwidth and performance requirements. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-routing) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext4\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query4\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure that you're using unlimited-data ExpressRoute circuits only if you reach the bandwidth that justifies their cost. Check [this link](https://learn.microsoft.com/azure/expressroute/plan-manage-cost) for further information.\"\n },\n \"name\": \"querytext5\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query5\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Leverage the Local SKU of ExpressRoute to reduce the cost of your circuits, if your circuits' peering location supports your Azure regions for the Local SKU. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-faqs#expressroute-local) for further information.\"\n },\n \"name\": \"querytext6\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query6\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Deploy a zone-redundant ExpressRoute gateway in the supported Azure regions. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext7\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query7\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use VPN gateways to connect branches or remote locations to Azure. For higher resilience, deploy zone-redundant gateways (where available). Check [this link](https://learn.microsoft.com/azure/vpn-gateway/create-zone-redundant-vnet-gateway) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-vpn-gateway/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext8\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query8\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If you are using a route table in the GatewaySubnet, make sure that gateway routes are propagated. Check [this link](https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings#gwsub) for further information.\"\n },\n \"name\": \"querytext9\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation)) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query9\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab4\"\n },\n \"name\": \"tab4\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## PaaS\"\n },\n \"name\": \"tab5title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Don't enable virtual network service endpoints by default on all subnets. Check [this link](https://learn.microsoft.com/azure/app-service/networking-features) for further information.. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn) can help to educate yourself on this.\"\n },\n \"name\": \"querytext18\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets = properties.subnets | mv-expand subnets | project id = subnets.id, resourceGroup, VNet = name, serviceEndpoints = subnets.properties.serviceEndpoints, compliant = (isnull(subnets.properties.serviceEndpoints) or array_length(subnets.properties.serviceEndpoints) == 0) | order by compliant asc | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query18\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab5\"\n },\n \"name\": \"tab5\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## IP plan\"\n },\n \"name\": \"tab6title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use IP addresses from the address allocation ranges for private internets (RFC 1918). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext10\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\\\.|172\\\\.(1[6-9]|2[0-9]|3[01])\\\\.|192\\\\.168\\\\.)') | project id, compliant, cidr | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query10\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure that IP address space isn't wasted, don't create unnecessarily large virtual networks (for example /16). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext11\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query11\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab6\"\n },\n \"name\": \"tab6\"\n }\n ],\n \"$schema\": \"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"\n}", "version": "1.0", "sourceId": "[parameters('workbookSourceId')]", "category": "[parameters('workbookType')]"