diff --git a/checklists/alz_checklist.en.json b/checklists/alz_checklist.en.json index 08b5a1653..eb89c2cf8 100644 --- a/checklists/alz_checklist.en.json +++ b/checklists/alz_checklist.en.json @@ -1400,7 +1400,6 @@ "severity": "High", "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-faq#what-is-the-recommended-hub-address-space-during-hub-creation" }, - { "category": "Governance", "subcategory": "Governance", @@ -2337,6 +2336,6 @@ "metadata": { "name": "Azure Landing Zone Review", "state": "GA", - "timestamp": "September 28, 2023" + "timestamp": "November 06, 2023" } } \ No newline at end of file diff --git a/checklists/alz_checklist.es.json b/checklists/alz_checklist.es.json index aa9861064..4fdd40c58 100644 --- a/checklists/alz_checklist.es.json +++ b/checklists/alz_checklist.es.json @@ -1,7 +1,7 @@ { "categories": [ { - "name": "Inquilinos de Azure Billing y Microsoft Entra ID" + "name": "Inquilinos de Facturación de Azure y de Id. de Microsoft Entra" }, { "name": "Gestión de identidades y accesos" @@ -27,57 +27,57 @@ ], "items": [ { - "category": "Inquilinos de Azure Billing y Microsoft Entra ID", + "category": "Inquilinos de Facturación de Azure y de Id. de Microsoft Entra", "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", "severity": "Medio", "subcategory": "Inquilinos de Microsoft Entra ID", - "text": "Use un inquilino de Entra para administrar los recursos de Azure, a menos que tenga un requisito normativo o empresarial claro para los multiinquilinos.", + "text": "Use un inquilino de Entra para administrar los recursos de Azure, a menos que tenga un requisito normativo o empresarial claro para varios inquilinos.", "waf": "Operaciones" }, { - "category": "Inquilinos de Azure Billing y Microsoft Entra ID", + "category": "Inquilinos de Facturación de Azure y de Id. de Microsoft Entra", "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", "severity": "Bajo", "subcategory": "Inquilinos de Microsoft Entra ID", - "text": "Asegúrese de tener un enfoque de automatización multiinquilino para administrar sus inquilinos de Microsoft Entra ID", + "text": "Asegúrese de que tiene un enfoque de automatización multiinquilino para administrar los inquilinos de Microsoft Entra ID", "waf": "Operaciones" }, { - "category": "Inquilinos de Azure Billing y Microsoft Entra ID", + "category": "Inquilinos de Facturación de Azure y de Id. de Microsoft Entra", "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", "severity": "Bajo", "subcategory": "Inquilinos de Microsoft Entra ID", - "text": "Aproveche Azure Lighthouse para la administración de varios inquilinos", + "text": "Aprovechamiento de Azure Lighthouse para la administración multiinquilino", "waf": "Operaciones" }, { - "category": "Inquilinos de Azure Billing y Microsoft Entra ID", + "category": "Inquilinos de Facturación de Azure y de Id. de Microsoft Entra", "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", "severity": "Medio", "subcategory": "Proveedor de soluciones en la nube", - "text": "Asegúrese de que Azure Lighthouse se usa para administrar el inquilino por asociado", + "text": "Asegúrese de que el asociado usa Azure Lighthouse para administrar el inquilino", "waf": "Costar" }, { - "category": "Inquilinos de Azure Billing y Microsoft Entra ID", + "category": "Inquilinos de Facturación de Azure y de Id. de Microsoft Entra", "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", "severity": "Bajo", "subcategory": "Proveedor de soluciones en la nube", - "text": "Discutir la solicitud de soporte y el proceso de escalamiento con el socio de CSP", + "text": "Analizar la solicitud de soporte técnico y el proceso de escalamiento con el socio de CSP", "waf": "Costar" }, { - "category": "Inquilinos de Azure Billing y Microsoft Entra ID", + "category": "Inquilinos de Facturación de Azure y de Id. de Microsoft Entra", "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", @@ -87,7 +87,7 @@ "waf": "Costar" }, { - "category": "Inquilinos de Azure Billing y Microsoft Entra ID", + "category": "Inquilinos de Facturación de Azure y de Id. de Microsoft Entra", "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", @@ -97,7 +97,7 @@ "waf": "Costar" }, { - "category": "Inquilinos de Azure Billing y Microsoft Entra ID", + "category": "Inquilinos de Facturación de Azure y de Id. de Microsoft Entra", "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", @@ -108,7 +108,7 @@ }, { "ammp": true, - "category": "Inquilinos de Azure Billing y Microsoft Entra ID", + "category": "Inquilinos de Facturación de Azure y de Id. de Microsoft Entra", "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", @@ -118,17 +118,17 @@ "waf": "Seguridad" }, { - "category": "Inquilinos de Azure Billing y Microsoft Entra ID", + "category": "Inquilinos de Facturación de Azure y de Id. de Microsoft Entra", "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", "severity": "Medio", "subcategory": "Contrato Enterprise", - "text": "Habilite tanto los cargos de vista de DA como los cargos de vista de AO en sus inscripciones de EA para permitir que los usuarios con las permanentes correctas revisen los datos de costo y facturación.", + "text": "Habilite los cargos de visualización de DA y los cargos de vista de AO en sus inscripciones de EA para permitir que los usuarios con las permanentes correctas revisen los datos de costos y facturación.", "waf": "Seguridad" }, { - "category": "Inquilinos de Azure Billing y Microsoft Entra ID", + "category": "Inquilinos de Facturación de Azure y de Id. de Microsoft Entra", "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", @@ -138,53 +138,53 @@ "waf": "Costar" }, { - "category": "Inquilinos de Azure Billing y Microsoft Entra ID", + "category": "Inquilinos de Facturación de Azure y de Id. de Microsoft Entra", "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", "severity": "Medio", "subcategory": "Contrato Enterprise", - "text": "Audite periódicamente las asignaciones de roles para revisar quién tiene acceso a su inscripción en el Contrato Enterprise", + "text": "Audite periódicamente las asignaciones de roles para revisar quién tiene acceso a la inscripción del Contrato Enterprise", "waf": "Costar" }, { - "category": "Inquilinos de Azure Billing y Microsoft Entra ID", + "category": "Inquilinos de Facturación de Azure y de Id. de Microsoft Entra", "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", "severity": "Bajo", "subcategory": "Contrato de cliente de Microsoft", - "text": "Configurar el acuerdo de notificación de cuenta de facturación correo electrónico de contacto", + "text": "Configurar el correo electrónico de contacto de notificación de la cuenta de facturación del acuerdo", "waf": "Costar" }, { - "category": "Inquilinos de Azure Billing y Microsoft Entra ID", + "category": "Inquilinos de Facturación de Azure y de Id. de Microsoft Entra", "guid": "90e87802-602f-4dfb-acea-67c60689f1d7", "id": "A04.02", "link": "https://learn.microsoft.com/azure/cost-management-billing/manage/mca-section-invoice", "severity": "Bajo", "subcategory": "Contrato de cliente de Microsoft", - "text": "Utilice las secciones Perfiles de facturación y Facturas para estructurar la facturación de sus acuerdos para una gestión eficaz de los costes", + "text": "Utilice las secciones Perfiles de facturación y Factura para estructurar la facturación de los acuerdos y lograr una administración eficaz de los costos", "waf": "Costar" }, { - "category": "Inquilinos de Azure Billing y Microsoft Entra ID", + "category": "Inquilinos de Facturación de Azure y de Id. de Microsoft Entra", "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", "severity": "Bajo", "subcategory": "Contrato de cliente de Microsoft", - "text": "Uso de Azure Plan para reducir los costos de las cargas de trabajo que no son de producción", + "text": "Uso del plan de Azure para reducir los costos de las cargas de trabajo que no son de producción", "waf": "Costar" }, { - "category": "Inquilinos de Azure Billing y Microsoft Entra ID", + "category": "Inquilinos de Facturación de Azure y de Id. de Microsoft Entra", "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", "severity": "Medio", "subcategory": "Contrato de cliente de Microsoft", - "text": "Audite periódicamente las asignaciones de roles RBAC de facturación del acuerdo para revisar quién tiene acceso a su cuenta de facturación de MCA", + "text": "Audite periódicamente las asignaciones de roles de RBAC de facturación del acuerdo para revisar quién tiene acceso a su cuenta de facturación de MCA", "waf": "Costar" }, { @@ -194,7 +194,7 @@ "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", "severity": "Alto", - "subcategory": "ID de Microsoft Entra e identidad híbrida", + "subcategory": "Id. de Microsoft Entra e identidad híbrida", "text": "Uso de identidades administradas en lugar de entidades de servicio para la autenticación en los servicios de Azure", "training": "https://learn.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview", "waf": "Seguridad" @@ -205,8 +205,8 @@ "id": "B02.01", "link": "https://learn.microsoft.com/azure/active-directory/hybrid/how-to-connect-sync-staging-server", "severity": "Medio", - "subcategory": "Microsoft Entra ID", - "text": "Al implementar una máquina virtual de AD Connect, considere la posibilidad de tener un servidor de ensayo para alta disponibilidad / recuperación ante desastres", + "subcategory": "Id. de Microsoft Entra", + "text": "Al implementar una máquina virtual de AD Connect, considere la posibilidad de tener un servidor de ensayo para alta disponibilidad o recuperación ante desastres", "waf": "Fiabilidad" }, { @@ -217,7 +217,7 @@ "link": "https://learn.microsoft.com/azure/active-directory/roles/security-emergency-access", "severity": "Alto", "subcategory": "Identidad", - "text": "Implementar un acceso de emergencia o cuentas de vidrio roto para evitar el bloqueo de la cuenta de todo el inquilino", + "text": "Implemente un acceso de emergencia o cuentas de emergencia para evitar el bloqueo de cuentas en todo el inquilino", "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/", "waf": "Seguridad" }, @@ -228,7 +228,7 @@ "link": "https://learn.microsoft.com/azure/active-directory/reports-monitoring/concept-activity-logs-azure-monitor", "severity": "Medio", "subcategory": "Identidad", - "text": "Integre los registros de ID de Microsoft Entra con Azure Monitor de plataforma central. Azure Monitor permite una única fuente de información sobre los datos de registro y supervisión en Azure, lo que brinda a las organizaciones opciones nativas en la nube para cumplir con los requisitos relacionados con la recopilación y retención de registros.", + "text": "Integre los registros de identificador de Microsoft Entra con Azure Monitor central de la plataforma. Azure Monitor permite una única fuente de información en torno a los datos de registro y supervisión en Azure, lo que ofrece a las organizaciones opciones nativas en la nube para cumplir los requisitos relacionados con la recopilación y retención de registros.", "waf": "Seguridad" }, { @@ -250,7 +250,7 @@ "link": "https://learn.microsoft.com/azure/active-directory/conditional-access/overview", "severity": "Bajo", "subcategory": "Identidad", - "text": "Aplicar directivas de acceso condicional de Microsoft Entra ID para cualquier usuario con derechos en entornos de Azure", + "text": "Aplicación de directivas de acceso condicional de Microsoft Entra ID para cualquier usuario con derechos en entornos de Azure", "training": "https://learn.microsoft.com/learn/modules/plan-implement-administer-conditional-access/", "waf": "Seguridad" }, @@ -262,7 +262,7 @@ "link": "https://learn.microsoft.com/azure/active-directory/authentication/concept-mfa-howitworks", "severity": "Alto", "subcategory": "Identidad", - "text": "Aplicar la autenticación multifactor para cualquier usuario con derechos en los entornos de Azure", + "text": "Aplicación de la autenticación multifactor para cualquier usuario con derechos en los entornos de Azure", "training": "https://learn.microsoft.com/learn/modules/secure-aad-users-with-mfa/", "waf": "Seguridad" }, @@ -284,7 +284,7 @@ "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-configure", "severity": "Medio", "subcategory": "Identidad", - "text": "Aplicar Microsoft Entra ID Privileged Identity Management (PIM) para establecer acceso sin pie y privilegios mínimos", + "text": "Aplique la administración de identidades privilegiadas (PIM) de Microsoft Entra ID para establecer el acceso permanente cero y los privilegios mínimos", "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/", "waf": "Seguridad" }, @@ -296,7 +296,7 @@ "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", "severity": "Alto", "subcategory": "Identidad", - "text": "Utilice únicamente el tipo de autenticación Cuenta profesional o educativa para todos los tipos de cuenta. Evite usar la cuenta Microsoft", + "text": "Utilice solo el tipo de autenticación Cuenta profesional o educativa para todos los tipos de cuenta. Evite usar la cuenta de Microsoft", "training": "https://learn.microsoft.com/learn/modules/explore-basic-services-identity-types/", "waf": "Seguridad" }, @@ -307,7 +307,7 @@ "link": "https://learn.microsoft.com/azure/active-directory/fundamentals/active-directory-groups-create-azure-portal", "severity": "Medio", "subcategory": "Identidad", - "text": "Utilice solo grupos para asignar permisos. Agregue grupos locales al grupo solo de Azure AD si ya hay un sistema de administración de grupos implementado.", + "text": "Utilice solo grupos para asignar permisos. Agregue grupos locales al grupo solo de Azure-AD si ya existe un sistema de administración de grupos.", "training": "https://learn.microsoft.com/learn/paths/manage-identity-and-access/", "waf": "Seguridad" }, @@ -329,7 +329,7 @@ "link": "https://learn.microsoft.com/azure/active-directory-domain-services/overview", "severity": "Medio", "subcategory": "Identidad", - "text": "Si Azure Active Directory Domains Services (AADDS) está en uso, implemente AADDS dentro de la región principal, ya que este servicio solo se puede proyectar en una suscripción.", + "text": "Si Azure Active Directory Domains Services (AADDS) está en uso, implemente AADDS dentro de la región primaria, ya que este servicio solo se puede proyectar en una suscripción", "training": "https://learn.microsoft.com/learn/modules/azure-active-directory/", "waf": "Seguridad" }, @@ -362,7 +362,7 @@ "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy", "severity": "Medio", "subcategory": "Identidad", - "text": "Considere la posibilidad de usar Microsoft Entra ID Application Proxy como reemplazo de VPN o proxy inverso para proporcionar a los usuarios remotos acceso seguro y autenticado a las aplicaciones internas (hospedadas en la nube o localmente).", + "text": "Considere la posibilidad de usar Microsoft Entra ID Application Proxy como reemplazo de VPN o proxy inverso para proporcionar a los usuarios remotos acceso seguro y autenticado a las aplicaciones internas (hospedadas en la nube o en el entorno local).", "training": "https://learn.microsoft.com/learn/paths/implement-applications-external-access-azure-ad/", "waf": "Seguridad" }, @@ -373,7 +373,7 @@ "link": "https://learn.microsoft.com/azure/active-directory/roles/best-practices", "severity": "Medio", "subcategory": "Identidad", - "text": "Evite usar cuentas sincronizadas locales para las asignaciones de roles de Microsoft Entra ID.", + "text": "Evite el uso de cuentas sincronizadas locales para las asignaciones de roles de identificador de Microsoft Entra.", "training": "https://learn.microsoft.com/learn/modules/design-identity-security-strategy/", "waf": "Seguridad" }, @@ -384,7 +384,7 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/identity-access-landing-zones#managed-identities", "severity": "Bajo", "subcategory": "Zonas de aterrizaje", - "text": "Configure la segmentación de red de identidad (ADDS) mediante el uso de una red virtual y vuelva al concentrador. Proporcionar autenticación dentro de la zona de aterrizaje de la aplicación (heredada).", + "text": "Configure la segmentación de red de identidad (ADDS) mediante el uso de una red virtual y vuelva a emparejarse con el centro. Proporcionar autenticación dentro de la zona de aterrizaje de la aplicación (heredada).", "training": "https://learn.microsoft.com/azure/architecture/example-scenario/identity/adds-extend-domain", "waf": "Seguridad" }, @@ -395,7 +395,7 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/identity-access-landing-zones#rbac-recommendations", "severity": "Medio", "subcategory": "Zonas de aterrizaje", - "text": "Use RBAC de Azure para administrar el acceso del plano de datos a los recursos, si es posible. Por ejemplo, operaciones de datos en Key Vault, cuenta de almacenamiento y servicios de base de datos. ", + "text": "Use Azure RBAC para administrar el acceso del plano de datos a los recursos, si es posible. Por ejemplo, operaciones de datos en Key Vault, cuentas de almacenamiento y servicios de base de datos. ", "training": "https://learn.microsoft.com/azure/role-based-access-control/overview", "waf": "Seguridad" }, @@ -406,7 +406,7 @@ "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-create-roles-and-resource-roles-review", "severity": "Medio", "subcategory": "Zonas de aterrizaje", - "text": "Use las revisiones de acceso PIM de ID de Microsoft Entra para validar periódicamente los derechos de recursos.", + "text": "Use las revisiones de acceso PIM de Microsoft Entra ID para validar periódicamente los derechos de recursos.", "waf": "Seguridad" }, { @@ -439,7 +439,7 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/resource-org-management-groups#management-group-recommendations", "severity": "Medio", "subcategory": "Suscripciones", - "text": "Aplicación de un grupo de administración de espacio aislado para permitir a los usuarios experimentar inmediatamente con Azure", + "text": "Aplicación de un grupo de administración de espacio aislado para permitir que los usuarios experimenten inmediatamente con Azure", "training": "https://learn.microsoft.com/learn/paths/enterprise-scale-architecture/", "waf": "Seguridad" }, @@ -461,7 +461,7 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/resource-org-management-groups#management-group-recommendations", "severity": "Medio", "subcategory": "Suscripciones", - "text": "Aplique una suscripción de conectividad dedicada en el grupo de administración de conectividad para hospedar un concentrador WAN virtual de Azure, un sistema de nombres de dominio (DNS) privado, un circuito ExpressRoute y otros recursos de red.", + "text": "Aplique una suscripción de conectividad dedicada en el grupo de administración de conectividad para hospedar un centro de conectividad de Azure Virtual WAN, un sistema de nombres de dominio (DNS) privado, un circuito ExpressRoute y otros recursos de red.", "training": "https://learn.microsoft.com/learn/paths/enterprise-scale-architecture/", "waf": "Seguridad" }, @@ -483,7 +483,7 @@ "link": "https://learn.microsoft.com/azure/governance/management-groups/how-to/protect-resource-hierarchy#setting---require-authorization", "severity": "Medio", "subcategory": "Suscripciones", - "text": "Exigir que solo los usuarios con privilegios puedan operar grupos de administración en el inquilino habilitando la autorización RBAC de Azure en la configuración de la jerarquía de grupos de administración", + "text": "Exija que solo los usuarios con privilegios puedan operar grupos de administración en el inquilino habilitando la autorización de Azure RBAC en la configuración de la jerarquía del grupo de administración", "waf": "Seguridad" }, { @@ -493,7 +493,7 @@ "link": "https://learn.microsoft.com/azure/governance/management-groups/overview", "severity": "Medio", "subcategory": "Suscripciones", - "text": "Aplique grupos de administración bajo el grupo de administración de nivel raíz para representar los tipos de cargas de trabajo, en función de sus necesidades de seguridad, cumplimiento, conectividad y características.", + "text": "Aplique grupos de administración en el grupo de administración de nivel raíz para representar los tipos de cargas de trabajo, en función de sus necesidades de seguridad, cumplimiento, conectividad y características.", "waf": "Seguridad" }, { @@ -504,7 +504,7 @@ "link": "https://learn.microsoft.com/azure/governance/management-groups/overview", "severity": "Alto", "subcategory": "Suscripciones", - "text": "Aplique un proceso para que los propietarios de recursos conozcan sus roles y responsabilidades, acceda a la revisión, la revisión del presupuesto, el cumplimiento de las políticas y corrija cuando sea necesario.", + "text": "Aplique un proceso para que los propietarios de recursos sean conscientes de sus funciones y responsabilidades, la revisión de acceso, la revisión del presupuesto, el cumplimiento de las políticas y la corrección cuando sea necesario.", "waf": "Seguridad" }, { @@ -514,7 +514,7 @@ "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits", "severity": "Medio", "subcategory": "Suscripciones", - "text": "Asegúrese de que todos los propietarios de suscripciones y el equipo central de TI conozcan las cuotas de suscripción y el impacto que tienen en la provisión de recursos para una suscripción determinada.", + "text": "Asegúrese de que todos los propietarios de suscripciones y el equipo central de TI conozcan las cuotas de suscripción y el impacto que tienen en el aprovisionamiento de recursos para una suscripción determinada.", "waf": "Seguridad" }, { @@ -525,7 +525,7 @@ "link": "https://learn.microsoft.com/azure/cost-management-billing/reservations/save-compute-costs-reservations", "severity": "Alto", "subcategory": "Suscripciones", - "text": "Utilice instancias reservadas cuando corresponda para optimizar los costos y garantizar la capacidad disponible en las regiones de destino. Explique el uso de SKU de máquina virtual de instancia reservada adquiridas a través de Azure Policy.", + "text": "Utilice instancias reservadas cuando corresponda para optimizar los costos y garantizar la capacidad disponible en las regiones de destino. Aplique el uso de SKU de máquina virtual de instancia reservada adquiridas a través de Azure Policy.", "training": "https://learn.microsoft.com/learn/paths/improve-reliability-modern-operations/", "waf": "Seguridad" }, @@ -537,7 +537,7 @@ "link": "https://learn.microsoft.com/azure/architecture/framework/scalability/design-capacity", "severity": "Alto", "subcategory": "Suscripciones", - "text": "Aplicar un panel, un libro de trabajo o un proceso manual para supervisar los niveles de capacidad utilizados", + "text": "Aplique un panel, un libro de trabajo o un proceso manual para supervisar los niveles de capacidad utilizados", "training": "https://learn.microsoft.com/learn/paths/monitor-usage-performance-availability-resources-azure-monitor/", "waf": "Seguridad" }, @@ -548,7 +548,7 @@ "link": "https://azure.microsoft.com/global-infrastructure/services/", "severity": "Medio", "subcategory": "Suscripciones", - "text": "Asegúrese de que los servicios y características necesarios estén disponibles dentro de las regiones de implementación elegidas", + "text": "Asegúrese de que los servicios y las características necesarios estén disponibles en las regiones de implementación elegidas", "training": "https://learn.microsoft.com/learn/modules/azure-architecture-fundamentals/", "waf": "Seguridad" }, @@ -571,7 +571,7 @@ "link": "https://learn.microsoft.com/azure/governance/management-groups/overview", "severity": "Medio", "subcategory": "Suscripciones", - "text": "Si AD en Windows Server, establezca una suscripción de identidad dedicada en el grupo de administración Indentity para hospedar controladores de dominio de Windows Server Active Directory", + "text": "Si AD está en Windows Server, establezca una suscripción de identidad dedicada en el grupo de administración Indentity para hospedar controladores de dominio de Windows Server Active Directory", "training": "https://learn.microsoft.com/learn/paths/enterprise-scale-architecture/", "waf": "Seguridad" }, @@ -589,12 +589,12 @@ }, { "category": "Topología y conectividad de red", - "guid": "f00a69de-7076-4734-a734-6e4552cad9e1", + "guid": "373f482f-3e39-4d39-8aa4-7e566f6082b6", "id": "D01.01", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-latest-version-for-customer-managed-certificates", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-app-delivery", "severity": "Medio", "subcategory": "Entrega de aplicaciones", - "text": "Si usa certificados TLS administrados por el cliente con Azure Front Door, use la versión de certificado \"más reciente\". Reduzca el riesgo de interrupciones causadas por la renovación manual de certificados.", + "text": "Desarrolle un plan para proteger el contenido de la aplicación de entrega de los radios de carga de trabajo mediante Application Gateway y Azure Front Door. Puede utilizar la lista de comprobación de entrega de aplicaciones para obtener recomendaciones.", "waf": "Operaciones" }, { @@ -604,221 +604,21 @@ "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", "severity": "Medio", "subcategory": "Entrega de aplicaciones", - "text": "Realice la entrega de aplicaciones dentro de las zonas de aterrizaje para aplicaciones internas (corporativas) y externas (en línea).", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", - "waf": "Seguridad" - }, - { - "category": "Topología y conectividad de red", - "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": "D01.03", - "link": "https://learn.microsoft.com/azure/application-gateway/overview-v2", - "severity": "Medio", - "subcategory": "Entrega de aplicaciones", - "text": "Asegúrese de que está utilizando SKU de Application Gateway v2", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", - "waf": "Seguridad" - }, - { - "category": "Topología y conectividad de red", - "graph": "resources | where type == 'microsoft.network/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard')", - "guid": "4e35fbf5-0ae2-48b2-97ce-753353edbd1a", - "id": "D01.04", - "link": "https://learn.microsoft.com/azure/load-balancer/load-balancer-overview", - "severity": "Medio", - "subcategory": "Entrega de aplicaciones", - "text": "Asegúrese de que está usando la SKU estándar para los equilibradores de carga de Azure", - "waf": "Seguridad" - }, - { - "category": "Topología y conectividad de red", - "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 | project id, subnetId = tostring(subnets.id), subnetPrefixLength = split(subnets.properties.addressPrefix, '/')[1]) on subnetId | extend compliant = (subnetPrefixLength <= 26) | distinct id,compliant", - "guid": "dfc50f87-3800-424c-937b-ed5f186e7c15", - "id": "D01.05", - "link": "https://learn.microsoft.com/azure/application-gateway/configuration-infrastructure#size-of-the-subnet", - "severity": "Medio", - "subcategory": "Entrega de aplicaciones", - "text": "Las puertas de enlace de aplicaciones deben implementarse en subredes con prefijos IP iguales o mayores que /26", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", - "waf": "Seguridad" - }, - { - "category": "Topología y conectividad de red", - "description": "La administración de proxies inversos en general y WAF en particular está más cerca de la aplicación que de la red, por lo que pertenecen a la misma suscripción que la aplicación. La centralización de Application Gateway y WAF en la suscripción de conectividad podría estar bien si está administrada por un solo equipo.", - "guid": "48b662d6-d15f-4512-a654-98f6dfe237de", - "id": "D01.06", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", - "severity": "Medio", - "subcategory": "Entrega de aplicaciones", - "text": "Implemente Azure Application Gateway v2 o NVA de asociados que se usan para enviar conexiones HTTP(S) entrantes dentro de la red virtual de la zona de aterrizaje y con las aplicaciones que están protegiendo.", + "text": "Realice la entrega de aplicaciones dentro de las zonas de aterrizaje tanto para aplicaciones internas (corp) como externas (en línea).", "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", "waf": "Seguridad" }, { "category": "Topología y conectividad de red", "guid": "143b16c3-1d7a-4a9b-9470-4489a8042d88", - "id": "D01.07", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", - "severity": "Medio", - "subcategory": "Entrega de aplicaciones", - "text": "Utilice una red DDoS o planes de protección IP para todas las direcciones IP públicas en las zonas de aterrizaje de la aplicación.", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", - "waf": "Seguridad" - }, - { - "category": "Topología y conectividad de red", - "guid": "e79d17b7-3b22-4a5a-97e7-a8ed4b30e38c", - "id": "D01.08", + "id": "D01.03", "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", "severity": "Medio", "subcategory": "Entrega de aplicaciones", - "text": "Use Azure Front Door con directivas WAF para entregar y ayudar a proteger aplicaciones HTTP/S globales que abarcan varias regiones de Azure.", + "text": "Use una red DDoS o planes de protección IP para todas las direcciones IP públicas en las zonas de aterrizaje de la aplicación.", "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", "waf": "Seguridad" }, - { - "category": "Topología y conectividad de red", - "guid": "3f29812b-2363-4cef-b179-b599de0d5973", - "id": "D01.09", - "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", - "severity": "Medio", - "subcategory": "Entrega de aplicaciones", - "text": "Cuando use Front Door y Application Gateway para ayudar a proteger las aplicaciones HTTP/S, use directivas WAF en Front Door. Bloquee Application Gateway para recibir tráfico solo desde Front Door.", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", - "waf": "Seguridad" - }, - { - "ammp": true, - "category": "Topología y conectividad de red", - "guid": "cd4cd21b-0881-437f-9e6c-4cfd3e504547", - "id": "D01.10", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", - "severity": "Alto", - "subcategory": "Entrega de aplicaciones", - "text": "Use el Administrador de tráfico para entregar aplicaciones globales que abarquen protocolos distintos de HTTP/S.", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", - "waf": "Fiabilidad" - }, - { - "category": "Topología y conectividad de red", - "guid": "3b4b3e88-a459-4ed5-a22f-644dfbc58204", - "id": "D01.11", - "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy#how-application-proxy-works", - "severity": "Bajo", - "subcategory": "Entrega de aplicaciones", - "text": "Si los usuarios solo necesitan acceso a aplicaciones internas, ¿se ha considerado Microsoft Entra ID Application Proxy como una alternativa a Azure Virtual Desktop (AVD)?", - "training": "https://learn.microsoft.com/learn/modules/configure-azure-ad-application-proxy/", - "waf": "Seguridad" - }, - { - "category": "Topología y conectividad de red", - "guid": "01ca7cf1-5754-442d-babb-8ba6772e5c30", - "id": "D01.12", - "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy#how-application-proxy-works", - "severity": "Medio", - "subcategory": "Entrega de aplicaciones", - "text": "Para reducir el número de puertos de firewall abiertos para las conexiones entrantes en la red, considere la posibilidad de usar el proxy de aplicación de identificador de Microsoft Entra para proporcionar a los usuarios remotos acceso seguro y autenticado a las aplicaciones internas.", - "training": "https://learn.microsoft.com/learn/paths/implement-applications-external-access-azure-ad/", - "waf": "Seguridad" - }, - { - "ammp": true, - "category": "Topología y conectividad de red", - "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": "D01.13", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-policy-settings", - "severity": "Alto", - "subcategory": "Entrega de aplicaciones", - "text": "Implemente sus perfiles WAF para Front Door en modo 'Prevención'.", - "waf": "Seguridad" - }, - { - "ammp": true, - "category": "Topología y conectividad de red", - "guid": "062d5839-4d36-402f-bfa4-02811eb936e9", - "id": "D01.14", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#avoid-combining-traffic-manager-and-front-door", - "severity": "Alto", - "subcategory": "Entrega de aplicaciones", - "text": "Evite combinar Azure Traffic Manager y Azure Front Door.", - "waf": "Seguridad" - }, - { - "ammp": true, - "category": "Topología y conectividad de red", - "guid": "5efeb96a-003f-4b18-8fcd-b4d84459c2b2", - "id": "D01.15", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-the-same-domain-name-on-front-door-and-your-origin", - "severity": "Alto", - "subcategory": "Entrega de aplicaciones", - "text": "Use el mismo nombre de dominio en Azure Front Door y su origen. Los nombres de host no coincidentes pueden causar errores sutiles.", - "waf": "Seguridad" - }, - { - "category": "Topología y conectividad de red", - "guid": "0b5a380c-4bfb-47bc-b1d7-dcfef363a61b", - "id": "D01.16", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#disable-health-probes-when-theres-only-one-origin-in-an-origin-group", - "severity": "Bajo", - "subcategory": "Entrega de aplicaciones", - "text": "Deshabilite los sondeos de mantenimiento cuando solo hay un origen en un grupo de origen de Azure Front Door.", - "waf": "Rendimiento" - }, - { - "category": "Topología y conectividad de red", - "guid": "5567048e-e5d7-4206-9c55-b5ed45d2cc0c", - "id": "D01.17", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#select-good-health-probe-endpoints", - "severity": "Medio", - "subcategory": "Entrega de aplicaciones", - "text": "Seleccione puntos de conexión de sondeo de buen estado para Azure Front Door. Considere la posibilidad de crear extremos de mantenimiento que comprueben todas las dependencias de la aplicación.", - "waf": "Fiabilidad" - }, - { - "category": "Topología y conectividad de red", - "guid": "a13f72f3-8f5c-4864-95e5-75bf37fbbeb1", - "id": "D01.18", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-head-health-probes", - "severity": "Bajo", - "subcategory": "Entrega de aplicaciones", - "text": "Use sondeos de estado HEAD con Azure Front Door para reducir el tráfico que Front Door envía a la aplicación.", - "waf": "Rendimiento" - }, - { - "ammp": true, - "category": "Topología y conectividad de red", - "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": "D01.19", - "link": "https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity", - "severity": "Alto", - "subcategory": "Entrega de aplicaciones", - "text": "Use Azure NAT Gateway en lugar de reglas de salida del equilibrador de carga para una mejor escalabilidad de SNAT", - "waf": "Fiabilidad" - }, - { - "ammp": true, - "category": "Topología y conectividad de red", - "guid": "af95c92d-d723-4f4a-98d7-8722324efd4d", - "id": "D01.20", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-managed-tls-certificates", - "severity": "Alto", - "subcategory": "Entrega de aplicaciones", - "text": "Use certificados TLS administrados con Azure Front Door. Reduzca el costo operativo y el riesgo de interrupciones debido a la renovación de certificados.", - "waf": "Operaciones" - }, - { - "category": "Topología y conectividad de red", - "guid": "189ea962-3969-4863-8f5a-5ad808c2cf4b", - "id": "D01.21", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#define-your-waf-configuration-as-code", - "severity": "Medio", - "subcategory": "Entrega de aplicaciones", - "text": "Defina la configuración de Azure Front Door WAF como código. Mediante el uso de código, puede adoptar más fácilmente nuevas versiones del conjunto de reglas y obtener protección adicional.", - "waf": "Operaciones" - }, { "category": "Topología y conectividad de red", "guid": "de0d5973-cd4c-4d21-a088-137f5e6c4cfd", @@ -826,7 +626,7 @@ "link": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", "severity": "Medio", "subcategory": "Encriptación", - "text": "Cuando use ExpressRoute Direct, configure MACsec para cifrar el tráfico en el nivel de capa dos entre los enrutadores de la organización y MSEE. El diagrama muestra este cifrado en flujo.", + "text": "Cuando use ExpressRoute Direct, configure MACsec para cifrar el tráfico en el nivel de capa dos entre los enrutadores de la organización y MSEE. El diagrama muestra este cifrado en el flujo.", "waf": "Seguridad" }, { @@ -836,7 +636,7 @@ "link": "https://learn.microsoft.com/azure/expressroute/expressroute-erdirect-about", "severity": "Bajo", "subcategory": "Encriptación", - "text": "Para escenarios en los que MACsec no es una opción (por ejemplo, no usar ExpressRoute Direct), use una puerta de enlace VPN para establecer túneles IPsec sobre el emparejamiento privado de ExpressRoute. ", + "text": "En escenarios en los que MACsec no es una opción (por ejemplo, no usar ExpressRoute Direct), use una puerta de enlace de VPN para establecer túneles IPsec a través del emparejamiento privado de ExpressRoute. ", "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", "waf": "Seguridad" }, @@ -846,7 +646,7 @@ "id": "D03.01", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/enterprise-scale/network-topology-and-connectivity", "severity": "Medio", - "subcategory": "Hub and spoke", + "subcategory": "Cubo y radio", "text": "Considere un diseño de red basado en la topología de red radial tradicional para escenarios de red que requieren la máxima flexibilidad.", "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", "waf": "Seguridad" @@ -858,8 +658,8 @@ "id": "D03.02", "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/hybrid-networking/expressroute", "severity": "Alto", - "subcategory": "Hub and spoke", - "text": "Asegúrese de que los servicios de red compartidos, incluidas las puertas de enlace de ExpressRoute, las puertas de enlace VPN y Azure Firewall o NVA asociados en la red virtual del concentrador central. Si es necesario, implemente también servidores DNS.", + "subcategory": "Cubo y radio", + "text": "Asegúrese de que los servicios de redes compartidas, incluidas las puertas de enlace de ExpressRoute, las puertas de enlace de VPN y Azure Firewall o las aplicaciones virtuales de red de asociados en la red virtual del centro central. Si es necesario, implemente también servidores DNS.", "waf": "Costar" }, { @@ -868,8 +668,8 @@ "id": "D03.03", "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/dmz/nva-ha", "severity": "Medio", - "subcategory": "Hub and spoke", - "text": "Al implementar tecnologías de red de socios o NVA, siga las instrucciones del proveedor del socio", + "subcategory": "Cubo y radio", + "text": "Al implementar tecnologías de redes de asociados o aplicaciones virtuales de red, siga las instrucciones del proveedor de asociados", "waf": "Fiabilidad" }, { @@ -878,8 +678,8 @@ "id": "D03.04", "link": "https://learn.microsoft.com/azure/expressroute/expressroute-howto-coexist-resource-manager#to-enable-transit-routing-between-expressroute-and-azure-vpn", "severity": "Bajo", - "subcategory": "Hub and spoke", - "text": "Si necesita tránsito entre ExpressRoute y puertas de enlace VPN en escenarios radiales, use Azure Route Server.", + "subcategory": "Cubo y radio", + "text": "Si necesita el tránsito entre ExpressRoute y puertas de enlace de VPN en escenarios en estrella tipo hub-and-spoke, use Azure Route Server.", "waf": "Seguridad" }, { @@ -889,8 +689,8 @@ "id": "D03.05", "link": "https://learn.microsoft.com/azure/route-server/quickstart-configure-route-server-portal#create-a-route-server-1", "severity": "Bajo", - "subcategory": "Hub and spoke", - "text": "Si utiliza Route Server, utilice un prefijo /27 para la subred de Route Server.", + "subcategory": "Cubo y radio", + "text": "Si utiliza el servidor de rutas, utilice un prefijo /27 para la subred del servidor de rutas.", "waf": "Seguridad" }, { @@ -899,8 +699,8 @@ "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", "severity": "Medio", - "subcategory": "Hub and spoke", - "text": "Para arquitecturas de red con varias topologías radiales en regiones de Azure, use emparejamientos de redes virtuales globales entre las redes virtuales de concentradores para conectar las regiones entre sí. ", + "subcategory": "Cubo y radio", + "text": "En el caso de las arquitecturas de red con varias topologías en estrella tipo hub-and-spoke en las regiones de Azure, use emparejamientos de red virtual global entre las redes virtuales del centro para conectar las regiones entre sí. ", "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-virtual-networks/", "waf": "Rendimiento" }, @@ -910,8 +710,8 @@ "id": "D03.07", "link": "https://learn.microsoft.com/azure/azure-monitor/insights/network-insights-overview", "severity": "Medio", - "subcategory": "Hub and spoke", - "text": "Use Azure Monitor for Networks para supervisar el estado completo de las redes en Azure.", + "subcategory": "Cubo y radio", + "text": "Use Azure Monitor para redes para supervisar el estado de un extremo a otro de las redes en Azure.", "training": "https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/", "waf": "Operaciones" }, @@ -922,8 +722,8 @@ "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", "severity": "Medio", - "subcategory": "Hub and spoke", - "text": "Al conectar redes virtuales radiales a la red virtual del concentrador central, tenga en cuenta los límites de emparejamiento de red virtual (500), el número máximo de prefijos que se pueden anunciar a través de ExpressRoute (1000)", + "subcategory": "Cubo y radio", + "text": "Al conectar redes virtuales de radio a la red virtual del centro central, tenga en cuenta los límites de emparejamiento de red virtual (500), el número máximo de prefijos que se pueden anunciar a través de ExpressRoute (1000)", "waf": "Fiabilidad" }, { @@ -933,8 +733,8 @@ "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", "severity": "Medio", - "subcategory": "Hub and spoke", - "text": "Considere el límite de rutas por tabla de rutas (400).", + "subcategory": "Cubo y radio", + "text": "Tenga en cuenta el límite de rutas por tabla de rutas (400).", "waf": "Fiabilidad" }, { @@ -945,8 +745,8 @@ "id": "D03.10", "link": "https://learn.microsoft.com/azure/virtual-network/virtual-network-manage-peering", "severity": "Alto", - "subcategory": "Hub and spoke", - "text": "Use la configuración \"Permitir tráfico a la red virtual remota\" al configurar emparejamientos de red virtual de red virtual", + "subcategory": "Cubo y radio", + "text": "Use la opción \"Permitir tráfico a la red virtual remota\" al configurar emparejamientos de red virtual", "waf": "Fiabilidad" }, { @@ -962,7 +762,7 @@ }, { "category": "Topología y conectividad de red", - "description": "Puede usar los pesos de conexión y pendientes de ruta para influir en el tráfico de Azure al local, y toda la gama de atributos BGP en sus propios enrutadores para influir en el tráfico del entorno local a Azure.", + "description": "Puede usar la anteposición de AS y los pesos de conexión para influir en el tráfico de Azure al entorno local, y la gama completa de atributos de BGP en sus propios enrutadores para influir en el tráfico del entorno local a Azure.", "guid": "f29812b2-363c-4efe-879b-599de0d5973c", "id": "D04.02", "link": "https://learn.microsoft.com/azure/expressroute/expressroute-routing", @@ -980,7 +780,7 @@ "link": "https://learn.microsoft.com/azure/expressroute/expressroute-routing", "severity": "Medio", "subcategory": "Híbrido", - "text": "Asegúrese de usar la SKU correcta para las puertas de enlace ExpressRoute/VPN en función de los requisitos de ancho de banda y rendimiento.", + "text": "Asegúrese de que usa la SKU correcta para las puertas de enlace de ExpressRoute/VPN en función de los requisitos de ancho de banda y rendimiento.", "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", "waf": "Rendimiento" }, @@ -993,7 +793,7 @@ "link": "https://learn.microsoft.com/azure/expressroute/plan-manage-cost", "severity": "Alto", "subcategory": "Híbrido", - "text": "Asegúrese de usar circuitos ExpressRoute de datos ilimitados solo si alcanza el ancho de banda que justifica su costo.", + "text": "Asegúrese de que usa circuitos ExpressRoute de datos ilimitados solo si alcanza el ancho de banda que justifica su costo.", "waf": "Costar" }, { @@ -1027,7 +827,7 @@ "link": "https://learn.microsoft.com/azure/networking/", "severity": "Medio", "subcategory": "Híbrido", - "text": "Para escenarios que requieren un ancho de banda superior a 10 Gbps o puertos dedicados de 10/100 Gbps, use ExpressRoute Direct.", + "text": "En escenarios que requieren un ancho de banda superior a 10 Gbps o puertos dedicados de 10/100 Gbps, use ExpressRoute Direct.", "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", "waf": "Rendimiento" }, @@ -1038,7 +838,7 @@ "link": "https://learn.microsoft.com/azure/expressroute/about-fastpath", "severity": "Medio", "subcategory": "Híbrido", - "text": "Cuando se requiera una latencia baja o el rendimiento del entorno local a Azure deba ser superior a 10 Gbps, habilite FastPath para omitir la puerta de enlace de ExpressRoute de la ruta de datos.", + "text": "Cuando se requiera una latencia baja o el rendimiento del entorno local a Azure sea superior a 10 Gbps, habilite FastPath para omitir la puerta de enlace de ExpressRoute de la ruta de acceso de datos.", "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", "waf": "Rendimiento" }, @@ -1050,7 +850,7 @@ "link": "https://learn.microsoft.com/azure/vpn-gateway/create-zone-redundant-vnet-gateway", "severity": "Medio", "subcategory": "Híbrido", - "text": "Use puertas de enlace VPN para conectar sucursales o ubicaciones remotas a Azure. Para una mayor resiliencia, implemente puertas de enlace con redundancia de zona (donde estén disponibles).", + "text": "Use puertas de enlace de VPN para conectar sucursales o ubicaciones remotas a Azure. Para una mayor resistencia, implemente puertas de enlace con redundancia de zona (cuando estén disponibles).", "training": "https://learn.microsoft.com/training/modules/intro-to-azure-vpn-gateway/", "waf": "Fiabilidad" }, @@ -1062,7 +862,7 @@ "link": "https://learn.microsoft.com/azure/expressroute/expressroute-erdirect-about", "severity": "Alto", "subcategory": "Híbrido", - "text": "Si usa ExpressRoute Direct, considere la posibilidad de usar circuitos locales de ExpressRoute en las regiones locales de Azure para ahorrar costos", + "text": "Si usa ExpressRoute Direct, considere la posibilidad de usar circuitos locales de ExpressRoute a las regiones locales de Azure para ahorrar costos", "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", "waf": "Costar" }, @@ -1073,7 +873,7 @@ "link": "https://learn.microsoft.com/azure/architecture/framework/services/networking/expressroute/reliability", "severity": "Medio", "subcategory": "Híbrido", - "text": "Cuando se requiere aislamiento de tráfico o ancho de banda dedicado, como para separar entornos de producción y no producción, use circuitos ExpressRoute diferentes. Le ayudará a garantizar dominios de enrutamiento aislados y aliviar los riesgos de vecinos ruidosos.", + "text": "Cuando se requiera aislamiento de tráfico o ancho de banda dedicado, por ejemplo, para separar entornos de producción y no de producción, use circuitos ExpressRoute diferentes. Le ayudará a garantizar dominios de enrutamiento aislados y a aliviar los riesgos de vecinos ruidosos.", "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", "waf": "Seguridad" }, @@ -1095,7 +895,7 @@ "link": "https://learn.microsoft.com/azure/expressroute/how-to-configure-connection-monitor", "severity": "Medio", "subcategory": "Híbrido", - "text": "Utilice el Monitor de conexión para la supervisión de la conectividad en todo el entorno.", + "text": "Utilice el Monitor de conexión para supervisar la conectividad en todo el entorno.", "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", "waf": "Operaciones" }, @@ -1106,7 +906,7 @@ "link": "https://learn.microsoft.com/azure/expressroute/designing-for-disaster-recovery-with-expressroute-privatepeering#challenges-of-using-multiple-expressroute-circuits", "severity": "Medio", "subcategory": "Híbrido", - "text": "Use circuitos ExpressRoute de diferentes ubicaciones de emparejamiento para la redundancia.", + "text": "Use circuitos ExpressRoute de diferentes ubicaciones de emparejamiento para obtener redundancia.", "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", "waf": "Fiabilidad" }, @@ -1118,7 +918,7 @@ "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/identity/adds-extend-domain#vm-recommendations", "severity": "Alto", "subcategory": "Híbrido", - "text": "Si va a implementar al menos dos máquinas virtuales que ejecutan AD DS como controladores de dominio, agréguelas a diferentes zonas de disponibilidad. Si no está disponible en la región, implemente en un conjunto de disponibilidad.", + "text": "Si va a implementar al menos dos máquinas virtuales que ejecutan AD DS como controladores de dominio, agréguelas a diferentes zonas de disponibilidad. Si no está disponible en la región, impleméntelo en un conjunto de disponibilidad.", "waf": "Fiabilidad" }, { @@ -1128,8 +928,8 @@ "id": "D05.01", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing", "severity": "Alto", - "subcategory": "Plan IP", - "text": "Asegúrese de que no se usen espacios de direcciones IP superpuestos entre regiones de Azure y ubicaciones locales", + "subcategory": "Plan de propiedad intelectual", + "text": "Asegúrese de que no se usan espacios de direcciones IP superpuestos en las regiones de Azure y las ubicaciones locales", "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", "waf": "Seguridad" }, @@ -1140,8 +940,8 @@ "id": "D05.02", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing", "severity": "Bajo", - "subcategory": "Plan IP", - "text": "Utilice direcciones IP de los intervalos de asignación de direcciones para Internets privadas (RFC 1918).", + "subcategory": "Plan de propiedad intelectual", + "text": "Utilice direcciones IP de los rangos de asignación de direcciones para Internet privadas (RFC 1918).", "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", "waf": "Seguridad" }, @@ -1153,7 +953,7 @@ "id": "D05.03", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing", "severity": "Alto", - "subcategory": "Plan IP", + "subcategory": "Plan de propiedad intelectual", "text": "Asegúrese de que no se desperdicie espacio de direcciones IP, no cree redes virtuales innecesariamente grandes (por ejemplo, /16) ", "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", "waf": "Rendimiento" @@ -1165,8 +965,8 @@ "id": "D05.04", "link": "https://learn.microsoft.com/azure/site-recovery/concepts-on-premises-to-azure-networking#retain-ip-addresses", "severity": "Alto", - "subcategory": "Plan IP", - "text": "Evite usar rangos de direcciones IP superpuestos para los sitios de producción y DR.", + "subcategory": "Plan de propiedad intelectual", + "text": "Evite el uso de intervalos de direcciones IP superpuestos para los sitios de producción y recuperación ante desastres.", "training": "https://learn.microsoft.com/learn/paths/az-104-manage-virtual-networks/", "waf": "Fiabilidad" }, @@ -1176,8 +976,8 @@ "id": "D05.05", "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-name-resolution-for-vms-and-role-instances", "severity": "Medio", - "subcategory": "Plan IP", - "text": "Para entornos en los que la resolución de nombres en Azure es todo lo que se requiere, use Azure Private DNS para la resolución con una zona delegada para la resolución de nombres (como 'azure.contoso.com').", + "subcategory": "Plan de propiedad intelectual", + "text": "En entornos en los que la resolución de nombres en Azure es todo lo que se requiere, use Azure Private DNS para la resolución con una zona delegada para la resolución de nombres (como 'azure.contoso.com').", "training": "https://learn.microsoft.com/learn/paths/az-104-manage-virtual-networks/", "waf": "Operaciones" }, @@ -1187,8 +987,8 @@ "id": "D05.06", "link": "https://learn.microsoft.com/azure/dns/dns-private-resolver-overview", "severity": "Medio", - "subcategory": "Plan IP", - "text": "Para entornos en los que se requiere la resolución de nombres en Azure y en el entorno local, considere la posibilidad de usar Azure DNS Private Resolver.", + "subcategory": "Plan de propiedad intelectual", + "text": "En el caso de los entornos en los que se requiere la resolución de nombres en Azure y en el entorno local, considere la posibilidad de usar Azure DNS Private Resolver.", "training": "https://learn.microsoft.com/training/modules/intro-to-azure-dns-private-resolver/", "waf": "Seguridad" }, @@ -1198,8 +998,8 @@ "id": "D05.07", "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-name-resolution-for-vms-and-role-instances", "severity": "Bajo", - "subcategory": "Plan IP", - "text": "Las cargas de trabajo especiales que requieren e implementan su propio DNS (como Red Hat OpenShift) deben usar su solución DNS preferida.", + "subcategory": "Plan de propiedad intelectual", + "text": "Las cargas de trabajo especiales que requieren e implementan su propio DNS (como Red Hat OpenShift) deben utilizar su solución DNS preferida.", "waf": "Operaciones" }, { @@ -1209,8 +1009,8 @@ "id": "D05.08", "link": "https://learn.microsoft.com/azure/dns/private-dns-autoregistration", "severity": "Alto", - "subcategory": "Plan IP", - "text": "Habilite el registro automático de DNS de Azure para administrar automáticamente el ciclo de vida de los registros DNS de las máquinas virtuales implementadas en una red virtual.", + "subcategory": "Plan de propiedad intelectual", + "text": "Habilite el registro automático de Azure DNS para administrar automáticamente el ciclo de vida de los registros DNS de las máquinas virtuales implementadas en una red virtual.", "training": "https://learn.microsoft.com/learn/paths/az-104-manage-virtual-networks/", "waf": "Operaciones" }, @@ -1243,7 +1043,7 @@ "link": "https://learn.microsoft.com/azure/app-service/networking-features", "severity": "Alto", "subcategory": "Internet", - "text": "Use Azure Firewall para controlar el tráfico saliente de Azure a Internet, las conexiones entrantes que no son HTTP/S y el filtrado de tráfico Este/Oeste (si la organización lo requiere)", + "text": "Use Azure Firewall para controlar el tráfico saliente de Azure a Internet, las conexiones entrantes que no son HTTP/S y el filtrado del tráfico Este/Oeste (si la organización lo requiere)", "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", "waf": "Seguridad" }, @@ -1254,7 +1054,7 @@ "link": "https://learn.microsoft.com/azure/firewall/", "severity": "Medio", "subcategory": "Internet", - "text": "Cree una directiva global de Azure Firewall para controlar la postura de seguridad en todo el entorno de red global y asígnela a todas las instancias de Azure Firewall. Permita que las directivas granulares cumplan los requisitos de regiones específicas delegando directivas de firewall incrementales a equipos de seguridad locales a través del control de acceso basado en roles de Azure.", + "text": "Cree una directiva global de Azure Firewall para controlar la posición de seguridad en todo el entorno de red global y asígnela a todas las instancias de Azure Firewall. Permita que las directivas granulares satisfagan los requisitos de regiones específicas delegando directivas de firewall incrementales a los equipos de seguridad locales a través del control de acceso basado en roles de Azure.", "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", "waf": "Seguridad" }, @@ -1265,7 +1065,7 @@ "link": "https://learn.microsoft.com/azure/firewall/", "severity": "Bajo", "subcategory": "Internet", - "text": "Configure los proveedores de seguridad SaaS de socios compatibles en Firewall Manager si la organización desea usar dichas soluciones para ayudar a proteger las conexiones salientes.", + "text": "Configure los proveedores de seguridad SaaS de socios compatibles dentro de Firewall Manager si la organización desea utilizar dichas soluciones para ayudar a proteger las conexiones salientes.", "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", "waf": "Seguridad" }, @@ -1276,7 +1076,7 @@ "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/afds-overview", "severity": "Medio", "subcategory": "Internet", - "text": "Use Azure Front Door y las directivas WAF para proporcionar protección global en todas las regiones de Azure para las conexiones HTTP/S entrantes a una zona de aterrizaje.", + "text": "Use directivas de Azure Front Door y WAF para proporcionar protección global en todas las regiones de Azure para las conexiones HTTP/S entrantes a una zona de aterrizaje.", "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", "waf": "Seguridad" }, @@ -1287,7 +1087,7 @@ "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", "severity": "Bajo", "subcategory": "Internet", - "text": "Cuando use Azure Front Door y Azure Application Gateway para ayudar a proteger las aplicaciones HTTP/S, use directivas WAF en Azure Front Door. Bloquee Azure Application Gateway para recibir tráfico solo de Azure Front Door.", + "text": "Al usar Azure Front Door y Azure Application Gateway para ayudar a proteger las aplicaciones HTTP/S, use directivas de WAF en Azure Front Door. Bloquee Azure Application Gateway para recibir tráfico solo de Azure Front Door.", "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", "waf": "Seguridad" }, @@ -1299,7 +1099,7 @@ "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", "severity": "Alto", "subcategory": "Internet", - "text": "Se requieren implementar WAF y otros proxies inversos para las conexiones HTTP / S entrantes, implementarlos dentro de una red virtual de zona de aterrizaje y junto con las aplicaciones que están protegiendo y exponiendo a Internet.", + "text": "La implementación de WAF y otros servidores proxy inversos son necesarios para las conexiones HTTP/S entrantes, impleméntelos dentro de una red virtual de zona de aterrizaje y junto con las aplicaciones que protegen y exponen a Internet.", "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", "waf": "Seguridad" }, @@ -1348,7 +1148,7 @@ "link": "https://learn.microsoft.com/azure/firewall/premium-features", "severity": "Alto", "subcategory": "Internet", - "text": "Configure el modo Inteligencia de amenazas de Azure Firewall en Alerta y Denegar para obtener protección adicional.", + "text": "Configure el modo de inteligencia sobre amenazas de Azure Firewall en Alerta y Denegación para obtener protección adicional.", "waf": "Seguridad" }, { @@ -1372,7 +1172,7 @@ "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview", "severity": "Alto", "subcategory": "Internet", - "text": "Para las subredes de redes virtuales no conectadas a Virtual WAN, adjunte una tabla de ruteo para que el tráfico de Internet se redirija a Azure Firewall o a un dispositivo virtual de red", + "text": "En el caso de las subredes de las redes virtuales que no están conectadas a Virtual WAN, adjunte una tabla de rutas para que el tráfico de Internet se redirija a Azure Firewall o a una aplicación virtual de red", "waf": "Seguridad" }, { @@ -1383,7 +1183,7 @@ "link": "https://learn.microsoft.com/azure/virtual-network/vnet-integration-for-azure-services", "severity": "Alto", "subcategory": "Paas", - "text": "Asegúrese de que la comunicación del plano de control para los servicios PaaS de Azure insertados en una red virtual no se interrumpe, por ejemplo, con una ruta 0.0.0.0/0 o una regla de NSG que bloquee el tráfico del plano de control.", + "text": "Asegúrese de que la comunicación del plano de control para los servicios PaaS de Azure insertados en una red virtual no se interrumpa, por ejemplo, con una ruta 0.0.0.0/0 o una regla de grupo de seguridad de red que bloquee el tráfico del plano de control.", "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", "waf": "Seguridad" }, @@ -1394,7 +1194,7 @@ "link": "https://learn.microsoft.com/azure/app-service/networking-features", "severity": "Medio", "subcategory": "Paas", - "text": "Use Private Link, donde esté disponible, para los servicios PaaS de Azure compartidos.", + "text": "Use Private Link, cuando esté disponible, para los servicios PaaS compartidos de Azure.", "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", "waf": "Seguridad" }, @@ -1417,7 +1217,7 @@ "link": "https://learn.microsoft.com/azure/app-service/networking-features", "severity": "Medio", "subcategory": "Paas", - "text": "No habilite los extremos del servicio de red virtual de forma predeterminada en todas las subredes.", + "text": "No habilite los puntos de conexión de servicio de red virtual de forma predeterminada en todas las subredes.", "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", "waf": "Seguridad" }, @@ -1428,7 +1228,7 @@ "link": "https://learn.microsoft.com/azure/app-service/networking-features", "severity": "Medio", "subcategory": "Paas", - "text": "Filtre el tráfico de salida a los servicios PaaS de Azure mediante FQDN en lugar de direcciones IP en Azure Firewall o un NVA para evitar la exfiltración de datos. Si utiliza Private Link, puede bloquear todos los FQDN, de lo contrario, permita solo los servicios PaaS necesarios.", + "text": "Filtre el tráfico de salida a los servicios PaaS de Azure mediante FQDN en lugar de direcciones IP en Azure Firewall o una aplicación virtual de red para evitar la filtración de datos. Si usa Private Link, puede bloquear todos los FQDN, de lo contrario, permita solo los servicios PaaS necesarios.", "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", "waf": "Seguridad" }, @@ -1453,7 +1253,7 @@ "link": "https://learn.microsoft.com/azure/expressroute/expressroute-howto-add-gateway-resource-manager#add-a-gateway", "severity": "Alto", "subcategory": "Segmentación", - "text": "Usar al menos un prefijo /27 para las subredes de puerta de enlace", + "text": "Use al menos un prefijo /27 para las subredes de puerta de enlace", "waf": "Seguridad" }, { @@ -1464,7 +1264,7 @@ "link": "https://learn.microsoft.com/azure/virtual-network/service-tags-overview#available-service-tags", "severity": "Medio", "subcategory": "Segmentación", - "text": "No confíe en las reglas predeterminadas de entrada de NSG mediante la etiqueta de servicio VirtualNetwork para limitar la conectividad.", + "text": "No confíe en las reglas predeterminadas de entrada del grupo de seguridad de red que usan la etiqueta de servicio VirtualNetwork para limitar la conectividad.", "waf": "Seguridad" }, { @@ -1485,7 +1285,7 @@ "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", "severity": "Medio", "subcategory": "Segmentación", - "text": "Utilice NSG para ayudar a proteger el tráfico a través de subredes, así como el tráfico este/oeste a través de la plataforma (tráfico entre zonas de aterrizaje).", + "text": "Use grupos de seguridad de red para ayudar a proteger el tráfico entre subredes, así como el tráfico este/oeste a través de la plataforma (tráfico entre zonas de aterrizaje).", "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", "waf": "Seguridad" }, @@ -1507,7 +1307,7 @@ "link": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", "severity": "Medio", "subcategory": "Segmentación", - "text": "Utilice grupos de seguridad de aplicaciones y NSG para microsegmentar el tráfico dentro de la zona de aterrizaje y evite usar un NVA central para filtrar los flujos de tráfico.", + "text": "Use grupos de seguridad de red y grupos de seguridad de aplicaciones para microsegmentar el tráfico dentro de la zona de aterrizaje y evitar el uso de una aplicación virtual de red central para filtrar los flujos de tráfico.", "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", "waf": "Seguridad" }, @@ -1518,7 +1318,7 @@ "link": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", "severity": "Medio", "subcategory": "Segmentación", - "text": "Habilite los registros de flujo de NSG y introdúzcalos en Traffic Analytics para obtener información sobre los flujos de tráfico internos y externos.", + "text": "Habilite los registros de flujo de NSG e introdúzcalos en Análisis de tráfico para obtener información sobre los flujos de tráfico internos y externos.", "training": "https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/", "waf": "Seguridad" }, @@ -1529,7 +1329,7 @@ "link": "https://learn.microsoft.com/azure/virtual-wan/scenario-any-to-any", "severity": "Medio", "subcategory": "Virtual WAN", - "text": "Considere Virtual WAN para simplificar la administración de redes de Azure y asegúrese de que su escenario se describe explícitamente en la lista de diseños de enrutamiento de Virtual WAN", + "text": "Considere la posibilidad de utilizar Virtual WAN para simplificar la administración de redes de Azure y asegúrese de que el escenario se describe explícitamente en la lista de diseños de enrutamiento de Virtual WAN", "training": "https://learn.microsoft.com/learn/modules/introduction-azure-virtual-wan/", "waf": "Operaciones" }, @@ -1540,7 +1340,7 @@ "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-about", "severity": "Medio", "subcategory": "Virtual WAN", - "text": "Use un centro de WAN virtual por región de Azure para conectar varias zonas de aterrizaje entre regiones de Azure a través de una WAN virtual de Azure global común.", + "text": "Use un centro de conectividad de Virtual WAN por región de Azure para conectar varias zonas de aterrizaje entre sí en las regiones de Azure a través de una instancia global común de Azure Virtual WAN.", "waf": "Rendimiento" }, { @@ -1550,7 +1350,7 @@ "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-about", "severity": "Bajo", "subcategory": "Virtual WAN", - "text": "Siga el principio \"el tráfico en Azure permanece en Azure\" para que la comunicación entre los recursos de Azure se produzca a través de la red troncal de Microsoft", + "text": "Siga el principio \"el tráfico de Azure permanece en Azure\" para que la comunicación entre los recursos de Azure se produzca a través de la red troncal de Microsoft", "waf": "Rendimiento" }, { @@ -1561,7 +1361,7 @@ "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-about", "severity": "Medio", "subcategory": "Virtual WAN", - "text": "Para la protección y el filtrado del tráfico saliente de Internet, implemente Azure Firewall en centros seguros", + "text": "Para la protección y el filtrado del tráfico de Internet saliente, implemente Azure Firewall en centros seguros", "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", "waf": "Seguridad" }, @@ -1582,7 +1382,7 @@ "link": "https://learn.microsoft.com/azure/virtual-wan/azure-monitor-insights", "severity": "Medio", "subcategory": "Virtual WAN", - "text": "Use Azure Monitor Insights for Virtual WAN para supervisar la topología de un extremo a otro de la WAN virtual, el estado y las métricas clave.", + "text": "Use Azure Monitor Insights para Virtual WAN para supervisar la topología de un extremo a otro de Virtual WAN, el estado y las métricas clave.", "waf": "Operaciones" }, { @@ -1592,7 +1392,7 @@ "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-faq#is-branch-to-branch-connectivity-allowed-in-virtual-wan", "severity": "Medio", "subcategory": "Virtual WAN", - "text": "Asegúrese de que las implementaciones de IaC no deshabilitan el tráfico de rama a rama en Virtual WAN, a menos que estos flujos se bloqueen explícitamente.", + "text": "Asegúrese de que las implementaciones de IaC no deshabiliten el tráfico de sucursal a sucursal en Virtual WAN, a menos que estos flujos se bloqueen explícitamente.", "waf": "Fiabilidad" }, { @@ -1602,7 +1402,7 @@ "link": "https://learn.microsoft.com/azure/virtual-wan/about-virtual-hub-routing-preference", "severity": "Medio", "subcategory": "Virtual WAN", - "text": "Utilice AS-Path como preferencia de enrutamiento de concentradores, ya que es más flexible que ExpressRoute o VPN.", + "text": "Use AS-Path como preferencia de enrutamiento del centro, ya que es más flexible que ExpressRoute o VPN.", "waf": "Fiabilidad" }, { @@ -1612,7 +1412,7 @@ "link": "https://learn.microsoft.com/azure/virtual-wan/about-virtual-hub-routing#labels", "severity": "Medio", "subcategory": "Virtual WAN", - "text": "Asegúrese de que las implementaciones de IaC configuran la propagación basada en etiquetas en Virtual WAN; de lo contrario, la conectividad entre los concentradores virtuales se verá afectada.", + "text": "Asegúrese de que las implementaciones de IaC configuran la propagación basada en etiquetas en Virtual WAN, de lo contrario, la conectividad entre los centros virtuales se verá afectada.", "waf": "Fiabilidad" }, { @@ -1623,135 +1423,9 @@ "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-faq#what-is-the-recommended-hub-address-space-during-hub-creation", "severity": "Alto", "subcategory": "Virtual WAN", - "text": "Asigne suficiente espacio IP a los concentradores virtuales, idealmente un prefijo /23.", + "text": "Asigne suficiente espacio IP a los centros virtuales, idealmente un prefijo /23.", "waf": "Fiabilidad" }, - { - "ammp": true, - "category": "Topología y conectividad de red", - "guid": "2e30abab-5478-417c-81bf-bf1ad4ed1ed4", - "id": "D10.01", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-end-to-end-tls", - "severity": "Alto", - "subcategory": "Entrega de aplicaciones", - "text": "Use TLS de un extremo a otro con Azure Front Door. Utilice TLS para las conexiones de sus clientes a la puerta principal, y de la puerta principal a su origen.", - "waf": "Seguridad" - }, - { - "category": "Topología y conectividad de red", - "guid": "10aa45af-166f-44c4-9f36-b6d592dac2ca", - "id": "D10.02", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-http-to-https-redirection", - "severity": "Medio", - "subcategory": "Entrega de aplicaciones", - "text": "Use la redirección de HTTP a HTTPS con Azure Front Door. Admite clientes más antiguos redirigiéndolos automáticamente a una solicitud HTTPS.", - "waf": "Seguridad" - }, - { - "ammp": true, - "category": "Topología y conectividad de red", - "guid": "28b9ee82-b2c7-45aa-bc98-6de6f59a095d", - "id": "D10.03", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#enable-the-waf", - "severity": "Alto", - "subcategory": "Entrega de aplicaciones", - "text": "Habilite Azure Front Door WAF. Proteja su aplicación de una variedad de ataques.", - "waf": "Seguridad" - }, - { - "ammp": true, - "category": "Topología y conectividad de red", - "guid": "2902d8cc-1b0c-4495-afad-624ab70f7bd6", - "id": "D10.04", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#tune-your-waf", - "severity": "Alto", - "subcategory": "Entrega de aplicaciones", - "text": "Ajuste el WAF de puerta delantera de Azure para su carga de trabajo. Reduzca las detecciones de falsos positivos.", - "waf": "Seguridad" - }, - { - "ammp": true, - "category": "Topología y conectividad de red", - "guid": "17ba124b-127d-42b6-9322-388d5b2bbcfc", - "id": "D10.05", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-prevention-mode", - "severity": "Alto", - "subcategory": "Entrega de aplicaciones", - "text": "Use el modo de prevención con Azure Front Door WAF. El modo de prevención garantiza que el WAF bloquee las solicitudes maliciosas.", - "waf": "Seguridad" - }, - { - "ammp": true, - "category": "Topología y conectividad de red", - "guid": "49a98f2b-ec22-4a87-9415-6a10b00d6555", - "id": "D10.06", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#enable-default-rule-sets", - "severity": "Alto", - "subcategory": "Entrega de aplicaciones", - "text": "Habilite los conjuntos de reglas predeterminadas de Azure Front Door WAF. Los conjuntos de reglas predeterminados detectan y bloquean ataques comunes.", - "waf": "Seguridad" - }, - { - "ammp": true, - "category": "Topología y conectividad de red", - "guid": "147a13d4-2a2f-4824-a524-f5855b52b946", - "id": "D10.07", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#enable-bot-management-rules", - "severity": "Alto", - "subcategory": "Entrega de aplicaciones", - "text": "Habilite las reglas de administración de bots de Azure Front Door WAF. Las reglas del bot detectan bots buenos y malos.", - "waf": "Seguridad" - }, - { - "category": "Topología y conectividad de red", - "guid": "d7dcdcb9-0d99-44b9-baab-ac7570ede79a", - "id": "D10.08", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-the-latest-ruleset-versions", - "severity": "Medio", - "subcategory": "Entrega de aplicaciones", - "text": "Use las versiones más recientes del conjunto de reglas de Azure Front Door WAF. Las actualizaciones del conjunto de reglas se actualizan periódicamente para tener en cuenta el panorama actual de amenazas.", - "waf": "Seguridad" - }, - { - "category": "Topología y conectividad de red", - "guid": "b9620385-1cde-418f-914b-a84a06982ffc", - "id": "D10.09", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#add-rate-limiting", - "severity": "Medio", - "subcategory": "Entrega de aplicaciones", - "text": "Agregue limitación de velocidad al WAF de Azure Front Door. La limitación de velocidad bloquea a los clientes accidental o intencionalmente enviando grandes cantidades de tráfico en un corto período de tiempo.", - "waf": "Seguridad" - }, - { - "category": "Topología y conectividad de red", - "guid": "6dc36c52-0124-4ffe-9eaf-23ec1282dedb", - "id": "D10.10", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-a-high-threshold-for-rate-limits", - "severity": "Medio", - "subcategory": "Entrega de aplicaciones", - "text": "Use un umbral alto para los límites de velocidad WAF de Azure Front Door. Los umbrales de límite de alta velocidad evitan bloquear el tráfico legítimo, al tiempo que proporcionan protección contra un número extremadamente alto de solicitudes que podrían abrumar su infraestructura. ", - "waf": "Seguridad" - }, - { - "category": "Topología y conectividad de red", - "guid": "388a3d0e-0a43-4367-90b2-3dd2aeece5ee", - "id": "D10.11", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#geo-filter-traffic", - "severity": "Bajo", - "subcategory": "Entrega de aplicaciones", - "text": "Filtre geográficamente el tráfico mediante Azure Front Door WAF. Permitir el tráfico solo de las regiones esperadas y bloquear el tráfico de otras regiones.", - "waf": "Seguridad" - }, - { - "category": "Topología y conectividad de red", - "guid": "00acd8a9-6975-414f-8491-2be6309893b8", - "id": "D10.12", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#specify-the-unknown-zz-location", - "severity": "Medio", - "subcategory": "Entrega de aplicaciones", - "text": "Especifique la ubicación desconocida (ZZ) al filtrar geográficamente el tráfico con Azure Front Door WAF. Evite bloquear accidentalmente solicitudes legítimas cuando las direcciones IP no se pueden igualar geográficamente.", - "waf": "Seguridad" - }, { "ammp": true, "category": "Gobernanza", @@ -1760,7 +1434,7 @@ "link": "https://learn.microsoft.com/azure/governance/policy/overview", "severity": "Alto", "subcategory": "Gobernanza", - "text": "Aproveche Azure Policy estratégicamente, defina controles para su entorno y use Policy Initiatives para agrupar directivas relacionadas.", + "text": "Aproveche Azure Policy estratégicamente, defina controles para su entorno y use iniciativas de directivas para agrupar directivas relacionadas.", "waf": "Seguridad" }, { @@ -1770,7 +1444,7 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/naming-and-tagging", "severity": "Medio", "subcategory": "Gobernanza", - "text": "Identifique las etiquetas de Azure necesarias y use el modo de directiva 'anexar' para aplicar el uso a través de Azure Policy.", + "text": "Identifique las etiquetas de Azure necesarias y use el modo de directiva \"anexar\" para aplicar el uso a través de Azure Policy.", "waf": "Seguridad" }, { @@ -1780,7 +1454,7 @@ "link": "https://learn.microsoft.com/azure/governance/policy/overview", "severity": "Medio", "subcategory": "Gobernanza", - "text": "Asigne los requisitos normativos y de cumplimiento a las definiciones de directivas de Azure y las asignaciones de roles de Azure.", + "text": "Asigne los requisitos normativos y de cumplimiento normativo a las definiciones de Azure Policy y a las asignaciones de roles de Azure.", "waf": "Seguridad" }, { @@ -1790,7 +1464,7 @@ "link": "https://learn.microsoft.com/azure/governance/policy/overview", "severity": "Medio", "subcategory": "Gobernanza", - "text": "Establecer definiciones de directivas de Azure en el grupo de administración raíz intermedio para que se puedan asignar en ámbitos heredados", + "text": "Establezca definiciones de Azure Policy en el grupo de administración raíz intermedio para que se puedan asignar en ámbitos heredados", "waf": "Seguridad" }, { @@ -1800,7 +1474,7 @@ "link": "https://learn.microsoft.com/azure/governance/policy/overview", "severity": "Medio", "subcategory": "Gobernanza", - "text": "Administre las asignaciones de políticas en el nivel más alto apropiado con exclusiones en los niveles inferiores, si es necesario.", + "text": "Administre las asignaciones de directivas en el nivel más alto y adecuado con exclusiones en los niveles inferiores, si es necesario.", "waf": "Seguridad" }, { @@ -1810,7 +1484,7 @@ "link": "https://learn.microsoft.com/security/benchmark/azure/mcsb-asset-management#am-2-use-only-approved-services", "severity": "Bajo", "subcategory": "Gobernanza", - "text": "Use Azure Policy para controlar qué servicios pueden aprovisionar los usuarios en el nivel de grupo de suscripción/administración", + "text": "Uso de Azure Policy para controlar qué servicios pueden aprovisionar los usuarios en el nivel de suscripción o grupo de administración", "waf": "Seguridad" }, { @@ -1825,13 +1499,13 @@ }, { "category": "Gobernanza", - "description": "La asignación del rol Colaborador de directivas de recursos a ámbitos específicos permite delegar la administración de directivas a los equipos pertinentes. Por ejemplo, un equipo central de TI puede supervisar las políticas de nivel de grupo de administración, mientras que los equipos de aplicaciones manejan las políticas para sus suscripciones, lo que permite un gobierno distribuido con el cumplimiento de los estándares de la organización.", + "description": "La asignación del rol Colaborador de directivas de recursos a ámbitos específicos le permite delegar la administración de directivas a los equipos pertinentes. Por ejemplo, un equipo de TI central puede supervisar las directivas a nivel de grupo de administración, mientras que los equipos de aplicaciones se encargan de las directivas de sus suscripciones, lo que permite la gobernanza distribuida con el cumplimiento de los estándares de la organización.", "guid": "3f988795-25d6-4268-a6d7-0ba6c97be995", "id": "E01.08", "link": "https://learn.microsoft.com/azure/governance/policy/overview#azure-rbac-permissions-in-azure-policy", "severity": "Medio", "subcategory": "Gobernanza", - "text": "Asigne el rol integrado de colaborador de directivas de recursos en un ámbito determinado para habilitar el gobierno de nivel de aplicación.", + "text": "Asigne el rol integrado Colaborador de directivas de recursos en un ámbito determinado para habilitar la gobernanza de nivel de aplicación.", "waf": "Seguridad" }, { @@ -1841,7 +1515,7 @@ "link": "https://learn.microsoft.com/azure/governance/policy/overview", "severity": "Medio", "subcategory": "Gobernanza", - "text": "Limite el número de asignaciones de directivas de Azure realizadas en el ámbito del grupo de administración raíz para evitar la administración mediante exclusiones en ámbitos heredados.", + "text": "Limite el número de asignaciones de Azure Policy realizadas en el ámbito del grupo de administración raíz para evitar la administración a través de exclusiones en ámbitos heredados.", "waf": "Seguridad" }, { @@ -1862,7 +1536,7 @@ "link": "https://learn.microsoft.com/azure/automation/automation-solution-vm-management-config", "severity": "Bajo", "subcategory": "Optimice su inversión en la nube", - "text": "Considere el uso de etiquetas de automatización para iniciar/detener máquinas virtuales en su entorno para ahorrar costos.", + "text": "Considere la posibilidad de usar etiquetas de automatización para iniciar o detener máquinas virtuales en su entorno para ahorrar costos.", "waf": "Seguridad" }, { @@ -1872,7 +1546,7 @@ "link": "https://learn.microsoft.com/azure/virtual-machine-scale-sets/overview", "severity": "Medio", "subcategory": "Escalabilidad", - "text": "Aproveche los conjuntos de Azure Virtual Machine Scale para escalar dentro y fuera en función de la carga.", + "text": "Aproveche los conjuntos de escalado de máquinas virtuales de Azure para escalar horizontalmente y horizontalmente en función de la carga.", "waf": "Fiabilidad" }, { @@ -1882,7 +1556,7 @@ "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", "severity": "Medio", "subcategory": "Optimice su inversión en la nube", - "text": "Configure alertas de presupuesto \"reales\" y \"previstas\".", + "text": "Configure alertas de presupuesto \"real\" y \"pronosticado\".", "waf": "Costar" }, { @@ -1893,7 +1567,7 @@ "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#add-diagnostic-settings-to-save-your-wafs-logs", "severity": "Alto", "subcategory": "Entrega de aplicaciones", - "text": "Agregue la configuración de diagnóstico para guardar los registros de WAF de Azure Front Door. Revise regularmente los registros para comprobar si hay ataques y detecciones de falsos positivos.", + "text": "Agregue la configuración de diagnóstico para guardar los registros de WAF de los servicios de entrega de aplicaciones, como Azure Front Door y Azure Application Gateway. Revise periódicamente los registros para comprobar si hay ataques y detecciones de falsos positivos.", "waf": "Operaciones" }, { @@ -1903,7 +1577,7 @@ "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#send-logs-to-microsoft-sentinel", "severity": "Medio", "subcategory": "Entrega de aplicaciones", - "text": "Envíe los registros de Azure Front Door a Microsoft Sentinel. Detecte ataques e integre la telemetría de puerta principal en su entorno general de Azure.", + "text": "Envíe registros de WAF desde los servicios de entrega de aplicaciones, como Azure Front Door y Azure Application Gateway, a Microsoft Sentinel. Detecte ataques e integre la telemetría de WAF en su entorno general de Azure.", "waf": "Operaciones" }, { @@ -1913,7 +1587,7 @@ "link": "https://learn.microsoft.com/azure/reliability/cross-region-replication-azure", "severity": "Medio", "subcategory": "Protección de datos", - "text": "Considere la replicación entre regiones en Azure para BCDR con regiones emparejadas", + "text": "Considere la posibilidad de replicar entre regiones en Azure para BCDR con regiones emparejadas", "waf": "Fiabilidad" }, { @@ -1923,7 +1597,7 @@ "link": "https://learn.microsoft.com/azure/storage/common/storage-redundancy", "severity": "Medio", "subcategory": "Protección de datos", - "text": "Al usar Azure Backup, tenga en cuenta los diferentes tipos de copia de seguridad (GRS, ZRS Y LRS) ya que la configuración predeterminada es GRS", + "text": "Al usar Azure Backup, tenga en cuenta los diferentes tipos de copia de seguridad (GRS, ZRS Y LRS), ya que la configuración predeterminada es GRS", "waf": "Fiabilidad" }, { @@ -1933,7 +1607,7 @@ "link": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", "severity": "Medio", "subcategory": "Monitorización", - "text": "Use un único área de trabajo de registros de monitor para administrar plataformas de forma centralizada, excepto donde el control de acceso basado en rol de Azure (RBAC de Azure), los requisitos de soberanía de datos o las directivas de retención de datos exijan áreas de trabajo independientes.", + "text": "Use un área de trabajo de registros de un único monitor para administrar las plataformas de forma centralizada, excepto cuando el control de acceso basado en rol de Azure (Azure RBAC), los requisitos de soberanía de datos o las directivas de retención de datos exijan áreas de trabajo independientes.", "training": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", "waf": "Operaciones" }, @@ -1953,7 +1627,7 @@ "link": "https://learn.microsoft.com/azure/azure-monitor/logs/data-retention-archive?tabs=portal-1%2Cportal-2#how-retention-and-archiving-work", "severity": "Medio", "subcategory": "Monitorización", - "text": "Use los registros de Azure Monitor cuando los requisitos de retención de registros superen los dos años. Actualmente puede mantener los datos en estado archivado durante un máximo de 7 años.", + "text": "Use los registros de Azure Monitor cuando los requisitos de retención de registros superen los dos años. Actualmente puede mantener los datos archivados durante un máximo de 7 años.", "training": "https://learn.microsoft.com/learn/paths/architect-infrastructure-operations/", "waf": "Operaciones" }, @@ -1975,7 +1649,7 @@ "link": "https://learn.microsoft.com/azure/governance/policy/how-to/guest-configuration-create", "severity": "Medio", "subcategory": "Monitorización", - "text": "Supervise la desviación de la configuración de la máquina virtual (VM) invitada mediante Azure Policy. Habilitar las capacidades de auditoría de configuración de invitados a través de políticas ayuda a las cargas de trabajo del equipo de aplicaciones a consumir inmediatamente las capacidades de las características con poco esfuerzo.", + "text": "Supervise el desfase de configuración de la máquina virtual (VM) invitada mediante Azure Policy. La habilitación de las capacidades de auditoría de configuración de invitado a través de la política ayuda a las cargas de trabajo del equipo de aplicaciones a consumir inmediatamente las capacidades de las funciones con poco esfuerzo.", "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", "waf": "Operaciones" }, @@ -1986,7 +1660,7 @@ "link": "https://learn.microsoft.com/azure/automation/update-management/overview", "severity": "Medio", "subcategory": "Monitorización", - "text": "Use Update Management en Azure Automation como mecanismo de revisión a largo plazo para máquinas virtuales Windows y Linux. ", + "text": "Use Update Management en Azure Automation como mecanismo de aplicación de revisiones a largo plazo para máquinas virtuales Windows y Linux. ", "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-compute-resources/", "waf": "Operaciones" }, @@ -1997,7 +1671,7 @@ "link": "https://learn.microsoft.com/azure/network-watcher/network-watcher-monitoring-overview", "severity": "Medio", "subcategory": "Monitorización", - "text": "Usar Network Watcher para supervisar de forma proactiva los flujos de tráfico", + "text": "Utilice Network Watcher para supervisar de forma proactiva los flujos de tráfico", "training": "https://learn.microsoft.com/learn/modules/configure-network-watcher/", "waf": "Operaciones" }, @@ -2029,7 +1703,7 @@ "link": "https://learn.microsoft.com/azure/service-health/alerts-activity-log-service-notifications-portal", "severity": "Medio", "subcategory": "Monitorización", - "text": "Incluya eventos de estado de servicio y recursos como parte de la solución general de supervisión de la plataforma. El seguimiento del estado del servicio y de los recursos desde la perspectiva de la plataforma es un componente importante de la administración de recursos en Azure.", + "text": "Incluya eventos de estado de servicios y recursos como parte de la solución general de supervisión de la plataforma. El seguimiento del estado del servicio y de los recursos desde la perspectiva de la plataforma es un componente importante de la administración de recursos en Azure.", "waf": "Operaciones" }, { @@ -2039,7 +1713,7 @@ "link": "https://learn.microsoft.com/azure/azure-monitor/alerts/action-groups", "severity": "Medio", "subcategory": "Monitorización", - "text": "Incluir alertas y grupos de acción como parte de la plataforma Azure Service Health para garantizar que se puedan realizar acciones en las alertas o los problemas.", + "text": "Incluya alertas y grupos de acciones como parte de la plataforma Azure Service Health para asegurarse de que se pueden realizar las alertas o los problemas", "waf": "Operaciones" }, { @@ -2049,7 +1723,7 @@ "link": "https://learn.microsoft.com/azure/sentinel/quickstart-onboard", "severity": "Medio", "subcategory": "Monitorización", - "text": "No envíe entradas de registro sin procesar a los sistemas de supervisión locales. En su lugar, adopte el principio de que los datos nacidos en Azure permanezcan en Azure. Si se requiere la integración de SIEM local, envíe alertas críticas en lugar de registros.", + "text": "No envíe entradas de registro sin procesar a los sistemas de supervisión locales. En su lugar, adopte el principio de que los datos nacidos en Azure permanecen en Azure. Si se requiere la integración de SIEM local, envíe alertas críticas en lugar de registros.", "waf": "Operaciones" }, { @@ -2059,7 +1733,7 @@ "link": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", "severity": "Medio", "subcategory": "Monitorización", - "text": "Use un área de trabajo centralizada de Azure Monitor Log Analytics para recopilar registros y métricas de los recursos de aplicaciones de IaaS y PaaS y controlar el acceso al registro con RBAC de Azure.", + "text": "Use un área de trabajo centralizada de Log Analytics de Azure Monitor para recopilar registros y métricas de los recursos de aplicaciones IaaS y PaaS y controlar el acceso a los registros con Azure RBAC.", "waf": "Operaciones" }, { @@ -2079,7 +1753,7 @@ "link": "https://learn.microsoft.com/azure/azure-monitor/agents/diagnostics-extension-overview", "severity": "Medio", "subcategory": "Monitorización", - "text": "Cuando sea necesario, use cuentas de almacenamiento compartido dentro de la zona de aterrizaje para el almacenamiento del registro de extensión de diagnóstico de Azure.", + "text": "Cuando sea necesario, use cuentas de almacenamiento compartido dentro de la zona de aterrizaje para el almacenamiento de registros de la extensión de diagnóstico de Azure.", "waf": "Operaciones" }, { @@ -2099,7 +1773,7 @@ "link": "https://learn.microsoft.com/azure/architecture/best-practices/monitoring", "severity": "Medio", "subcategory": "Monitorización", - "text": "Asegúrese de que se han evaluado los requisitos de supervisión y que se aplican las configuraciones adecuadas de recopilación de datos y alertas.", + "text": "Asegúrese de que se han evaluado los requisitos de supervisión y de que se aplican las configuraciones adecuadas de recopilación de datos y alertas.", "waf": "Operaciones" }, { @@ -2109,7 +1783,7 @@ "link": "https://learn.microsoft.com/azure/automation/how-to/region-mappings", "severity": "Medio", "subcategory": "Monitorización", - "text": "Considerar las regiones admitidas para el área de trabajo de Log Analytics vinculada y las cuentas de automatización", + "text": "Tenga en cuenta las regiones admitidas para el área de trabajo de Log Analytics vinculada y las cuentas de automatización", "waf": "Operaciones" }, { @@ -2118,19 +1792,19 @@ "id": "F04.01", "link": "https://learn.microsoft.com/azure/governance/policy/concepts/guest-configuration", "severity": "Medio", - "subcategory": "Cumplimiento operativo", + "subcategory": "Cumplimiento operacional", "text": "Use directivas de Azure para implementar automáticamente configuraciones de software a través de extensiones de máquina virtual y aplicar una configuración de máquina virtual de línea base compatible.", "waf": "Seguridad" }, { "category": "Administración", - "description": "Las características de configuración de invitado de Azure Policy pueden auditar y corregir la configuración del equipo (por ejemplo, SO, aplicación, entorno) para garantizar que los recursos se alineen con las configuraciones esperadas, y Update Management puede aplicar la administración de revisiones para máquinas virtuales.", + "description": "Las características de configuración de invitado de Azure Policy pueden auditar y corregir la configuración de la máquina (por ejemplo, el sistema operativo, la aplicación, el entorno) para asegurarse de que los recursos se alinean con las configuraciones esperadas, y Update Management puede aplicar la administración de revisiones para las máquinas virtuales.", "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", "severity": "Medio", - "subcategory": "Cumplimiento operativo", - "text": "Supervise la desviación de la configuración de seguridad de VM a través de Azure Policy.", + "subcategory": "Cumplimiento operacional", + "text": "Supervise el desfase de la configuración de seguridad de la máquina virtual a través de Azure Policy.", "waf": "Seguridad" }, { @@ -2140,7 +1814,7 @@ "link": "https://learn.microsoft.com/azure/site-recovery/site-recovery-overview", "severity": "Medio", "subcategory": "Proteger y recuperar", - "text": "Use Azure Site Recovery para escenarios de recuperación ante desastres de Azure a Azure Virtual Machines. Esto le permite replicar cargas de trabajo entre regiones.", + "text": "Use Azure Site Recovery para escenarios de recuperación ante desastres de Azure a Azure Virtual Machines. Esto le permite replicar cargas de trabajo en todas las regiones.", "waf": "Operaciones" }, { @@ -2160,7 +1834,7 @@ "link": "https://learn.microsoft.com/azure/backup/backup-center-overview", "severity": "Medio", "subcategory": "Proteger y recuperar", - "text": "Use funcionalidades de copia de seguridad nativas de Azure o una solución de copia de seguridad de 3ª parte compatible con Azure.", + "text": "Use funcionalidades de copia de seguridad nativas de Azure o una solución de copia de seguridad de terceros compatible con Azure.", "waf": "Operaciones" }, { @@ -2171,7 +1845,7 @@ "link": "https://learn.microsoft.com/azure/reliability/availability-zones-overview", "severity": "Alto", "subcategory": "Tolerancia a fallos", - "text": "Aproveche las zonas de disponibilidad para sus máquinas virtuales en las regiones donde son compatibles.", + "text": "Aproveche las zonas de disponibilidad para las máquinas virtuales en las regiones en las que se admiten.", "waf": "Fiabilidad" }, { @@ -2223,7 +1897,7 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/overview", "severity": "Alto", "subcategory": "Cifrado y claves", - "text": "Uso del Almacén de claves de Azure para almacenar sus secretos y credenciales", + "text": "Uso de Azure Key Vault para almacenar los secretos y las credenciales", "waf": "Seguridad" }, { @@ -2234,7 +1908,7 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/overview-throttling", "severity": "Medio", "subcategory": "Cifrado y claves", - "text": "Use diferentes almacenes de claves de Azure para diferentes aplicaciones y regiones para evitar los límites de escala de transacciones y restringir el acceso a los secretos.", + "text": "Use diferentes instancias de Azure Key Vaults para diferentes aplicaciones y regiones para evitar límites de escala de transacciones y restringir el acceso a los secretos.", "waf": "Seguridad" }, { @@ -2244,7 +1918,7 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "severity": "Medio", "subcategory": "Cifrado y claves", - "text": "Aprovisione Azure Key Vault con las directivas de eliminación y purga temporal habilitadas para permitir la protección de retención de objetos eliminados.", + "text": "Aprovisione Azure Key Vault con las directivas de eliminación temporal y purga habilitadas para permitir la protección de retención de los objetos eliminados.", "waf": "Seguridad" }, { @@ -2254,7 +1928,7 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "severity": "Medio", "subcategory": "Cifrado y claves", - "text": "Siga un modelo de privilegios mínimos limitando la autorización para eliminar permanentemente claves, secretos y certificados a roles personalizados especializados de Microsoft Entra ID.", + "text": "Siga un modelo de privilegios mínimos limitando la autorización para eliminar claves, secretos y certificados de forma permanente a roles de identificador personalizados especializados de Microsoft Entra.", "waf": "Seguridad" }, { @@ -2264,7 +1938,7 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "severity": "Medio", "subcategory": "Cifrado y claves", - "text": "Automatice el proceso de gestión y renovación de certificados con las autoridades de certificación públicas para facilitar la administración.", + "text": "Automatice el proceso de gestión y renovación de certificados con autoridades de certificación públicas para facilitar la administración.", "waf": "Seguridad" }, { @@ -2284,7 +1958,7 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "severity": "Medio", "subcategory": "Cifrado y claves", - "text": "Habilite el firewall y el punto de conexión del servicio de red virtual o el punto de conexión privado en el almacén para controlar el acceso al almacén de claves.", + "text": "Habilite el firewall y el punto de conexión de servicio de red virtual o el punto de conexión privado en el almacén para controlar el acceso al almacén de claves.", "waf": "Seguridad" }, { @@ -2294,7 +1968,7 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/monitor-key-vault", "severity": "Medio", "subcategory": "Cifrado y claves", - "text": "Use el área de trabajo de Azure Monitor Log Analytics central para auditar el uso de claves, certificados y secretos dentro de cada instancia de Key Vault.", + "text": "Use el área de trabajo de Log Analytics de Azure Monitor central de la plataforma para auditar el uso de claves, certificados y secretos en cada instancia de Key Vault.", "waf": "Seguridad" }, { @@ -2304,7 +1978,7 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "severity": "Medio", "subcategory": "Cifrado y claves", - "text": "Delegue la creación de instancias del Almacén de claves y el acceso con privilegios, y use Azure Policy para aplicar una configuración compatible coherente.", + "text": "Delegue la creación de instancias de Key Vault y el acceso con privilegios, y use Azure Policy para aplicar una configuración coherente y compatible.", "waf": "Seguridad" }, { @@ -2314,7 +1988,7 @@ "link": "https://learn.microsoft.com/azure/security/fundamentals/encryption-atrest", "severity": "Medio", "subcategory": "Cifrado y claves", - "text": "De forma predeterminada, utilice las claves administradas por Microsoft para la funcionalidad de cifrado principal y use claves administradas por el cliente cuando sea necesario.", + "text": "De forma predeterminada, utilice claves administradas por Microsoft para la funcionalidad de cifrado de entidad de seguridad y use claves administradas por el cliente cuando sea necesario.", "waf": "Seguridad" }, { @@ -2324,7 +1998,7 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "severity": "Medio", "subcategory": "Cifrado y claves", - "text": "Use un Almacén de claves de Azure por aplicación por entorno y región.", + "text": "Use una instancia de Azure Key Vault por aplicación, por entorno, por región.", "waf": "Seguridad" }, { @@ -2334,7 +2008,7 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "severity": "Medio", "subcategory": "Cifrado y claves", - "text": "Si desea traer sus propias claves, es posible que no se admitan en todos los servicios considerados. Implemente una mitigación relevante para que las inconsistencias no obstaculicen los resultados deseados. Elija pares de regiones y regiones de recuperación ante desastres adecuadas que minimicen la latencia.", + "text": "Si desea traer sus propias claves, es posible que esto no sea compatible con todos los servicios considerados. Implemente la mitigación pertinente para que las inconsistencias no obstaculicen los resultados deseados. Elija los pares de regiones y las regiones de recuperación ante desastres adecuados que minimicen la latencia.", "waf": "Seguridad" }, { @@ -2344,7 +2018,7 @@ "link": "https://learn.microsoft.com/azure/active-directory/reports-monitoring/overview-reports", "severity": "Medio", "subcategory": "Operaciones", - "text": "Use las capacidades de informes de Microsoft Entra ID para generar informes de auditoría de control de acceso.", + "text": "Use las funcionalidades de informes de Microsoft Entra ID para generar informes de auditoría de control de acceso.", "waf": "Seguridad" }, { @@ -2354,7 +2028,7 @@ "link": "https://learn.microsoft.com/azure/azure-monitor/logs/logs-data-export?tabs=portal", "severity": "Medio", "subcategory": "Operaciones", - "text": "Exporte los registros de actividad de Azure a los registros de Azure Monitor para la retención de datos a largo plazo. Exporte a Azure Storage para almacenamiento a largo plazo más allá de dos años, si es necesario.", + "text": "Exporte los registros de actividad de Azure a los registros de Azure Monitor para la retención de datos a largo plazo. Exporte a Azure Storage para un almacenamiento a largo plazo superior a dos años, si es necesario.", "waf": "Seguridad" }, { @@ -2365,7 +2039,7 @@ "link": "https://learn.microsoft.com/azure/defender-for-cloud/concept-cloud-security-posture-management", "severity": "Alto", "subcategory": "Operaciones", - "text": "Habilite Defender Cloud Security Posture Management para todas las suscripciones.", + "text": "Habilite la administración de la posición de seguridad en la nube de Defender para todas las suscripciones.", "waf": "Seguridad" }, { @@ -2408,7 +2082,7 @@ "link": "https://learn.microsoft.com/azure/security-center/", "severity": "Medio", "subcategory": "Operaciones", - "text": "Supervise la desviación de la revisión del sistema operativo base a través de Azure Monitor Logs y Defender for Cloud.", + "text": "Supervise el desfase de revisiones del sistema operativo base a través de los registros de Azure Monitor y Defender for Cloud.", "waf": "Seguridad" }, { @@ -2418,7 +2092,7 @@ "link": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", "severity": "Medio", "subcategory": "Operaciones", - "text": "Conecte las configuraciones de recursos predeterminadas a un área de trabajo centralizada de Azure Monitor Log Analytics.", + "text": "Conecte las configuraciones de recursos predeterminadas a un área de trabajo centralizada de Log Analytics de Azure Monitor.", "waf": "Seguridad" }, { @@ -2451,7 +2125,7 @@ "link": "https://learn.microsoft.com/azure/active-directory/roles/security-planning", "severity": "Alto", "subcategory": "Acceso privilegiado seguro", - "text": "Cuentas de administrador con privilegios independientes para las tareas administrativas de Azure.", + "text": "Separe las cuentas de administrador con privilegios para las tareas administrativas de Azure.", "waf": "Seguridad" }, { @@ -2482,7 +2156,7 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/platform-automation-devops", "severity": "Alto", "subcategory": "Topologías de equipo de DevOps", - "text": "Asegúrese de contar con un equipo de plataforma de DevOps multifuncional para crear, administrar y mantener su arquitectura de Azure Landing Zone.", + "text": "Asegúrese de que cuenta con un equipo multifuncional de la plataforma DevOps para crear, administrar y mantener la arquitectura de la zona de aterrizaje de Azure.", "waf": "Operaciones" }, { @@ -2492,7 +2166,7 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/devops-teams-topologies#design-recommendations", "severity": "Bajo", "subcategory": "Topologías de equipo de DevOps", - "text": "Objetivo de definir funciones para el equipo de Azure Landing Zone Platform.", + "text": "Trate de definir funciones para el equipo de la plataforma de zona de aterrizaje de Azure.", "waf": "Operaciones" }, { @@ -2502,7 +2176,7 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/devops-teams-topologies#design-recommendations", "severity": "Bajo", "subcategory": "Topologías de equipo de DevOps", - "text": "Intente definir funciones para que los equipos de carga de trabajo de aplicaciones sean autosuficientes y no requieran el soporte del equipo de la plataforma DevOps. Logre esto mediante el uso del rol RBAC personalizado.", + "text": "Trate de definir funciones para que los equipos de carga de trabajo de las aplicaciones sean autosuficientes y no requieran el soporte del equipo de la plataforma DevOps. Logre esto mediante el uso del rol RBAC personalizado.", "waf": "Operaciones" }, { @@ -2534,7 +2208,7 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/development-strategy-development-lifecycle#automated-builds", "severity": "Alto", "subcategory": "Topologías de equipo de DevOps", - "text": "Use los secretos del Almacén de claves para evitar codificar información confidencial, como credenciales (contraseñas de usuario de máquinas virtuales), certificados o claves.", + "text": "Use secretos de Key Vault para evitar codificar de forma rígida información confidencial, como credenciales (máquinas virtuales, contraseñas de usuario), certificados o claves.", "waf": "Operaciones" }, { @@ -2544,7 +2218,7 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/subscription-vending", "severity": "Bajo", "subcategory": "Topologías de equipo de DevOps", - "text": "Implemente la automatización para File > New > Landing Zone para aplicaciones y cargas de trabajo.", + "text": "Implemente la automatización de la zona de aterrizaje de archivos > nueva > para aplicaciones y cargas de trabajo.", "waf": "Operaciones" }, { @@ -2555,7 +2229,7 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/infrastructure-as-code", "severity": "Alto", "subcategory": "Ciclo de vida de desarrollo", - "text": "Asegúrese de que se utiliza un sistema de control de versiones para el código fuente de las aplicaciones y se desarrolla IaC. Microsoft recomienda Git.", + "text": "Asegúrese de que se utiliza un sistema de control de versiones para el código fuente de las aplicaciones y la IaC desarrollada. Microsoft recomienda Git.", "waf": "Operaciones" }, { @@ -2565,7 +2239,7 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/development-strategy-development-lifecycle", "severity": "Bajo", "subcategory": "Ciclo de vida de desarrollo", - "text": "Siga una estrategia de bifurcación para permitir que los equipos colaboren mejor y administren de manera eficiente el control de versiones de IaC y el código de la aplicación. Revisa opciones como Github Flow.", + "text": "Siga una estrategia de ramificación para permitir que los equipos colaboren mejor y administren de manera eficiente el control de versiones de IaC y el código de la aplicación. Revisa opciones como Github Flow.", "waf": "Operaciones" }, { @@ -2575,7 +2249,7 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/development-strategy-development-lifecycle", "severity": "Medio", "subcategory": "Ciclo de vida de desarrollo", - "text": "Adopte una estrategia de solicitud de extracción para ayudar a mantener el control de los cambios de código combinados en ramas.", + "text": "Adopte una estrategia de solicitud de incorporación de cambios para ayudar a mantener el control de los cambios de código fusionados en ramas.", "waf": "Operaciones" }, { @@ -2586,7 +2260,7 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/infrastructure-as-code", "severity": "Alto", "subcategory": "Estrategia de desarrollo", - "text": "Aproveche la infraestructura declarativa como herramientas de código como Azure Bicep, plantillas ARM o Terraform para crear y mantener su arquitectura de Azure Landing Zone. Tanto desde la perspectiva de la carga de trabajo de la plataforma como de la aplicación.", + "text": "Aproveche la infraestructura declarativa como herramientas de código, como Azure Bicep, plantillas de ARM o Terraform, para crear y mantener la arquitectura de la zona de aterrizaje de Azure. Tanto desde el punto de vista de la carga de trabajo de la plataforma como de la aplicación.", "waf": "Operaciones" }, { @@ -2604,7 +2278,7 @@ "metadata": { "name": "Azure Landing Zone Review", "state": "GA", - "timestamp": "September 28, 2023" + "timestamp": "November 06, 2023" }, "severities": [ { @@ -2627,7 +2301,7 @@ "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" }, { diff --git a/checklists/alz_checklist.ja.json b/checklists/alz_checklist.ja.json index 715bd92fe..faf0bf96f 100644 --- a/checklists/alz_checklist.ja.json +++ b/checklists/alz_checklist.ja.json @@ -1,13 +1,13 @@ { "categories": [ { - "name": "Azure Billing and Microsoft Entra ID Tenants" + "name": "Azure 課金と Microsoft Entra ID テナント" }, { - "name": "ID およびアクセス管理" + "name": "IDおよびアクセス管理" }, { - "name": "ネットワーク トポロジと接続性" + "name": "ネットワークトポロジと接続性" }, { "name": "安全" @@ -16,10 +16,10 @@ "name": "管理" }, { - "name": "リソース構成" + "name": "リソース編成" }, { - "name": "プラットフォームの自動化と DevOps" + "name": "プラットフォームの自動化とDevOps" }, { "name": "統治" @@ -27,236 +27,236 @@ ], "items": [ { - "category": "Azure Billing and Microsoft Entra ID Tenants", + "category": "Azure 課金と Microsoft Entra ID テナント", "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", "severity": "中程度", - "subcategory": "Microsoft Entra ID Tenants", - "text": "マルチテナントの明確な規制要件またはビジネス要件がない限り、Azure リソースの管理には 1 つの Entra テナントを使用します。", + "subcategory": "Microsoft Entra ID テナント", + "text": "マルチテナントに関する明確な規制要件またはビジネス要件がない限り、Azure リソースの管理には 1 つの Entra テナントを使用します。", "waf": "オペレーションズ" }, { - "category": "Azure Billing and Microsoft Entra ID Tenants", + "category": "Azure 課金と Microsoft Entra ID テナント", "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", "severity": "低い", - "subcategory": "Microsoft Entra ID Tenants", + "subcategory": "Microsoft Entra ID テナント", "text": "Microsoft Entra ID テナントを管理するためのマルチテナント自動化アプローチがあることを確認する", "waf": "オペレーションズ" }, { - "category": "Azure Billing and Microsoft Entra ID Tenants", + "category": "Azure 課金と Microsoft Entra ID テナント", "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", "severity": "低い", - "subcategory": "Microsoft Entra ID Tenants", - "text": "マルチテナント管理のための Azure Lighthouse の活用", + "subcategory": "Microsoft Entra ID テナント", + "text": "マルチテナント管理に Azure Lighthouse を活用する", "waf": "オペレーションズ" }, { - "category": "Azure Billing and Microsoft Entra ID Tenants", + "category": "Azure 課金と Microsoft Entra ID テナント", "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", "severity": "中程度", "subcategory": "クラウドソリューションプロバイダー", - "text": "パートナーによるテナントの管理に Azure Lighthouse が使用されていることを確認します", + "text": "パートナーによるテナントの管理に Azure Lighthouse が使用されていることを確認する", "waf": "費用" }, { - "category": "Azure Billing and Microsoft Entra ID Tenants", + "category": "Azure 課金と Microsoft Entra ID テナント", "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", "severity": "低い", "subcategory": "クラウドソリューションプロバイダー", - "text": "CSP パートナーとサポート要求とエスカレーション プロセスについて話し合う", + "text": "サポート要求とエスカレーション プロセスについてCSP パートナーと話し合う", "waf": "費用" }, { - "category": "Azure Billing and Microsoft Entra ID Tenants", + "category": "Azure 課金と Microsoft Entra ID テナント", "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", "severity": "中程度", "subcategory": "クラウドソリューションプロバイダー", - "text": "Azure コスト管理を使用したコスト レポートとビューのセットアップ", + "text": "Azure Cost Management を使用したコスト レポートとビューの設定Setup Cost Reporting and Views with Azure Cost Management", "waf": "費用" }, { - "category": "Azure Billing and Microsoft Entra ID Tenants", + "category": "Azure 課金と Microsoft Entra ID テナント", "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", "severity": "中程度", "subcategory": "エンタープライズ契約", - "text": "通知用連絡先をグループ メールボックスに構成する", + "text": "グループ メールボックスへの通知連絡先の構成", "waf": "費用" }, { - "category": "Azure Billing and Microsoft Entra ID Tenants", + "category": "Azure 課金と Microsoft Entra ID テナント", "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", "severity": "低い", "subcategory": "エンタープライズ契約", - "text": "部門とアカウントを使用して、組織の構造を登録階層にマップし、課金の分離に役立ちます。", + "text": "部門とアカウントを使用して、組織の構造を登録階層にマップし、課金の分離に役立てることができます。", "waf": "費用" }, { "ammp": true, - "category": "Azure Billing and Microsoft Entra ID Tenants", + "category": "Azure 課金と Microsoft Entra ID テナント", "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", "severity": "高い", "subcategory": "エンタープライズ契約", - "text": "アカウントの種類が '職場または学校アカウント\" に構成されていることを確認します", + "text": "アカウントの種類が \"職場または学校アカウント\" に構成されていることを確認します", "waf": "安全" }, { - "category": "Azure Billing and Microsoft Entra ID Tenants", + "category": "Azure 課金と Microsoft Entra ID テナント", "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", "severity": "中程度", "subcategory": "エンタープライズ契約", - "text": "EA 登録で DA ビュー料金と AO ビュー料金の両方を有効にして、正しい権限を持つユーザーがコストと請求データを確認できるようにします。", + "text": "EA 加入契約で DA View Charges と AO View Charges の両方を有効にして、正しい権限を持つユーザーがコストと課金データを確認できるようにします。", "waf": "安全" }, { - "category": "Azure Billing and Microsoft Entra ID Tenants", + "category": "Azure 課金と Microsoft Entra ID テナント", "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", "severity": "低い", "subcategory": "エンタープライズ契約", - "text": "エンタープライズ開発/テスト サブスクリプションを利用して、非運用ワークロードのコストを削減する", + "text": "Enterprise Dev/Test サブスクリプションを利用して、非運用ワークロードのコストを削減する", "waf": "費用" }, { - "category": "Azure Billing and Microsoft Entra ID Tenants", + "category": "Azure 課金と Microsoft Entra ID テナント", "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", "severity": "中程度", "subcategory": "エンタープライズ契約", - "text": "ロールの割り当てを定期的に監査して、マイクロソフト エンタープライズ契約の登録にアクセスできるユーザーを確認する", + "text": "ロールの割り当てを定期的に監査して、Enterprise Agreement 加入契約にアクセスできるユーザーを確認します", "waf": "費用" }, { - "category": "Azure Billing and Microsoft Entra ID Tenants", + "category": "Azure 課金と Microsoft Entra ID テナント", "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", "severity": "低い", - "subcategory": "マイクロソフト顧客契約", - "text": "契約の課金アカウント通知の連絡先メールを構成する", + "subcategory": "Microsoft 顧客契約", + "text": "契約の請求先アカウント通知の連絡先メールを構成する", "waf": "費用" }, { - "category": "Azure Billing and Microsoft Entra ID Tenants", + "category": "Azure 課金と Microsoft Entra ID テナント", "guid": "90e87802-602f-4dfb-acea-67c60689f1d7", "id": "A04.02", "link": "https://learn.microsoft.com/azure/cost-management-billing/manage/mca-section-invoice", "severity": "低い", - "subcategory": "マイクロソフト顧客契約", - "text": "[課金プロファイル] セクションと [請求書] セクションを使用して、効果的なコスト管理のための契約請求を構成します", + "subcategory": "Microsoft 顧客契約", + "text": "[課金プロファイル] セクションと [請求書] セクションを使用して、効果的なコスト管理のための契約の請求を構造化します", "waf": "費用" }, { - "category": "Azure Billing and Microsoft Entra ID Tenants", + "category": "Azure 課金と Microsoft Entra ID テナント", "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", "severity": "低い", - "subcategory": "マイクロソフト顧客契約", + "subcategory": "Microsoft 顧客契約", "text": "Azure プランを利用して、非運用ワークロードのコストを削減する", "waf": "費用" }, { - "category": "Azure Billing and Microsoft Entra ID Tenants", + "category": "Azure 課金と Microsoft Entra ID テナント", "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", "severity": "中程度", - "subcategory": "マイクロソフト顧客契約", - "text": "契約請求 RBAC ロールの割り当てを定期的に監査して、MCA 請求アカウントにアクセスできるユーザーを確認する", + "subcategory": "Microsoft 顧客契約", + "text": "契約課金 RBAC ロールの割り当てを定期的に監査して、MCA 課金アカウントにアクセスできるユーザーを確認します", "waf": "費用" }, { "ammp": true, - "category": "ID およびアクセス管理", + "category": "IDおよびアクセス管理", "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", "severity": "高い", "subcategory": "Microsoft Entra ID とハイブリッド ID", - "text": "Azure サービスに対する認証にサービス プリンシパルの代わりにマネージド ID を使用する", + "text": "Azure サービスに対する認証にサービス プリンシパルの代わりにマネージド ID を使用するUse managed identity instead of service principals for authentication to Azure services", "training": "https://learn.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview", "waf": "安全" }, { - "category": "ID およびアクセス管理", + "category": "IDおよびアクセス管理", "guid": "cd163e39-84a5-4b39-97b7-6973abd70d94", "id": "B02.01", "link": "https://learn.microsoft.com/azure/active-directory/hybrid/how-to-connect-sync-staging-server", "severity": "中程度", - "subcategory": "マイクロソフトエントラID", + "subcategory": "Microsoft Entra ID", "text": "AD Connect VM をデプロイする場合は、高可用性/ディザスター リカバリーのためにステージング サーバーを用意することを検討してください", "waf": "確実" }, { "ammp": true, - "category": "ID およびアクセス管理", + "category": "IDおよびアクセス管理", "guid": "984a859c-773e-47d2-9162-3a765a917e1f", "id": "B03.01", "link": "https://learn.microsoft.com/azure/active-directory/roles/security-emergency-access", "severity": "高い", "subcategory": "同一性", - "text": "緊急アクセスまたは非常用アカウントを実装して、テナント全体のアカウントのロックアウトを防止します", + "text": "テナント全体のアカウント ロックアウトを防ぐために、緊急アクセスまたは非常用アカウントを実装する", "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/", "waf": "安全" }, { - "category": "ID およびアクセス管理", + "category": "IDおよびアクセス管理", "guid": "1cf0b8da-70bd-44d0-94af-8d99cfc89ae1", "id": "B03.02", "link": "https://learn.microsoft.com/azure/active-directory/reports-monitoring/concept-activity-logs-azure-monitor", "severity": "中程度", "subcategory": "同一性", - "text": "Microsoft Entra ID ログをプラットフォーム中心の Azure Monitor と統合します。Azure Monitor を使用すると、Azure のログと監視データに関する信頼できる唯一の情報源を使用できるため、ログの収集と保持に関する要件を満たすためのクラウド ネイティブ オプションを組織に提供します。", + "text": "Microsoft Entra ID ログをプラットフォーム中心の Azure Monitor と統合します。Azure Monitor を使用すると、Azure のログと監視データに関する信頼できる唯一の情報源が提供され、組織はログの収集と保持に関する要件を満たすためのクラウド ネイティブ オプションを利用できます。", "waf": "安全" }, { "ammp": true, - "category": "ID およびアクセス管理", + "category": "IDおよびアクセス管理", "guid": "348ef254-c27d-442e-abba-c7571559ab91", "id": "B03.03", "link": "https://learn.microsoft.com/azure/role-based-access-control/overview", "severity": "高い", "subcategory": "同一性", - "text": "クラウド運用モデルに合わせた RBAC モデルを適用します。管理グループとサブスクリプション全体のスコープを設定し、割り当てます。", + "text": "クラウド運用モデルに合わせた RBAC モデルを適用します。管理グループとサブスクリプション全体のスコープと割り当てを行います。", "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", "waf": "安全" }, { - "category": "ID およびアクセス管理", + "category": "IDおよびアクセス管理", "guid": "53e8908a-e28c-484c-93b6-b7808b9fe5c4", "id": "B03.04", "link": "https://learn.microsoft.com/azure/active-directory/conditional-access/overview", "severity": "低い", "subcategory": "同一性", - "text": "Azure 環境に対する権限を持つすべてのユーザーに Microsoft Entra ID の条件付きアクセス ポリシーを適用する", + "text": "Azure 環境に対する権限を持つすべてのユーザーに Microsoft Entra ID 条件付きアクセス ポリシーを適用する", "training": "https://learn.microsoft.com/learn/modules/plan-implement-administer-conditional-access/", "waf": "安全" }, { "ammp": true, - "category": "ID およびアクセス管理", + "category": "IDおよびアクセス管理", "guid": "1049d403-a923-4c34-94d0-0018ac6a9e01", "id": "B03.05", "link": "https://learn.microsoft.com/azure/active-directory/authentication/concept-mfa-howitworks", @@ -267,74 +267,74 @@ "waf": "安全" }, { - "category": "ID およびアクセス管理", + "category": "IDおよびアクセス管理", "guid": "e6a83de5-de32-4c19-a248-1607d5d1e4e6", "id": "B03.06", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/manage/centralize-operations", "severity": "中程度", "subcategory": "同一性", - "text": "役割とセキュリティの要件に基づいて、ランディング ゾーン内にデプロイされたリソースを管理するための一元化された委任された責任を適用します", + "text": "役割とセキュリティの要件に基づいて、ランディング ゾーン内にデプロイされたリソースを管理するために、一元化された委任された責任を適用します", "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-identities-governance/", "waf": "安全" }, { - "category": "ID およびアクセス管理", + "category": "IDおよびアクセス管理", "guid": "14658d35-58fd-4772-99b8-21112df27ee4", "id": "B03.07", "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-configure", "severity": "中程度", "subcategory": "同一性", - "text": "Microsoft Entra ID 特権 ID 管理 (PIM) を適用して、ゼロ スタンディング アクセスと最小特権を確立する", + "text": "Microsoft Entra ID Privileged Identity Management (PIM) を適用して、ゼロの永続的なアクセスと最小限の特権を確立します", "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/", "waf": "安全" }, { "ammp": true, - "category": "ID およびアクセス管理", + "category": "IDおよびアクセス管理", "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", "severity": "高い", "subcategory": "同一性", - "text": "すべてのアカウントの種類に対して、認証の種類である職場または学校アカウントのみを使用します。マイクロソフト アカウントの使用を避ける", + "text": "すべてのアカウントの種類には、認証の種類である [職場または学校アカウント] のみを使用します。Microsoft アカウントの使用は避けてください", "training": "https://learn.microsoft.com/learn/modules/explore-basic-services-identity-types/", "waf": "安全" }, { - "category": "ID およびアクセス管理", + "category": "IDおよびアクセス管理", "guid": "4b69bad3-3aad-45e8-a68e-1d76667313b4", "id": "B03.09", "link": "https://learn.microsoft.com/azure/active-directory/fundamentals/active-directory-groups-create-azure-portal", "severity": "中程度", "subcategory": "同一性", - "text": "グループのみを使用してアクセス許可を割り当てます。グループ管理システムが既に配置されている場合は、オンプレミスのグループを Azure AD 専用グループに追加します。", + "text": "アクセス許可の割り当てには、グループのみを使用します。グループ管理システムが既に導入されている場合は、オンプレミス グループを Azure-AD 専用グループに追加します。", "training": "https://learn.microsoft.com/learn/paths/manage-identity-and-access/", "waf": "安全" }, { - "category": "ID およびアクセス管理", + "category": "IDおよびアクセス管理", "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", "severity": "中程度", "subcategory": "同一性", - "text": "Azure プラットフォーム所有者、ネットワーク管理、セキュリティ運用、サブスクリプション所有者、アプリケーション所有者の主要なロールに Azure カスタム ロールを使用することを検討してください", + "text": "Azure プラットフォーム所有者、ネットワーク管理、セキュリティ運用、サブスクリプション所有者、アプリケーション所有者の主要なロールには、Azure カスタム ロールの使用を検討してください", "training": "https://learn.microsoft.com/learn/modules/create-custom-azure-roles-with-rbac/", "waf": "安全" }, { - "category": "ID およびアクセス管理", + "category": "IDおよびアクセス管理", "guid": "1559ab91-53e8-4908-ae28-c84c33b6b780", "id": "B03.11", "link": "https://learn.microsoft.com/azure/active-directory-domain-services/overview", "severity": "中程度", "subcategory": "同一性", - "text": "Azure Active Directory ドメイン サービス (AADDS) が使用されている場合は、このサービスは 1 つのサブスクリプションにしか投影できないため、プライマリ リージョン内に AADDS をデプロイします", + "text": "Azure Active Directory Domains Services (AADDS) が使用されている場合は、このサービスは 1 つのサブスクリプションにしか投影できないため、プライマリ リージョン内に AADDS をデプロイします", "training": "https://learn.microsoft.com/learn/modules/azure-active-directory/", "waf": "安全" }, { - "category": "ID およびアクセス管理", + "category": "IDおよびアクセス管理", "guid": "8b9fe5c4-1049-4d40-9a92-3c3474d00018", "id": "B03.12", "link": "https://learn.microsoft.com/azure/active-directory-domain-services/overview", @@ -345,62 +345,62 @@ "waf": "安全" }, { - "category": "ID およびアクセス管理", + "category": "IDおよびアクセス管理", "guid": "ac6a9e01-e6a8-43de-9de3-2c1992481607", "id": "B03.13", "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/identity/adds-extend-domain", "severity": "中程度", "subcategory": "同一性", - "text": "Windows サーバー上の AD が使用中の場合、Azure のリソースは正しいドメイン コントローラーを使用していますか?", + "text": "Windows サーバー上の AD が使用されている場合、Azure のリソースは正しいドメイン コントローラーを使用していますか?", "training": "https://learn.microsoft.com/learn/paths/implement-windows-server-iaas-virtual-machine-identity/", "waf": "安全" }, { - "category": "ID およびアクセス管理", + "category": "IDおよびアクセス管理", "guid": "d5d1e4e6-1465-48d3-958f-d77249b82111", "id": "B03.14", "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy", "severity": "中程度", "subcategory": "同一性", - "text": "Microsoft Entra ID アプリケーション プロキシを VPN またはリバース プロキシの代わりに使用して、リモート ユーザーに内部アプリケーション (クラウドまたはオンプレミスでホストされている) への安全で認証されたアクセスを提供することを検討してください。", + "text": "Microsoft Entra ID アプリケーション プロキシを VPN またはリバース プロキシの代わりとして使用して、リモート ユーザーに内部アプリケーション (クラウドまたはオンプレミスでホストされている) への安全で認証されたアクセスを提供することを検討してください。", "training": "https://learn.microsoft.com/learn/paths/implement-applications-external-access-azure-ad/", "waf": "安全" }, { - "category": "ID およびアクセス管理", + "category": "IDおよびアクセス管理", "guid": "35037e68-9349-4c15-b371-228514f4cdff", "id": "B03.15", "link": "https://learn.microsoft.com/azure/active-directory/roles/best-practices", "severity": "中程度", "subcategory": "同一性", - "text": "オンプレミスの同期されたアカウントを Microsoft Entra ID ロールの割り当てに使用しないでください。", + "text": "Microsoft Entra ID ロールの割り当てにオンプレミスの同期アカウントを使用しないでください。", "training": "https://learn.microsoft.com/learn/modules/design-identity-security-strategy/", "waf": "安全" }, { - "category": "ID およびアクセス管理", + "category": "IDおよびアクセス管理", "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", "severity": "低い", "subcategory": "ランディング ゾーン", - "text": "仮想ネットワークを使用して ID (ADDS) ネットワーク セグメント化を構成し、ハブにピアバックします。アプリケーション ランディング ゾーン (レガシ) 内で認証を提供する。", + "text": "仮想ネットワークを使用して ID (ADDS) ネットワーク セグメント化を構成し、ハブにピア バックします。アプリケーション ランディング ゾーン (レガシ) 内での認証の提供。", "training": "https://learn.microsoft.com/azure/architecture/example-scenario/identity/adds-extend-domain", "waf": "安全" }, { - "category": "ID およびアクセス管理", + "category": "IDおよびアクセス管理", "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", "severity": "中程度", "subcategory": "ランディング ゾーン", - "text": "可能であれば、Azure RBAC を使用して、リソースへのデータ プレーン アクセスを管理します。たとえば、Key Vault、ストレージ アカウント、データベース サービス全体のデータ操作。", + "text": "可能であれば、Azure RBAC を使用して、リソースへのデータ プレーン アクセスを管理します。例: Key Vault、ストレージ アカウント、データベース サービス全体のデータ操作。", "training": "https://learn.microsoft.com/azure/role-based-access-control/overview", "waf": "安全" }, { - "category": "ID およびアクセス管理", + "category": "IDおよびアクセス管理", "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", @@ -411,40 +411,40 @@ }, { "ammp": true, - "category": "リソース構成", + "category": "リソース編成", "guid": "cacf55bc-e4e4-46be-96bc-57a5f23a269a", "id": "C01.01", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/resource-naming", "severity": "高い", "subcategory": "名前付けとタグ付け", - "text": "マイクロソフトのベスト プラクティスの名前付け基準に従うことをお勧めします", + "text": "Microsoft のベスト プラクティスの名前付け標準に従うことをお勧めします", "waf": "安全" }, { - "category": "リソース構成", + "category": "リソース編成", "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", "severity": "中程度", "subcategory": "サブスクリプション", - "text": "4 レベル以下の適度にフラットな管理グループ階層を適用します。", + "text": "4 レベル以下の合理的にフラットな管理グループ階層を適用します。", "training": "https://learn.microsoft.com/learn/modules/azure-architecture-fundamentals/", "waf": "安全" }, { - "category": "リソース構成", + "category": "リソース編成", "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", "severity": "中程度", "subcategory": "サブスクリプション", - "text": "サンドボックス管理グループを適用して、ユーザーがすぐに Azure を試せるようにします", + "text": "サンドボックス管理グループを適用して、ユーザーがすぐに Azure を試せるようにする", "training": "https://learn.microsoft.com/learn/paths/enterprise-scale-architecture/", "waf": "安全" }, { - "category": "リソース構成", + "category": "リソース編成", "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", @@ -455,106 +455,106 @@ "waf": "安全" }, { - "category": "リソース構成", + "category": "リソース編成", "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", "severity": "中程度", "subcategory": "サブスクリプション", - "text": "接続管理グループで専用の接続サブスクリプションを適用して、Azure Virtual WAN ハブ、プライベート ドメイン ネーム システム (DNS)、ExpressRoute 回線、およびその他のネットワーク リソースをホストします。", + "text": "接続管理グループで専用の接続サブスクリプションを適用して、Azure Virtual WAN ハブ、プライベート ドメイン ネーム システム (DNS)、ExpressRoute 回線、その他のネットワーク リソースをホストします。", "training": "https://learn.microsoft.com/learn/paths/enterprise-scale-architecture/", "waf": "安全" }, { - "category": "リソース構成", + "category": "リソース編成", "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", "severity": "中程度", "subcategory": "サブスクリプション", - "text": "[サブスクリプションがルート管理グループに配置されないように強制する]", + "text": "ルート管理グループの下にサブスクリプションを配置しないように強制する", "waf": "安全" }, { - "category": "リソース構成", + "category": "リソース編成", "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", "severity": "中程度", "subcategory": "サブスクリプション", - "text": "管理グループ階層設定で Azure RBAC 承認を有効にすることで、特権ユーザーのみがテナント内の管理グループを操作できるようにする", + "text": "管理グループ階層の設定で Azure RBAC 承認を有効にすることで、特権ユーザーのみがテナント内の管理グループを操作できるようにします", "waf": "安全" }, { - "category": "リソース構成", + "category": "リソース編成", "guid": "92481607-d5d1-4e4e-9146-58d3558fd772", "id": "C02.07", "link": "https://learn.microsoft.com/azure/governance/management-groups/overview", "severity": "中程度", "subcategory": "サブスクリプション", - "text": "ルート レベルの管理グループの下に管理グループを適用して、セキュリティ、コンプライアンス、接続、機能のニーズに基づいてワークロードの種類を表します。", + "text": "ルートレベルの管理グループの下に管理グループを適用し、セキュリティ、コンプライアンス、接続性、機能のニーズに基づいてワークロードの種類を表します。", "waf": "安全" }, { "ammp": true, - "category": "リソース構成", + "category": "リソース編成", "guid": "49b82111-2df2-47ee-912e-7f983f630472", "id": "C02.08", "link": "https://learn.microsoft.com/azure/governance/management-groups/overview", "severity": "高い", "subcategory": "サブスクリプション", - "text": "リソース所有者に自分の役割と責任を認識させ、アクセス レビュー、予算レビュー、ポリシー コンプライアンス、必要に応じて修復するプロセスを適用します。", + "text": "リソース所有者に自分の役割と責任を認識させ、レビュー、予算レビュー、ポリシーコンプライアンスにアクセスし、必要に応じて修復するプロセスを実施します。", "waf": "安全" }, { - "category": "リソース構成", + "category": "リソース編成", "guid": "2dd69c5b-5c26-422f-94b6-9bad33aad5e8", "id": "C02.09", "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits", "severity": "中程度", "subcategory": "サブスクリプション", - "text": "すべてのサブスクリプション所有者と IT コア チームが、サブスクリプション クォータと、特定のサブスクリプションのプロビジョニング リソースに与える影響を認識していることを確認します。", + "text": "すべてのサブスクリプション所有者と IT コア チームが、サブスクリプションのクォータと、それらが特定のサブスクリプションのプロビジョニング リソースに与える影響を認識していることを確認します。", "waf": "安全" }, { "ammp": true, - "category": "リソース構成", + "category": "リソース編成", "guid": "c68e1d76-6673-413b-9f56-64b5e984a859", "id": "C02.10", "link": "https://learn.microsoft.com/azure/cost-management-billing/reservations/save-compute-costs-reservations", "severity": "高い", "subcategory": "サブスクリプション", - "text": "必要に応じてリザーブドインスタンスを使用して、コストを最適化し、ターゲットリージョンで使用可能な容量を確保します。Azure ポリシーを使用して、購入した予約インスタンス VM SKU の使用を強制します。", + "text": "必要に応じてリザーブドインスタンスを使用して、コストを最適化し、ターゲットリージョンで使用可能な容量を確保します。購入した予約インスタンス VM SKU の使用を Azure Policy で強制します。", "training": "https://learn.microsoft.com/learn/paths/improve-reliability-modern-operations/", "waf": "安全" }, { "ammp": true, - "category": "リソース構成", + "category": "リソース編成", "guid": "c773e7d2-6162-43a7-95a9-17e1f348ef25", "id": "C02.11", "link": "https://learn.microsoft.com/azure/architecture/framework/scalability/design-capacity", "severity": "高い", "subcategory": "サブスクリプション", - "text": "ダッシュボード、ワークブック、または手動プロセスを適用して、使用されている容量レベルを監視する", + "text": "ダッシュボード、ブック、または手動プロセスを適用して、使用済み容量レベルを監視します", "training": "https://learn.microsoft.com/learn/paths/monitor-usage-performance-availability-resources-azure-monitor/", "waf": "安全" }, { - "category": "リソース構成", + "category": "リソース編成", "guid": "4c27d42e-8bba-4c75-9155-9ab9153e8908", "id": "C02.12", "link": "https://azure.microsoft.com/global-infrastructure/services/", "severity": "中程度", "subcategory": "サブスクリプション", - "text": "必要なサービスと機能が、選択した展開リージョン内で利用可能であることを確認する", + "text": "必要なサービスと機能が、選択したデプロイ リージョン内で使用可能であることを確認する", "training": "https://learn.microsoft.com/learn/modules/azure-architecture-fundamentals/", "waf": "安全" }, { "ammp": true, - "category": "リソース構成", + "category": "リソース編成", "guid": "ae28c84c-33b6-4b78-88b9-fe5c41049d40", "id": "C02.13", "link": "https://learn.microsoft.com/azure/cost-management-billing/cost-management-billing-overview", @@ -565,100 +565,53 @@ "waf": "安全" }, { - "category": "リソース構成", + "category": "リソース編成", "guid": "3a923c34-74d0-4001-aac6-a9e01e6a83de", "id": "C02.14", "link": "https://learn.microsoft.com/azure/governance/management-groups/overview", "severity": "中程度", "subcategory": "サブスクリプション", - "text": "Windows Server 上の AD の場合は、Indentity 管理グループに専用の ID サブスクリプションを確立して、Windows Server Active Directory ドメイン コントローラーをホストします", + "text": "Windows Server 上の AD の場合は、Windows Server Active Directory ドメイン コントローラーをホストするために、Indentity 管理グループに専用の ID サブスクリプションを確立します", "training": "https://learn.microsoft.com/learn/paths/enterprise-scale-architecture/", "waf": "安全" }, { - "category": "リソース構成", + "category": "リソース編成", "graph": "resources | extend compliant = isnotnull(['tags']) | project name, id, subscriptionId, resourceGroup, tags, compliant", "guid": "5de32c19-9248-4160-9d5d-1e4e614658d3", "id": "C02.15", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/track-costs", "severity": "中程度", "subcategory": "サブスクリプション", - "text": "タグが請求とコスト管理に使用されていることを確認する", + "text": "タグが課金とコスト管理に使用されていることを確認する", "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", "waf": "安全" }, { - "category": "ネットワーク トポロジと接続性", - "guid": "f00a69de-7076-4734-a734-6e4552cad9e1", + "category": "ネットワークトポロジと接続性", + "guid": "373f482f-3e39-4d39-8aa4-7e566f6082b6", "id": "D01.01", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-latest-version-for-customer-managed-certificates", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-app-delivery", "severity": "中程度", "subcategory": "アプリ配信", - "text": "Azure Front Door でカスタマー マネージド TLS 証明書を使用する場合は、\"最新\" の証明書バージョンを使用します。証明書の手動更新による停止のリスクを軽減します。", + "text": "Application Gateway と Azure Front door を使用して、ワークロードのスポークから配信アプリケーション コンテンツをセキュリティで保護するための計画を作成します。 アプリケーション配信チェックリストを使用して、推奨事項を確認できます。", "waf": "オペレーションズ" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "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", "severity": "中程度", "subcategory": "アプリ配信", - "text": "内部向けアプリ (企業) と外部向けアプリ (オンライン) の両方のランディング ゾーン内でアプリ配信を実行します。", + "text": "内部向けアプリ (corp) と外部向けアプリ (online) の両方のランディング ゾーン内でアプリ配信を実行します。", "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", "waf": "安全" }, { - "category": "ネットワーク トポロジと接続性", - "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": "D01.03", - "link": "https://learn.microsoft.com/azure/application-gateway/overview-v2", - "severity": "中程度", - "subcategory": "アプリ配信", - "text": "アプリケーション ゲートウェイ v2 SKU を使用していることを確認する", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", - "waf": "安全" - }, - { - "category": "ネットワーク トポロジと接続性", - "graph": "resources | where type == 'microsoft.network/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard')", - "guid": "4e35fbf5-0ae2-48b2-97ce-753353edbd1a", - "id": "D01.04", - "link": "https://learn.microsoft.com/azure/load-balancer/load-balancer-overview", - "severity": "中程度", - "subcategory": "アプリ配信", - "text": "Azure ロード バランサーに標準 SKU を使用していることを確認する", - "waf": "安全" - }, - { - "category": "ネットワーク トポロジと接続性", - "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 | project id, subnetId = tostring(subnets.id), subnetPrefixLength = split(subnets.properties.addressPrefix, '/')[1]) on subnetId | extend compliant = (subnetPrefixLength <= 26) | distinct id,compliant", - "guid": "dfc50f87-3800-424c-937b-ed5f186e7c15", - "id": "D01.05", - "link": "https://learn.microsoft.com/azure/application-gateway/configuration-infrastructure#size-of-the-subnet", - "severity": "中程度", - "subcategory": "アプリ配信", - "text": "アプリケーション ゲートウェイは、IP プレフィックスが /26 以上のサブネットにデプロイする必要があります", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", - "waf": "安全" - }, - { - "category": "ネットワーク トポロジと接続性", - "description": "リバースプロキシ全般、特にWAFの管理は、ネットワークよりもアプリケーションに近いため、アプリと同じサブスクリプションに属します。アプリケーション ゲートウェイと WAF を接続サブスクリプションに一元化しても、1 つのチームで管理されている場合は問題ない可能性があります。", - "guid": "48b662d6-d15f-4512-a654-98f6dfe237de", - "id": "D01.06", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", - "severity": "中程度", - "subcategory": "アプリ配信", - "text": "ランディング ゾーン仮想ネットワーク内およびセキュリティ保護されているアプリを使用して、受信 HTTP(S) 接続をプロキシするために使用される Azure Application Gateway v2 またはパートナー NVA をデプロイします。", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", - "waf": "安全" - }, - { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "143b16c3-1d7a-4a9b-9470-4489a8042d88", - "id": "D01.07", + "id": "D01.03", "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", "severity": "中程度", "subcategory": "アプリ配信", @@ -667,313 +620,160 @@ "waf": "安全" }, { - "category": "ネットワーク トポロジと接続性", - "guid": "e79d17b7-3b22-4a5a-97e7-a8ed4b30e38c", - "id": "D01.08", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", - "severity": "中程度", - "subcategory": "アプリ配信", - "text": "Azure Front Door と WAF ポリシーを使用して、複数の Azure リージョンにまたがるグローバル HTTP/S アプリを配信し、保護します。", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", - "waf": "安全" - }, - { - "category": "ネットワーク トポロジと接続性", - "guid": "3f29812b-2363-4cef-b179-b599de0d5973", - "id": "D01.09", - "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", - "severity": "中程度", - "subcategory": "アプリ配信", - "text": "Front Door とアプリケーション ゲートウェイを使用して HTTP/S アプリを保護する場合は、Front Door で WAF ポリシーを使用します。アプリケーション ゲートウェイをロックダウンして、Front Door からのトラフィックのみを受信します。", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", - "waf": "安全" - }, - { - "ammp": true, - "category": "ネットワーク トポロジと接続性", - "guid": "cd4cd21b-0881-437f-9e6c-4cfd3e504547", - "id": "D01.10", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", - "severity": "高い", - "subcategory": "アプリ配信", - "text": "トラフィック マネージャーを使用して、HTTP/S 以外のプロトコルにまたがるグローバル アプリを配信します。", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", - "waf": "確実" - }, - { - "category": "ネットワーク トポロジと接続性", - "guid": "3b4b3e88-a459-4ed5-a22f-644dfbc58204", - "id": "D01.11", - "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy#how-application-proxy-works", - "severity": "低い", - "subcategory": "アプリ配信", - "text": "ユーザーが内部アプリケーションへのアクセスのみを必要とする場合、Microsoft Entra ID アプリケーション プロキシは Azure Virtual Desktop (AVD) の代替として検討されていますか?", - "training": "https://learn.microsoft.com/learn/modules/configure-azure-ad-application-proxy/", - "waf": "安全" - }, - { - "category": "ネットワーク トポロジと接続性", - "guid": "01ca7cf1-5754-442d-babb-8ba6772e5c30", - "id": "D01.12", - "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy#how-application-proxy-works", - "severity": "中程度", - "subcategory": "アプリ配信", - "text": "ネットワーク内の着信接続用に開いているファイアウォール ポートの数を減らすには、Microsoft Entra ID アプリケーション プロキシを使用して、リモート ユーザーに内部アプリケーションへのセキュリティで保護された認証されたアクセスを提供することを検討してください。", - "training": "https://learn.microsoft.com/learn/paths/implement-applications-external-access-azure-ad/", - "waf": "安全" - }, - { - "ammp": true, - "category": "ネットワーク トポロジと接続性", - "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": "D01.13", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-policy-settings", - "severity": "高い", - "subcategory": "アプリ配信", - "text": "フロント ドアの WAF プロファイルを \"防止\" モードでデプロイします。", - "waf": "安全" - }, - { - "ammp": true, - "category": "ネットワーク トポロジと接続性", - "guid": "062d5839-4d36-402f-bfa4-02811eb936e9", - "id": "D01.14", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#avoid-combining-traffic-manager-and-front-door", - "severity": "高い", - "subcategory": "アプリ配信", - "text": "Azure Traffic Manager と Azure Front Door を組み合わせることは避けてください。", - "waf": "安全" - }, - { - "ammp": true, - "category": "ネットワーク トポロジと接続性", - "guid": "5efeb96a-003f-4b18-8fcd-b4d84459c2b2", - "id": "D01.15", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-the-same-domain-name-on-front-door-and-your-origin", - "severity": "高い", - "subcategory": "アプリ配信", - "text": "Azure フロント ドアと配信元で同じドメイン名を使用します。ホスト名が一致しないと、微妙なバグが発生する可能性があります。", - "waf": "安全" - }, - { - "category": "ネットワーク トポロジと接続性", - "guid": "0b5a380c-4bfb-47bc-b1d7-dcfef363a61b", - "id": "D01.16", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#disable-health-probes-when-theres-only-one-origin-in-an-origin-group", - "severity": "低い", - "subcategory": "アプリ配信", - "text": "Azure Front Door 配信元グループに配信元が 1 つしかない場合は、正常性プローブを無効にします。", - "waf": "パフォーマンス" - }, - { - "category": "ネットワーク トポロジと接続性", - "guid": "5567048e-e5d7-4206-9c55-b5ed45d2cc0c", - "id": "D01.17", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#select-good-health-probe-endpoints", - "severity": "中程度", - "subcategory": "アプリ配信", - "text": "Azure フロント ドアの正常な正常性プローブ エンドポイントを選択します。アプリケーションのすべての依存関係をチェックする正常性エンドポイントを構築することを検討してください。", - "waf": "確実" - }, - { - "category": "ネットワーク トポロジと接続性", - "guid": "a13f72f3-8f5c-4864-95e5-75bf37fbbeb1", - "id": "D01.18", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-head-health-probes", - "severity": "低い", - "subcategory": "アプリ配信", - "text": "Azure Front Door で HEAD 正常性プローブを使用して、Front Door がアプリケーションに送信するトラフィックを削減します。", - "waf": "パフォーマンス" - }, - { - "ammp": true, - "category": "ネットワーク トポロジと接続性", - "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": "D01.19", - "link": "https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity", - "severity": "高い", - "subcategory": "アプリ配信", - "text": "SNAT のスケーラビリティを向上させるために、ロード バランサーのアウトバウンド規則の代わりに Azure NAT ゲートウェイを使用する", - "waf": "確実" - }, - { - "ammp": true, - "category": "ネットワーク トポロジと接続性", - "guid": "af95c92d-d723-4f4a-98d7-8722324efd4d", - "id": "D01.20", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-managed-tls-certificates", - "severity": "高い", - "subcategory": "アプリ配信", - "text": "マネージド TLS 証明書を Azure Front Door で使用します。運用コストと証明書の更新による停止のリスクを軽減します。", - "waf": "オペレーションズ" - }, - { - "category": "ネットワーク トポロジと接続性", - "guid": "189ea962-3969-4863-8f5a-5ad808c2cf4b", - "id": "D01.21", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#define-your-waf-configuration-as-code", - "severity": "中程度", - "subcategory": "アプリ配信", - "text": "Azure Front Door WAF 構成をコードとして定義します。コードを使用すると、新しいバージョンのルールセットをより簡単に採用し、保護を強化できます。", - "waf": "オペレーションズ" - }, - { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "de0d5973-cd4c-4d21-a088-137f5e6c4cfd", "id": "D02.01", "link": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", "severity": "中程度", "subcategory": "暗号化", - "text": "ExpressRoute ダイレクトを使用している場合は、組織のルーターと MSEE の間のレイヤー 2 レベルでトラフィックを暗号化するように MACsec を構成します。この図は、この暗号化をフローで示しています。", + "text": "ExpressRoute Direct を使用している場合は、組織のルーターと MSEE 間のレイヤー 2 レベルでトラフィックを暗号化するために MACsec を構成します。この図は、この暗号化をフローで示しています。", "waf": "安全" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "ed301d6e-872e-452e-9611-cc58b5a4b151", "id": "D02.02", "link": "https://learn.microsoft.com/azure/expressroute/expressroute-erdirect-about", "severity": "低い", "subcategory": "暗号化", - "text": "MACsec がオプションではないシナリオ (たとえば、ExpressRoute Direct を使用しない場合) の場合は、VPN ゲートウェイを使用して、ExpressRoute プライベート ピアリング経由で IPsec トンネルを確立します。", + "text": "MACsec がオプションではないシナリオ (ExpressRoute Direct を使用しない場合など) では、VPN ゲートウェイを使用して、ExpressRoute プライベート ピアリング経由で IPsec トンネルを確立します。", "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", "waf": "安全" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "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", "severity": "中程度", - "subcategory": "ハブアンドスポーク", + "subcategory": "ハブ アンド スポーク", "text": "最大限の柔軟性を必要とするネットワーク シナリオでは、従来のハブ アンド スポーク ネットワーク トポロジに基づくネットワーク設計を検討してください。", "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", "waf": "安全" }, { "ammp": true, - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "7dd61623-a364-4a90-9eca-e48ebd54cd7d", "id": "D03.02", "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/hybrid-networking/expressroute", "severity": "高い", - "subcategory": "ハブアンドスポーク", - "text": "ExpressRoute ゲートウェイ、VPN ゲートウェイ、Azure ファイアウォールなどの共有ネットワーク サービス、または中央ハブ仮想ネットワーク内のパートナー NVA を確認します。必要に応じて、DNS サーバーも展開します。", + "subcategory": "ハブ アンド スポーク", + "text": "ExpressRoute ゲートウェイ、VPN ゲートウェイ、Azure Firewall などの共有ネットワーク サービス、または中央ハブ仮想ネットワーク内のパートナーの NVA を確認します。必要に応じて、DNS サーバーも展開します。", "waf": "費用" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "e2e8abac-3571-4559-ab91-53e89f89dc7b", "id": "D03.03", "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/dmz/nva-ha", "severity": "中程度", - "subcategory": "ハブアンドスポーク", - "text": "パートナーのネットワーク テクノロジまたは NVA をデプロイする場合は、パートナー ベンダーのガイダンスに従ってください", + "subcategory": "ハブ アンド スポーク", + "text": "パートナー ネットワーク テクノロジまたは NVA をデプロイする場合は、パートナー ベンダーのガイダンスに従ってください", "waf": "確実" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "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", "severity": "低い", - "subcategory": "ハブアンドスポーク", - "text": "ハブ アンド スポークのシナリオで ExpressRoute ゲートウェイと VPN ゲートウェイ間のトランジットが必要な場合は、Azure Route Server を使用します。", + "subcategory": "ハブ アンド スポーク", + "text": "ハブ アンド スポーク シナリオで ExpressRoute と VPN ゲートウェイ間の転送が必要な場合は、Azure Route Server を使用します。", "waf": "安全" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "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", "severity": "低い", - "subcategory": "ハブアンドスポーク", - "text": "ルートサーバーを使用している場合は、ルートサーバーサブネットに /27 プレフィックスを使用します。", + "subcategory": "ハブ アンド スポーク", + "text": "Route Server を使用する場合は、Route Server サブネットに /27 プレフィックスを使用します。", "waf": "安全" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "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", "severity": "中程度", - "subcategory": "ハブアンドスポーク", - "text": "Azure リージョンにまたがる複数のハブ アンド スポーク トポロジを持つネットワーク アーキテクチャの場合は、ハブ VNet 間のグローバル仮想ネットワーク ピアリングを使用して、リージョンを相互に接続します。", + "subcategory": "ハブ アンド スポーク", + "text": "複数のハブ アンド スポーク トポロジを持つネットワーク アーキテクチャでは、ハブ VNet 間のグローバル仮想ネットワーク ピアリングを使用して、リージョンを相互に接続します。", "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-virtual-networks/", "waf": "パフォーマンス" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "4722d929-c1b1-4cd6-81f5-4b29bade39ad", "id": "D03.07", "link": "https://learn.microsoft.com/azure/azure-monitor/insights/network-insights-overview", "severity": "中程度", - "subcategory": "ハブアンドスポーク", - "text": "Azure モニター (ネットワーク用) を使用して、Azure 上のネットワークのエンド ツー エンドの状態を監視します。", + "subcategory": "ハブ アンド スポーク", + "text": "Azure Monitor for Networks を使用して、Azure 上のネットワークのエンド ツー エンドの状態を監視します。", "training": "https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/", "waf": "オペレーションズ" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "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", "severity": "中程度", - "subcategory": "ハブアンドスポーク", - "text": "スポーク仮想ネットワークを中央ハブ仮想ネットワークに接続する場合は、VNet ピアリングの制限 (500)、ExpressRoute 経由でアドバタイズできるプレフィックスの最大数 (1000) を考慮してください", + "subcategory": "ハブ アンド スポーク", + "text": "スポーク仮想ネットワークを中央ハブ仮想ネットワークに接続する場合は、ExpressRoute 経由でアドバタイズできるプレフィックスの最大数である VNet ピアリングの制限 (500) (1000) を考慮してください", "waf": "確実" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "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", "severity": "中程度", - "subcategory": "ハブアンドスポーク", - "text": "ルート テーブルあたりのルートの制限 (400) について考えてみます。", + "subcategory": "ハブ アンド スポーク", + "text": "ルート テーブルあたりのルート数の制限 (400) を考慮します。", "waf": "確実" }, { "ammp": true, - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "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", "severity": "高い", - "subcategory": "ハブアンドスポーク", - "text": "VNet ピアリングを構成するときは、\"リモート仮想ネットワークへのトラフィックを許可する\" 設定を使用します", + "subcategory": "ハブ アンド スポーク", + "text": "VNet ピアリングを構成するときに [リモート仮想ネットワークへのトラフィックを許可する] 設定を使用します", "waf": "確実" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "359c373e-7dd6-4162-9a36-4a907ecae48e", "id": "D04.01", "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/hybrid-networking/hub-spoke?tabs=cli", "severity": "中程度", "subcategory": "ハイブリッド", - "text": "Azure へのプライマリ接続として ExpressRoute を使用する可能性を調査したことを確認します。", + "text": "ExpressRoute を Azure へのプライマリ接続として使用する可能性を調査したことを確認します。", "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", "waf": "パフォーマンス" }, { - "category": "ネットワーク トポロジと接続性", - "description": "AS パスのプリペンドと接続の重みを使用して Azure からオンプレミスへのトラフィックに影響を与え、独自のルーターの BGP 属性の全範囲を使用してオンプレミスから Azure へのトラフィックに影響を与えることができます。", + "category": "ネットワークトポロジと接続性", + "description": "AS パスのプリペンドと接続の重みを使用して、Azure からオンプレミスへのトラフィックに影響を与え、独自のルーターの全範囲の BGP 属性を使用して、オンプレミスから Azure へのトラフィックに影響を与えることができます。", "guid": "f29812b2-363c-4efe-879b-599de0d5973c", "id": "D04.02", "link": "https://learn.microsoft.com/azure/expressroute/expressroute-routing", "severity": "中程度", "subcategory": "ハイブリッド", - "text": "複数の ExpressRoute 回線または複数のオンプレミスの場所を使用する場合、特定のパスが優先される場合は、BGP 属性を使用してルーティングを最適化してください。", + "text": "複数の ExpressRoute 回線、または複数のオンプレミスの場所を使用する場合、特定のパスが優先される場合は、BGP 属性を使用してルーティングを最適化してください。", "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", "waf": "確実" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "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", @@ -986,30 +786,30 @@ }, { "ammp": true, - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "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", "severity": "高い", "subcategory": "ハイブリッド", - "text": "無制限のデータ ExpressRoute 回線は、コストを正当化する帯域幅に達した場合にのみ使用してください。", + "text": "無制限のデータ ExpressRoute 回線は、コストに見合った帯域幅に達した場合にのみ使用してください。", "waf": "費用" }, { "ammp": true, - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "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", "severity": "高い", "subcategory": "ハイブリッド", - "text": "回線のピアリングの場所がローカル SKU の Azure リージョンをサポートしている場合は、ExpressRoute のローカル SKU を活用して回線のコストを削減します。", + "text": "回線のピアリングの場所がローカル SKU の Azure リージョンをサポートしている場合は、ExpressRoute のローカル SKU を利用して回線のコストを削減します。", "waf": "費用" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "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", @@ -1021,29 +821,29 @@ "waf": "確実" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "72e52e36-11cc-458b-9a4b-1511e43a58a9", "id": "D04.07", "link": "https://learn.microsoft.com/azure/networking/", "severity": "中程度", "subcategory": "ハイブリッド", - "text": "10 Gbps を超える帯域幅または専用の 10/100 Gbps ポートを必要とするシナリオでは、ExpressRoute ダイレクトを使用します。", + "text": "10 Gbps を超える帯域幅または専用の 10/100 Gbps ポートを必要とするシナリオでは、ExpressRoute Direct を使用します。", "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", "waf": "パフォーマンス" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "c2299c4d-7b57-4d0c-9555-62f2b3e4563a", "id": "D04.08", "link": "https://learn.microsoft.com/azure/expressroute/about-fastpath", "severity": "中程度", "subcategory": "ハイブリッド", - "text": "短い待機時間が必要な場合、またはオンプレミスから Azure へのスループットが 10 Gbps を超える必要がある場合は、FastPath を有効にして、データ パスから ExpressRoute ゲートウェイをバイパスします。", + "text": "待機時間を短くする必要がある場合、またはオンプレミスから Azure へのスループットを 10 Gbps を超える必要がある場合は、FastPath を有効にして、データ パスから ExpressRoute ゲートウェイをバイパスします。", "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", "waf": "パフォーマンス" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "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", @@ -1056,63 +856,63 @@ }, { "ammp": true, - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "718cb437-b060-2589-8856-2e93a5c6633b", "id": "D04.10", "link": "https://learn.microsoft.com/azure/expressroute/expressroute-erdirect-about", "severity": "高い", "subcategory": "ハイブリッド", - "text": "ExpressRoute Direct を使用する場合は、コストを節約するために、ローカルの Azure リージョンへの ExpressRoute ローカル回線を使用することを検討してください", + "text": "ExpressRoute Direct を使用する場合は、コストを節約するために、ローカルの Azure リージョンへの ExpressRoute Local 回線の使用を検討してください", "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", "waf": "費用" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "8042d88e-79d1-47b7-9b22-a5a67e7a8ed4", "id": "D04.11", "link": "https://learn.microsoft.com/azure/architecture/framework/services/networking/expressroute/reliability", "severity": "中程度", "subcategory": "ハイブリッド", - "text": "運用環境と非運用環境の分離など、トラフィックの分離または専用の帯域幅が必要な場合は、異なる ExpressRoute 回線を使用します。これは、分離されたルーティングドメインを確保し、ノイズの多いネイバーのリスクを軽減するのに役立ちます。", + "text": "運用環境と非運用環境を分離する場合など、トラフィックの分離または専用の帯域幅が必要な場合は、異なる ExpressRoute 回線を使用します。これにより、ルーティング ドメインが分離され、ノイジー ネイバーのリスクが軽減されます。", "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", "waf": "安全" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "b30e38c3-f298-412b-8363-cefe179b599d", "id": "D04.12", "link": "https://learn.microsoft.com/azure/expressroute/expressroute-monitoring-metrics-alerts", "severity": "中程度", "subcategory": "ハイブリッド", - "text": "組み込みのエクスプレス ルート分析情報を使用して、ExpressRoute の可用性と使用率を監視します。", + "text": "組み込みの Express Route Insights を使用して、ExpressRoute の可用性と使用率を監視します。", "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", "waf": "オペレーションズ" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "5bf68dc9-325e-4873-bf88-f8214ef2e5d2", "id": "D04.13", "link": "https://learn.microsoft.com/azure/expressroute/how-to-configure-connection-monitor", "severity": "中程度", "subcategory": "ハイブリッド", - "text": "接続モニターは、環境全体の接続を監視するために使用します。", + "text": "接続モニターを使用して、環境全体の接続を監視します。", "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", "waf": "オペレーションズ" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "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", "severity": "中程度", "subcategory": "ハイブリッド", - "text": "冗長性のために、異なるピアリング場所からの ExpressRoute 回線を使用します。", + "text": "冗長性のために、異なるピアリングの場所からの ExpressRoute 回線を使用します。", "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", "waf": "確実" }, { "ammp": true, - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "2df4930f-6a43-49a3-926b-309f02c302f0", "id": "D04.15", "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/identity/adds-extend-domain#vm-recommendations", @@ -1123,363 +923,363 @@ }, { "ammp": true, - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "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", "severity": "高い", - "subcategory": "知財プラン", + "subcategory": "IPプラン", "text": "Azure リージョンとオンプレミスの場所間で重複する IP アドレス空間が使用されていないことを確認する", "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", "waf": "安全" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "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", "severity": "低い", - "subcategory": "知財プラン", + "subcategory": "IPプラン", "text": "プライベート インターネットのアドレス割り当て範囲 (RFC 1918) の IP アドレスを使用します。", "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", "waf": "安全" }, { "ammp": true, - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "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", "severity": "高い", - "subcategory": "知財プラン", - "text": "IP アドレス空間が無駄にならないようにし、不必要に大きな仮想ネットワーク (/16 など) を作成しないようにします。", + "subcategory": "IPプラン", + "text": "IP アドレス空間が無駄にならないようにし、不必要に大きな仮想ネットワーク (/16 など) を作成しないようにします", "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", "waf": "パフォーマンス" }, { "ammp": true, - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "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", "severity": "高い", - "subcategory": "知財プラン", - "text": "運用サイトと DR サイトで重複する IP アドレス範囲を使用しないようにします。", + "subcategory": "IPプラン", + "text": "運用サイトと DR サイトで重複する IP アドレス範囲を使用しないでください。", "training": "https://learn.microsoft.com/learn/paths/az-104-manage-virtual-networks/", "waf": "確実" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "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", "severity": "中程度", - "subcategory": "知財プラン", - "text": "Azure での名前解決のみが必要な環境では、名前解決用の委任されたゾーン (\"azure.contoso.com\" など) による解決に Azure プライベート DNS を使用します。", + "subcategory": "IPプラン", + "text": "Azure での名前解決のみが必要な環境では、名前解決用の委任されたゾーン ('azure.contoso.com' など) を使用して解決に Azure プライベート DNS を使用します。", "training": "https://learn.microsoft.com/learn/paths/az-104-manage-virtual-networks/", "waf": "オペレーションズ" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "41049d40-3a92-43c3-974d-00018ac6a9e0", "id": "D05.06", "link": "https://learn.microsoft.com/azure/dns/dns-private-resolver-overview", "severity": "中程度", - "subcategory": "知財プラン", - "text": "Azure とオンプレミスでの名前解決が必要な環境では、Azure DNS プライベート リゾルバーの使用を検討してください。", + "subcategory": "IPプラン", + "text": "Azure とオンプレミスでの名前解決が必要な環境では、Azure DNS Private Resolver の使用を検討してください。", "training": "https://learn.microsoft.com/training/modules/intro-to-azure-dns-private-resolver/", "waf": "安全" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "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", "severity": "低い", - "subcategory": "知財プラン", - "text": "独自の DNS (Red Hat OpenShift など) を必要とし、デプロイする特別なワークロードでは、優先 DNS ソリューションを使用する必要があります。", + "subcategory": "IPプラン", + "text": "独自の DNS (Red Hat OpenShift など) を必要としてデプロイする特別なワークロードでは、優先 DNS ソリューションを使用する必要があります。", "waf": "オペレーションズ" }, { "ammp": true, - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "614658d3-558f-4d77-849b-821112df27ee", "id": "D05.08", "link": "https://learn.microsoft.com/azure/dns/private-dns-autoregistration", "severity": "高い", - "subcategory": "知財プラン", - "text": "Azure DNS の自動登録を有効にして、仮想ネットワーク内にデプロイされた仮想マシンの DNS レコードのライフサイクルを自動的に管理します。", + "subcategory": "IPプラン", + "text": "Azure DNS の自動登録を有効にすると、仮想ネットワーク内にデプロイされた仮想マシンの DNS レコードのライフサイクルが自動的に管理されます。", "training": "https://learn.microsoft.com/learn/paths/az-104-manage-virtual-networks/", "waf": "オペレーションズ" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "ee1ac551-c4d5-46cf-b035-d0a3c50d87ad", "id": "D06.01", "link": "https://learn.microsoft.com/azure/bastion/bastion-overview", "severity": "中程度", "subcategory": "インターネット", - "text": "Azure 要塞を使用して、ネットワークに安全に接続することを検討してください。", + "text": "Azure Bastion を使用してネットワークに安全に接続することを検討してください。", "waf": "安全" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "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", "severity": "中程度", "subcategory": "インターネット", - "text": "Azure 要塞はサブネット /26 以上で使用します。", + "text": "Azure Bastion は、サブネット /26 以上で使用します。", "waf": "安全" }, { "ammp": true, - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "e6c4cfd3-e504-4547-a244-7ec66138a720", "id": "D06.03", "link": "https://learn.microsoft.com/azure/app-service/networking-features", "severity": "高い", "subcategory": "インターネット", - "text": "Azure Firewall を使用して、インターネットへの Azure 送信トラフィック、非 HTTP/S 受信接続、および東部/西部トラフィック フィルター処理 (組織で必要な場合) を管理します", + "text": "Azure Firewall を使用して、インターネットへの Azure 送信トラフィック、HTTP/S 以外の受信接続、East/West トラフィック フィルター処理 (組織で必要な場合) を管理します", "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", "waf": "安全" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "5a4b1511-e43a-458a-ac22-99c4d7b57d0c", "id": "D06.04", "link": "https://learn.microsoft.com/azure/firewall/", "severity": "中程度", "subcategory": "インターネット", - "text": "グローバル ネットワーク環境全体のセキュリティ体制を管理するグローバル Azure ファイアウォール ポリシーを作成し、すべての Azure Firewall インスタンスに割り当てます。Azure のロールベースのアクセス制御を介して増分ファイアウォール ポリシーをローカル セキュリティ チームに委任することで、特定のリージョンの要件を満たすためのきめ細かなポリシーを可能にします。", + "text": "グローバル ネットワーク環境全体のセキュリティ体制を管理するグローバル Azure Firewall ポリシーを作成し、それをすべての Azure Firewall インスタンスに割り当てます。Azure のロールベースのアクセス制御を介して増分ファイアウォール ポリシーをローカルのセキュリティ チームに委任することで、特定のリージョンの要件を満たすきめ細かなポリシーが可能になります。", "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", "waf": "安全" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "655562f2-b3e4-4563-a4d8-739748b662d6", "id": "D06.05", "link": "https://learn.microsoft.com/azure/firewall/", "severity": "低い", "subcategory": "インターネット", - "text": "組織が送信接続を保護するためにそのようなソリューションを使用する場合、Firewall Manager 内でサポートされているパートナー SaaS セキュリティ プロバイダーを構成します。", + "text": "組織がそのようなソリューションを使用してアウトバウンド接続を保護する場合は、Firewall Manager 内でサポートされているパートナーの SaaS セキュリティ プロバイダーを構成します。", "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", "waf": "安全" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "1d7aa9b6-4704-4489-a804-2d88e79d17b7", "id": "D06.06", "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/afds-overview", "severity": "中程度", "subcategory": "インターネット", - "text": "Azure Front Door ポリシーと WAF ポリシーを使用して、ランディング ゾーンへの受信 HTTP/S 接続に対して Azure リージョン全体でグローバル保護を提供します。", + "text": "Azure Front Door と WAF ポリシーを使用して、ランディング ゾーンへの受信 HTTP/S 接続に対して Azure リージョン全体でグローバル保護を提供します。", "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", "waf": "安全" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "3b22a5a6-7e7a-48ed-9b30-e38c3f29812b", "id": "D06.07", "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", "severity": "低い", "subcategory": "インターネット", - "text": "Azure Front Door と Azure Application Gateway を使用して HTTP/S アプリを保護する場合は、Azure Front Door で WAF ポリシーを使用します。Azure Front Door からのトラフィックのみを受信するように Azure Application Gateway をロックダウンします。", + "text": "Azure Front Door と Azure Application Gateway を使用して HTTP/S アプリを保護する場合は、Azure Front Door で WAF ポリシーを使用します。Azure Application Gateway をロックダウンして、Azure Front Door からのトラフィックのみを受信するようにします。", "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", "waf": "安全" }, { "ammp": true, - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "2363cefe-179b-4599-be0d-5973cd4cd21b", "id": "D06.08", "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", "severity": "高い", "subcategory": "インターネット", - "text": "WAF やその他のリバース プロキシをデプロイするには、受信 HTTP/S 接続に必要であり、ランディング ゾーン仮想ネットワーク内にデプロイし、保護してインターネットに公開しているアプリと共にデプロイします。", + "text": "受信 HTTP/S 接続には WAF とその他のリバース プロキシをデプロイし、ランディング ゾーン仮想ネットワーク内にデプロイし、保護してインターネットに公開しているアプリと共にデプロイします。", "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", "waf": "安全" }, { "ammp": true, - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "088137f5-e6c4-4cfd-9e50-4547c2447ec6", "id": "D06.09", "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-reference-architectures", "severity": "高い", "subcategory": "インターネット", - "text": "Azure DDoS ネットワークまたは IP 保護プランを使用して、仮想ネットワーク内のパブリック IP アドレス エンドポイントを保護します。", + "text": "Azure DDoS ネットワークまたは IP Protection プランを使用して、仮想ネットワーク内のパブリック IP アドレス エンドポイントを保護します。", "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", "waf": "安全" }, { "ammp": true, - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "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", "severity": "高い", "subcategory": "インターネット", - "text": "FQDN ベースのネットワーク ルールと DNS プロキシを使用した Azure Firewall を使用して、アプリケーション ルールでサポートされていないプロトコルを介してインターネットへのエグレス トラフィックをフィルター処理します。", + "text": "FQDN ベースのネットワーク ルールと DNS プロキシを備えた Azure Firewall を使用して、アプリケーション ルールでサポートされていないプロトコルを介してインターネットへのエグレス トラフィックをフィルター処理します。", "waf": "安全" }, { "ammp": true, - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "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", "severity": "高い", "subcategory": "インターネット", - "text": "Azure ファイアウォール プレミアムを使用して、セキュリティと保護を強化します。", + "text": "Azure Firewall Premium を使用して、セキュリティと保護を強化します。", "waf": "安全" }, { "ammp": true, - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "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", "severity": "高い", "subcategory": "インターネット", - "text": "Azure Firewall 脅威インテリジェンス モードを [アラート] と [拒否] に構成して、保護を強化します。", + "text": "保護を強化するために、Azure Firewall 脅威インテリジェンス モードを [アラート] と [拒否] に構成します。", "waf": "安全" }, { "ammp": true, - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "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", "severity": "高い", "subcategory": "インターネット", - "text": "保護を強化するために、Azure ファイアウォールの IDPS モードを [拒否] に構成します。", + "text": "保護を強化するために、Azure Firewall IDPS モードを [拒否] に構成します。", "waf": "安全" }, { "ammp": true, - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "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", "severity": "高い", "subcategory": "インターネット", - "text": "仮想 WAN に接続されていない VNet 内のサブネットの場合は、インターネット トラフィックが Azure Firewall またはネットワーク仮想アプライアンスにリダイレクトされるようにルート テーブルをアタッチします", + "text": "Virtual WAN に接続されていない VNet 内のサブネットの場合は、インターネット トラフィックが Azure Firewall またはネットワーク仮想アプライアンスにリダイレクトされるようにルート テーブルをアタッチします", "waf": "安全" }, { "ammp": true, - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "d301d6e8-72e5-42e3-911c-c58b5a4b1511", "id": "D07.01", "link": "https://learn.microsoft.com/azure/virtual-network/vnet-integration-for-azure-services", "severity": "高い", - "subcategory": "PaaS", - "text": "仮想ネットワークに挿入された Azure PaaS サービスのコントロール プレーン通信 (0.0.0.0/0 ルートやコントロール プレーン トラフィックをブロックする NSG ルールなど) が切断されていないことを確認します。", + "subcategory": "PaaS(パーエス)", + "text": "仮想ネットワークに挿入された Azure PaaS サービスのコントロール プレーン通信が、たとえば、コントロール プレーンのトラフィックをブロックする 0.0.0.0/0 ルートや NSG ルールによって切断されていないことを確認します。", "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", "waf": "安全" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "e43a58a9-c229-49c4-b7b5-7d0c655562f2", "id": "D07.02", "link": "https://learn.microsoft.com/azure/app-service/networking-features", "severity": "中程度", - "subcategory": "PaaS", - "text": "プライベート リンク (使用可能な場合) は、共有 Azure PaaS サービスに使用します。", + "subcategory": "PaaS(パーエス)", + "text": "共有 Azure PaaS サービスには、使用可能な場合は Private Link を使用します。", "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", "waf": "安全" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "b3e4563a-4d87-4397-98b6-62d6d15f512a", "id": "D07.03", "link": "https://learn.microsoft.com/azure/app-service/networking-features", "severity": "中程度", - "subcategory": "PaaS", - "text": "プライベート エンドポイントと ExpressRoute プライベート ピアリングを介してオンプレミスから Azure PaaS サービスにアクセスします。この方法では、パブリック インターネット経由のトランジットが回避されます。", + "subcategory": "PaaS(パーエス)", + "text": "オンプレミスからプライベート エンドポイントと ExpressRoute プライベート ピアリングを介して Azure PaaS サービスにアクセスします。この方法では、パブリック インターネット経由のトランジットが回避されます。", "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", "waf": "安全" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "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", "severity": "中程度", - "subcategory": "PaaS", - "text": "仮想ネットワーク サービス エンドポイントは、既定ですべてのサブネットで有効にしないでください。", + "subcategory": "PaaS(パーエス)", + "text": "すべてのサブネットで仮想ネットワーク サービス エンドポイントを既定で有効にしないでください。", "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", "waf": "安全" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "7e7a8ed4-b30e-438c-9f29-812b2363cefe", "id": "D07.05", "link": "https://learn.microsoft.com/azure/app-service/networking-features", "severity": "中程度", - "subcategory": "PaaS", - "text": "Azure ファイアウォールまたは NVA で IP アドレスではなく FQDN を使用して Azure PaaS サービスへのエグレス トラフィックをフィルター処理し、データの流出を防ぎます。プライベート リンクを使用している場合は、すべての FQDN をブロックし、それ以外の場合は必要な PaaS サービスのみを許可できます。", + "subcategory": "PaaS(パーエス)", + "text": "Azure Firewall または NVA の IP アドレスの代わりに FQDN を使用して Azure PaaS サービスへのエグレス トラフィックをフィルター処理し、データ流出を防止します。Private Link を使用している場合は、すべての FQDN をブロックし、それ以外の場合は必要な PaaS サービスのみを許可できます。", "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", "waf": "安全" }, { "ammp": true, - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "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", "severity": "高い", "subcategory": "セグメンテーション", - "text": "Azure ファイアウォール サブネットには /26 プレフィックスを使用します。", + "text": "Azure Firewall サブネットに /26 プレフィックスを使用します。", "waf": "安全" }, { "ammp": true, - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "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", "severity": "高い", "subcategory": "セグメンテーション", - "text": "ゲートウェイサブネットに少なくとも /27 プレフィックスを使用する", + "text": "Gateway サブネットに少なくとも /27 プレフィックスを使用する", "waf": "安全" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "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", "severity": "中程度", "subcategory": "セグメンテーション", - "text": "接続を制限するために、仮想ネットワーク サービス タグを使用する NSG 受信の既定の規則に依存しないでください。", + "text": "接続を制限するために、VirtualNetwork サービス タグを使用する NSG 受信の既定の規則に依存しないでください。", "waf": "安全" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "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", "severity": "中程度", "subcategory": "セグメンテーション", - "text": "サブネットの作成をランディング ゾーンの所有者に委任します。", + "text": "サブネットの作成をランディングゾーンの所有者に委任します。", "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", "waf": "安全" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "872e52e3-611c-4c58-a5a4-b1511e43a58a", "id": "D08.05", "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", @@ -1490,7 +1290,7 @@ "waf": "安全" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "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", @@ -1501,18 +1301,18 @@ "waf": "安全" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "a4d87397-48b6-462d-9d15-f512a65498f6", "id": "D08.07", "link": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", "severity": "中程度", "subcategory": "セグメンテーション", - "text": "NSG とアプリケーション セキュリティ グループを使用して、ランディング ゾーン内のトラフィックをマイクロセグメント化し、中央の NVA を使用してトラフィック フローをフィルター処理しないようにします。", + "text": "NSG とアプリケーション セキュリティ グループを使用して、ランディング ゾーン内のトラフィックを細分化し、中央の NVA を使用してトラフィック フローをフィルター処理しないようにします。", "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", "waf": "安全" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "dfe237de-143b-416c-91d7-aa9b64704489", "id": "D08.08", "link": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", @@ -1523,235 +1323,109 @@ "waf": "安全" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "412e7f98-3f63-4047-82dd-69c5b5c2622f", "id": "D09.01", "link": "https://learn.microsoft.com/azure/virtual-wan/scenario-any-to-any", "severity": "中程度", - "subcategory": "仮想 WAN", - "text": "Azure ネットワーク管理を簡素化するために Virtual WAN を検討し、仮想 WAN ルーティング設計の一覧にシナリオが明示的に記述されていることを確認します", + "subcategory": "仮想WAN", + "text": "Azure ネットワーク管理を簡素化するために Virtual WAN を検討し、Virtual WAN ルーティング設計の一覧にシナリオが明示的に記述されていることを確認します", "training": "https://learn.microsoft.com/learn/modules/introduction-azure-virtual-wan/", "waf": "オペレーションズ" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "54b69bad-33aa-4d5e-ac68-e1d76667313b", "id": "D09.02", "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-about", "severity": "中程度", - "subcategory": "仮想 WAN", - "text": "Azure リージョンごとに仮想 WAN ハブを使用して、共通のグローバル Azure 仮想 WAN を介して Azure リージョン間で複数のランディング ゾーンを接続します。", + "subcategory": "仮想WAN", + "text": "Azure リージョンごとに Virtual WAN ハブを使用して、共通のグローバル Azure Virtual WAN を介して Azure リージョン間で複数のランディング ゾーンを接続します。", "waf": "パフォーマンス" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "8ac6a9e0-1e6a-483d-b5de-32c199248160", "id": "D09.03", "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-about", "severity": "低い", - "subcategory": "仮想 WAN", - "text": "\"Azure 内のトラフィックは Azure にとどまる\" という原則に従って、Azure 内のリソース間の通信が Microsoft のバックボーン ネットワーク経由で行われるようにします", + "subcategory": "仮想WAN", + "text": "\"Azure のトラフィックは Azure にとどまる\" という原則に従って、Azure のリソース間の通信が Microsoft のバックボーン ネットワーク経由で行われるようにします", "waf": "パフォーマンス" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "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", "severity": "中程度", - "subcategory": "仮想 WAN", + "subcategory": "仮想WAN", "text": "送信インターネット トラフィックの保護とフィルター処理のために、セキュリティで保護されたハブに Azure Firewall をデプロイします", "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", "waf": "安全" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "6667313b-4f56-464b-9e98-4a859c773e7d", "id": "D09.05", "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits", "severity": "中程度", - "subcategory": "仮想 WAN", - "text": "ネットワーク アーキテクチャが Azure 仮想 WAN の制限内にあることを確認します。", + "subcategory": "仮想WAN", + "text": "ネットワーク アーキテクチャが Azure Virtual WAN の制限内にあることを確認します。", "waf": "確実" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "261623a7-65a9-417e-8f34-8ef254c27d42", "id": "D09.06", "link": "https://learn.microsoft.com/azure/virtual-wan/azure-monitor-insights", "severity": "中程度", - "subcategory": "仮想 WAN", - "text": "仮想 WAN の Azure Monitor インサイトを使用して、仮想 WAN のエンド ツー エンドのトポロジ、状態、および主要なメトリックを監視します。", + "subcategory": "仮想WAN", + "text": "Azure Monitor Insights for Virtual WAN を使用して、Virtual WAN のエンドツーエンドのトポロジ、状態、主要なメトリックを監視します。", "waf": "オペレーションズ" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "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", "severity": "中程度", - "subcategory": "仮想 WAN", - "text": "これらのフローを明示的にブロックする必要がない限り、IaC デプロイで Virtual WAN のブランチ間トラフィックが無効にならないようにしてください。", + "subcategory": "仮想WAN", + "text": "IaC デプロイで、これらのフローを明示的にブロックする必要がない限り、Virtual WAN のブランチ間トラフィックが無効にならないようにしてください。", "waf": "確実" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "d49ac006-6670-4bc9-9948-d3e0a3a94f4d", "id": "D09.08", "link": "https://learn.microsoft.com/azure/virtual-wan/about-virtual-hub-routing-preference", "severity": "中程度", - "subcategory": "仮想 WAN", - "text": "ハブ ルーティングの優先順位として AS パスを使用すると、ExpressRoute や VPN よりも柔軟性が高いためです。", + "subcategory": "仮想WAN", + "text": "AS-Path は ExpressRoute や VPN よりも柔軟性が高いため、ハブ ルーティングの基本設定として使用します。", "waf": "確実" }, { - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "guid": "2586b854-237e-47f1-84a1-d45d4cd2310d", "id": "D09.09", "link": "https://learn.microsoft.com/azure/virtual-wan/about-virtual-hub-routing#labels", "severity": "中程度", - "subcategory": "仮想 WAN", - "text": "IaC デプロイで Virtual WAN でラベルベースの伝達を構成していることを確認してください。そうしないと、仮想ハブ間の接続が損なわれます。", + "subcategory": "仮想WAN", + "text": "IaC デプロイで Virtual WAN でラベルベースの伝達が構成されていることを確認すると、仮想ハブ間の接続が損なわれます。", "waf": "確実" }, { "ammp": true, - "category": "ネットワーク トポロジと接続性", + "category": "ネットワークトポロジと接続性", "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", "severity": "高い", - "subcategory": "仮想 WAN", + "subcategory": "仮想WAN", "text": "仮想ハブに十分な IP 空間 (理想的には /23 プレフィックス) を割り当てます。", "waf": "確実" }, - { - "ammp": true, - "category": "ネットワーク トポロジと接続性", - "guid": "2e30abab-5478-417c-81bf-bf1ad4ed1ed4", - "id": "D10.01", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-end-to-end-tls", - "severity": "高い", - "subcategory": "アプリ配信", - "text": "Azure Front Door でエンド ツー エンドの TLS を使用します。クライアントからフロント ドアへの接続、およびフロント ドアから配信元への接続には、TLS を使用します。", - "waf": "安全" - }, - { - "category": "ネットワーク トポロジと接続性", - "guid": "10aa45af-166f-44c4-9f36-b6d592dac2ca", - "id": "D10.02", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-http-to-https-redirection", - "severity": "中程度", - "subcategory": "アプリ配信", - "text": "HTTP から HTTPS へのリダイレクトを Azure Front Door と共に使用します。古いクライアントを HTTPS 要求に自動的にリダイレクトすることでサポートします。", - "waf": "安全" - }, - { - "ammp": true, - "category": "ネットワーク トポロジと接続性", - "guid": "28b9ee82-b2c7-45aa-bc98-6de6f59a095d", - "id": "D10.03", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#enable-the-waf", - "severity": "高い", - "subcategory": "アプリ配信", - "text": "Azure フロント ドアの WAF を有効にします。さまざまな攻撃からアプリケーションを保護します。", - "waf": "安全" - }, - { - "ammp": true, - "category": "ネットワーク トポロジと接続性", - "guid": "2902d8cc-1b0c-4495-afad-624ab70f7bd6", - "id": "D10.04", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#tune-your-waf", - "severity": "高い", - "subcategory": "アプリ配信", - "text": "ワークロードに合わせて Azure Front Door WAF を調整します。誤検出を減らします。", - "waf": "安全" - }, - { - "ammp": true, - "category": "ネットワーク トポロジと接続性", - "guid": "17ba124b-127d-42b6-9322-388d5b2bbcfc", - "id": "D10.05", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-prevention-mode", - "severity": "高い", - "subcategory": "アプリ配信", - "text": "Azure Front Door WAF で防止モードを使用します。防止モードは、WAF が悪意のある要求を確実にブロックします。", - "waf": "安全" - }, - { - "ammp": true, - "category": "ネットワーク トポロジと接続性", - "guid": "49a98f2b-ec22-4a87-9415-6a10b00d6555", - "id": "D10.06", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#enable-default-rule-sets", - "severity": "高い", - "subcategory": "アプリ配信", - "text": "Azure Front Door WAF の既定の規則セットを有効にします。既定のルール セットは、一般的な攻撃を検出してブロックします。", - "waf": "安全" - }, - { - "ammp": true, - "category": "ネットワーク トポロジと接続性", - "guid": "147a13d4-2a2f-4824-a524-f5855b52b946", - "id": "D10.07", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#enable-bot-management-rules", - "severity": "高い", - "subcategory": "アプリ配信", - "text": "Azure Front Door WAF ボット管理ルールを有効にします。ボットルールは、良いボットと悪いボットを検出します。", - "waf": "安全" - }, - { - "category": "ネットワーク トポロジと接続性", - "guid": "d7dcdcb9-0d99-44b9-baab-ac7570ede79a", - "id": "D10.08", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-the-latest-ruleset-versions", - "severity": "中程度", - "subcategory": "アプリ配信", - "text": "最新の Azure Front Door WAF ルールセット バージョンを使用します。ルールセットの更新は、現在の脅威の状況を考慮して定期的に更新されます。", - "waf": "安全" - }, - { - "category": "ネットワーク トポロジと接続性", - "guid": "b9620385-1cde-418f-914b-a84a06982ffc", - "id": "D10.09", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#add-rate-limiting", - "severity": "中程度", - "subcategory": "アプリ配信", - "text": "Azure Front Door WAF にレート制限を追加します。レート制限は、クライアントが誤ってまたは意図的に大量のトラフィックを短時間に送信するのをブロックします。", - "waf": "安全" - }, - { - "category": "ネットワーク トポロジと接続性", - "guid": "6dc36c52-0124-4ffe-9eaf-23ec1282dedb", - "id": "D10.10", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-a-high-threshold-for-rate-limits", - "severity": "中程度", - "subcategory": "アプリ配信", - "text": "Azure Front Door の WAF レート制限には高いしきい値を使用します。レート制限のしきい値を高くすると、正当なトラフィックのブロックを回避しながら、インフラストラクチャを圧倒する可能性のある非常に多くの要求に対する保護が提供されます。", - "waf": "安全" - }, - { - "category": "ネットワーク トポロジと接続性", - "guid": "388a3d0e-0a43-4367-90b2-3dd2aeece5ee", - "id": "D10.11", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#geo-filter-traffic", - "severity": "低い", - "subcategory": "アプリ配信", - "text": "Azure Front Door WAF を使用してトラフィックを geo フィルター処理します。予想されるリージョンからのトラフィックのみを許可し、他のリージョンからのトラフィックをブロックします。", - "waf": "安全" - }, - { - "category": "ネットワーク トポロジと接続性", - "guid": "00acd8a9-6975-414f-8491-2be6309893b8", - "id": "D10.12", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#specify-the-unknown-zz-location", - "severity": "中程度", - "subcategory": "アプリ配信", - "text": "Azure フロント ドア WAF を使用してトラフィックを地理的にフィルター処理するときに、不明 (ZZ) の場所を指定します。IP アドレスを geo 一致できない場合に、正当な要求を誤ってブロックしないようにします。", - "waf": "安全" - }, { "ammp": true, "category": "統治", @@ -1760,7 +1434,7 @@ "link": "https://learn.microsoft.com/azure/governance/policy/overview", "severity": "高い", "subcategory": "統治", - "text": "Azure Policy を戦略的に活用し、ポリシー イニシアチブを使用して関連するポリシーをグループ化することで、環境のコントロールを定義します。", + "text": "Azure Policy を戦略的に活用し、環境のコントロールを定義し、ポリシー イニシアチブを使用して関連するポリシーをグループ化します。", "waf": "安全" }, { @@ -1770,7 +1444,7 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/naming-and-tagging", "severity": "中程度", "subcategory": "統治", - "text": "必要な Azure タグを特定し、\"追加\" ポリシー モードを使用して、Azure Policy を介して使用を適用します。", + "text": "必要な Azure タグを特定し、\"追加\" ポリシー モードを使用して、Azure Policy を介して使用を強制します。", "waf": "安全" }, { @@ -1790,7 +1464,7 @@ "link": "https://learn.microsoft.com/azure/governance/policy/overview", "severity": "中程度", "subcategory": "統治", - "text": "中間ルート管理グループで Azure Policy 定義を確立して、継承されたスコープで割り当てることができるようにします", + "text": "中間ルート管理グループで Azure Policy 定義を確立し、継承されたスコープで割り当てられるようにする", "waf": "安全" }, { @@ -1800,7 +1474,7 @@ "link": "https://learn.microsoft.com/azure/governance/policy/overview", "severity": "中程度", "subcategory": "統治", - "text": "必要に応じて、ポリシー割り当てを最上位の適切なレベルで管理し、除外を下位レベルで管理します。", + "text": "必要に応じて、最下位レベルで除外し、最下位レベルでポリシー割り当てを管理します。", "waf": "安全" }, { @@ -1825,13 +1499,13 @@ }, { "category": "統治", - "description": "リソース ポリシー共同作成者の役割を特定のスコープに割り当てると、ポリシー管理を関連するチームに委任できます。たとえば、中央の IT チームが管理グループ レベルのポリシーを監督し、アプリケーション チームがサブスクリプションのポリシーを処理して、組織の標準に準拠した分散ガバナンスを実現できます。", + "description": "リソース ポリシー共同作成者ロールを特定のスコープに割り当てると、ポリシー管理を関連するチームに委任できます。たとえば、中央の IT チームが管理グループ レベルのポリシーを監督し、アプリケーション チームがサブスクリプションのポリシーを処理することで、組織の標準に準拠した分散ガバナンスが可能になります。", "guid": "3f988795-25d6-4268-a6d7-0ba6c97be995", "id": "E01.08", "link": "https://learn.microsoft.com/azure/governance/policy/overview#azure-rbac-permissions-in-azure-policy", "severity": "中程度", "subcategory": "統治", - "text": "組み込みのリソース ポリシー共同作成者ロールを特定のスコープに割り当てて、アプリケーション レベルのガバナンスを有効にします。", + "text": "組み込みのリソース ポリシー共同作成者ロールを特定のスコープで割り当てて、アプリケーション レベルのガバナンスを有効にします。", "waf": "安全" }, { @@ -1861,8 +1535,8 @@ "id": "E02.01", "link": "https://learn.microsoft.com/azure/automation/automation-solution-vm-management-config", "severity": "低い", - "subcategory": "クラウドへの投資を最適化する", - "text": "コストを節約するために、自動化タグを使用して環境内の VM を起動/停止することを検討してください。", + "subcategory": "クラウドへの投資を最適化", + "text": "コストを節約するために、環境内の VM を開始/停止するために、自動化タグの使用を検討してください。", "waf": "安全" }, { @@ -1872,7 +1546,7 @@ "link": "https://learn.microsoft.com/azure/virtual-machine-scale-sets/overview", "severity": "中程度", "subcategory": "拡張性", - "text": "Azure 仮想マシン スケール セットを活用して、負荷に基づいてスケールインおよびスケールアウトします。", + "text": "Azure Virtual Machine スケール セットを活用して、負荷に基づいてスケールインおよびスケールアウトします。", "waf": "確実" }, { @@ -1881,8 +1555,8 @@ "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", "severity": "中程度", - "subcategory": "クラウドへの投資を最適化する", - "text": "「実績」および「予測」予算アラートを設定します。", + "subcategory": "クラウドへの投資を最適化", + "text": "「実績」と「予測」の予算アラートを設定します。", "waf": "費用" }, { @@ -1893,7 +1567,7 @@ "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#add-diagnostic-settings-to-save-your-wafs-logs", "severity": "高い", "subcategory": "アプリ配信", - "text": "診断設定を追加して、Azure Front Door WAF のログを保存します。ログを定期的に確認して、攻撃や誤検知がないか確認します。", + "text": "診断設定を追加して、Azure Front Door や Azure Application Gateway などのアプリケーション デリバリー サービスからの WAF ログを保存します。ログを定期的に確認して、攻撃や誤検知がないか確認します。", "waf": "オペレーションズ" }, { @@ -1903,7 +1577,7 @@ "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#send-logs-to-microsoft-sentinel", "severity": "中程度", "subcategory": "アプリ配信", - "text": "Azure Front Door ログを Microsoft Sentinel に送信します。攻撃を検出し、Front Door テレメトリを Azure 環境全体に統合します。", + "text": "Azure Front Door や Azure Application Gateway などのアプリケーション配信サービスから Microsoft Sentinel に WAF ログを送信します。攻撃を検出し、WAF テレメトリを Azure 環境全体に統合します。", "waf": "オペレーションズ" }, { @@ -1913,7 +1587,7 @@ "link": "https://learn.microsoft.com/azure/reliability/cross-region-replication-azure", "severity": "中程度", "subcategory": "データ保護", - "text": "ペアのリージョンを使用した BCDR の Azure でのリージョン間レプリケーションを検討する", + "text": "ペアのリージョンを持つ BCDR の Azure でのリージョン間レプリケーションを検討する", "waf": "確実" }, { @@ -1933,7 +1607,7 @@ "link": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", "severity": "中程度", "subcategory": "モニタリング", - "text": "単一のモニター ログ ワークスペースを使用して、Azure ロールベースのアクセス制御 (Azure RBAC)、データ主権要件、またはデータ保持ポリシーで個別のワークスペースが義務付けられている場合を除き、プラットフォームを一元的に管理します。", + "text": "Azure ロールベースのアクセス制御 (Azure RBAC)、データ主権要件、またはデータ保持ポリシーで個別のワークスペースが義務付けられている場合を除き、1 つのモニター ログ ワークスペースを使用してプラットフォームを一元的に管理します。", "training": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", "waf": "オペレーションズ" }, @@ -1953,7 +1627,7 @@ "link": "https://learn.microsoft.com/azure/azure-monitor/logs/data-retention-archive?tabs=portal-1%2Cportal-2#how-retention-and-archiving-work", "severity": "中程度", "subcategory": "モニタリング", - "text": "Azure Monitor ログは、ログの保有期間の要件が 2 年を超える場合に使用します。現在、データをアーカイブ状態で最大 7 年間保持できます。", + "text": "Azure Monitor ログは、ログの保持期間の要件が 2 年を超える場合に使用します。現在、データをアーカイブ状態に保持できる期間は最大 7 年間です。", "training": "https://learn.microsoft.com/learn/paths/architect-infrastructure-operations/", "waf": "オペレーションズ" }, @@ -1964,7 +1638,7 @@ "link": "https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/govern/policy-compliance/regulatory-compliance", "severity": "中程度", "subcategory": "モニタリング", - "text": "アクセス制御とコンプライアンス レポートには Azure Policy を使用します。Azure Policy には、組織全体の設定を適用して、一貫したポリシーの遵守と迅速な違反検出を保証する機能が用意されています。", + "text": "アクセス制御とコンプライアンス レポートに Azure Policy を使用します。Azure Policy には、一貫したポリシーの遵守と迅速な違反検出を保証するために、組織全体の設定を適用する機能が用意されています。", "training": "https://learn.microsoft.com/en-us/azure/governance/policy/concepts/effects", "waf": "オペレーションズ" }, @@ -1975,7 +1649,7 @@ "link": "https://learn.microsoft.com/azure/governance/policy/how-to/guest-configuration-create", "severity": "中程度", "subcategory": "モニタリング", - "text": "Azure Policy を使用して、ゲスト内仮想マシン (VM) の構成ドリフトを監視します。ポリシーを使用してゲスト構成監査機能を有効にすると、アプリケーション チームのワークロードは、わずかな労力で機能機能をすぐに使用できます。", + "text": "Azure Policy を使用して、ゲスト内の仮想マシン (VM) の構成のずれを監視します。ポリシーを使用してゲスト構成監査機能を有効にすると、アプリケーション チームのワークロードは、ほとんど労力をかけずに機能をすぐに使用できます。", "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", "waf": "オペレーションズ" }, @@ -1986,7 +1660,7 @@ "link": "https://learn.microsoft.com/azure/automation/update-management/overview", "severity": "中程度", "subcategory": "モニタリング", - "text": "Azure Automation での更新管理は、Windows VM と Linux VM の両方の長期的な修正プログラム適用メカニズムとして使用します。", + "text": "Azure Automation の Update Management を、Windows VM と Linux VM の両方に対する長期的な修正プログラムの適用メカニズムとして使用します。", "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-compute-resources/", "waf": "オペレーションズ" }, @@ -1997,7 +1671,7 @@ "link": "https://learn.microsoft.com/azure/network-watcher/network-watcher-monitoring-overview", "severity": "中程度", "subcategory": "モニタリング", - "text": "ネットワーク ウォッチャーを使用してトラフィック フローをプロアクティブに監視する", + "text": "Network Watcher を使用してトラフィック フローをプロアクティブに監視する", "training": "https://learn.microsoft.com/learn/modules/configure-network-watcher/", "waf": "オペレーションズ" }, @@ -2008,7 +1682,7 @@ "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/lock-resources?tabs=json", "severity": "中程度", "subcategory": "モニタリング", - "text": "リソース ロックを使用して、重要な共有サービスが誤って削除されないようにします。", + "text": "リソースロックを使用して、重要な共有サービスが誤って削除されないようにします。", "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", "waf": "オペレーションズ" }, @@ -2019,7 +1693,7 @@ "link": "https://learn.microsoft.com/azure/governance/policy/overview", "severity": "低い", "subcategory": "モニタリング", - "text": "拒否ポリシーを使用して、Azure ロールの割り当てを補完します。拒否ポリシーと Azure ロールの割り当てを組み合わせることで、リソースをデプロイおよび構成できるユーザーと、デプロイおよび構成できるリソースを適用するための適切なガードレールが配置されます。", + "text": "拒否ポリシーを使用して、Azure ロールの割り当てを補完します。拒否ポリシーと Azure ロールの割り当ての組み合わせにより、リソースをデプロイおよび構成できるユーザーと、デプロイおよび構成できるリソースを適用するための適切なガードレールが確実に配置されます。", "waf": "オペレーションズ" }, { @@ -2029,7 +1703,7 @@ "link": "https://learn.microsoft.com/azure/service-health/alerts-activity-log-service-notifications-portal", "severity": "中程度", "subcategory": "モニタリング", - "text": "サービスとリソースの正常性イベントを、プラットフォーム監視ソリューション全体の一部として含めます。プラットフォームの観点からサービスとリソースの正常性を追跡することは、Azure のリソース管理の重要なコンポーネントです。", + "text": "サービスとリソースの正常性イベントを、プラットフォーム全体の監視ソリューションの一部として含めます。プラットフォームの観点からサービスとリソースの正常性を追跡することは、Azure のリソース管理の重要なコンポーネントです。", "waf": "オペレーションズ" }, { @@ -2039,7 +1713,7 @@ "link": "https://learn.microsoft.com/azure/azure-monitor/alerts/action-groups", "severity": "中程度", "subcategory": "モニタリング", - "text": "アラートとアクション グループを Azure Service Health プラットフォームの一部として含めて、アラートや問題に対処できるようにします", + "text": "アラートとアクション グループを Azure Service Health プラットフォームの一部として含め、アラートまたは問題に確実に対処できるようにします", "waf": "オペレーションズ" }, { @@ -2059,7 +1733,7 @@ "link": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", "severity": "中程度", "subcategory": "モニタリング", - "text": "一元化された Azure Monitor ログ分析ワークスペースを使用して、IaaS および PaaS アプリケーション リソースからログとメトリックを収集し、Azure RBAC でログ アクセスを制御します。", + "text": "一元化された Azure Monitor Log Analytics ワークスペースを使用して、IaaS および PaaS アプリケーション リソースからログとメトリックを収集し、Azure RBAC でログ アクセスを制御します。", "waf": "オペレーションズ" }, { @@ -2069,7 +1743,7 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-setup-guide/monitoring-reporting?tabs=AzureMonitor", "severity": "中程度", "subcategory": "モニタリング", - "text": "分析情報とレポートには、Azure モニター ログを使用します。", + "text": "分析情報とレポートには Azure Monitor ログを使用します。", "waf": "オペレーションズ" }, { @@ -2079,7 +1753,7 @@ "link": "https://learn.microsoft.com/azure/azure-monitor/agents/diagnostics-extension-overview", "severity": "中程度", "subcategory": "モニタリング", - "text": "必要に応じて、Azure 診断拡張機能のログ ストレージのランディング ゾーン内の共有ストレージ アカウントを使用します。", + "text": "必要に応じて、ランディング ゾーン内の共有ストレージ アカウントを Azure 診断拡張機能のログ ストレージに使用します。", "waf": "オペレーションズ" }, { @@ -2109,7 +1783,7 @@ "link": "https://learn.microsoft.com/azure/automation/how-to/region-mappings", "severity": "中程度", "subcategory": "モニタリング", - "text": "リンクされた Log Analytics ワークスペースとオートメーション アカウントでサポートされているリージョンを検討する", + "text": "リンクされた Log Analytics ワークスペースと Automation アカウントでサポートされているリージョンを検討する", "waf": "オペレーションズ" }, { @@ -2119,18 +1793,18 @@ "link": "https://learn.microsoft.com/azure/governance/policy/concepts/guest-configuration", "severity": "中程度", "subcategory": "運用コンプライアンス", - "text": "Azure ポリシーを使用して、VM 拡張機能を介してソフトウェア構成を自動的にデプロイし、準拠しているベースライン VM 構成を適用します。", + "text": "Azure ポリシーを使用して、VM 拡張機能を介してソフトウェア構成を自動的にデプロイし、準拠したベースライン VM 構成を適用します。", "waf": "安全" }, { "category": "管理", - "description": "Azure Policy のゲスト構成機能では、マシン設定 (OS、アプリケーション、環境など) を監査および修復して、リソースが予想される構成に整合していることを確認でき、Update Management では VM のパッチ管理を適用できます。", + "description": "Azure Policy のゲスト構成機能では、マシンの設定 (OS、アプリケーション、環境など) を監査して修復し、リソースが想定される構成と一致していることを確認できます。", "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", "severity": "中程度", "subcategory": "運用コンプライアンス", - "text": "Azure ポリシーを使用して VM のセキュリティ構成のドリフトを監視します。", + "text": "VM のセキュリティ構成のドリフトを Azure Policy で監視します。", "waf": "安全" }, { @@ -2140,7 +1814,7 @@ "link": "https://learn.microsoft.com/azure/site-recovery/site-recovery-overview", "severity": "中程度", "subcategory": "保護と回復", - "text": "Azure 間の仮想マシンのディザスター リカバリー シナリオには、Azure サイト回復を使用します。これにより、リージョン間でワークロードをレプリケートできます。", + "text": "Azure から Azure Virtual Machines へのディザスター リカバリー シナリオには、Azure Site Recovery を使用します。これにより、リージョン間でワークロードをレプリケートできます。", "waf": "オペレーションズ" }, { @@ -2150,7 +1824,7 @@ "link": "https://learn.microsoft.com/azure/architecture/framework/resiliency/backup-and-recovery", "severity": "中程度", "subcategory": "保護と回復", - "text": "ネイティブの PaaS サービスのディザスター リカバリー機能を使用してテストしてください。", + "text": "ネイティブの PaaS サービスのディザスター リカバリー機能を使用し、テストしてください。", "waf": "オペレーションズ" }, { @@ -2160,7 +1834,7 @@ "link": "https://learn.microsoft.com/azure/backup/backup-center-overview", "severity": "中程度", "subcategory": "保護と回復", - "text": "Azure ネイティブのバックアップ機能、または Azure と互換性のあるサード パーティのバックアップ ソリューションを使用します。", + "text": "Azure ネイティブのバックアップ機能、または Azure 互換のサード パーティのバックアップ ソリューションを使用します。", "waf": "オペレーションズ" }, { @@ -2171,7 +1845,7 @@ "link": "https://learn.microsoft.com/azure/reliability/availability-zones-overview", "severity": "高い", "subcategory": "フォールトトレランス", - "text": "可用性ゾーンは、サポートされているリージョンの VM に活用します。", + "text": "Availability Zones は、サポートされているリージョンの VM に活用します。", "waf": "確実" }, { @@ -2182,7 +1856,7 @@ "link": "https://learn.microsoft.com/azure/virtual-machines/availability", "severity": "高い", "subcategory": "フォールトトレランス", - "text": "単一の VM で運用ワークロードを実行することは避けてください。", + "text": "運用ワークロードを 1 つの VM で実行することは避けてください。", "waf": "確実" }, { @@ -2192,7 +1866,7 @@ "link": "https://learn.microsoft.com/azure/load-balancer/load-balancer-overview", "severity": "中程度", "subcategory": "フォールトトレランス", - "text": "Azure ロード バランサーとアプリケーション ゲートウェイは、受信ネットワーク トラフィックを複数のリソースに分散します。", + "text": "Azure Load Balancer と Application Gateway は、受信ネットワーク トラフィックを複数のリソースに分散します。", "waf": "確実" }, { @@ -2202,7 +1876,7 @@ "link": "https://learn.microsoft.com/security/benchmark/azure/security-control-incident-response", "severity": "中程度", "subcategory": "アクセス制御", - "text": "運用環境へのアクセスを許可する前に、Azure サービスのインシデント対応計画を決定します。", + "text": "運用環境に導入する前に、Azure サービスのインシデント対応計画を決定します。", "waf": "安全" }, { @@ -2212,7 +1886,7 @@ "link": "https://www.microsoft.com/security/business/zero-trust", "severity": "中程度", "subcategory": "アクセス制御", - "text": "必要に応じて、Azure プラットフォームにアクセスするためのゼロトラスト アプローチを実装します。", + "text": "必要に応じて、Azure プラットフォームへのアクセスにゼロトラスト アプローチを実装します。", "waf": "安全" }, { @@ -2223,7 +1897,7 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/overview", "severity": "高い", "subcategory": "暗号化とキー", - "text": "Azure キー コンテナーを使用してシークレットと資格情報を格納する", + "text": "Azure Key Vault を使用してシークレットと資格情報を格納する", "waf": "安全" }, { @@ -2254,7 +1928,7 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "severity": "中程度", "subcategory": "暗号化とキー", - "text": "最小特権モデルに従って、キー、シークレット、および証明書を完全に削除する承認を、特殊なカスタム Microsoft Entra ID ロールに制限します。", + "text": "最小特権モデルに従って、キー、シークレット、証明書を完全に削除する承認を特殊なカスタム Microsoft Entra ID ロールに制限します。", "waf": "安全" }, { @@ -2264,7 +1938,7 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "severity": "中程度", "subcategory": "暗号化とキー", - "text": "パブリック認証局による証明書の管理と更新プロセスを自動化して、管理を容易にします。", + "text": "公的認証局による証明書の管理と更新プロセスを自動化し、管理を容易にします。", "waf": "安全" }, { @@ -2274,7 +1948,7 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "severity": "中程度", "subcategory": "暗号化とキー", - "text": "キーと証明書のローテーションの自動化プロセスを確立します。", + "text": "キーと証明書のローテーションの自動化されたプロセスを確立します。", "waf": "安全" }, { @@ -2294,7 +1968,7 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/monitor-key-vault", "severity": "中程度", "subcategory": "暗号化とキー", - "text": "プラットフォーム中央の Azure Monitor ログ分析ワークスペースを使用して、Key Vault の各インスタンス内のキー、証明書、シークレットの使用状況を監査します。", + "text": "プラットフォーム中央の Azure Monitor Log Analytics ワークスペースを使用して、Key Vault の各インスタンス内のキー、証明書、シークレットの使用状況を監査します。", "waf": "安全" }, { @@ -2304,7 +1978,7 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "severity": "中程度", "subcategory": "暗号化とキー", - "text": "Key Vault のインスタンス化と特権アクセスを委任し、Azure Policy を使用して一貫した準拠構成を適用します。", + "text": "Key Vault のインスタンス化と特権アクセスを委任し、Azure Policy を使用して一貫性のある準拠構成を適用します。", "waf": "安全" }, { @@ -2324,7 +1998,7 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "severity": "中程度", "subcategory": "暗号化とキー", - "text": "アプリケーションごとに、環境ごとに、リージョンごとに Azure Key Vault を使用します。", + "text": "Azure Key Vault は、アプリケーションごと、環境ごと、リージョンごとに使用します。", "waf": "安全" }, { @@ -2334,7 +2008,7 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "severity": "中程度", "subcategory": "暗号化とキー", - "text": "独自のキーを持ち込む場合、これは考慮されるすべてのサービスでサポートされているとは限りません。不整合が望ましい結果を妨げないように、関連する軽減策を実装します。待機時間を最小限に抑える適切なリージョン ペアとディザスター リカバリー リージョンを選択します。", + "text": "独自のキーを持ち込む場合、これは考慮されているすべてのサービスでサポートされていない可能性があります。不整合が望ましい結果を妨げないように、関連する軽減策を実装します。待機時間を最小限に抑える適切なリージョン ペアとディザスター リカバリー リージョンを選択します。", "waf": "安全" }, { @@ -2344,7 +2018,7 @@ "link": "https://learn.microsoft.com/azure/active-directory/reports-monitoring/overview-reports", "severity": "中程度", "subcategory": "オペレーションズ", - "text": "アクセス制御監査レポートを生成するには、Microsoft Entra ID レポート機能を使用しています。", + "text": "Microsoft Entra ID レポート機能を使用して、アクセス制御監査レポートを生成します。", "waf": "安全" }, { @@ -2354,7 +2028,7 @@ "link": "https://learn.microsoft.com/azure/azure-monitor/logs/logs-data-export?tabs=portal", "severity": "中程度", "subcategory": "オペレーションズ", - "text": "Azure アクティビティ ログを Azure Monitor ログにエクスポートして、長期的なデータ保持を実現します。必要に応じて、2 年を超える長期ストレージのために Azure Storage にエクスポートします。", + "text": "Azure アクティビティ ログを Azure Monitor ログにエクスポートして、データを長期間保持します。必要に応じて、2 年を超える長期保存のために Azure Storage にエクスポートします。", "waf": "安全" }, { @@ -2365,7 +2039,7 @@ "link": "https://learn.microsoft.com/azure/defender-for-cloud/concept-cloud-security-posture-management", "severity": "高い", "subcategory": "オペレーションズ", - "text": "すべてのサブスクリプションに対して Defender クラウド セキュリティ体制管理を有効にします。", + "text": "すべてのサブスクリプションに対して Defender Cloud Security Posture Management を有効にします。", "waf": "安全" }, { @@ -2376,7 +2050,7 @@ "link": "https://learn.microsoft.com/azure/defender-for-cloud/plan-defender-for-servers-select-plan", "severity": "高い", "subcategory": "オペレーションズ", - "text": "すべてのサブスクリプションでサーバーの Defender クラウド ワークロード保護プランを有効にします。", + "text": "すべてのサブスクリプションでサーバーに対して Defender Cloud ワークロード保護プランを有効にします。", "waf": "安全" }, { @@ -2387,7 +2061,7 @@ "link": "https://www.microsoft.com/en-gb/security/business/solutions/cloud-workload-protection", "severity": "高い", "subcategory": "オペレーションズ", - "text": "すべてのサブスクリプションで Azure リソースの Defender クラウド ワークロード保護プランを有効にします。", + "text": "すべてのサブスクリプションで Azure リソースの Defender Cloud Workload Protection プランを有効にします。", "waf": "安全" }, { @@ -2398,7 +2072,7 @@ "link": "https://learn.microsoft.com/mem/configmgr/protect/deploy-use/endpoint-protection", "severity": "高い", "subcategory": "オペレーションズ", - "text": "IaaS サーバーでエンドポイント保護を有効にします。", + "text": "IaaS サーバーで Endpoint Protection を有効にします。", "waf": "安全" }, { @@ -2408,7 +2082,7 @@ "link": "https://learn.microsoft.com/azure/security-center/", "severity": "中程度", "subcategory": "オペレーションズ", - "text": "Azure Monitor ログと Defender for Cloud を使用して、基本オペレーティング システムの修正プログラムの適用ドリフトを監視します。", + "text": "Azure Monitor ログと Defender for Cloud を使用して、基本オペレーティング システムの修正プログラムの適用誤差を監視します。", "waf": "安全" }, { @@ -2418,7 +2092,7 @@ "link": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", "severity": "中程度", "subcategory": "オペレーションズ", - "text": "既定のリソース構成を一元化された Azure Monitor ログ分析ワークスペースに接続します。", + "text": "既定のリソース構成を一元化された Azure Monitor Log Analytics ワークスペースに接続します。", "waf": "安全" }, { @@ -2450,8 +2124,8 @@ "id": "G05.01", "link": "https://learn.microsoft.com/azure/active-directory/roles/security-planning", "severity": "高い", - "subcategory": "安全な特権アクセス", - "text": "Azure 管理タスク用に個別の特権管理者アカウント。", + "subcategory": "特権アクセスの保護", + "text": "Azure 管理タスク用に特権管理者アカウントを分離します。", "waf": "安全" }, { @@ -2460,7 +2134,7 @@ "id": "G06.01", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/service-enablement-framework", "severity": "中程度", - "subcategory": "サービスイネーブルメントフレームワーク", + "subcategory": "サービス有効化フレームワーク", "text": "新しい Azure サービスの実装方法を計画する", "waf": "安全" }, @@ -2470,141 +2144,141 @@ "id": "G06.02", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/service-enablement-framework", "severity": "中程度", - "subcategory": "サービスイネーブルメントフレームワーク", - "text": "Azure サービスのサービス要求を満たす方法を計画する", + "subcategory": "サービス有効化フレームワーク", + "text": "Azure サービスのサービス要求の履行方法を計画する", "waf": "安全" }, { "ammp": true, - "category": "プラットフォームの自動化と DevOps", + "category": "プラットフォームの自動化とDevOps", "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", "severity": "高い", - "subcategory": "DevOps チームのトポロジ", - "text": "Azure ランディング ゾーン アーキテクチャを構築、管理、保守するためのクロスファンクショナルな DevOps プラットフォーム チームがあることを確認します。", + "subcategory": "DevOps チーム トポロジ", + "text": "Azure ランディング ゾーン アーキテクチャを構築、管理、保守するための機能横断的な DevOps プラットフォーム チームがあることを確認します。", "waf": "オペレーションズ" }, { - "category": "プラットフォームの自動化と DevOps", + "category": "プラットフォームの自動化とDevOps", "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", "severity": "低い", - "subcategory": "DevOps チームのトポロジ", + "subcategory": "DevOps チーム トポロジ", "text": "Azure ランディング ゾーン プラットフォーム チームの関数を定義することを目指します。", "waf": "オペレーションズ" }, { - "category": "プラットフォームの自動化と DevOps", + "category": "プラットフォームの自動化とDevOps", "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", "severity": "低い", - "subcategory": "DevOps チームのトポロジ", - "text": "アプリケーション ワークロード チームが自給自足し、DevOps プラットフォーム チームのサポートを必要としない機能を定義することを目指します。これは、カスタム RBAC ロールを使用して実現します。", + "subcategory": "DevOps チーム トポロジ", + "text": "アプリケーション ワークロード チームが自己完結し、DevOps プラットフォーム チームのサポートを必要としないように機能を定義することを目指します。これは、カスタム RBAC ロールを使用して実現します。", "waf": "オペレーションズ" }, { "ammp": true, - "category": "プラットフォームの自動化と DevOps", + "category": "プラットフォームの自動化とDevOps", "guid": "165eb5e9-b434-448a-9e24-178632186212", "id": "H01.04", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/infrastructure-as-code", "severity": "高い", - "subcategory": "DevOps チームのトポロジ", - "text": "CI/CD パイプラインを使用して IaC アーティファクトをデプロイし、デプロイと Azure 環境の品質を確保します。", + "subcategory": "DevOps チーム トポロジ", + "text": "CI/CD パイプラインを使用して IaC 成果物をデプロイし、デプロイと Azure 環境の品質を確保します。", "waf": "オペレーションズ" }, { - "category": "プラットフォームの自動化と DevOps", + "category": "プラットフォームの自動化とDevOps", "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", "severity": "中程度", - "subcategory": "DevOps チームのトポロジ", - "text": "ビルド プロセスの一部として IaC とアプリケーション コードの単体テストを含めます。", + "subcategory": "DevOps チーム トポロジ", + "text": "ビルド プロセスの一部として、IaC とアプリケーション コードの単体テストを含めます。", "waf": "オペレーションズ" }, { "ammp": true, - "category": "プラットフォームの自動化と DevOps", + "category": "プラットフォームの自動化とDevOps", "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", "severity": "高い", - "subcategory": "DevOps チームのトポロジ", - "text": "Key Vault シークレットを使用して、資格情報 (仮想マシンのユーザー パスワード)、証明書、キーなどの機密情報がハードコーディングされないようにします。", + "subcategory": "DevOps チーム トポロジ", + "text": "Key Vault シークレットを使用して、資格情報 (仮想マシン、ユーザー パスワード)、証明書、キーなどの機密情報をハードコーディングしないようにします。", "waf": "オペレーションズ" }, { - "category": "プラットフォームの自動化と DevOps", + "category": "プラットフォームの自動化とDevOps", "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", "severity": "低い", - "subcategory": "DevOps チームのトポロジ", - "text": "アプリケーションとワークロードのファイル>新しい>ランディング ゾーンの自動化を実装します。", + "subcategory": "DevOps チーム トポロジ", + "text": "アプリケーションとワークロードの File > New > ランディング ゾーンの自動化を実装します。", "waf": "オペレーションズ" }, { "ammp": true, - "category": "プラットフォームの自動化と DevOps", + "category": "プラットフォームの自動化とDevOps", "guid": "cfe363b5-f579-4284-bc56-a42153e4c10b", "id": "H02.01", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/infrastructure-as-code", "severity": "高い", "subcategory": "開発ライフサイクル", - "text": "アプリケーションと開発された IaC のソース コードにバージョン管理システムが使用されていることを確認します。マイクロソフトは Git を推奨しています。", + "text": "アプリケーションや IaC のソース コードにバージョン管理システムが使用されていることを確認します。Microsoft では Git を推奨しています。", "waf": "オペレーションズ" }, { - "category": "プラットフォームの自動化と DevOps", + "category": "プラットフォームの自動化とDevOps", "guid": "c7245dd4-af8a-403a-8bb7-890c1a7cfa9d", "id": "H02.02", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/development-strategy-development-lifecycle", "severity": "低い", "subcategory": "開発ライフサイクル", - "text": "分岐戦略に従って、チームがより適切にコラボレーションし、IaC とアプリケーション コードのバージョン管理を効率的に管理できるようにします。Github Flow などのオプションを確認します。", + "text": "分岐戦略に従って、チームのコラボレーションを改善し、IaC とアプリケーション コードのバージョン管理を効率的に管理できるようにします。Github Flow などのオプションを確認します。", "waf": "オペレーションズ" }, { - "category": "プラットフォームの自動化と DevOps", + "category": "プラットフォームの自動化とDevOps", "guid": "12aeea20-9165-4b3e-bdf2-6795fcd3cdbe", "id": "H02.03", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/development-strategy-development-lifecycle", "severity": "中程度", "subcategory": "開発ライフサイクル", - "text": "プル要求戦略を採用して、ブランチにマージされたコード変更の制御を維持します。", + "text": "プル要求戦略を採用して、ブランチにマージされたコード変更を制御し続けるのに役立ちます。", "waf": "オペレーションズ" }, { "ammp": true, - "category": "プラットフォームの自動化と DevOps", + "category": "プラットフォームの自動化とDevOps", "guid": "2cdc9d99-dbcc-4ad4-97f5-e7d358bdfa73", "id": "H03.01", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/infrastructure-as-code", "severity": "高い", "subcategory": "開発戦略", - "text": "Azure Bicep、ARM テンプレート、Terraform などの宣言型インフラストラクチャをコードとして活用して、Azure ランディング ゾーン アーキテクチャを構築および保守します。プラットフォームとアプリケーションの両方のワークロードの観点から。", + "text": "Azure Bicep、ARM テンプレート、Terraform などの宣言型インフラストラクチャ as Code ツールを活用して、Azure ランディング ゾーン アーキテクチャを構築および維持します。プラットフォームとアプリケーションのワークロードの両方の観点から。", "waf": "オペレーションズ" }, { "ammp": true, - "category": "プラットフォームの自動化と DevOps", + "category": "プラットフォームの自動化とDevOps", "guid": "cc87a3bc-c572-4ad2-92ed-8cabab66160f", "id": "H04.01", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/landing-zone-security#secure", "severity": "高い", "subcategory": "安全", - "text": "DevOps の開発と運用のすでに組み合わされたプロセスにセキュリティを統合して、イノベーション プロセスのリスクを軽減します。", + "text": "DevOpsの開発と運用のすでに組み合わされているプロセスにセキュリティを統合して、イノベーションプロセスのリスクを軽減します。", "waf": "オペレーションズ" } ], "metadata": { "name": "Azure Landing Zone Review", "state": "GA", - "timestamp": "September 28, 2023" + "timestamp": "November 06, 2023" }, "severities": [ { @@ -2623,16 +2297,16 @@ "name": "未確認" }, { - "description": "このチェックに関連付けられているアクションアイテムがあります", + "description": "このチェックにはアクションアイテムが関連付けられています", "name": "開ける" }, { - "description": "このチェックは検証済みであり、それ以上のアクションアイテムは関連付けられていません", + "description": "このチェックは検証済みで、これ以上のアクションアイテムは関連付けられていません", "name": "達成" }, { - "description": "推奨事項は理解されていますが、現在の要件では必要ありません", - "name": "必須ではありません" + "description": "推奨事項は理解されているが、現在の要件では不要", + "name": "必要なし" }, { "description": "現在のデザインには適用されません", diff --git a/checklists/alz_checklist.ko.json b/checklists/alz_checklist.ko.json index 4629c42d8..eeac38b2e 100644 --- a/checklists/alz_checklist.ko.json +++ b/checklists/alz_checklist.ko.json @@ -22,7 +22,7 @@ "name": "플랫폼 자동화 및 DevOps" }, { - "name": "거버넌스" + "name": "지배구조" } ], "items": [ @@ -73,7 +73,7 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", "severity": "낮다", "subcategory": "클라우드 솔루션 공급자", - "text": "CSP 파트너와 지원 요청 및 에스컬레이션 프로세스에 대해 논의", + "text": "CSP 파트너와 지원 요청 및 에스컬레이션 프로세스 논의", "waf": "비용" }, { @@ -83,7 +83,7 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", "severity": "보통", "subcategory": "클라우드 솔루션 공급자", - "text": "Azure Cost Management를 사용하여 비용 보고 및 보기 설정Setup Cost Reporting and Views with Azure Cost Management", + "text": "Azure Cost Management를 사용하여 Cost Reporting 및 뷰 설정Setup Cost Reporting and Views with Azure Cost Management", "waf": "비용" }, { @@ -92,8 +92,8 @@ "id": "A03.01", "link": "https://learn.microsoft.com/azure/cost-management-billing/manage/direct-ea-administration#manage-notification-contacts", "severity": "보통", - "subcategory": "기업계약", - "text": "그룹 사서함에 대한 알림 연락처 구성", + "subcategory": "기업 계약", + "text": "Configure Notification Contacts to a group mailbox 그룹 사서함에 대한 알림 연락처 구성Configure Notification Contacts to a group mailbox", "waf": "비용" }, { @@ -102,7 +102,7 @@ "id": "A03.02", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-enterprise-agreement#design-considerations", "severity": "낮다", - "subcategory": "기업계약", + "subcategory": "기업 계약", "text": "부서 및 계정을 사용하여 조직의 구조를 등록 계층 구조에 매핑하면 청구를 분리하는 데 도움이 될 수 있습니다.", "waf": "비용" }, @@ -113,8 +113,8 @@ "id": "A03.03", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-enterprise-agreement#design-considerations", "severity": "높다", - "subcategory": "기업계약", - "text": "계정이 '회사 또는 학교 계정' 형식으로 구성되어 있는지 확인합니다.", + "subcategory": "기업 계약", + "text": "계정이 '회사 또는 학교 계정' 유형으로 구성되어 있는지 확인합니다.", "waf": "안전" }, { @@ -123,8 +123,8 @@ "id": "A03.04", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-enterprise-agreement#design-considerations", "severity": "보통", - "subcategory": "기업계약", - "text": "EA 등록에서 DA 요금 보기 및 AO 요금 보기를 모두 사용하도록 설정하여 올바른 권한이 있는 사용자가 비용 및 청구 데이터를 검토할 수 있도록 합니다.", + "subcategory": "기업 계약", + "text": "EA 등록에서 DA 보기 요금과 AO 보기 요금을 모두 활성화하여 올바른 권한을 가진 사용자가 비용 및 청구 데이터를 검토할 수 있도록 합니다.", "waf": "안전" }, { @@ -133,8 +133,8 @@ "id": "A03.05", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-enterprise-agreement#design-considerations", "severity": "낮다", - "subcategory": "기업계약", - "text": "Enterprise 개발/테스트 구독을 사용하여 비프로덕션 워크로드에 대한 비용 절감Make use of Enterprise Dev/Test Subscriptions to reduce costs for non-production workloads", + "subcategory": "기업 계약", + "text": "Enterprise 개발/테스트 구독을 사용하여 비프로덕션 워크로드에 대한 비용 절감", "waf": "비용" }, { @@ -143,7 +143,7 @@ "id": "A03.06", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-enterprise-agreement#design-considerations", "severity": "보통", - "subcategory": "기업계약", + "subcategory": "기업 계약", "text": "역할 할당을 정기적으로 감사하여 기업계약 등록에 액세스할 수 있는 사용자를 검토합니다.", "waf": "비용" }, @@ -154,7 +154,7 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", "severity": "낮다", "subcategory": "Microsoft 고객 계약", - "text": "계약 청구 계정 알림 연락처 전자 메일 구성", + "text": "계약 청구 계정 알림 연락처 이메일 구성", "waf": "비용" }, { @@ -164,7 +164,7 @@ "link": "https://learn.microsoft.com/azure/cost-management-billing/manage/mca-section-invoice", "severity": "낮다", "subcategory": "Microsoft 고객 계약", - "text": "청구 프로필 및 청구서 섹션을 사용하여 효과적인 비용 관리를 위해 계약 청구를 구성합니다", + "text": "청구 프로필 및 청구서 섹션을 사용하여 효과적인 비용 관리를 위한 계약 청구를 구성합니다.", "waf": "비용" }, { @@ -174,7 +174,7 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", "severity": "낮다", "subcategory": "Microsoft 고객 계약", - "text": "Azure Plan을 사용하여 비프로덕션 워크로드에 대한 비용 절감", + "text": "Azure 플랜을 사용하여 비프로덕션 워크로드에 대한 비용 절감", "waf": "비용" }, { @@ -184,7 +184,7 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", "severity": "보통", "subcategory": "Microsoft 고객 계약", - "text": "계약 청구 RBAC 역할 할당을 주기적으로 감사하여 MCA 청구 계정에 액세스할 수 있는 사용자를 검토합니다", + "text": "계약 청구 RBAC 역할 할당을 정기적으로 감사하여 MCA 청구 계정에 액세스할 수 있는 사용자를 검토합니다.", "waf": "비용" }, { @@ -195,7 +195,7 @@ "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", "severity": "높다", "subcategory": "Microsoft Entra ID 및 하이브리드 ID", - "text": "Azure 서비스에 대한 인증에 서비스 주체 대신 관리 ID 사용Use managed identities instead of service principals for authentication to Azure services", + "text": "Azure 서비스에 대한 인증을 위해 서비스 주체 대신 관리 ID 사용", "training": "https://learn.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview", "waf": "안전" }, @@ -205,7 +205,7 @@ "id": "B02.01", "link": "https://learn.microsoft.com/azure/active-directory/hybrid/how-to-connect-sync-staging-server", "severity": "보통", - "subcategory": "마이크로소프트 엔트라 ID", + "subcategory": "Microsoft Entra ID", "text": "AD Connect VM을 배포할 때 고가용성/재해 복구를 위한 스테이징 서버를 사용하는 것이 좋습니다", "waf": "신뢰도" }, @@ -228,7 +228,7 @@ "link": "https://learn.microsoft.com/azure/active-directory/reports-monitoring/concept-activity-logs-azure-monitor", "severity": "보통", "subcategory": "신원", - "text": "Microsoft Entra ID 로그를 플랫폼 중앙 Azure Monitor와 통합합니다. Azure Monitor를 사용하면 Azure의 로그 및 모니터링 데이터에 대한 단일 정보 원본을 사용할 수 있으므로 조직에 로그 수집 및 보존에 대한 요구 사항을 충족하는 클라우드 네이티브 옵션을 제공합니다.", + "text": "Microsoft Entra ID 로그를 플랫폼 중앙 Azure Monitor와 통합합니다. Azure Monitor를 사용하면 Azure의 로그 및 모니터링 데이터에 대한 단일 정보 원본을 사용할 수 있으므로 조직에 로그 수집 및 보존에 대한 요구 사항을 충족할 수 있는 클라우드 네이티브 옵션을 제공합니다.", "waf": "안전" }, { @@ -239,7 +239,7 @@ "link": "https://learn.microsoft.com/azure/role-based-access-control/overview", "severity": "높다", "subcategory": "신원", - "text": "클라우드 운영 모델에 맞는 RBAC 모델을 적용합니다. 관리 그룹 및 구독에 대한 범위 지정 및 할당Scope and assign across management groups and subscriptions.", + "text": "클라우드 운영 모델에 맞는 RBAC 모델을 적용합니다. 관리 그룹 및 구독에서 범위 지정 및 할당Scope and Assign across Management Groups and Subscriptions.", "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", "waf": "안전" }, @@ -262,7 +262,7 @@ "link": "https://learn.microsoft.com/azure/active-directory/authentication/concept-mfa-howitworks", "severity": "높다", "subcategory": "신원", - "text": "Azure 환경에 대한 권한이 있는 모든 사용자에 대해 다단계 인증 적용Enforce multi-factor authentication for any user with rights to the Azure environments", + "text": "Azure 환경에 대한 권한이 있는 모든 사용자에 대해 다단계 인증 적용", "training": "https://learn.microsoft.com/learn/modules/secure-aad-users-with-mfa/", "waf": "안전" }, @@ -273,7 +273,7 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/manage/centralize-operations", "severity": "보통", "subcategory": "신원", - "text": "역할 및 보안 요구 사항에 따라 landing zone 내에 배포된 리소스를 관리하기 위해 중앙 집중화되고 위임된 책임을 적용합니다", + "text": "역할 및 보안 요구 사항에 따라 landing zone 내에 배포된 리소스를 관리하기 위해 중앙 집중식 및 위임된 책임을 적용합니다.", "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-identities-governance/", "waf": "안전" }, @@ -307,7 +307,7 @@ "link": "https://learn.microsoft.com/azure/active-directory/fundamentals/active-directory-groups-create-azure-portal", "severity": "보통", "subcategory": "신원", - "text": "사용 권한을 할당하는 데는 그룹만 사용합니다. 그룹 관리 시스템이 이미 있는 경우 Azure-AD 전용 그룹에 온-프레미스 그룹을 추가합니다.", + "text": "그룹만 사용하여 권한을 할당합니다. 그룹 관리 시스템이 이미 있는 경우 Azure-AD 전용 그룹에 온-프레미스 그룹을 추가합니다.", "training": "https://learn.microsoft.com/learn/paths/manage-identity-and-access/", "waf": "안전" }, @@ -340,7 +340,7 @@ "link": "https://learn.microsoft.com/azure/active-directory-domain-services/overview", "severity": "보통", "subcategory": "신원", - "text": "AADDS를 사용 중인 경우 모든 워크로드의 호환성을 평가합니다.", + "text": "AADDS가 사용 중인 경우 모든 워크로드의 호환성을 평가합니다", "training": "https://learn.microsoft.com/learn/modules/implement-hybrid-identity-windows-server/", "waf": "안전" }, @@ -362,7 +362,7 @@ "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy", "severity": "보통", "subcategory": "신원", - "text": "Microsoft Entra ID 애플리케이션 프록시를 VPN 또는 역방향 프록시 대체로 사용하여 원격 사용자에게 내부 애플리케이션(클라우드 또는 온-프레미스에서 호스트됨)에 대한 안전하고 인증된 액세스를 제공하는 것이 좋습니다.", + "text": "Microsoft Entra ID 애플리케이션 프록시를 VPN 또는 역방향 프록시 대체품으로 사용하여 원격 사용자에게 내부 애플리케이션(클라우드 또는 온-프레미스에서 호스트됨)에 대한 안전하고 인증된 액세스를 제공하는 것이 좋습니다.", "training": "https://learn.microsoft.com/learn/paths/implement-applications-external-access-azure-ad/", "waf": "안전" }, @@ -373,7 +373,7 @@ "link": "https://learn.microsoft.com/azure/active-directory/roles/best-practices", "severity": "보통", "subcategory": "신원", - "text": "Microsoft Entra ID 역할 할당에 온-프레미스 동기화 계정을 사용하지 마세요.", + "text": "Microsoft Entra ID 역할 할당에 온-프레미스 동기화된 계정을 사용하지 마세요.", "training": "https://learn.microsoft.com/learn/modules/design-identity-security-strategy/", "waf": "안전" }, @@ -383,8 +383,8 @@ "id": "B04.01", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/identity-access-landing-zones#managed-identities", "severity": "낮다", - "subcategory": "착륙 구역", - "text": "가상 네트워크를 사용하여 ID(ADDS) 네트워크 구분을 구성하고 허브에 다시 피어링합니다. 응용 프로그램 랜딩 존(레거시) 내에서 인증을 제공합니다.", + "subcategory": "랜딩 존", + "text": "가상 네트워크를 사용하여 ID(ADDS) 네트워크 구분을 구성하고 허브로 다시 피어링합니다. 응용 프로그램 랜딩 존(레거시) 내에서 인증을 제공합니다.", "training": "https://learn.microsoft.com/azure/architecture/example-scenario/identity/adds-extend-domain", "waf": "안전" }, @@ -394,8 +394,8 @@ "id": "B04.02", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/identity-access-landing-zones#rbac-recommendations", "severity": "보통", - "subcategory": "착륙 구역", - "text": "가능한 경우 Azure RBAC를 사용하여 리소스에 대한 데이터 평면 액세스를 관리합니다. 예: Key Vault, 스토리지 계정 및 데이터베이스 서비스 전반의 데이터 작업. ", + "subcategory": "랜딩 존", + "text": "가능한 경우 Azure RBAC를 사용하여 리소스에 대한 데이터 평면 액세스를 관리합니다. 예: Key Vault, Storage 계정 및 데이터베이스 서비스에서 데이터 작업E.G - Data Operations across Key Vault, Storage Account and Database Services. ", "training": "https://learn.microsoft.com/azure/role-based-access-control/overview", "waf": "안전" }, @@ -405,7 +405,7 @@ "id": "B04.03", "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-create-roles-and-resource-roles-review", "severity": "보통", - "subcategory": "착륙 구역", + "subcategory": "랜딩 존", "text": "Microsoft Entra ID PIM 액세스 검토를 사용하여 리소스 자격의 유효성을 주기적으로 검사합니다.", "waf": "안전" }, @@ -416,7 +416,7 @@ "id": "C01.01", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/resource-naming", "severity": "높다", - "subcategory": "이름 지정 및 태깅", + "subcategory": "이름 지정 및 태그 지정", "text": "Microsoft 모범 사례 명명 표준을 따르는 것이 좋습니다", "waf": "안전" }, @@ -428,7 +428,7 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/resource-org-management-groups", "severity": "보통", "subcategory": "구독", - "text": "4개 수준 이하의 합리적으로 플랫한 관리 그룹 계층 구조를 적용합니다.", + "text": "4개 이하의 수준으로 합리적으로 평평한 관리 그룹 계층 구조를 적용합니다.", "training": "https://learn.microsoft.com/learn/modules/azure-architecture-fundamentals/", "waf": "안전" }, @@ -450,7 +450,7 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/resource-org-management-groups#management-group-recommendations", "severity": "보통", "subcategory": "구독", - "text": "루트 관리 그룹 아래에 플랫폼 관리 그룹을 적용하여 일반적인 플랫폼 정책 및 Azure 역할 할당을 지원합니다.", + "text": "루트 관리 그룹 아래에 플랫폼 관리 그룹을 적용하여 공통 플랫폼 정책 및 Azure 역할 할당을 지원합니다.", "training": "https://learn.microsoft.com/learn/paths/enterprise-scale-architecture/", "waf": "안전" }, @@ -473,7 +473,7 @@ "link": "https://learn.microsoft.com/azure/governance/management-groups/how-to/protect-resource-hierarchy#setting---default-management-group", "severity": "보통", "subcategory": "구독", - "text": "루트 관리 그룹 아래에 구독이 배치되지 않도록 합니다.", + "text": "루트 관리 그룹 아래에 구독이 배치되지 않도록 적용", "waf": "안전" }, { @@ -483,7 +483,7 @@ "link": "https://learn.microsoft.com/azure/governance/management-groups/how-to/protect-resource-hierarchy#setting---require-authorization", "severity": "보통", "subcategory": "구독", - "text": "관리 그룹 계층 구조 설정에서 Azure RBAC 권한 부여를 사용하도록 설정하여 권한 있는 사용자만 테넌트에서 관리 그룹을 작동할 수 있도록 적용합니다", + "text": "관리 그룹 계층 설정에서 Azure RBAC 권한 부여를 사용하도록 설정하여 권한 있는 사용자만 테넌트에서 관리 그룹을 작동할 수 있도록 적용", "waf": "안전" }, { @@ -514,7 +514,7 @@ "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits", "severity": "보통", "subcategory": "구독", - "text": "모든 구독 소유자와 IT 핵심 팀이 구독 할당량 및 지정된 구독에 대한 프로비전 리소스에 미치는 영향을 알고 있는지 확인합니다.", + "text": "모든 구독 소유자와 IT 핵심 팀이 구독 할당량 및 지정된 구독에 대한 리소스 프로비전에 미치는 영향을 알고 있는지 확인합니다.", "waf": "안전" }, { @@ -525,7 +525,7 @@ "link": "https://learn.microsoft.com/azure/cost-management-billing/reservations/save-compute-costs-reservations", "severity": "높다", "subcategory": "구독", - "text": "적절한 경우 예약 인스턴스를 사용하여 비용을 최적화하고 대상 리전에서 사용 가능한 용량을 보장합니다. Azure Policy를 통해 구매한 예약 인스턴스 VM SKU의 사용을 적용합니다.", + "text": "적절한 경우 예약 인스턴스를 사용하여 비용을 최적화하고 대상 리전에서 사용 가능한 용량을 확보합니다. Azure Policy를 통해 구매한 Reserved Instance VM SKU의 사용을 적용합니다.", "training": "https://learn.microsoft.com/learn/paths/improve-reliability-modern-operations/", "waf": "안전" }, @@ -537,7 +537,7 @@ "link": "https://learn.microsoft.com/azure/architecture/framework/scalability/design-capacity", "severity": "높다", "subcategory": "구독", - "text": "대시보드, 통합 문서 또는 수동 프로세스를 적용하여 사용된 용량 수준 모니터링Enforce a dashboard, workbook, or manual process to monitor used capacity levels", + "text": "대시보드, 통합 문서 또는 수동 프로세스를 적용하여 사용된 용량 수준을 모니터링합니다", "training": "https://learn.microsoft.com/learn/paths/monitor-usage-performance-availability-resources-azure-monitor/", "waf": "안전" }, @@ -571,7 +571,7 @@ "link": "https://learn.microsoft.com/azure/governance/management-groups/overview", "severity": "보통", "subcategory": "구독", - "text": "Windows Server의 AD인 경우 Windows Server Active Directory 도메인 컨트롤러를 호스트하기 위해 Indentity 관리 그룹에 전용 ID 구독을 설정합니다", + "text": "Windows Server의 AD인 경우 Indentity 관리 그룹에서 전용 ID 구독을 설정하여 Windows Server Active Directory 도메인 컨트롤러를 호스트합니다.", "training": "https://learn.microsoft.com/learn/paths/enterprise-scale-architecture/", "waf": "안전" }, @@ -589,12 +589,12 @@ }, { "category": "네트워크 토폴로지 및 연결", - "guid": "f00a69de-7076-4734-a734-6e4552cad9e1", + "guid": "373f482f-3e39-4d39-8aa4-7e566f6082b6", "id": "D01.01", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-latest-version-for-customer-managed-certificates", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-app-delivery", "severity": "보통", "subcategory": "앱 제공", - "text": "Azure Front Door에서 고객 관리형 TLS 인증서를 사용하는 경우 '최신' 인증서 버전을 사용합니다. 수동 인증서 갱신으로 인한 중단 위험을 줄입니다.", + "text": "Application Gateway 및 Azure Front door를 사용하여 워크로드 스포크에서 배달 애플리케이션 콘텐츠를 보호하기 위한 계획을 개발합니다. 응용 프로그램 배달 검사 목록을 사용하여 권장 사항을 확인할 수 있습니다.", "waf": "작업" }, { @@ -604,61 +604,14 @@ "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", "severity": "보통", "subcategory": "앱 제공", - "text": "내부(corp) 및 외부용 앱(online) 모두에 대해 랜딩 존 내에서 앱 배달을 수행합니다.", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", - "waf": "안전" - }, - { - "category": "네트워크 토폴로지 및 연결", - "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": "D01.03", - "link": "https://learn.microsoft.com/azure/application-gateway/overview-v2", - "severity": "보통", - "subcategory": "앱 제공", - "text": "Application Gateway v2 SKU를 사용하고 있는지 확인", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", - "waf": "안전" - }, - { - "category": "네트워크 토폴로지 및 연결", - "graph": "resources | where type == 'microsoft.network/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard')", - "guid": "4e35fbf5-0ae2-48b2-97ce-753353edbd1a", - "id": "D01.04", - "link": "https://learn.microsoft.com/azure/load-balancer/load-balancer-overview", - "severity": "보통", - "subcategory": "앱 제공", - "text": "Azure Load Balancer에 표준 SKU를 사용하고 있는지 확인합니다.", - "waf": "안전" - }, - { - "category": "네트워크 토폴로지 및 연결", - "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 | project id, subnetId = tostring(subnets.id), subnetPrefixLength = split(subnets.properties.addressPrefix, '/')[1]) on subnetId | extend compliant = (subnetPrefixLength <= 26) | distinct id,compliant", - "guid": "dfc50f87-3800-424c-937b-ed5f186e7c15", - "id": "D01.05", - "link": "https://learn.microsoft.com/azure/application-gateway/configuration-infrastructure#size-of-the-subnet", - "severity": "보통", - "subcategory": "앱 제공", - "text": "응용 프로그램 게이트웨이는 IP 접두사가 /26보다 크거나 같은 서브넷에 배포해야 합니다", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", - "waf": "안전" - }, - { - "category": "네트워크 토폴로지 및 연결", - "description": "일반적으로 역방향 프록시 및 특히 WAF의 관리는 네트워킹보다 애플리케이션에 더 가깝기 때문에 앱과 동일한 구독에 속합니다. 연결 구독에서 Application Gateway 및 WAF를 중앙 집중화하는 것은 단일 팀에서 관리하는 경우 괜찮을 수 있습니다.", - "guid": "48b662d6-d15f-4512-a654-98f6dfe237de", - "id": "D01.06", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", - "severity": "보통", - "subcategory": "앱 제공", - "text": "랜딩 존 가상 네트워크 내에서 그리고 보안 중인 앱을 사용하여 인바운드 HTTP(S) 연결을 프록시하는 데 사용되는 Azure Application Gateway v2 또는 파트너 NVA를 배포합니다.", + "text": "랜딩 존 내에서 내부 연결(corp) 및 외부 연결 앱(온라인) 모두에 대해 앱 배달을 수행합니다.", "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", "waf": "안전" }, { "category": "네트워크 토폴로지 및 연결", "guid": "143b16c3-1d7a-4a9b-9470-4489a8042d88", - "id": "D01.07", + "id": "D01.03", "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", "severity": "보통", "subcategory": "앱 제공", @@ -666,159 +619,6 @@ "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", "waf": "안전" }, - { - "category": "네트워크 토폴로지 및 연결", - "guid": "e79d17b7-3b22-4a5a-97e7-a8ed4b30e38c", - "id": "D01.08", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", - "severity": "보통", - "subcategory": "앱 제공", - "text": "WAF 정책과 함께 Azure Front Door를 사용하여 여러 Azure 지역에 걸쳐 있는 글로벌 HTTP/S 앱을 제공하고 보호할 수 있습니다.", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", - "waf": "안전" - }, - { - "category": "네트워크 토폴로지 및 연결", - "guid": "3f29812b-2363-4cef-b179-b599de0d5973", - "id": "D01.09", - "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", - "severity": "보통", - "subcategory": "앱 제공", - "text": "Front Door 및 Application Gateway를 사용하여 HTTP/S 앱을 보호하는 경우 Front Door에서 WAF 정책을 사용합니다. Front Door에서만 트래픽을 수신하도록 Application Gateway를 잠급니다.", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", - "waf": "안전" - }, - { - "ammp": true, - "category": "네트워크 토폴로지 및 연결", - "guid": "cd4cd21b-0881-437f-9e6c-4cfd3e504547", - "id": "D01.10", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", - "severity": "높다", - "subcategory": "앱 제공", - "text": "Traffic Manager를 사용하여 HTTP/S 이외의 프로토콜에 걸쳐 있는 글로벌 앱을 제공합니다.", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", - "waf": "신뢰도" - }, - { - "category": "네트워크 토폴로지 및 연결", - "guid": "3b4b3e88-a459-4ed5-a22f-644dfbc58204", - "id": "D01.11", - "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy#how-application-proxy-works", - "severity": "낮다", - "subcategory": "앱 제공", - "text": "사용자가 내부 애플리케이션에만 액세스해야 하는 경우 Microsoft Entra ID 애플리케이션 프록시가 AVD(Azure Virtual Desktop)의 대안으로 고려되었나요?", - "training": "https://learn.microsoft.com/learn/modules/configure-azure-ad-application-proxy/", - "waf": "안전" - }, - { - "category": "네트워크 토폴로지 및 연결", - "guid": "01ca7cf1-5754-442d-babb-8ba6772e5c30", - "id": "D01.12", - "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy#how-application-proxy-works", - "severity": "보통", - "subcategory": "앱 제공", - "text": "네트워크에서 들어오는 연결에 대해 열려 있는 방화벽 포트 수를 줄이려면 Microsoft Entra ID 애플리케이션 프록시를 사용하여 원격 사용자에게 내부 애플리케이션에 대한 안전하고 인증된 액세스를 제공하는 것이 좋습니다.", - "training": "https://learn.microsoft.com/learn/paths/implement-applications-external-access-azure-ad/", - "waf": "안전" - }, - { - "ammp": true, - "category": "네트워크 토폴로지 및 연결", - "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": "D01.13", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-policy-settings", - "severity": "높다", - "subcategory": "앱 제공", - "text": "'방지' 모드에서 Front Door에 대한 WAF 프로필을 배포합니다.", - "waf": "안전" - }, - { - "ammp": true, - "category": "네트워크 토폴로지 및 연결", - "guid": "062d5839-4d36-402f-bfa4-02811eb936e9", - "id": "D01.14", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#avoid-combining-traffic-manager-and-front-door", - "severity": "높다", - "subcategory": "앱 제공", - "text": "Azure Traffic Manager와 Azure Front Door를 결합하지 마세요.", - "waf": "안전" - }, - { - "ammp": true, - "category": "네트워크 토폴로지 및 연결", - "guid": "5efeb96a-003f-4b18-8fcd-b4d84459c2b2", - "id": "D01.15", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-the-same-domain-name-on-front-door-and-your-origin", - "severity": "높다", - "subcategory": "앱 제공", - "text": "Azure Front Door 및 원본에서 동일한 도메인 이름을 사용합니다. 호스트 이름이 일치하지 않으면 미묘한 버그가 발생할 수 있습니다.", - "waf": "안전" - }, - { - "category": "네트워크 토폴로지 및 연결", - "guid": "0b5a380c-4bfb-47bc-b1d7-dcfef363a61b", - "id": "D01.16", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#disable-health-probes-when-theres-only-one-origin-in-an-origin-group", - "severity": "낮다", - "subcategory": "앱 제공", - "text": "Azure Front Door 원본 그룹에 원본이 하나만 있는 경우 상태 프로브를 사용하지 않도록 설정합니다.", - "waf": "공연" - }, - { - "category": "네트워크 토폴로지 및 연결", - "guid": "5567048e-e5d7-4206-9c55-b5ed45d2cc0c", - "id": "D01.17", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#select-good-health-probe-endpoints", - "severity": "보통", - "subcategory": "앱 제공", - "text": "Azure Front Door에 대한 양호한 상태 프로브 엔드포인트를 선택합니다. 애플리케이션의 모든 종속성을 확인하는 상태 엔드포인트를 빌드하는 것이 좋습니다.", - "waf": "신뢰도" - }, - { - "category": "네트워크 토폴로지 및 연결", - "guid": "a13f72f3-8f5c-4864-95e5-75bf37fbbeb1", - "id": "D01.18", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-head-health-probes", - "severity": "낮다", - "subcategory": "앱 제공", - "text": "Azure Front Door에서 HEAD 상태 프로브를 사용하여 Front Door가 애플리케이션으로 보내는 트래픽을 줄입니다.", - "waf": "공연" - }, - { - "ammp": true, - "category": "네트워크 토폴로지 및 연결", - "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": "D01.19", - "link": "https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity", - "severity": "높다", - "subcategory": "앱 제공", - "text": "SNAT 확장성 향상을 위해 Load Balancer 아웃바운드 규칙 대신 Azure NAT Gateway 사용Use Azure NAT Gateway instead of Load Balancer outbound rules for better SNAT scalability", - "waf": "신뢰도" - }, - { - "ammp": true, - "category": "네트워크 토폴로지 및 연결", - "guid": "af95c92d-d723-4f4a-98d7-8722324efd4d", - "id": "D01.20", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-managed-tls-certificates", - "severity": "높다", - "subcategory": "앱 제공", - "text": "Azure Front Door에서 관리되는 TLS 인증서를 사용합니다. 운영 비용과 인증서 갱신으로 인한 중단 위험을 줄입니다.", - "waf": "작업" - }, - { - "category": "네트워크 토폴로지 및 연결", - "guid": "189ea962-3969-4863-8f5a-5ad808c2cf4b", - "id": "D01.21", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#define-your-waf-configuration-as-code", - "severity": "보통", - "subcategory": "앱 제공", - "text": "Azure Front Door WAF 구성을 코드로 정의합니다. 코드를 사용하면 새 규칙 집합 버전을 보다 쉽게 채택하고 추가 보호를 받을 수 있습니다.", - "waf": "작업" - }, { "category": "네트워크 토폴로지 및 연결", "guid": "de0d5973-cd4c-4d21-a088-137f5e6c4cfd", @@ -826,7 +626,7 @@ "link": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", "severity": "보통", "subcategory": "암호화", - "text": "ExpressRoute Direct를 사용하는 경우 조직의 라우터와 MSEE 간의 계층 2 수준에서 트래픽을 암호화하도록 MACsec을 구성합니다. 다이어그램은 이 암호화 흐름을 보여 줍니다.", + "text": "ExpressRoute Direct를 사용하는 경우 조직의 라우터와 MSEE 간의 계층 2 수준에서 트래픽을 암호화하도록 MACsec을 구성합니다. 다이어그램은 흐름에서 이 암호화를 보여 줍니다.", "waf": "안전" }, { @@ -836,7 +636,7 @@ "link": "https://learn.microsoft.com/azure/expressroute/expressroute-erdirect-about", "severity": "낮다", "subcategory": "암호화", - "text": "MACsec이 옵션이 아닌 시나리오(예: ExpressRoute Direct를 사용하지 않음)의 경우 VPN 게이트웨이를 사용하여 ExpressRoute 프라이빗 피어링을 통해 IPsec 터널을 설정합니다. ", + "text": "MACsec을 사용할 수 없는 시나리오(예: ExpressRoute Direct를 사용하지 않는 경우)의 경우 VPN Gateway를 사용하여 ExpressRoute 개인 피어링을 통해 IPsec 터널을 설정합니다. ", "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", "waf": "안전" }, @@ -846,8 +646,8 @@ "id": "D03.01", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/enterprise-scale/network-topology-and-connectivity", "severity": "보통", - "subcategory": "허브 및 스포크", - "text": "최대한의 유연성이 필요한 네트워크 시나리오에 대해 기존의 허브 앤 스포크 네트워크 토폴로지를 기반으로 하는 네트워크 설계를 고려합니다.", + "subcategory": "허브 앤 스포크", + "text": "최대한의 유연성이 필요한 네트워크 시나리오에 대해 기존의 허브 앤 스포크(hub-and-spoke) 네트워크 토폴로지를 기반으로 하는 네트워크 설계를 고려합니다.", "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", "waf": "안전" }, @@ -858,8 +658,8 @@ "id": "D03.02", "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/hybrid-networking/expressroute", "severity": "높다", - "subcategory": "허브 및 스포크", - "text": "ExpressRoute 게이트웨이, VPN 게이트웨이, Azure Firewall 또는 파트너 NVA를 포함한 공유 네트워킹 서비스가 중앙 허브 가상 네트워크에 있는지 확인합니다. 필요한 경우 DNS 서버도 배포합니다.", + "subcategory": "허브 앤 스포크", + "text": "ExpressRoute 게이트웨이, VPN 게이트웨이 및 Azure Firewall 또는 중앙 허브 가상 네트워크의 파트너 NVA를 포함한 공유 네트워킹 서비스를 확인합니다. 필요한 경우 DNS 서버도 배포합니다.", "waf": "비용" }, { @@ -868,7 +668,7 @@ "id": "D03.03", "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/dmz/nva-ha", "severity": "보통", - "subcategory": "허브 및 스포크", + "subcategory": "허브 앤 스포크", "text": "파트너 네트워킹 기술 또는 NVA를 배포할 때 파트너 공급업체의 지침을 따릅니다", "waf": "신뢰도" }, @@ -878,7 +678,7 @@ "id": "D03.04", "link": "https://learn.microsoft.com/azure/expressroute/expressroute-howto-coexist-resource-manager#to-enable-transit-routing-between-expressroute-and-azure-vpn", "severity": "낮다", - "subcategory": "허브 및 스포크", + "subcategory": "허브 앤 스포크", "text": "허브 및 스포크 시나리오에서 ExpressRoute와 VPN 게이트웨이 간에 전송해야 하는 경우 Azure Route Server를 사용합니다.", "waf": "안전" }, @@ -889,7 +689,7 @@ "id": "D03.05", "link": "https://learn.microsoft.com/azure/route-server/quickstart-configure-route-server-portal#create-a-route-server-1", "severity": "낮다", - "subcategory": "허브 및 스포크", + "subcategory": "허브 앤 스포크", "text": "Route Server를 사용하는 경우 Route Server 서브넷에 /27 접두사를 사용합니다.", "waf": "안전" }, @@ -899,8 +699,8 @@ "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", "severity": "보통", - "subcategory": "허브 및 스포크", - "text": "Azure 지역에 걸쳐 여러 허브 및 스포크 토폴로지가 있는 네트워크 아키텍처의 경우 허브 VNet 간의 글로벌 가상 네트워크 피어링을 사용하여 지역을 서로 연결합니다. ", + "subcategory": "허브 앤 스포크", + "text": "Azure 지역에 걸쳐 여러 허브 및 스포크 토폴로지가 있는 네트워크 아키텍처의 경우 허브 VNet 간에 글로벌 가상 네트워크 피어링을 사용하여 지역을 서로 연결합니다. ", "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-virtual-networks/", "waf": "공연" }, @@ -910,7 +710,7 @@ "id": "D03.07", "link": "https://learn.microsoft.com/azure/azure-monitor/insights/network-insights-overview", "severity": "보통", - "subcategory": "허브 및 스포크", + "subcategory": "허브 앤 스포크", "text": "네트워크용 Azure Monitor를 사용하여 Azure에서 네트워크의 엔드투엔드 상태를 모니터링합니다.", "training": "https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/", "waf": "작업" @@ -922,8 +722,8 @@ "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", "severity": "보통", - "subcategory": "허브 및 스포크", - "text": "스포크 가상 네트워크를 중앙 허브 가상 네트워크에 연결할 때 VNet 피어링 제한(500), ExpressRoute를 통해 보급할 수 있는 최대 접두사 수(1000)를 고려합니다", + "subcategory": "허브 앤 스포크", + "text": "스포크 가상 네트워크를 중앙 허브 가상 네트워크에 연결할 때 ExpressRoute를 통해 보급할 수 있는 최대 접두사 수(1000)인 VNet 피어링 제한(500)을 고려합니다", "waf": "신뢰도" }, { @@ -933,7 +733,7 @@ "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", "severity": "보통", - "subcategory": "허브 및 스포크", + "subcategory": "허브 앤 스포크", "text": "경로 테이블당 경로 제한(400)을 고려합니다.", "waf": "신뢰도" }, @@ -945,7 +745,7 @@ "id": "D03.10", "link": "https://learn.microsoft.com/azure/virtual-network/virtual-network-manage-peering", "severity": "높다", - "subcategory": "허브 및 스포크", + "subcategory": "허브 앤 스포크", "text": "VNet 피어링을 구성할 때 '원격 가상 네트워크에 대한 트래픽 허용' 설정을 사용합니다", "waf": "신뢰도" }, @@ -962,7 +762,7 @@ }, { "category": "네트워크 토폴로지 및 연결", - "description": "AS-path 접두사 및 연결 가중치를 사용하여 Azure에서 온-프레미스로의 트래픽에 영향을 주고, 자체 라우터의 전체 BGP 특성을 사용하여 온-프레미스에서 Azure로의 트래픽에 영향을 줄 수 있습니다.", + "description": "AS-path 접두사 및 연결 가중치를 사용하여 Azure에서 온-프레미스로의 트래픽에 영향을 주고, 사용자 고유의 라우터에서 전체 범위의 BGP 특성을 사용하여 온-프레미스에서 Azure로의 트래픽에 영향을 줄 수 있습니다.", "guid": "f29812b2-363c-4efe-879b-599de0d5973c", "id": "D04.02", "link": "https://learn.microsoft.com/azure/expressroute/expressroute-routing", @@ -993,7 +793,7 @@ "link": "https://learn.microsoft.com/azure/expressroute/plan-manage-cost", "severity": "높다", "subcategory": "잡종", - "text": "비용을 정당화하는 대역폭에 도달하는 경우에만 무제한 데이터 ExpressRoute 회로를 사용하고 있는지 확인합니다.", + "text": "비용을 정당화하는 대역폭에 도달하는 경우에만 무제한 데이터 ExpressRoute 회로를 사용해야 합니다.", "waf": "비용" }, { @@ -1027,7 +827,7 @@ "link": "https://learn.microsoft.com/azure/networking/", "severity": "보통", "subcategory": "잡종", - "text": "10Gbps 이상의 대역폭 또는 전용 10/100Gbps 포트가 필요한 시나리오의 경우 ExpressRoute Direct를 사용합니다.", + "text": "10Gbps보다 높은 대역폭 또는 전용 10/100Gbps 포트가 필요한 시나리오의 경우 ExpressRoute Direct를 사용합니다.", "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", "waf": "공연" }, @@ -1038,7 +838,7 @@ "link": "https://learn.microsoft.com/azure/expressroute/about-fastpath", "severity": "보통", "subcategory": "잡종", - "text": "짧은 대기 시간이 필요하거나 온-프레미스에서 Azure로의 처리량이 10Gbps보다 커야 하는 경우 FastPath를 사용하도록 설정하여 데이터 경로에서 ExpressRoute 게이트웨이를 우회합니다.", + "text": "짧은 대기 시간이 필요하거나 온-프레미스에서 Azure로의 처리량이 10Gbps보다 커야 하는 경우 FastPath를 사용하여 데이터 경로에서 ExpressRoute 게이트웨이를 우회합니다.", "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", "waf": "공연" }, @@ -1073,7 +873,7 @@ "link": "https://learn.microsoft.com/azure/architecture/framework/services/networking/expressroute/reliability", "severity": "보통", "subcategory": "잡종", - "text": "프로덕션 환경과 비프로덕션 환경을 분리하는 경우와 같이 트래픽 격리 또는 전용 대역폭이 필요한 경우 다른 ExpressRoute 회로를 사용합니다. 격리된 라우팅 도메인을 보장하고 시끄러운 이웃 위험을 완화하는 데 도움이 됩니다.", + "text": "트래픽 격리 또는 전용 대역폭이 필요한 경우(예: 프로덕션 환경과 비프로덕션 환경을 분리하기 위해) 다른 ExpressRoute 회로를 사용합니다. 격리된 라우팅 도메인을 보장하고 시끄러운 이웃 위험을 완화하는 데 도움이 됩니다.", "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", "waf": "안전" }, @@ -1095,7 +895,7 @@ "link": "https://learn.microsoft.com/azure/expressroute/how-to-configure-connection-monitor", "severity": "보통", "subcategory": "잡종", - "text": "환경 전반의 연결 모니터링에 연결 모니터를 사용합니다.", + "text": "환경 전체의 연결을 모니터링하려면 연결 모니터를 사용합니다.", "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", "waf": "작업" }, @@ -1118,7 +918,7 @@ "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/identity/adds-extend-domain#vm-recommendations", "severity": "높다", "subcategory": "잡종", - "text": "AD DS를 실행하는 VM을 두 개 이상 도메인 컨트롤러로 배포하는 경우 다른 가용성 영역에 추가합니다. 지역에서 사용할 수 없는 경우 가용성 집합에 배포합니다.", + "text": "AD DS를 실행하는 VM을 도메인 컨트롤러로 두 개 이상 배포하는 경우 서로 다른 가용성 영역에 추가합니다. 지역에서 사용할 수 없는 경우 가용성 집합에 배포합니다.", "waf": "신뢰도" }, { @@ -1141,7 +941,7 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing", "severity": "낮다", "subcategory": "IP 플랜", - "text": "개인 인터넷의 주소 할당 범위에서 IP 주소를 사용합니다(RFC 1918).", + "text": "개인 인터넷에 대한 주소 할당 범위의 IP 주소를 사용합니다(RFC 1918).", "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", "waf": "안전" }, @@ -1166,7 +966,7 @@ "link": "https://learn.microsoft.com/azure/site-recovery/concepts-on-premises-to-azure-networking#retain-ip-addresses", "severity": "높다", "subcategory": "IP 플랜", - "text": "프로덕션 사이트와 DR 사이트에 겹치는 IP 주소 범위를 사용하지 마십시오.", + "text": "프로덕션 및 DR 사이트에 겹치는 IP 주소 범위를 사용하지 마십시오.", "training": "https://learn.microsoft.com/learn/paths/az-104-manage-virtual-networks/", "waf": "신뢰도" }, @@ -1177,7 +977,7 @@ "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-name-resolution-for-vms-and-role-instances", "severity": "보통", "subcategory": "IP 플랜", - "text": "Azure에서 이름 확인만 필요한 환경의 경우 이름 확인을 위해 위임된 영역(예: 'azure.contoso.com')으로 확인하기 위해 Azure 프라이빗 DNS를 사용합니다.", + "text": "Azure에서 이름 확인만 필요한 환경의 경우 이름 확인을 위해 위임된 영역(예: 'azure.contoso.com')을 사용하여 확인을 위해 Azure 프라이빗 DNS를 사용합니다.", "training": "https://learn.microsoft.com/learn/paths/az-104-manage-virtual-networks/", "waf": "작업" }, @@ -1199,7 +999,7 @@ "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-name-resolution-for-vms-and-role-instances", "severity": "낮다", "subcategory": "IP 플랜", - "text": "자체 DNS(예: Red Hat OpenShift)가 필요하고 배포하는 특수 워크로드는 기본 DNS 솔루션을 사용해야 합니다.", + "text": "자체 DNS(예: Red Hat OpenShift)를 요구하고 배포하는 특수 워크로드는 선호하는 DNS 솔루션을 사용해야 합니다.", "waf": "작업" }, { @@ -1243,7 +1043,7 @@ "link": "https://learn.microsoft.com/azure/app-service/networking-features", "severity": "높다", "subcategory": "인터넷", - "text": "Azure Firewall을 사용하여 인터넷에 대한 Azure 아웃바운드 트래픽, 비 HTTP/S 인바운드 연결 및 East/West 트래픽 필터링(조직에서 필요한 경우)을 제어합니다.", + "text": "Azure Firewall을 사용하여 인터넷에 대한 Azure 아웃바운드 트래픽, 비 HTTP/S 인바운드 연결 및 East/West 트래픽 필터링(조직에 필요한 경우)을 제어합니다", "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", "waf": "안전" }, @@ -1254,7 +1054,7 @@ "link": "https://learn.microsoft.com/azure/firewall/", "severity": "보통", "subcategory": "인터넷", - "text": "글로벌 네트워크 환경에서 보안 태세를 제어하는 글로벌 Azure Firewall 정책을 만들고 모든 Azure Firewall 인스턴스에 할당합니다. Azure 역할 기반 액세스 제어를 통해 증분 방화벽 정책을 로컬 보안 팀에 위임하여 특정 지역의 요구 사항을 충족하는 세분화된 정책을 허용합니다.", + "text": "글로벌 Azure Firewall 정책을 만들어 글로벌 네트워크 환경에서 보안 태세를 제어하고 모든 Azure Firewall 인스턴스에 할당합니다. Azure 역할 기반 액세스 제어를 통해 증분 방화벽 정책을 로컬 보안 팀에 위임하여 특정 지역의 요구 사항을 충족하는 세분화된 정책을 허용합니다.", "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", "waf": "안전" }, @@ -1276,7 +1076,7 @@ "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/afds-overview", "severity": "보통", "subcategory": "인터넷", - "text": "Azure Front Door 및 WAF 정책을 사용하여 랜딩 존에 대한 인바운드 HTTP/S 연결에 대해 Azure 지역 간에 전역 보호를 제공합니다.", + "text": "Azure Front Door 및 WAF 정책을 사용하여 랜딩 존에 대한 인바운드 HTTP/S 연결을 위해 Azure 지역에서 전역 보호를 제공합니다.", "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", "waf": "안전" }, @@ -1299,7 +1099,7 @@ "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", "severity": "높다", "subcategory": "인터넷", - "text": "인바운드 HTTP/S 연결에는 WIF 배포 및 기타 역방향 프록시가 필요하며, 랜딩 존 가상 네트워크 내에 배포하고 보호하고 인터넷에 노출하는 앱과 함께 배포합니다.", + "text": "WAF 및 기타 역방향 프록시 배포는 인바운드 HTTP/S 연결에 필요하며, 랜딩 존 가상 네트워크 내에 배포하고 보호하고 인터넷에 노출하는 앱과 함께 배포합니다.", "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", "waf": "안전" }, @@ -1324,7 +1124,7 @@ "link": "https://learn.microsoft.com/azure/firewall/fqdn-filtering-network-rules", "severity": "높다", "subcategory": "인터넷", - "text": "DNS 프록시와 함께 FQDN 기반 네트워크 규칙 및 Azure Firewall을 사용하여 애플리케이션 규칙에서 지원하지 않는 프로토콜을 통해 인터넷으로의 송신 트래픽을 필터링합니다.", + "text": "FQDN 기반 네트워크 규칙 및 DNS 프록시와 함께 Azure Firewall을 사용하여 애플리케이션 규칙에서 지원하지 않는 프로토콜을 통해 인터넷으로의 송신 트래픽을 필터링합니다.", "waf": "안전" }, { @@ -1372,7 +1172,7 @@ "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview", "severity": "높다", "subcategory": "인터넷", - "text": "VNet의 서브넷이 Virtual WAN에 연결되지 않은 경우 인터넷 트래픽이 Azure Firewall 또는 네트워크 가상 어플라이언스로 리디렉션되도록 경로 테이블을 연결합니다", + "text": "Virtual WAN에 연결되지 않은 VNet의 서브넷의 경우 인터넷 트래픽이 Azure Firewall 또는 네트워크 가상 어플라이언스로 리디렉션되도록 경로 테이블을 연결합니다", "waf": "안전" }, { @@ -1382,8 +1182,8 @@ "id": "D07.01", "link": "https://learn.microsoft.com/azure/virtual-network/vnet-integration-for-azure-services", "severity": "높다", - "subcategory": "파스 보안", - "text": "가상 네트워크에 삽입된 Azure PaaS 서비스에 대한 컨트롤 플레인 통신이 끊어지지 않았는지 확인합니다(예: 0.0.0.0/0 경로 또는 컨트롤 플레인 트래픽을 차단하는 NSG 규칙).", + "subcategory": "PaaS (영문)", + "text": "가상 네트워크에 삽입된 Azure PaaS 서비스에 대한 컨트롤 플레인 통신이 중단되지 않았는지 확인합니다(예: 컨트롤 플레인 트래픽을 차단하는 0.0.0.0/0 경로 또는 NSG 규칙).", "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", "waf": "안전" }, @@ -1393,7 +1193,7 @@ "id": "D07.02", "link": "https://learn.microsoft.com/azure/app-service/networking-features", "severity": "보통", - "subcategory": "파스 보안", + "subcategory": "PaaS (영문)", "text": "사용 가능한 경우 공유 Azure PaaS 서비스에 Private Link를 사용합니다.", "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", "waf": "안전" @@ -1404,7 +1204,7 @@ "id": "D07.03", "link": "https://learn.microsoft.com/azure/app-service/networking-features", "severity": "보통", - "subcategory": "파스 보안", + "subcategory": "PaaS (영문)", "text": "프라이빗 엔드포인트 및 ExpressRoute 프라이빗 피어링을 통해 온-프레미스에서 Azure PaaS 서비스에 액세스합니다. 이 방법을 사용하면 공용 인터넷을 통한 전송을 방지할 수 있습니다.", "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", "waf": "안전" @@ -1416,8 +1216,8 @@ "id": "D07.04", "link": "https://learn.microsoft.com/azure/app-service/networking-features", "severity": "보통", - "subcategory": "파스 보안", - "text": "기본적으로 모든 서브넷에서 가상 네트워크 서비스 엔드포인트를 사용하도록 설정하지 마세요.", + "subcategory": "PaaS (영문)", + "text": "모든 서브넷에서 기본적으로 가상 네트워크 서비스 엔드포인트를 사용하도록 설정하지 마세요.", "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", "waf": "안전" }, @@ -1427,8 +1227,8 @@ "id": "D07.05", "link": "https://learn.microsoft.com/azure/app-service/networking-features", "severity": "보통", - "subcategory": "파스 보안", - "text": "데이터 반출을 방지하기 위해 Azure Firewall 또는 NVA의 IP 주소 대신 FQDN을 사용하여 Azure PaaS 서비스로의 송신 트래픽을 필터링합니다. Private Link를 사용하는 경우 모든 FQDN을 차단할 수 있으며, 그렇지 않으면 필요한 PaaS 서비스만 허용할 수 있습니다.", + "subcategory": "PaaS (영문)", + "text": "데이터 반출을 방지하기 위해 Azure Firewall 또는 NVA의 IP 주소 대신 FQDN을 사용하여 Azure PaaS 서비스에 대한 송신 트래픽을 필터링합니다. Private Link를 사용하는 경우 모든 FQDN을 차단할 수 있으며, 그렇지 않으면 필요한 PaaS 서비스만 허용할 수 있습니다.", "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", "waf": "안전" }, @@ -1453,7 +1253,7 @@ "link": "https://learn.microsoft.com/azure/expressroute/expressroute-howto-add-gateway-resource-manager#add-a-gateway", "severity": "높다", "subcategory": "세분화", - "text": "게이트웨이 서브넷에 대해 최소 /27 접두사 사용Use at least a /27 prefix for your Gateway subnets", + "text": "게이트웨이 서브넷에 /27 이상의 접두사를 사용합니다", "waf": "안전" }, { @@ -1474,7 +1274,7 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-landing-zone-network-segmentation", "severity": "보통", "subcategory": "세분화", - "text": "서브넷 생성을 랜딩 존 소유자에게 위임합니다. ", + "text": "landing zone 소유자에게 서브넷 생성을 위임합니다. ", "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", "waf": "안전" }, @@ -1485,7 +1285,7 @@ "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", "severity": "보통", "subcategory": "세분화", - "text": "NSG를 사용하여 서브넷 간 트래픽과 플랫폼 전체의 동/서 트래픽(랜딩 존 간 트래픽)을 보호할 수 있습니다.", + "text": "NSG를 사용하여 서브넷 간의 트래픽과 플랫폼 전체의 East/West 트래픽(랜딩 존 간 트래픽)을 보호할 수 있습니다.", "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", "waf": "안전" }, @@ -1507,7 +1307,7 @@ "link": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", "severity": "보통", "subcategory": "세분화", - "text": "NSG 및 애플리케이션 보안 그룹을 사용하여 랜딩 존 내의 트래픽을 마이크로 분할하고 중앙 NVA를 사용하여 트래픽 흐름을 필터링하지 않도록 합니다.", + "text": "NSG 및 애플리케이션 보안 그룹을 사용하여 랜딩 존 내에서 트래픽을 마이크로 세그먼트화하고 중앙 NVA를 사용하여 트래픽 흐름을 필터링하지 않도록 합니다.", "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", "waf": "안전" }, @@ -1518,7 +1318,7 @@ "link": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", "severity": "보통", "subcategory": "세분화", - "text": "NSG 흐름 로그를 사용하도록 설정하고 트래픽 분석에 공급하여 내부 및 외부 트래픽 흐름에 대한 인사이트를 얻습니다.", + "text": "NSG 흐름 로그를 사용하도록 설정하고 Traffic Analytics에 제공하여 내부 및 외부 트래픽 흐름에 대한 인사이트를 얻습니다.", "training": "https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/", "waf": "안전" }, @@ -1550,7 +1350,7 @@ "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-about", "severity": "낮다", "subcategory": "가상 WAN", - "text": "'Azure의 트래픽은 Azure에 유지됨' 원칙에 따라 Azure의 리소스 간 통신이 Microsoft 백본 네트워크를 통해 발생합니다", + "text": "Azure의 리소스 간 통신이 Microsoft 백본 네트워크를 통해 발생하도록 'Azure의 트래픽이 Azure에 유지됨' 원칙에 따라", "waf": "공연" }, { @@ -1561,7 +1361,7 @@ "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-about", "severity": "보통", "subcategory": "가상 WAN", - "text": "아웃바운드 인터넷 트래픽 보호 및 필터링의 경우 보안 허브에 Azure Firewall을 배포합니다", + "text": "아웃바운드 인터넷 트래픽 보호 및 필터링을 위해 보안 허브에 Azure Firewall을 배포합니다", "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", "waf": "안전" }, @@ -1582,7 +1382,7 @@ "link": "https://learn.microsoft.com/azure/virtual-wan/azure-monitor-insights", "severity": "보통", "subcategory": "가상 WAN", - "text": "Virtual WAN용 Azure Monitor Insights를 사용하여 Virtual WAN의 엔드투엔드 토폴로지, 상태 및 주요 메트릭을 모니터링합니다.", + "text": "Virtual WAN용 Azure Monitor Insights를 사용하여 Virtual WAN, 상태 및 주요 메트릭의 엔드투엔드 토폴로지를 모니터링합니다.", "waf": "작업" }, { @@ -1612,7 +1412,7 @@ "link": "https://learn.microsoft.com/azure/virtual-wan/about-virtual-hub-routing#labels", "severity": "보통", "subcategory": "가상 WAN", - "text": "IaC 배포가 Virtual WAN에서 레이블 기반 전파를 구성하고 있는지 확인하고, 그렇지 않으면 가상 허브 간의 연결이 손상됩니다.", + "text": "IaC 배포가 Virtual WAN에서 레이블 기반 전파를 구성하는지 확인하며, 그렇지 않으면 가상 허브 간의 연결이 손상됩니다.", "waf": "신뢰도" }, { @@ -1628,235 +1428,109 @@ }, { "ammp": true, - "category": "네트워크 토폴로지 및 연결", - "guid": "2e30abab-5478-417c-81bf-bf1ad4ed1ed4", - "id": "D10.01", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-end-to-end-tls", - "severity": "높다", - "subcategory": "앱 제공", - "text": "Azure Front Door에서 엔드투엔드 TLS를 사용합니다. 클라이언트에서 Front Door로의 연결 및 Front Door에서 원본으로의 연결에 TLS를 사용합니다.", - "waf": "안전" - }, - { - "category": "네트워크 토폴로지 및 연결", - "guid": "10aa45af-166f-44c4-9f36-b6d592dac2ca", - "id": "D10.02", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-http-to-https-redirection", - "severity": "보통", - "subcategory": "앱 제공", - "text": "Azure Front Door에서 HTTP에서 HTTPS로 리디렉션을 사용합니다. 이전 클라이언트를 HTTPS 요청으로 자동으로 리디렉션하여 지원합니다.", - "waf": "안전" - }, - { - "ammp": true, - "category": "네트워크 토폴로지 및 연결", - "guid": "28b9ee82-b2c7-45aa-bc98-6de6f59a095d", - "id": "D10.03", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#enable-the-waf", - "severity": "높다", - "subcategory": "앱 제공", - "text": "Azure Front Door WAF를 사용하도록 설정합니다. 다양한 공격으로부터 애플리케이션을 보호합니다.", - "waf": "안전" - }, - { - "ammp": true, - "category": "네트워크 토폴로지 및 연결", - "guid": "2902d8cc-1b0c-4495-afad-624ab70f7bd6", - "id": "D10.04", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#tune-your-waf", - "severity": "높다", - "subcategory": "앱 제공", - "text": "워크로드에 맞게 Azure Front Door WAF를 조정합니다. 거짓 긍정 탐지를 줄입니다.", - "waf": "안전" - }, - { - "ammp": true, - "category": "네트워크 토폴로지 및 연결", - "guid": "17ba124b-127d-42b6-9322-388d5b2bbcfc", - "id": "D10.05", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-prevention-mode", - "severity": "높다", - "subcategory": "앱 제공", - "text": "Azure Front Door WAF에서 방지 모드를 사용합니다. 방지 모드에서는 WAF가 악의적인 요청을 차단합니다.", - "waf": "안전" - }, - { - "ammp": true, - "category": "네트워크 토폴로지 및 연결", - "guid": "49a98f2b-ec22-4a87-9415-6a10b00d6555", - "id": "D10.06", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#enable-default-rule-sets", - "severity": "높다", - "subcategory": "앱 제공", - "text": "Azure Front Door WAF 기본 규칙 집합을 사용하도록 설정합니다. 기본 규칙 집합은 일반적인 공격을 탐지하고 차단합니다.", - "waf": "안전" - }, - { - "ammp": true, - "category": "네트워크 토폴로지 및 연결", - "guid": "147a13d4-2a2f-4824-a524-f5855b52b946", - "id": "D10.07", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#enable-bot-management-rules", - "severity": "높다", - "subcategory": "앱 제공", - "text": "Azure Front Door WAF 봇 관리 규칙을 사용하도록 설정합니다. 봇 규칙은 좋은 봇과 나쁜 봇을 감지합니다.", - "waf": "안전" - }, - { - "category": "네트워크 토폴로지 및 연결", - "guid": "d7dcdcb9-0d99-44b9-baab-ac7570ede79a", - "id": "D10.08", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-the-latest-ruleset-versions", - "severity": "보통", - "subcategory": "앱 제공", - "text": "최신 Azure Front Door WAF 규칙 집합 버전을 사용합니다. 규칙 집합 업데이트는 현재 위협 환경을 고려하여 정기적으로 업데이트됩니다.", - "waf": "안전" - }, - { - "category": "네트워크 토폴로지 및 연결", - "guid": "b9620385-1cde-418f-914b-a84a06982ffc", - "id": "D10.09", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#add-rate-limiting", - "severity": "보통", - "subcategory": "앱 제공", - "text": "Azure Front Door WAF에 속도 제한을 추가합니다. 속도 제한은 클라이언트가 실수로 또는 의도적으로 단기간에 많은 양의 트래픽을 보내는 것을 차단합니다.", - "waf": "안전" - }, - { - "category": "네트워크 토폴로지 및 연결", - "guid": "6dc36c52-0124-4ffe-9eaf-23ec1282dedb", - "id": "D10.10", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-a-high-threshold-for-rate-limits", - "severity": "보통", - "subcategory": "앱 제공", - "text": "Azure Front Door WAF 속도 제한에 높은 임계값을 사용합니다. 높은 속도 제한 임계값은 합법적인 트래픽을 차단하는 동시에 인프라를 압도할 수 있는 매우 많은 수의 요청으로부터 보호합니다. ", - "waf": "안전" - }, - { - "category": "네트워크 토폴로지 및 연결", - "guid": "388a3d0e-0a43-4367-90b2-3dd2aeece5ee", - "id": "D10.11", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#geo-filter-traffic", - "severity": "낮다", - "subcategory": "앱 제공", - "text": "Azure Front Door WAF를 사용하여 트래픽을 지리적으로 필터링합니다. 예상 지역의 트래픽만 허용하고 다른 지역의 트래픽은 차단합니다.", - "waf": "안전" - }, - { - "category": "네트워크 토폴로지 및 연결", - "guid": "00acd8a9-6975-414f-8491-2be6309893b8", - "id": "D10.12", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#specify-the-unknown-zz-location", - "severity": "보통", - "subcategory": "앱 제공", - "text": "Azure Front Door WAF를 사용하여 트래픽을 지리적으로 필터링할 때 알 수 없는(ZZ) 위치를 지정합니다. IP 주소를 지리적으로 일치시킬 수 없는 경우 합법적인 요청을 실수로 차단하지 마세요.", - "waf": "안전" - }, - { - "ammp": true, - "category": "거버넌스", + "category": "지배구조", "guid": "5c986cb2-9131-456a-8247-6e49f541acdc", "id": "E01.01", "link": "https://learn.microsoft.com/azure/governance/policy/overview", "severity": "높다", - "subcategory": "거버넌스", - "text": "Azure Policy를 전략적으로 활용하고, 정책 이니셔티브를 사용하여 환경에 대한 제어를 정의하여 관련 정책을 그룹화합니다.", + "subcategory": "지배구조", + "text": "Azure Policy를 전략적으로 활용하고, 정책 이니셔티브를 사용하여 관련 정책을 그룹화하고, 환경에 대한 컨트롤을 정의합니다.", "waf": "안전" }, { - "category": "거버넌스", + "category": "지배구조", "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", "severity": "보통", - "subcategory": "거버넌스", - "text": "필요한 Azure 태그를 식별하고 '추가' 정책 모드를 사용하여 Azure Policy를 통해 사용량을 적용합니다.", + "subcategory": "지배구조", + "text": "필요한 Azure 태그를 식별하고 '추가' 정책 모드를 사용하여 Azure Policy를 통해 사용을 적용합니다.", "waf": "안전" }, { - "category": "거버넌스", + "category": "지배구조", "guid": "d8a2adb1-17d6-4326-af62-5ca44e5695f2", "id": "E01.03", "link": "https://learn.microsoft.com/azure/governance/policy/overview", "severity": "보통", - "subcategory": "거버넌스", + "subcategory": "지배구조", "text": "규정 및 규정 준수 요구 사항을 Azure Policy 정의 및 Azure 역할 할당에 매핑합니다.", "waf": "안전" }, { - "category": "거버넌스", + "category": "지배구조", "guid": "223ace8c-b123-408c-a501-7f154e3ab369", "id": "E01.04", "link": "https://learn.microsoft.com/azure/governance/policy/overview", "severity": "보통", - "subcategory": "거버넌스", - "text": "상속된 범위에서 할당할 수 있도록 중간 루트 관리 그룹에서 Azure Policy 정의를 설정합니다", + "subcategory": "지배구조", + "text": "상속된 범위에서 할당할 수 있도록 중간 루트 관리 그룹에서 Azure Policy 정의를 설정합니다.", "waf": "안전" }, { - "category": "거버넌스", + "category": "지배구조", "guid": "3829e7e3-1618-4368-9a04-77a209945bda", "id": "E01.05", "link": "https://learn.microsoft.com/azure/governance/policy/overview", "severity": "보통", - "subcategory": "거버넌스", - "text": "필요한 경우 가장 낮은 수준의 제외를 사용하여 가장 적절한 수준에서 정책 할당을 관리합니다.", + "subcategory": "지배구조", + "text": "필요한 경우 최하위 수준에서 제외를 사용하여 가장 적절한 수준에서 정책 할당을 관리합니다.", "waf": "안전" }, { - "category": "거버넌스", + "category": "지배구조", "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", "severity": "낮다", - "subcategory": "거버넌스", + "subcategory": "지배구조", "text": "Azure Policy를 사용하여 사용자가 구독/관리 그룹 수준에서 프로비전할 수 있는 서비스 제어", "waf": "안전" }, { - "category": "거버넌스", + "category": "지배구조", "guid": "be7d7e48-4327-46d8-adc0-55bcf619e8a1", "id": "E01.07", "link": "https://learn.microsoft.com/azure/governance/policy/overview", "severity": "보통", - "subcategory": "거버넌스", + "subcategory": "지배구조", "text": "가능한 경우 기본 제공 정책을 사용하여 운영 오버헤드를 최소화합니다.", "waf": "안전" }, { - "category": "거버넌스", - "description": "리소스 정책 참가자 역할을 특정 범위에 할당하면 관련 팀에 정책 관리를 위임할 수 있습니다. 예를 들어 중앙 IT 팀은 관리 그룹 수준 정책을 감독하고 애플리케이션 팀은 구독에 대한 정책을 처리하여 조직 표준을 준수하여 분산 거버넌스를 가능하게 할 수 있습니다.", + "category": "지배구조", + "description": "특정 범위에 Resource Policy Contributor 역할을 할당하면 관련 팀에 정책 관리를 위임할 수 있습니다. 예를 들어 중앙 IT 팀은 관리 그룹 수준 정책을 감독하고 응용 프로그램 팀은 구독에 대한 정책을 처리하여 조직 표준을 준수하는 분산 거버넌스를 사용할 수 있습니다.", "guid": "3f988795-25d6-4268-a6d7-0ba6c97be995", "id": "E01.08", "link": "https://learn.microsoft.com/azure/governance/policy/overview#azure-rbac-permissions-in-azure-policy", "severity": "보통", - "subcategory": "거버넌스", - "text": "특정 범위에서 기본 제공 Resource Policy Contributor 역할을 할당하여 응용 프로그램 수준 거버넌스를 사용하도록 설정합니다.", + "subcategory": "지배구조", + "text": "특정 범위에서 기본 제공 Resource Policy 기여자 역할을 할당하여 응용 프로그램 수준 거버넌스를 사용하도록 설정합니다.", "waf": "안전" }, { - "category": "거버넌스", + "category": "지배구조", "guid": "19048384-5c98-46cb-8913-156a12476e49", "id": "E01.09", "link": "https://learn.microsoft.com/azure/governance/policy/overview", "severity": "보통", - "subcategory": "거버넌스", - "text": "루트 관리 그룹 범위에서 수행된 Azure Policy 할당 수를 제한하여 상속된 범위에서 제외를 통해 관리되지 않도록 합니다.", + "subcategory": "지배구조", + "text": "상속된 범위에서 제외를 통해 관리하지 않도록 루트 관리 그룹 범위에서 수행된 Azure Policy 할당 수를 제한합니다.", "waf": "안전" }, { - "category": "거버넌스", + "category": "지배구조", "guid": "5a917e1f-348e-4f25-9c27-d42e8bbac757", "id": "E01.10", "link": "https://azure.microsoft.com/resources/achieving-compliant-data-residency-and-security-with-azure/", "severity": "보통", - "subcategory": "거버넌스", + "subcategory": "지배구조", "text": "데이터 주권 요구 사항이 있는 경우 Azure Policy를 배포하여 적용할 수 있습니다", "training": "https://learn.microsoft.com/learn/paths/secure-your-cloud-data/", "waf": "안전" }, { - "category": "거버넌스", + "category": "지배구조", "guid": "9b5e2a28-9823-4faf-ab7e-afa5f6c57221", "id": "E02.01", "link": "https://learn.microsoft.com/azure/automation/automation-solution-vm-management-config", @@ -1872,11 +1546,11 @@ "link": "https://learn.microsoft.com/azure/virtual-machine-scale-sets/overview", "severity": "보통", "subcategory": "확장성", - "text": "Azure Virtual Machine Scale sets를 활용하여 부하에 따라 스케일 인 및 스케일 아웃합니다.", + "text": "Azure Virtual Machine Scale Sets를 활용하여 부하에 따라 스케일 인 및 스케일 아웃합니다.", "waf": "신뢰도" }, { - "category": "거버넌스", + "category": "지배구조", "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", @@ -1893,7 +1567,7 @@ "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#add-diagnostic-settings-to-save-your-wafs-logs", "severity": "높다", "subcategory": "앱 제공", - "text": "진단 설정을 추가하여 Azure Front Door WAF의 로그를 저장합니다. 로그를 정기적으로 검토하여 공격 및 오탐지 탐지를 확인합니다.", + "text": "Azure Front Door 및 Azure Application Gateway와 같은 애플리케이션 배달 서비스에서 WAF 로그를 저장하는 진단 설정을 추가합니다. 로그를 정기적으로 검토하여 공격 및 가양성 탐지를 확인합니다.", "waf": "작업" }, { @@ -1903,7 +1577,7 @@ "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#send-logs-to-microsoft-sentinel", "severity": "보통", "subcategory": "앱 제공", - "text": "Azure Front Door 로그를 Microsoft Sentinel로 보냅니다. 공격을 감지하고 Front Door 원격 분석을 전체 Azure 환경에 통합합니다.", + "text": "Azure Front Door 및 Azure Application Gateway와 같은 애플리케이션 배달 서비스에서 Microsoft Sentinel로 WAF 로그를 보냅니다. 공격을 감지하고 WAF 원격 분석을 전체 Azure 환경에 통합합니다.", "waf": "작업" }, { @@ -1923,7 +1597,7 @@ "link": "https://learn.microsoft.com/azure/storage/common/storage-redundancy", "severity": "보통", "subcategory": "데이터 보호", - "text": "Azure Backup을 사용하는 경우 기본 설정이 GRS이므로 다양한 백업 유형(GRS, ZRS & LRS)을 고려합니다", + "text": "Azure Backup을 사용하는 경우 기본 설정은 GRS이므로 다양한 백업 유형(GRS, ZRS & LRS)을 고려합니다", "waf": "신뢰도" }, { @@ -1933,7 +1607,7 @@ "link": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", "severity": "보통", "subcategory": "모니터링", - "text": "단일 모니터 로그 작업 영역을 사용하여 Azure RBAC(Azure 역할 기반 액세스 제어), 데이터 주권 요구 사항 또는 데이터 보존 정책에서 별도의 작업 영역을 요구하는 경우를 제외하고 플랫폼을 중앙에서 관리합니다.", + "text": "Azure RBAC(Azure 역할 기반 액세스 제어), 데이터 주권 요구 사항 또는 데이터 보존 정책에 따라 별도의 작업 영역이 필요한 경우를 제외하고 단일 모니터 로그 작업 영역을 사용하여 플랫폼을 중앙에서 관리합니다.", "training": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", "waf": "작업" }, @@ -1953,7 +1627,7 @@ "link": "https://learn.microsoft.com/azure/azure-monitor/logs/data-retention-archive?tabs=portal-1%2Cportal-2#how-retention-and-archiving-work", "severity": "보통", "subcategory": "모니터링", - "text": "로그 보존 요구 사항이 2년을 초과하는 경우 Azure Monitor 로그를 사용합니다. 현재 최대 7년 동안 데이터를 보관된 상태로 유지할 수 있습니다.", + "text": "로그 보존 요구 사항이 2년을 초과하는 경우 Azure Monitor 로그를 사용합니다. 현재 최대 7년 동안 보관된 상태로 데이터를 보관할 수 있습니다.", "training": "https://learn.microsoft.com/learn/paths/architect-infrastructure-operations/", "waf": "작업" }, @@ -1964,7 +1638,7 @@ "link": "https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/govern/policy-compliance/regulatory-compliance", "severity": "보통", "subcategory": "모니터링", - "text": "액세스 제어 및 규정 준수 보고에 Azure Policy를 사용합니다. Azure Policy는 일관된 정책 준수 및 빠른 위반 검색을 보장하기 위해 조직 전체 설정을 적용하는 기능을 제공합니다. ", + "text": "액세스 제어 및 규정 준수 보고에 Azure Policy를 사용합니다. Azure Policy는 일관된 정책 준수와 빠른 위반 감지를 보장하기 위해 조직 전체 설정을 적용하는 기능을 제공합니다. ", "training": "https://learn.microsoft.com/en-us/azure/governance/policy/concepts/effects", "waf": "작업" }, @@ -2019,7 +1693,7 @@ "link": "https://learn.microsoft.com/azure/governance/policy/overview", "severity": "낮다", "subcategory": "모니터링", - "text": "거부 정책을 사용하여 Azure 역할 할당을 보완합니다. 거부 정책과 Azure 역할 할당의 조합은 리소스를 배포하고 구성할 수 있는 사용자와 배포 및 구성할 수 있는 리소스를 적용하기 위한 적절한 가드레일을 마련합니다.", + "text": "거부 정책을 사용하여 Azure 역할 할당을 보완합니다. 거부 정책과 Azure 역할 할당의 조합은 리소스를 배포하고 구성할 수 있는 사용자와 배포 및 구성할 수 있는 리소스를 적용하기 위한 적절한 가드레일을 제공합니다.", "waf": "작업" }, { @@ -2029,7 +1703,7 @@ "link": "https://learn.microsoft.com/azure/service-health/alerts-activity-log-service-notifications-portal", "severity": "보통", "subcategory": "모니터링", - "text": "서비스 및 리소스 상태 이벤트를 전체 플랫폼 모니터링 솔루션의 일부로 포함Include service and resource health events as part of the overall platform monitoring solution. 플랫폼 관점에서 서비스 및 리소스 상태를 추적하는 것은 Azure에서 리소스 관리의 중요한 구성 요소입니다.", + "text": "서비스 및 리소스 상태 이벤트를 전체 플랫폼 모니터링 솔루션의 일부로 포함합니다. 플랫폼 관점에서 서비스 및 리소스 상태를 추적하는 것은 Azure에서 리소스 관리의 중요한 구성 요소입니다.", "waf": "작업" }, { @@ -2039,7 +1713,7 @@ "link": "https://learn.microsoft.com/azure/azure-monitor/alerts/action-groups", "severity": "보통", "subcategory": "모니터링", - "text": "경고 또는 문제를 처리할 수 있도록 경고 및 작업 그룹을 Azure Service Health 플랫폼의 일부로 포함합니다", + "text": "경고 또는 문제를 실행할 수 있도록 Azure Service Health 플랫폼의 일부로 경고 및 작업 그룹을 포함합니다.", "waf": "작업" }, { @@ -2079,7 +1753,7 @@ "link": "https://learn.microsoft.com/azure/azure-monitor/agents/diagnostics-extension-overview", "severity": "보통", "subcategory": "모니터링", - "text": "필요한 경우 Azure 진단 확장 로그 스토리지에 대한 랜딩 존 내의 공유 스토리지 계정을 사용합니다.", + "text": "필요한 경우 Azure 진단 확장 로그 스토리지에 대한 랜딩 존 내에서 공유 스토리지 계정을 사용합니다.", "waf": "작업" }, { @@ -2089,7 +1763,7 @@ "link": "https://learn.microsoft.com/azure/azure-monitor/alerts/alerts-overview", "severity": "보통", "subcategory": "모니터링", - "text": "운영 경고 생성에 Azure Monitor 경고를 사용합니다.", + "text": "Azure Monitor 경고를 사용하여 운영 경고를 생성합니다.", "waf": "작업" }, { @@ -2119,12 +1793,12 @@ "link": "https://learn.microsoft.com/azure/governance/policy/concepts/guest-configuration", "severity": "보통", "subcategory": "운영 규정 준수", - "text": "Azure 정책을 사용하여 VM 확장을 통해 소프트웨어 구성을 자동으로 배포하고 규정 준수 기준 VM 구성을 적용합니다.", + "text": "Azure 정책을 사용하여 VM 확장을 통해 소프트웨어 구성을 자동으로 배포하고 규격 기준 VM 구성을 적용합니다.", "waf": "안전" }, { "category": "경영", - "description": "Azure Policy의 게스트 구성 기능은 컴퓨터 설정(예: OS, 애플리케이션, 환경)을 감사하고 수정하여 리소스가 예상 구성과 일치하도록 할 수 있으며, 업데이트 관리는 VM에 대한 패치 관리를 적용할 수 있습니다.", + "description": "Azure Policy의 게스트 구성 기능은 컴퓨터 설정(예: OS, 애플리케이션, 환경)을 감사하고 수정하여 리소스가 예상 구성에 맞는지 확인할 수 있으며, 업데이트 관리는 VM에 대한 패치 관리를 적용할 수 있습니다.", "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", @@ -2140,7 +1814,7 @@ "link": "https://learn.microsoft.com/azure/site-recovery/site-recovery-overview", "severity": "보통", "subcategory": "보호 및 복구", - "text": "Azure 간 Virtual Machines 재해 복구 시나리오에 Azure Site Recovery를 사용합니다. 이렇게 하면 여러 지역에 걸쳐 워크로드를 복제할 수 있습니다.", + "text": "Azure-Azure Virtual Machines 재해 복구 시나리오에 Azure Site Recovery를 사용합니다. 이렇게 하면 지역 간에 워크로드를 복제할 수 있습니다.", "waf": "작업" }, { @@ -2160,7 +1834,7 @@ "link": "https://learn.microsoft.com/azure/backup/backup-center-overview", "severity": "보통", "subcategory": "보호 및 복구", - "text": "Azure 네이티브 백업 기능 또는 Azure 호환 타사 백업 솔루션을 사용합니다.", + "text": "Azure 네이티브 백업 기능 또는 Azure 호환 제3자 백업 솔루션을 사용합니다.", "waf": "작업" }, { @@ -2171,7 +1845,7 @@ "link": "https://learn.microsoft.com/azure/reliability/availability-zones-overview", "severity": "높다", "subcategory": "내결함성", - "text": "VM이 지원되는 지역의 VM에 가용성 영역을 활용합니다.", + "text": "VM이 지원되는 지역의 VM에 대한 가용성 영역을 활용합니다.", "waf": "신뢰도" }, { @@ -2212,7 +1886,7 @@ "link": "https://www.microsoft.com/security/business/zero-trust", "severity": "보통", "subcategory": "출입 통제", - "text": "적절한 경우 Azure 플랫폼에 액세스하기 위한 제로 트러스트 접근 방식을 구현합니다.", + "text": "적절한 경우 Azure 플랫폼에 대한 액세스에 대한 제로 트러스트 접근 방식을 구현합니다.", "waf": "안전" }, { @@ -2244,7 +1918,7 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "severity": "보통", "subcategory": "암호화 및 키", - "text": "삭제된 개체에 대한 보존 보호를 허용하도록 일시 삭제 및 제거 정책을 사용하도록 설정된 Azure Key Vault 프로비전합니다.", + "text": "삭제된 개체에 대한 보존 보호를 허용하기 위해 일시 삭제 및 제거 정책을 사용하도록 설정된 Azure Key Vault를 프로비전합니다.", "waf": "안전" }, { @@ -2264,7 +1938,7 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "severity": "보통", "subcategory": "암호화 및 키", - "text": "공용 인증 기관과 함께 인증서 관리 및 갱신 프로세스를 자동화하여 관리를 용이하게 합니다.", + "text": "공용 인증 기관을 통해 인증서 관리 및 갱신 프로세스를 자동화하여 관리를 용이하게 합니다.", "waf": "안전" }, { @@ -2274,7 +1948,7 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "severity": "보통", "subcategory": "암호화 및 키", - "text": "키 및 인증서 회전을 위한 자동화된 프로세스를 설정합니다.", + "text": "키 및 인증서 교체를 위한 자동화된 프로세스를 설정합니다.", "waf": "안전" }, { @@ -2304,7 +1978,7 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "severity": "보통", "subcategory": "암호화 및 키", - "text": "Key Vault 인스턴스화 및 권한 있는 액세스를 위임하고 Azure Policy를 사용하여 일관된 규격 구성을 적용합니다.", + "text": "Key Vault 인스턴스화 및 권한 있는 액세스를 위임하고 Azure Policy를 사용하여 일관된 규정 준수 구성을 적용합니다.", "waf": "안전" }, { @@ -2314,7 +1988,7 @@ "link": "https://learn.microsoft.com/azure/security/fundamentals/encryption-atrest", "severity": "보통", "subcategory": "암호화 및 키", - "text": "보안 주체 암호화 기능을 위해 Microsoft 관리형 키로 기본 설정되고 필요한 경우 고객 관리형 키를 사용합니다.", + "text": "보안 주체 암호화 기능을 위해 기본적으로 Microsoft 관리형 키를 사용하고 필요한 경우 고객 관리형 키를 사용합니다.", "waf": "안전" }, { @@ -2324,7 +1998,7 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "severity": "보통", "subcategory": "암호화 및 키", - "text": "지역별 환경별로 애플리케이션별로 Azure Key Vault를 사용합니다.", + "text": "애플리케이션, 환경, 지역당 Azure Key Vault를 사용합니다.", "waf": "안전" }, { @@ -2334,7 +2008,7 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "severity": "보통", "subcategory": "암호화 및 키", - "text": "사용자 고유의 키를 가져오려는 경우 고려되는 모든 서비스에서 지원되지 않을 수 있습니다. 불일치가 원하는 결과를 방해하지 않도록 관련 완화를 구현합니다. 대기 시간을 최소화하는 적절한 지역 쌍 및 재해 복구 지역을 선택합니다.", + "text": "자체 키를 가져오려는 경우 고려되는 모든 서비스에서 지원되지 않을 수 있습니다. 불일치가 원하는 결과를 방해하지 않도록 관련 완화를 구현합니다. 대기 시간을 최소화하는 적절한 지역 쌍과 재해 복구 지역을 선택합니다.", "waf": "안전" }, { @@ -2354,7 +2028,7 @@ "link": "https://learn.microsoft.com/azure/azure-monitor/logs/logs-data-export?tabs=portal", "severity": "보통", "subcategory": "작업", - "text": "장기 데이터 보존을 위해 Azure 활동 로그를 Azure Monitor 로그로 내보냅니다. 필요한 경우 2년 이상의 장기 저장을 위해 Azure Storage로 내보냅니다.", + "text": "장기 데이터 보존을 위해 Azure 활동 로그를 Azure Monitor 로그로 내보냅니다. 필요한 경우 2년 이상의 장기 보관을 위해 Azure Storage로 내보냅니다.", "waf": "안전" }, { @@ -2429,7 +2103,7 @@ "link": "https://learn.microsoft.com/azure/storage/common/storage-require-secure-transfer", "severity": "높다", "subcategory": "개요", - "text": "스토리지 계정으로의 보안 전송을 사용하도록 설정해야 함", + "text": "스토리지 계정에 대한 보안 전송을 사용하도록 설정해야 함", "waf": "안전" }, { @@ -2450,7 +2124,7 @@ "id": "G05.01", "link": "https://learn.microsoft.com/azure/active-directory/roles/security-planning", "severity": "높다", - "subcategory": "권한 있는 액세스 보호Secure privileged access", + "subcategory": "권한 있는 액세스 보호", "text": "Azure 관리 작업에 대한 권한 있는 관리자 계정을 분리합니다.", "waf": "안전" }, @@ -2482,7 +2156,7 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/platform-automation-devops", "severity": "높다", "subcategory": "DevOps 팀 토폴로지", - "text": "Azure Landing Zone 아키텍처를 빌드, 관리 및 유지 관리할 수 있는 교차 기능 DevOps 플랫폼 팀이 있는지 확인합니다.", + "text": "Azure 랜딩 존 아키텍처를 빌드, 관리 및 유지 관리할 수 있는 교차 기능 DevOps 플랫폼 팀이 있는지 확인합니다.", "waf": "작업" }, { @@ -2492,7 +2166,7 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/devops-teams-topologies#design-recommendations", "severity": "낮다", "subcategory": "DevOps 팀 토폴로지", - "text": "Azure 랜딩 존 플랫폼 팀을 위한 함수를 정의하는 것을 목표로 합니다.", + "text": "Azure 랜딩 존 플랫폼 팀의 함수를 정의하는 것을 목표로 합니다.", "waf": "작업" }, { @@ -2523,7 +2197,7 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/development-strategy-development-lifecycle#automated-builds", "severity": "보통", "subcategory": "DevOps 팀 토폴로지", - "text": "빌드 프로세스의 일부로 IaC 및 애플리케이션 코드에 대한 단위 테스트를 포함합니다.", + "text": "IaC 및 애플리케이션 코드에 대한 단위 테스트를 빌드 프로세스의 일부로 포함합니다.", "waf": "작업" }, { @@ -2554,8 +2228,8 @@ "id": "H02.01", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/infrastructure-as-code", "severity": "높다", - "subcategory": "개발 라이프사이클", - "text": "버전 제어 시스템이 애플리케이션 및 개발된 IaC의 소스 코드에 사용되는지 확인합니다. Microsoft는 Git을 권장합니다.", + "subcategory": "개발 수명 주기", + "text": "버전 제어 시스템이 개발된 애플리케이션 및 IaC의 소스 코드에 사용되는지 확인합니다. Microsoft는 Git을 권장합니다.", "waf": "작업" }, { @@ -2564,8 +2238,8 @@ "id": "H02.02", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/development-strategy-development-lifecycle", "severity": "낮다", - "subcategory": "개발 라이프사이클", - "text": "팀이 더 잘 협업하고 IaC 및 애플리케이션 코드의 버전 제어를 효율적으로 관리할 수 있도록 하는 분기 전략을 따릅니다. Github Flow와 같은 옵션을 검토합니다.", + "subcategory": "개발 수명 주기", + "text": "팀이 더 잘 협업하고 IaC 및 애플리케이션 코드의 버전 제어를 효율적으로 관리할 수 있도록 분기 전략을 따릅니다. Github Flow와 같은 옵션을 검토합니다.", "waf": "작업" }, { @@ -2574,8 +2248,8 @@ "id": "H02.03", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/development-strategy-development-lifecycle", "severity": "보통", - "subcategory": "개발 라이프사이클", - "text": "분기에 병합된 코드 변경 내용을 계속 제어할 수 있도록 끌어오기 요청 전략을 채택합니다.", + "subcategory": "개발 수명 주기", + "text": "분기에 병합된 코드 변경 내용을 제어하는 데 도움이 되는 끌어오기 요청 전략을 채택합니다.", "waf": "작업" }, { @@ -2586,7 +2260,7 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/infrastructure-as-code", "severity": "높다", "subcategory": "개발 전략", - "text": "Azure Bicep, ARM 템플릿 또는 Terraform과 같은 선언적 IaaS(Infrastructure as Code) 도구를 활용하여 Azure 랜딩 존 아키텍처를 빌드하고 유지 관리합니다. 플랫폼 및 응용 프로그램 워크로드 관점 모두에서.", + "text": "Azure Bicep, ARM 템플릿 또는 Terraform과 같은 선언적 인프라를 코드 도구로 활용하여 Azure 랜딩 존 아키텍처를 빌드하고 유지 관리합니다. 플랫폼 및 응용 프로그램 워크로드 관점에서Both from a Platform and Application workload perspective.", "waf": "작업" }, { @@ -2604,7 +2278,7 @@ "metadata": { "name": "Azure Landing Zone Review", "state": "GA", - "timestamp": "September 28, 2023" + "timestamp": "November 06, 2023" }, "severities": [ { @@ -2631,12 +2305,12 @@ "name": "성취" }, { - "description": "권장 사항을 이해했지만 현재 요구 사항에는 필요하지 않습니다.", - "name": "필요하지 않음" + "description": "권장 사항은 이해되었지만 현재 요구 사항에 필요하지 않음", + "name": "필요 없음" }, { "description": "현재 설계에는 적용되지 않습니다.", - "name": "해당 사항 없음" + "name": "해당 없음" } ], "waf": [ diff --git a/checklists/alz_checklist.pt.json b/checklists/alz_checklist.pt.json index b810b0e16..937ac25f5 100644 --- a/checklists/alz_checklist.pt.json +++ b/checklists/alz_checklist.pt.json @@ -589,12 +589,12 @@ }, { "category": "Topologia de rede e conectividade", - "guid": "f00a69de-7076-4734-a734-6e4552cad9e1", + "guid": "373f482f-3e39-4d39-8aa4-7e566f6082b6", "id": "D01.01", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-latest-version-for-customer-managed-certificates", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-app-delivery", "severity": "Média", "subcategory": "Entrega de aplicativos", - "text": "Se você usar certificados TLS gerenciados pelo cliente com o Azure Front Door, use a versão de certificado 'Mais recente'. Reduza o risco de paralisações causadas pela renovação manual de certificados.", + "text": "Desenvolva um plano para proteger o conteúdo do aplicativo de entrega de seus raios de carga de trabalho usando o Gateway de Aplicativo e o Azure Front door. Você pode usar a lista de verificação de entrega de aplicativos para obter recomendações.", "waf": "Operações" }, { @@ -608,57 +608,10 @@ "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", "waf": "Segurança" }, - { - "category": "Topologia de rede e conectividade", - "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": "D01.03", - "link": "https://learn.microsoft.com/azure/application-gateway/overview-v2", - "severity": "Média", - "subcategory": "Entrega de aplicativos", - "text": "Verifique se você está usando o SKU do Application Gateway v2", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", - "waf": "Segurança" - }, - { - "category": "Topologia de rede e conectividade", - "graph": "resources | where type == 'microsoft.network/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard')", - "guid": "4e35fbf5-0ae2-48b2-97ce-753353edbd1a", - "id": "D01.04", - "link": "https://learn.microsoft.com/azure/load-balancer/load-balancer-overview", - "severity": "Média", - "subcategory": "Entrega de aplicativos", - "text": "Verifique se você está usando a SKU padrão para seus Balanceadores de Carga do Azure", - "waf": "Segurança" - }, - { - "category": "Topologia de rede e conectividade", - "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 | project id, subnetId = tostring(subnets.id), subnetPrefixLength = split(subnets.properties.addressPrefix, '/')[1]) on subnetId | extend compliant = (subnetPrefixLength <= 26) | distinct id,compliant", - "guid": "dfc50f87-3800-424c-937b-ed5f186e7c15", - "id": "D01.05", - "link": "https://learn.microsoft.com/azure/application-gateway/configuration-infrastructure#size-of-the-subnet", - "severity": "Média", - "subcategory": "Entrega de aplicativos", - "text": "Seus gateways de aplicativo devem ser implantados em sub-redes com prefixos IP iguais ou maiores que /26", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", - "waf": "Segurança" - }, - { - "category": "Topologia de rede e conectividade", - "description": "A administração de proxies reversos em geral e do WAF em particular está mais próxima do aplicativo do que da rede, portanto, eles pertencem à mesma assinatura do aplicativo. Centralizar o Application Gateway e o WAF na assinatura de conectividade pode ser OK se for gerenciado por uma única equipe.", - "guid": "48b662d6-d15f-4512-a654-98f6dfe237de", - "id": "D01.06", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", - "severity": "Média", - "subcategory": "Entrega de aplicativos", - "text": "Implante o Gateway de Aplicativo do Azure v2 ou NVAs de parceiros usados para fazer proxy de conexões HTTP(S) de entrada na rede virtual da zona de aterrissagem e com os aplicativos que eles estão protegendo.", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", - "waf": "Segurança" - }, { "category": "Topologia de rede e conectividade", "guid": "143b16c3-1d7a-4a9b-9470-4489a8042d88", - "id": "D01.07", + "id": "D01.03", "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", "severity": "Média", "subcategory": "Entrega de aplicativos", @@ -666,159 +619,6 @@ "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", "waf": "Segurança" }, - { - "category": "Topologia de rede e conectividade", - "guid": "e79d17b7-3b22-4a5a-97e7-a8ed4b30e38c", - "id": "D01.08", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", - "severity": "Média", - "subcategory": "Entrega de aplicativos", - "text": "Use o Azure Front Door com políticas WAF para fornecer e ajudar a proteger aplicativos HTTP/S globais que abrangem várias regiões do Azure.", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", - "waf": "Segurança" - }, - { - "category": "Topologia de rede e conectividade", - "guid": "3f29812b-2363-4cef-b179-b599de0d5973", - "id": "D01.09", - "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", - "severity": "Média", - "subcategory": "Entrega de aplicativos", - "text": "Ao usar o Front Door e o Application Gateway para ajudar a proteger aplicativos HTTP/S, use políticas WAF no Front Door. Bloqueie o Application Gateway para receber tráfego somente do Front Door.", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", - "waf": "Segurança" - }, - { - "ammp": true, - "category": "Topologia de rede e conectividade", - "guid": "cd4cd21b-0881-437f-9e6c-4cfd3e504547", - "id": "D01.10", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", - "severity": "Alto", - "subcategory": "Entrega de aplicativos", - "text": "Use o Gerenciador de Tráfego para fornecer aplicativos globais que abrangem protocolos diferentes de HTTP/S.", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", - "waf": "Fiabilidade" - }, - { - "category": "Topologia de rede e conectividade", - "guid": "3b4b3e88-a459-4ed5-a22f-644dfbc58204", - "id": "D01.11", - "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy#how-application-proxy-works", - "severity": "Baixo", - "subcategory": "Entrega de aplicativos", - "text": "Se os usuários precisarem apenas de acesso a aplicativos internos, o Proxy de Aplicativo de ID do Microsoft Entra foi considerado uma alternativa à Área de Trabalho Virtual (AVD) do Azure?", - "training": "https://learn.microsoft.com/learn/modules/configure-azure-ad-application-proxy/", - "waf": "Segurança" - }, - { - "category": "Topologia de rede e conectividade", - "guid": "01ca7cf1-5754-442d-babb-8ba6772e5c30", - "id": "D01.12", - "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy#how-application-proxy-works", - "severity": "Média", - "subcategory": "Entrega de aplicativos", - "text": "Para reduzir o número de portas de firewall abertas para conexões de entrada em sua rede, considere o uso do Microsoft Entra ID Application Proxy para dar aos usuários remotos acesso seguro e autenticado a aplicativos internos.", - "training": "https://learn.microsoft.com/learn/paths/implement-applications-external-access-azure-ad/", - "waf": "Segurança" - }, - { - "ammp": true, - "category": "Topologia de rede e conectividade", - "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": "D01.13", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-policy-settings", - "severity": "Alto", - "subcategory": "Entrega de aplicativos", - "text": "Implante seus perfis WAF para Front Door no modo 'Prevenção'.", - "waf": "Segurança" - }, - { - "ammp": true, - "category": "Topologia de rede e conectividade", - "guid": "062d5839-4d36-402f-bfa4-02811eb936e9", - "id": "D01.14", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#avoid-combining-traffic-manager-and-front-door", - "severity": "Alto", - "subcategory": "Entrega de aplicativos", - "text": "Evite combinar o Gerenciador de Tráfego do Azure e o Azure Front Door.", - "waf": "Segurança" - }, - { - "ammp": true, - "category": "Topologia de rede e conectividade", - "guid": "5efeb96a-003f-4b18-8fcd-b4d84459c2b2", - "id": "D01.15", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-the-same-domain-name-on-front-door-and-your-origin", - "severity": "Alto", - "subcategory": "Entrega de aplicativos", - "text": "Use o mesmo nome de domínio no Azure Front Door e sua origem. Nomes de host incompatíveis podem causar bugs sutis.", - "waf": "Segurança" - }, - { - "category": "Topologia de rede e conectividade", - "guid": "0b5a380c-4bfb-47bc-b1d7-dcfef363a61b", - "id": "D01.16", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#disable-health-probes-when-theres-only-one-origin-in-an-origin-group", - "severity": "Baixo", - "subcategory": "Entrega de aplicativos", - "text": "Desabilite os testes de integridade quando houver apenas uma origem em um grupo de origem do Azure Front Door.", - "waf": "Desempenho" - }, - { - "category": "Topologia de rede e conectividade", - "guid": "5567048e-e5d7-4206-9c55-b5ed45d2cc0c", - "id": "D01.17", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#select-good-health-probe-endpoints", - "severity": "Média", - "subcategory": "Entrega de aplicativos", - "text": "Selecione bons pontos de extremidade de teste de integridade para o Azure Front Door. Considere a criação de pontos de extremidade de integridade que verifiquem todas as dependências do seu aplicativo.", - "waf": "Fiabilidade" - }, - { - "category": "Topologia de rede e conectividade", - "guid": "a13f72f3-8f5c-4864-95e5-75bf37fbbeb1", - "id": "D01.18", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-head-health-probes", - "severity": "Baixo", - "subcategory": "Entrega de aplicativos", - "text": "Use testes de integridade do HEAD com o Azure Front Door para reduzir o tráfego que o Front Door envia para seu aplicativo.", - "waf": "Desempenho" - }, - { - "ammp": true, - "category": "Topologia de rede e conectividade", - "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": "D01.19", - "link": "https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity", - "severity": "Alto", - "subcategory": "Entrega de aplicativos", - "text": "Usar o Gateway NAT do Azure em vez das regras de saída do Load Balancer para melhor escalabilidade do SNAT", - "waf": "Fiabilidade" - }, - { - "ammp": true, - "category": "Topologia de rede e conectividade", - "guid": "af95c92d-d723-4f4a-98d7-8722324efd4d", - "id": "D01.20", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-managed-tls-certificates", - "severity": "Alto", - "subcategory": "Entrega de aplicativos", - "text": "Use certificados TLS gerenciados com o Azure Front Door. Reduza o custo operacional e o risco de paralisações devido a renovações de certificados.", - "waf": "Operações" - }, - { - "category": "Topologia de rede e conectividade", - "guid": "189ea962-3969-4863-8f5a-5ad808c2cf4b", - "id": "D01.21", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#define-your-waf-configuration-as-code", - "severity": "Média", - "subcategory": "Entrega de aplicativos", - "text": "Defina sua configuração do WAF do Azure Front Door como código. Usando o código, você pode adotar mais facilmente novas versões do conjunto de regras e obter proteção adicional.", - "waf": "Operações" - }, { "category": "Topologia de rede e conectividade", "guid": "de0d5973-cd4c-4d21-a088-137f5e6c4cfd", @@ -1626,132 +1426,6 @@ "text": "Atribua espaço IP suficiente a hubs virtuais, idealmente um prefixo /23.", "waf": "Fiabilidade" }, - { - "ammp": true, - "category": "Topologia de rede e conectividade", - "guid": "2e30abab-5478-417c-81bf-bf1ad4ed1ed4", - "id": "D10.01", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-end-to-end-tls", - "severity": "Alto", - "subcategory": "Entrega de aplicativos", - "text": "Use o TLS de ponta a ponta com o Azure Front Door. Use o TLS para conexões de seus clientes com o Front Door e do Front Door com sua origem.", - "waf": "Segurança" - }, - { - "category": "Topologia de rede e conectividade", - "guid": "10aa45af-166f-44c4-9f36-b6d592dac2ca", - "id": "D10.02", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-http-to-https-redirection", - "severity": "Média", - "subcategory": "Entrega de aplicativos", - "text": "Use o redirecionamento HTTP para HTTPS com o Azure Front Door. Ofereça suporte a clientes mais antigos redirecionando-os para uma solicitação HTTPS automaticamente.", - "waf": "Segurança" - }, - { - "ammp": true, - "category": "Topologia de rede e conectividade", - "guid": "28b9ee82-b2c7-45aa-bc98-6de6f59a095d", - "id": "D10.03", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#enable-the-waf", - "severity": "Alto", - "subcategory": "Entrega de aplicativos", - "text": "Habilite o WAF do Azure Front Door. Proteja seu aplicativo contra uma série de ataques.", - "waf": "Segurança" - }, - { - "ammp": true, - "category": "Topologia de rede e conectividade", - "guid": "2902d8cc-1b0c-4495-afad-624ab70f7bd6", - "id": "D10.04", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#tune-your-waf", - "severity": "Alto", - "subcategory": "Entrega de aplicativos", - "text": "Ajuste o WAF do Azure Front Door para sua carga de trabalho. Reduza as detecções de falsos positivos.", - "waf": "Segurança" - }, - { - "ammp": true, - "category": "Topologia de rede e conectividade", - "guid": "17ba124b-127d-42b6-9322-388d5b2bbcfc", - "id": "D10.05", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-prevention-mode", - "severity": "Alto", - "subcategory": "Entrega de aplicativos", - "text": "Use o modo de prevenção com o WAF do Azure Front Door. O modo de prevenção garante que o WAF bloqueie solicitações maliciosas.", - "waf": "Segurança" - }, - { - "ammp": true, - "category": "Topologia de rede e conectividade", - "guid": "49a98f2b-ec22-4a87-9415-6a10b00d6555", - "id": "D10.06", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#enable-default-rule-sets", - "severity": "Alto", - "subcategory": "Entrega de aplicativos", - "text": "Habilite os conjuntos de regras padrão do WAF do Azure Front Door. Os conjuntos de regras padrão detectam e bloqueiam ataques comuns.", - "waf": "Segurança" - }, - { - "ammp": true, - "category": "Topologia de rede e conectividade", - "guid": "147a13d4-2a2f-4824-a524-f5855b52b946", - "id": "D10.07", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#enable-bot-management-rules", - "severity": "Alto", - "subcategory": "Entrega de aplicativos", - "text": "Habilite as regras de gerenciamento de bot do WAF do Azure Front Door. As regras de bot detectam bots bons e ruins.", - "waf": "Segurança" - }, - { - "category": "Topologia de rede e conectividade", - "guid": "d7dcdcb9-0d99-44b9-baab-ac7570ede79a", - "id": "D10.08", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-the-latest-ruleset-versions", - "severity": "Média", - "subcategory": "Entrega de aplicativos", - "text": "Use as versões mais recentes do conjunto de regras do WAF do Azure Front Door. As atualizações do conjunto de regras são atualizadas regularmente para levar em conta o cenário atual de ameaças.", - "waf": "Segurança" - }, - { - "category": "Topologia de rede e conectividade", - "guid": "b9620385-1cde-418f-914b-a84a06982ffc", - "id": "D10.09", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#add-rate-limiting", - "severity": "Média", - "subcategory": "Entrega de aplicativos", - "text": "Adicione o limite de taxa ao WAF do Azure Front Door. A limitação de taxa bloqueia clientes que enviam acidentalmente ou intencionalmente grandes quantidades de tráfego em um curto período de tempo.", - "waf": "Segurança" - }, - { - "category": "Topologia de rede e conectividade", - "guid": "6dc36c52-0124-4ffe-9eaf-23ec1282dedb", - "id": "D10.10", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-a-high-threshold-for-rate-limits", - "severity": "Média", - "subcategory": "Entrega de aplicativos", - "text": "Use um limite alto para os limites de taxa do WAF do Azure Front Door. Limites de limite de taxa alta evitam o bloqueio de tráfego legítimo, ao mesmo tempo em que fornecem proteção contra um número extremamente alto de solicitações que podem sobrecarregar sua infraestrutura. ", - "waf": "Segurança" - }, - { - "category": "Topologia de rede e conectividade", - "guid": "388a3d0e-0a43-4367-90b2-3dd2aeece5ee", - "id": "D10.11", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#geo-filter-traffic", - "severity": "Baixo", - "subcategory": "Entrega de aplicativos", - "text": "Filtre geograficamente o tráfego usando o WAF do Azure Front Door. Permita o tráfego apenas de regiões esperadas e bloqueie o tráfego de outras regiões.", - "waf": "Segurança" - }, - { - "category": "Topologia de rede e conectividade", - "guid": "00acd8a9-6975-414f-8491-2be6309893b8", - "id": "D10.12", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#specify-the-unknown-zz-location", - "severity": "Média", - "subcategory": "Entrega de aplicativos", - "text": "Especifique o local desconhecido (ZZ) ao filtrar geograficamente o tráfego com o WAF do Azure Front Door. Evite bloquear acidentalmente solicitações legítimas quando os endereços IP não puderem ser correspondidos geograficamente.", - "waf": "Segurança" - }, { "ammp": true, "category": "Governança", @@ -1893,7 +1567,7 @@ "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#add-diagnostic-settings-to-save-your-wafs-logs", "severity": "Alto", "subcategory": "Entrega de aplicativos", - "text": "Adicione configurações de diagnóstico para salvar os logs do WAF do Azure Front Door. Analise regularmente os logs para verificar se há ataques e detecções de falsos positivos.", + "text": "Adicione configurações de diagnóstico para salvar logs WAF de serviços de entrega de aplicativos, como o Azure Front Door e o Azure Application Gateway. Analise regularmente os logs para verificar se há ataques e detecções de falsos positivos.", "waf": "Operações" }, { @@ -1903,7 +1577,7 @@ "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#send-logs-to-microsoft-sentinel", "severity": "Média", "subcategory": "Entrega de aplicativos", - "text": "Envie logs do Azure Front Door para o Microsoft Sentinel. Detecte ataques e integre a telemetria do Front Door ao seu ambiente geral do Azure.", + "text": "Envie logs do WAF de seus serviços de entrega de aplicativos, como o Azure Front Door e o Azure Application Gateway, para o Microsoft Sentinel. Detecte ataques e integre a telemetria WAF ao seu ambiente geral do Azure.", "waf": "Operações" }, { @@ -2604,7 +2278,7 @@ "metadata": { "name": "Azure Landing Zone Review", "state": "GA", - "timestamp": "September 28, 2023" + "timestamp": "November 06, 2023" }, "severities": [ { diff --git a/checklists/checklist.en.master.json b/checklists/checklist.en.master.json index 5b96059e0..722656e56 100644 --- a/checklists/checklist.en.master.json +++ b/checklists/checklist.en.master.json @@ -1,9766 +1,10522 @@ { "items": [ { - "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": "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": [ - "Subscriptions", - "Defender" + "Entra" ], - "severity": "High", - "subcategory": "Pricing & Settings", - "text": "Security Center/Defender enable in all subscriptions" + "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": "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": "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": [ - "Defender", - "Monitor" + "Entra" ], - "severity": "High", - "subcategory": "Pricing & Settings", - "text": "Security Center/Defender enabled on all Log Analytics workspaces" + "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": "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": "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": [ - "Defender" + "Entra" ], - "severity": "Medium", - "subcategory": "Pricing & Settings", - "text": "Data collection set to 'Common'" + "severity": "Low", + "subcategory": "Microsoft Entra ID Tenants", + "text": "Leverage Azure Lighthouse for Multi-Tenant Management", + "waf": "Operations" }, { - "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": "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": [ - "Defender" + "Entra" ], - "severity": "High", - "subcategory": "Pricing & Settings", - "text": "Defender for Cloud enhanced security features are all enabled" + "severity": "Medium", + "subcategory": "Cloud Solution Provider", + "text": "Ensure that Azure Lighthouse is used for administering the tenant by partner", + "waf": "Cost" }, { - "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": "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": [ - "AzurePolicy", - "Defender" + "Entra" ], - "severity": "Medium", - "subcategory": "Pricing & Settings", - "text": "Auto-provisioning enabled as per company policy (policy must exist)" + "severity": "Low", + "subcategory": "Cloud Solution Provider", + "text": "Discuss support request and escalation process with CSP partner", + "waf": "Cost" }, { - "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": "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": [ - "AzurePolicy", - "Defender" + "Cost", + "Entra" ], - "severity": "Low", - "subcategory": "Pricing & Settings", - "text": "Email notifications enabled as per company policy (policy must exist)" + "severity": "Medium", + "subcategory": "Cloud Solution Provider", + "text": "Setup Cost Reporting and Views with Azure Cost Management", + "waf": "Cost" }, { - "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": "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" + "LoadBalancer", + "Entra" ], "severity": "Medium", - "subcategory": "Pricing & Settings", - "text": "Enable integrations options are selected " + "subcategory": "Enterprise Agreement", + "text": "Configure Notification Contacts to a group mailbox", + "waf": "Cost" }, { - "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": "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": [ - "Defender" + "TrafficManager", + "Entra" ], - "severity": "Medium", - "subcategory": "Pricing & Settings", - "text": "CI/CD integration is configured" + "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" }, { - "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", + "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": [ - "Defender", - "EventHubs" + "Entra" ], "severity": "High", - "subcategory": "Pricing & Settings", - "text": "Continuous export 'Event Hub' is enabled if using 3rd party SIEM" + "subcategory": "Enterprise Agreement", + "text": "Ensure that Accounts are configured to be of the type 'Work or School Account", + "waf": "Security" }, { - "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": "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": [ - "Monitor", - "Defender", - "Sentinel" + "Cost", + "Entra" ], "severity": "Medium", - "subcategory": "Pricing & Settings", - "text": "Continuous export 'Log Analytics Workspace' is enabled if not using Azure Sentinel" + "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": "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": "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": [ - "Defender" + "Cost", + "Subscriptions", + "Entra" ], - "severity": "High", - "subcategory": "Pricing & Settings", - "text": "Cloud connector enabled for AWS" + "severity": "Low", + "subcategory": "Enterprise Agreement", + "text": "Make use of Enterprise Dev/Test Subscriptions to reduce costs for non-production workloads", + "waf": "Cost" }, { - "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": "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": [ - "Defender" + "RBAC", + "Entra" ], - "severity": "High", - "subcategory": "Pricing & Settings", - "text": "Cloud connector enabled for GCP" + "severity": "Medium", + "subcategory": "Enterprise Agreement", + "text": "Periodically audit the role assignments to review who has access to your Enterprise Agreement Enrollment", + "waf": "Cost" }, { - "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": "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": [ - "Defender", - "Entra", - "Monitor" + "Entra" ], "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." + "subcategory": "Microsoft Customer Agreement", + "text": "Configure Agreement billing account notification contact email", + "waf": "Cost" }, { - "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": "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" + "Storage", + "Cost", + "Entra" ], - "severity": "Medium", - "subcategory": "Recommendations", - "text": "All recommendations remediated or disabled if not required." + "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": "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": "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": [ - "Defender" + "Cost", + "Entra" ], - "severity": "High", - "subcategory": "Recommendations", - "text": "Security Score>70%" + "severity": "Low", + "subcategory": "Microsoft Customer Agreement", + "text": "Make use of Azure Plan to reduce costs for non-production workloads", + "waf": "Cost" }, { - "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": "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": [ - "Monitor", - "Defender" + "RBAC", + "Entra" ], "severity": "Medium", - "subcategory": "Security Alerts", - "text": "Security Alerts contain only those generated in the past 24 hours (remediate or disable older security alerts)" + "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": "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", + "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": [ - "Defender" + "Entra" ], - "severity": "Medium", - "subcategory": "Workbooks", - "text": "If continuous export is enabled, default workbooks published to custom security dashboard" + "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": "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": "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": [ - "Defender" + "ASR", + "Entra" ], "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": "Microsoft Entra ID", + "text": "When deploying an AD Connect VM, consider having a staging sever for high availability / Disaster recovery", + "waf": "Reliability" }, { - "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", + "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": [ - "Subscriptions", - "Defender" + "Entra" ], "severity": "High", - "subcategory": "Secure Score", - "text": "All subscriptions protected by Security Center are shown (no subscription filter set)" + "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": "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": "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": [ - "Defender" + "Monitor", + "Entra" ], - "severity": "High", - "subcategory": "Regulatory Compliance", - "text": "Compliance controls are green for any required compliance requirements" + "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" }, { - "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", + "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": [ - "Defender", - "VM" + "ACR", + "Subscriptions", + "RBAC", + "Entra" ], "severity": "High", - "subcategory": "Azure Defender", - "text": "High severity VM vulnerabilities is zero (empty)" + "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": "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": "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": [ - "Firewall", - "Defender" + "AzurePolicy", + "Entra" ], - "severity": "Medium", - "subcategory": "Firewall Manager", - "text": "Hubs are protected by an Azure Firewall" + "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": "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", + "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": [ - "Defender", - "Firewall", - "VNet" + "Entra" ], - "severity": "Medium", - "subcategory": "Firewall Manager", - "text": "Virtual Networks are protected by a Firewall" + "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": "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": "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": [ - "Defender", - "Firewall", - "DDoS" + "RBAC", + "Entra" ], "severity": "Medium", - "subcategory": "Firewall Manager", - "text": "DDoS Standard enabled" + "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": "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": "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": [ - "Subscriptions", - "Defender" + "Entra" ], - "severity": "High", - "subcategory": "Coverage", - "text": "Verify that all subscriptions are covered (see pricing and settings to modify)" + "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" }, { - "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", + "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": [ - "VNet", - "VM" + "Entra" ], "severity": "High", - "subcategory": "Public IPs", - "text": "VM's with public IPs should be protected by NSG " + "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": "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": [ - "Firewall", - "VM", - "EventHubs" - ], - "severity": "High", - "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", + "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": [ - "VM" + "Entra" ], - "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": "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": "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": "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": [ + "Subscriptions", "RBAC", - "VNet" + "Entra" ], "severity": "Medium", - "subcategory": "NSG", - "text": "NSG RBAC is used to restrict access to network security team" + "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": "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": "Identity and Access Management", + "checklist": "Azure Landing Zone Review", + "guid": "1559ab91-53e8-4908-ae28-c84c33b6b780", + "id": "B03.11", + "link": "https://learn.microsoft.com/azure/active-directory-domain-services/overview", "services": [ - "VNet" + "Subscriptions", + "Entra" ], - "severity": "High", - "subcategory": "NSG", - "text": "NSG Inbound security rules do not contain a * (wildcard) in Source field" + "severity": "Medium", + "subcategory": "Identity", + "text": "If Azure Active Directory Domains Services (AADDS) is in use, deploy AADDS within the primary region because this service can only be projected into one subscription", + "training": "https://learn.microsoft.com/learn/modules/azure-active-directory/", + "waf": "Security" }, { - "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": "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": [ - "VNet" + "Entra" ], "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": "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": "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": "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": [ - "VNet" + "Entra" ], - "severity": "High", - "subcategory": "NSG", - "text": "NSG do not have Source as a * (wildcard) in place." + "severity": "Medium", + "subcategory": "Identity", + "text": "If AD on Windows server in use, are the resources in Azure using the correct domain controller?", + "training": "https://learn.microsoft.com/learn/paths/implement-windows-server-iaas-virtual-machine-identity/", + "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": "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": [ - "VNet", - "Sentinel" + "VPN", + "Entra" ], "severity": "Medium", - "subcategory": "NSG", - "text": "NSG Diagnostics send NetworkSecurityGroupEvent and NetworkSecurityGroupRuleCounter traffic to Sentinel LAW" + "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": "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": "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": [ "RBAC", - "VNet" + "Entra" ], "severity": "Medium", - "subcategory": "UDR", - "text": "UDR RBAC is used to restrict access to the network security team" + "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": "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": "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": [ - "Firewall", - "VNet" + "VNet", + "Entra" ], - "severity": "High", - "subcategory": "UDR", - "text": "If Zero Trust, then UDR's are used to send all traffic to the Azure Firewall Premium" + "severity": "Low", + "subcategory": "Landing zones", + "text": "Configure Identity (ADDS) 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": "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": "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": [ - "VNet" + "Storage", + "ACR", + "AKV", + "RBAC", + "Entra" ], "severity": "Medium", - "subcategory": "UDR", - "text": "UDR's that do not send all traffic to AzureFirewallPremium are known and documented." + "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": "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": "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": [ - "VNet" + "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": "Virtual Networks", - "text": "Customer is familiar with Azure networking defaults / SDN default routing in Azure" + "subcategory": "Naming and tagging", + "text": "It is recommended to follow Microsoft Best Practice Naming Standards", + "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": "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": [ - "RBAC", - "VNet" + "Subscriptions" ], "severity": "Medium", - "subcategory": "Virtual Networks", - "text": "VNet RBAC is used to restrict access to the network security team" + "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": "Azure Networking", - "checklist": "Azure Security Review Checklist", - "guid": "85c2fa55-b56a-4948-808b-e7d7e4c476b6", - "link": "https://learn.microsoft.com/azure/virtual-network/policy-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": [ - "VNet" + "Subscriptions" ], - "severity": "High", - "subcategory": "Virtual Networks", - "text": "VNet Security recommendations are remediated and there are no 'At-risk' VNets " + "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": "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": [ - "VNet" - ], - "severity": "High", - "subcategory": "Virtual Networks", - "text": "VNet Peering connections are understood and expected traffic flows are documented" - }, - { - "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": "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": [ - "VNet" + "AzurePolicy", + "RBAC", + "Subscriptions" ], - "severity": "High", - "subcategory": "Virtual Networks", - "text": "VNet Service Endpoints are in use, no legacy Public Service Endpoints exist" + "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" }, { - "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": "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": [ - "PrivateLink", - "VNet" + "DNS", + "ExpressRoute", + "Subscriptions", + "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": "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": "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": "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": [ - "Monitor", - "VNet" + "Subscriptions" ], - "severity": "High", - "subcategory": "Virtual Networks", - "text": "VNet Monitoring enabled" + "severity": "Medium", + "subcategory": "Subscriptions", + "text": "Enforce no subscriptions are placed under the root management group", + "waf": "Security" }, { - "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": "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": [ - "AzurePolicy", - "AKS", - "VNet" + "Subscriptions", + "RBAC" ], - "severity": "High", - "subcategory": "Virtual Networks", - "text": "Secure traffic between pods using network policies in Azure Kubernetes Service (AKS)" + "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" }, { - "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": "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": [ - "NVA", - "VNet" + "Subscriptions" ], - "severity": "High", - "subcategory": "Virtual Networks", - "text": "VNet NVA (appliances) customer follows published architecture pattern" + "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" }, { - "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", + "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": [ - "Monitor", - "VNet", - "Sentinel" + "Subscriptions", + "Cost", + "AzurePolicy", + "RBAC" ], "severity": "High", - "subcategory": "Virtual Networks", - "text": "VNet Diagnostic settings are enabled and sending VMProtectionAlerts to the Azure Sentinel LAW" + "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": "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": "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": [ - "VPN", - "ExpressRoute" + "Subscriptions" ], - "severity": "High", - "subcategory": "Connectivity", - "text": "Use ExpressRoute or VPN to access Azure resources from on-premises environments" + "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" }, { - "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", + "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": [ - "RBAC", - "VWAN" + "Cost", + "AzurePolicy", + "Subscriptions", + "VM" ], "severity": "High", - "subcategory": "Virtual WAN", - "text": "VWAN RBAC is used to restrict access to the network security team" + "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": "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", + "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", - "VWAN" + "Subscriptions", + "Monitor" ], "severity": "High", - "subcategory": "Virtual WAN", - "text": "VWAN Customer is using Secure Hub or external Firewall to route and monitor traffic." + "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": "Azure Networking", - "checklist": "Azure Security Review Checklist", - "guid": "1213dbd7-fb01-42f7-8943-f6304722ea39", - "link": "https://learn.microsoft.com/azure/web-application-firewall/overview", + "category": "Resource Organization", + "checklist": "Azure Landing Zone Review", + "guid": "4c27d42e-8bba-4c75-9155-9ab9153e8908", + "id": "C02.12", + "link": "https://azure.microsoft.com/global-infrastructure/services/", "services": [ - "AppGW", - "RBAC" + "Subscriptions" ], - "severity": "High", - "subcategory": "Application Gateway", - "text": "AppGW RBAC is used to restrict access to the network security team" + "severity": "Medium", + "subcategory": "Subscriptions", + "text": "Ensure required services and features are available within the chosen deployment regions", + "training": "https://learn.microsoft.com/learn/modules/azure-architecture-fundamentals/", + "waf": "Security" }, { - "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", + "ammp": true, + "category": "Resource Organization", + "checklist": "Azure Landing Zone Review", + "guid": "ae28c84c-33b6-4b78-88b9-fe5c41049d40", + "id": "C02.13", + "link": "https://learn.microsoft.com/azure/cost-management-billing/cost-management-billing-overview", "services": [ - "AppGW", - "EventHubs", - "WAF" + "Cost", + "Subscriptions" ], "severity": "High", - "subcategory": "Application Gateway", - "text": "AppGW All external facing web services are behind Application Gateways with WAF enabled " + "subcategory": "Subscriptions", + "text": "Enforce a process for cost management", + "training": "https://learn.microsoft.com/learn/paths/control-spending-manage-bills/", + "waf": "Security" }, { - "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": "Resource Organization", + "checklist": "Azure Landing Zone Review", + "guid": "3a923c34-74d0-4001-aac6-a9e01e6a83de", + "id": "C02.14", + "link": "https://learn.microsoft.com/azure/governance/management-groups/overview", "services": [ - "AppGW", - "EventHubs", - "WAF" + "Subscriptions", + "Entra" ], - "severity": "High", - "subcategory": "Application Gateway", - "text": "AppGW All internal facing web services are behind Application Gateways with WAF enabled " + "severity": "Medium", + "subcategory": "Subscriptions", + "text": "If AD on Windows Server, establish a dedicated identity subscription in the Indentity management group, to host Windows Server Active Directory domain controllers", + "training": "https://learn.microsoft.com/learn/paths/enterprise-scale-architecture/", + "waf": "Security" }, { - "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": "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.15", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/track-costs", "services": [ - "AppGW" + "Cost", + "Subscriptions" ], - "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": "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": "Azure Networking", - "checklist": "Azure Security Review Checklist", - "guid": "f2e8bbbc-4681-455a-ac91-64e9909aed8c", - "link": "https://learn.microsoft.com/azure/frontdoor/", + "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", "services": [ - "RBAC", + "AppGW", "FrontDoor" ], - "severity": "High", - "subcategory": "FrontDoor", - "text": "Front Door RBAC is used to restrict access to the network security team" + "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" }, { - "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": [ - "AzurePolicy", - "FrontDoor", - "WAF" - ], - "severity": "High", - "subcategory": "FrontDoor", - "text": "Front Door is associated with a WAF policy" + "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", + "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": "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": "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": [ - "AzurePolicy", - "FrontDoor" + "DDoS" ], - "severity": "High", - "subcategory": "FrontDoor", - "text": "Front Door TLS/SSL policy is configured" + "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": "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": "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", "services": [ - "FrontDoor" + "ExpressRoute" ], - "severity": "High", - "subcategory": "FrontDoor", - "text": "Front Door redirect port 80 to port 443 is configured (listeners)" + "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.", + "waf": "Security" }, { - "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": "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": [ - "FrontDoor", - "Sentinel" + "ExpressRoute", + "VPN" ], - "severity": "High", - "subcategory": "FrontDoor", - "text": "Front Door diagnostics logs send ApplicationGatewayAccessLog &ApplicationGateway FirewallLog to Sentinel LAW" + "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/", + "waf": "Security" }, { - "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": "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", "services": [ - "DDoS" + "VNet" ], - "severity": "High", - "subcategory": "DDOS Protection", - "text": "Enabled for Firewall public IP's (all public IPs)" + "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" }, { - "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", + "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", "services": [ + "Firewall", + "DNS", + "VNet", + "VPN", + "NVA", + "ExpressRoute", "Entra" ], "severity": "High", - "subcategory": "Tenant", - "text": "Establish a single enterprise directory for managing identities of full-time employees and enterprise resources." + "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": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "a46108cd-6a76-4749-ae69-b7bf61410010", - "link": "https://learn.microsoft.com/security/compass/identity#synchronized-identity-systems", + "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", "services": [ - "Entra" + "NVA" ], - "severity": "High", - "subcategory": "Tenant", - "text": "Synchronize your cloud identity with your existing identity systems." + "severity": "Medium", + "subcategory": "Hub and spoke", + "text": "When deploying partner networking technologies or NVAs, follow the partner vendor's guidance", + "waf": "Reliability" }, { - "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": "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", "services": [ - "Entra" + "ExpressRoute", + "VPN", + "ARS" ], - "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": "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": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "343473ec-ed5c-49e1-98f4-cb09524a23cd", - "link": "https://learn.microsoft.com/security/compass/identity#block-legacy-authentication", + "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", "services": [ - "Entra" + "VNet", + "ARS" ], - "severity": "High", - "subcategory": "Tenant", - "text": "Disable insecure legacy protocols for internet-facing services." + "severity": "Low", + "subcategory": "Hub and spoke", + "text": "If using Route Server, use a /27 prefix for the Route Server subnet.", + "waf": "Security" }, { - "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": "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", "services": [ - "Entra" + "ACR", + "VNet" ], - "severity": "High", - "subcategory": "Tenant", - "text": "Enable single sign-on" + "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" }, { - "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": "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", "services": [ - "Entra" + "Monitor" ], - "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": "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" }, { - "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": [ - "Entra" - ], - "severity": "High", - "subcategory": "Privileged administration", - "text": "Limit the number of Global Administrators to less than 5" - }, - { - "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": "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", "services": [ - "RBAC", + "ExpressRoute", + "VNet", "Entra" ], - "severity": "High", - "subcategory": "Privileged administration", - "text": "Use groups for Azure AD role assignments and delegate the role assignment" + "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" }, { - "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": "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", "services": [ - "AzurePolicy", - "Entra" + "Storage" ], - "severity": "High", - "subcategory": "Privileged administration", - "text": "Ensure all critical impact admins are managed by enterprise directory to follow organizational policy enforcement." + "severity": "Medium", + "subcategory": "Hub and spoke", + "text": "Consider the limit of routes per route table (400).", + "waf": "Reliability" }, { - "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", + "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", "services": [ - "Entra" + "VNet" ], "severity": "High", - "subcategory": "Privileged administration", - "text": "Configure recurring access reviews to revoke unneeded permissions over time" + "subcategory": "Hub and spoke", + "text": "Use the setting 'Allow traffic to remote virtual network' when configuring VNet peerings", + "waf": "Reliability" }, { - "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": "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", "services": [ - "Monitor", - "Entra" + "ExpressRoute" ], "severity": "Medium", - "subcategory": "Privileged administration", - "text": "Ensure critical impact admins use a workstation with elevated security protections and monitoring" + "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": "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": "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", "services": [ - "Entra" + "ExpressRoute" ], - "severity": "High", - "subcategory": "External Identities", - "text": "Identity Providers: Verify external identity providers are known" + "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" }, { - "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": "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", "services": [ - "Entra" + "ExpressRoute", + "VPN" ], - "severity": "High", - "subcategory": "External Identities", - "text": "External Collaboration Settings: Guest user access set to 'Guest user access is restricted?'" + "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" }, { - "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", + "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", "services": [ - "RBAC", - "Entra" + "ExpressRoute", + "Cost" ], "severity": "High", - "subcategory": "External Identities", - "text": "External Collaboration Settings: Guest invite settings set to 'Only users assigned to specific admin roles'" + "subcategory": "Hybrid", + "text": "Ensure that you're using unlimited-data ExpressRoute circuits only if you reach the bandwidth that justifies their cost.", + "waf": "Cost" }, { - "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", + "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": [ - "Entra" + "ExpressRoute", + "Cost" ], "severity": "High", - "subcategory": "External Identities", - "text": "External Collaboration Settings: Enable guest self-service sign up via flows set to 'Disabled' " + "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": "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": "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", "services": [ - "Entra" + "ExpressRoute" ], - "severity": "High", - "subcategory": "External Identities", - "text": "External Collaboration Settings: Collaboration restrictions set to 'Allow invitations to the specified domains'" + "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" }, { - "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": "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": [ - "Entra" + "ExpressRoute" ], "severity": "Medium", - "subcategory": "External Identities", - "text": "Access Reviews: Enabled for all groups" + "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": "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": "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": [ - "Entra" + "ExpressRoute" ], "severity": "Medium", - "subcategory": "Enterprise Applications", - "text": "Consent & Permissions: Allow user consent for apps from verified publishers" + "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": "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": "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": [ - "Entra" + "VPN" ], "severity": "Medium", - "subcategory": "Enterprise Applications", - "text": "Consent & Permissions: Allow group owner consent for selected group owners " + "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": "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", + "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": [ - "Entra" + "ExpressRoute", + "Cost" ], "severity": "High", - "subcategory": "Custom Domains", - "text": "Only validated customer domains are registered" - }, - { - "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", - "Entra" - ], - "severity": "High", - "subcategory": "Password Reset", - "text": "Self-service password reset policy requirement verified compliant." + "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": "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": "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": [ - "Entra" + "ExpressRoute" ], "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": "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": "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": "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": [ - "Entra" + "ExpressRoute", + "Monitor" ], - "severity": "High", - "subcategory": "Password Reset", - "text": "Set number of methods required to reset password are selected" + "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" }, { - "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": "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": [ - "Entra" + "ACR", + "Monitor", + "NetworkWatcher" ], - "severity": "High", - "subcategory": "User Setting", - "text": "Disable 'Users can register applications'" + "severity": "Medium", + "subcategory": "Hybrid", + "text": "Use Connection Monitor for connectivity monitoring across the environment.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "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": "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": [ - "Entra" + "ExpressRoute" ], - "severity": "High", - "subcategory": "User Setting", - "text": "Restrict access to Administrative portal (portal.azure.com) to administrators only" + "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" }, { - "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", + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "2df4930f-6a43-49a3-926b-309f02c302f0", + "id": "D04.15", + "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/identity/adds-extend-domain#vm-recommendations", "services": [ - "Entra" + "VM" ], "severity": "High", - "subcategory": "User Setting", - "text": "Disable 'LinkedIn account connection'" + "subcategory": "Hybrid", + "text": "If you are deploying at least two VMs running AD DS as domain controllers, add them to different Availability Zones. If not available in the region, deploy in an Availability Set.", + "waf": "Reliability" }, { - "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", + "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": [ - "Monitor", - "Entra", - "Sentinel" + "ACR", + "VNet" ], "severity": "High", - "subcategory": "Diagnostic Settings", - "text": "Enabled and send to Log Analytics workspace with Sentinel" + "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": "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": "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": [ - "Entra" + "VNet" ], - "severity": "High", - "subcategory": "PIM enabled", - "text": "Privileged Identity Management enabled" + "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": "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", + "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": [ - "Entra" + "VNet" ], "severity": "High", - "subcategory": "PIM enabled", - "text": "Implement 'just in time' (JIT) access to further lower the exposure time for privileged accounts (reduce standing access)" + "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": "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", + "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": [ - "AzurePolicy", - "Entra" + "VNet" ], "severity": "High", - "subcategory": "Conditional Access Policies", - "text": "Configure conditional access policies / Access Controls" + "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": "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": "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": [ - "AzurePolicy", - "Entra" + "DNS", + "VNet" ], "severity": "Medium", - "subcategory": "Conditional Access Policies", - "text": "Conditions: Restricted Locations" + "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": "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": "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": [ - "AzurePolicy", - "Entra" + "DNS", + "ACR", + "VNet" ], - "severity": "High", - "subcategory": "Conditional Access Policies", - "text": "Access Controls: MFA enabled for all users" + "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" }, { - "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": "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": [ - "AzurePolicy", - "Entra" + "DNS", + "VNet" ], - "severity": "Medium", - "subcategory": "Conditional Access Policies", - "text": "Access Controls: Require MFA for Administrators" + "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": "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": "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", + "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": [ - "AzurePolicy", - "Entra" + "DNS", + "VNet", + "VM" ], "severity": "High", - "subcategory": "Conditional Access Policies", - "text": "Access Controls: Block Legacy Protocols" + "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": "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": "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": [ - "AzurePolicy", - "Entra" + "Bastion" ], - "severity": "High", - "subcategory": "Conditional Access Policies", - "text": "Access Controls: Require devices to be marked as compliant" + "severity": "Medium", + "subcategory": "Internet", + "text": "Consider using Azure Bastion to securely connect to your network.", + "waf": "Security" }, { - "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/", + "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": [ - "AzurePolicy", - "Entra" + "Bastion", + "VNet" ], "severity": "Medium", - "subcategory": "Guest users", - "text": "Is there a policy to track guest user accounts (i.e. usage/delete/disable)?" + "subcategory": "Internet", + "text": "Use Azure Bastion in a subnet /26 or larger.", + "waf": "Security" }, { - "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", + "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": [ - "Entra" + "Firewall" ], "severity": "High", - "subcategory": "Identity Secure Score", - "text": "Implement Identity Secure Score based on best practices in your industry" + "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": "Identity", - "checklist": "Azure Security Review Checklist", - "guid": "bcfc6998-a135-4e33-9897-e31c67d68cb6", - "link": "https://learn.microsoft.com/azure/active-directory/roles/security-emergency-access", + "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", "AzurePolicy", - "Entra" + "RBAC", + "Firewall" ], "severity": "Medium", - "subcategory": "Break Glass Accounts", - "text": "At least two break glass accounts have been created and policy around their use exists" + "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": "VM Security Checks", - "checklist": "Azure Security Review Checklist", - "guid": "0ac252b9-99a6-48af-a7c9-a8f821b8eb8c", - "link": "https://learn.microsoft.com/azure/governance/policy/overview", + "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": [ - "AzurePolicy", - "VM" + "Firewall" ], - "severity": "High", - "subcategory": "Access Control", - "text": "Control VM Access leveraging Azure Policy" + "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": "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", + "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": [ - "VM" + "ACR", + "AzurePolicy", + "WAF", + "FrontDoor" ], "severity": "Medium", - "subcategory": "Access Control", - "text": "Reduce variability in your setup and deployment of VMs by leveraging templates" + "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": "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": "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": [ - "VM" + "AppGW", + "AzurePolicy", + "WAF", + "FrontDoor" ], - "severity": "Medium", - "subcategory": "Access Control", - "text": "Secure privileged access to deploy VMS by reducing who has access to Resources through Governance" + "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" }, { - "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", + "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": [ - "VM" + "VNet", + "WAF" ], - "severity": "Medium", - "subcategory": "High Availability ", - "text": "Use multiple VMs for your workloads for better availability " + "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": "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", + "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": [ - "ASR", - "VM" + "VNet", + "DDoS" ], - "severity": "Medium", - "subcategory": "High Availability ", - "text": "Deploy and test a disaster recovery solution " + "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" }, { - "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", + "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": [ - "VM" + "DNS", + "Firewall" ], - "severity": "Medium", - "subcategory": "High Availability ", - "text": "Availability sets" + "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" }, { - "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", + "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": [ - "VM" + "Firewall" ], - "severity": "Medium", - "subcategory": "High Availability ", - "text": "Availability Zones" + "severity": "High", + "subcategory": "Internet", + "text": "Use Azure Firewall Premium for additional security and protection.", + "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", - "services": [ - "VM" - ], - "severity": "Medium", - "subcategory": "High Availability ", - "text": "Regional fault tolerance " - }, - { - "category": "VM Security Checks", - "checklist": "Azure Security Review Checklist", - "guid": "af225ca4-4e16-496f-bdde-ace4cb1deb4c", - "link": "https://learn.microsoft.com/azure/security/fundamentals/antimalware", + "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": [ - "VM" + "Firewall" ], "severity": "High", - "subcategory": "Protect against malware", - "text": "Install antimalware solutions" + "subcategory": "Internet", + "text": "Configure Azure Firewall Threat Intelligence mode to Alert and Deny for additional protection.", + "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", + "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": [ - "Defender", - "VM" + "Firewall" ], "severity": "High", - "subcategory": "Protect against malware", - "text": "Integrate antimalware solution with Security Center" + "subcategory": "Internet", + "text": "Configure Azure Firewall IDPS mode to Deny for additional protection.", + "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", + "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": [ - "VM" + "Storage", + "Firewall", + "VNet", + "VWAN", + "NVA" ], "severity": "High", - "subcategory": "Manage VM Updates", - "text": "Keep VMs up to date using Update Management with Azure Automation" + "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": "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", + "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": [ - "VM" + "VNet" ], - "severity": "Medium", - "subcategory": "Manage VM Updates", - "text": "Ensure Windows images for deployment have the most recent level of updates " + "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" }, { - "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": "Azure Landing Zone Review", + "guid": "e43a58a9-c229-49c4-b7b5-7d0c655562f2", + "id": "D07.02", + "link": "https://learn.microsoft.com/azure/app-service/networking-features", "services": [ - "Defender", - "VM" + "PrivateLink" ], - "severity": "High", - "subcategory": "Manage VM Updates", - "text": "Rapidly apply security updates to VMs using Microsoft Defender for Cloud" + "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": "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": "Azure Landing Zone Review", + "guid": "b3e4563a-4d87-4397-98b6-62d6d15f512a", + "id": "D07.03", + "link": "https://learn.microsoft.com/azure/app-service/networking-features", "services": [ - "VM" + "ExpressRoute", + "PrivateLink" ], - "severity": "High", - "subcategory": "Encrypt your VHDs", - "text": "Enable encryption on your VMs" + "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" }, { - "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": "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": [ - "VM" + "VNet" ], - "severity": "High", - "subcategory": "Encrypt your VHDs", - "text": "Add Key Encryption Key (KEK) for added layer of security for encryption " + "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": "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": "Azure Landing Zone Review", + "guid": "7e7a8ed4-b30e-438c-9f29-812b2363cefe", + "id": "D07.05", + "link": "https://learn.microsoft.com/azure/app-service/networking-features", "services": [ - "LoadBalancer", - "VM" + "DNS", + "Firewall", + "PrivateLink", + "NVA" ], "severity": "Medium", - "subcategory": "Encrypt your VHDs", - "text": "Take a snapshot of disks before encryption for rollback purposes" + "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": "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", + "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": [ - "Entra", - "VM" + "VNet", + "Firewall" ], "severity": "High", - "subcategory": "Restrict direct internet connection ", - "text": "Ensure only the central networking group has permissions to networking resources " + "subcategory": "Segmentation", + "text": "Use a /26 prefix for your Azure Firewall subnets.", + "waf": "Security" }, { - "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", + "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": [ - "Entra", - "VM" + "ExpressRoute", + "VNet", + "VPN" ], "severity": "High", - "subcategory": "Restrict direct internet connection ", - "text": "Identity and remediate exposed VMs that allow access from 'ANY' source IP address" + "subcategory": "Segmentation", + "text": "Use at least a /27 prefix for your Gateway subnets", + "waf": "Security" }, { - "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": "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": [ - "VM" + "VNet" ], - "severity": "High", - "subcategory": "Restrict direct internet connection ", - "text": "Restrict management ports (RDP, SSH) using Just-in-Time Access" + "severity": "Medium", + "subcategory": "Segmentation", + "text": "Don't rely on the NSG inbound default rules using the VirtualNetwork service tag to limit connectivity.", + "waf": "Security" }, { - "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": "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": [ - "VM" + "VNet" ], - "severity": "High", - "subcategory": "Restrict direct internet connection ", - "text": "Remove internet access and implement jump servers for RDP" + "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" }, { - "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", + "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": [ - "VPN", - "VM" + "ACR", + "VNet" ], - "severity": "High", - "subcategory": "Restrict direct internet connection ", - "text": "Remove direct logging into servers using RDP/SSH from internet and implement VPN or express route" + "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" }, { - "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": "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": [ - "Bastion", + "VNet", "VM" ], - "severity": "High", - "subcategory": "Restrict direct internet connection ", - "text": "Leverage Azure Bastion as your RDP/SSH broker for added security and reduction in footprint" + "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": "Sentinel", - "checklist": "Azure Security Review Checklist", - "guid": "cd5d1e54-a297-459e-9968-0e78289c9356", - "link": "https://learn.microsoft.com/azure/sentinel/quickstart-onboard", + "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": [ - "Monitor", - "Sentinel" + "VNet", + "Entra", + "NVA" ], - "severity": "High", - "subcategory": "Architecture ", - "text": "All tenants contain have Sentinel enabled on at least one Log Analytics workspace" + "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" }, { - "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": "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": [ - "Sentinel" + "NetworkWatcher", + "VNet" ], - "severity": "High", - "subcategory": "Architecture ", - "text": "Customer understands Sentinel architecture" + "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": "Sentinel", - "checklist": "Azure Security Review Checklist", - "guid": "e8f5c586-c7d9-4cdc-86ac-c075ef9b141a", - "link": "https://learn.microsoft.com/azure/sentinel/multiple-workspace-view", + "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": [ - "ACR", - "Sentinel", - "Monitor" + "VWAN" ], "severity": "Medium", - "subcategory": "Architecture ", - "text": "Customer knows how to monitor Incidents across multiple Sentinel instances" + "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": "Sentinel", - "checklist": "Azure Security Review Checklist", - "guid": "8989579e-76b8-497e-910a-7da7be9966e1", - "link": "https://learn.microsoft.com/azure/sentinel/manage-soc-with-incident-metrics", + "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": [ - "Sentinel" + "ACR", + "VWAN" ], "severity": "Medium", - "subcategory": "Overview", - "text": "No Incidents open more than 24 hours" + "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": "Sentinel", - "checklist": "Azure Security Review Checklist", - "guid": "5d3c4ada-97cb-43d1-925a-b225c6f4e068", - "link": "https://learn.microsoft.com/azure/sentinel/whats-new", + "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": [ - "Sentinel" + "ACR", + "VWAN" ], "severity": "Low", - "subcategory": "News & Guides", - "text": "Customer have been shown the News & Guides tab" + "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": "Sentinel", - "checklist": "Azure Security Review Checklist", - "guid": "5edddea8-a4b7-4cde-a4c6-1fc3fc14eea6", - "link": "https://learn.microsoft.com/azure/sentinel/enable-entity-behavior-analytics", + "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": [ - "Sentinel" + "VWAN", + "Firewall" ], "severity": "Medium", - "subcategory": "UEBA ", - "text": "UEBA Configured (Sentinel/Settings/Settings/Configure UEBA)" + "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": "Sentinel", - "checklist": "Azure Security Review Checklist", - "guid": "e69d8d9a-3eec-4218-b687-ab077adb49e5", - "link": "https://learn.microsoft.com/azure/sentinel/connect-azure-active-directory", + "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": [ - "Entra", - "Sentinel" + "VWAN" ], - "severity": "High", - "subcategory": "Data Connectors", - "text": "Azure Active Directory in configured and 'Last Log Received' shows today" + "severity": "Medium", + "subcategory": "Virtual WAN", + "text": "Ensure that the network architecture is within the Azure Virtual WAN limits.", + "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", + "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": [ - "Entra", - "Sentinel" + "VWAN", + "Monitor" ], - "severity": "High", - "subcategory": "Data Connectors", - "text": "Azure Active Directory Identity Protection is configured and 'Last Log Received' shows today" + "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" }, { - "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": "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": [ - "Sentinel" + "VWAN" ], - "severity": "High", - "subcategory": "Data Connectors", - "text": "Azure Activity is configured is configured and 'Last Log Received' shows today" + "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": "Sentinel", - "checklist": "Azure Security Review Checklist", - "guid": "8e13f9cc-bd46-4826-9abc-a264f9a19bfe", - "link": "https://learn.microsoft.com/azure/sentinel/connect-defender-for-cloud", + "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": [ - "Defender", - "Sentinel" + "ExpressRoute", + "VPN", + "VWAN" ], - "severity": "High", - "subcategory": "Data Connectors", - "text": "Microsoft Defender for Cloud is configured and 'Last Log Received' shows today" + "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": "Sentinel", - "checklist": "Azure Security Review Checklist", - "guid": "9d55d04c-3c49-419c-a1b2-d1215ae114b9", - "link": "https://learn.microsoft.com/azure/sentinel/data-connectors-reference#azure-firewall", + "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": [ - "Firewall", - "Sentinel" + "VWAN" ], - "severity": "High", - "subcategory": "Data Connectors", - "text": "Azure Firewall is configured and 'Last Log Received' shows today" + "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" }, { - "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", + "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": [ - "Sentinel" + "VWAN" ], "severity": "High", - "subcategory": "Data Connectors", - "text": "Windows Firewall is configured and 'Last Log Received' shows today" + "subcategory": "Virtual WAN", + "text": "Assign enough IP space to virtual hubs, ideally a /23 prefix.", + "waf": "Reliability" }, { - "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", + "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": [ - "Sentinel" + "AzurePolicy" ], "severity": "High", - "subcategory": "Data Connectors", - "text": "Security Events is configured with AMA and 'Last Log Received' shows today" + "subcategory": "Governance", + "text": "Leverage Azure Policy strategically, define controls for your environment, using Policy Initiatives to group related policies.", + "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": "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": [ - "Sentinel" + "AzurePolicy" ], - "severity": "High", - "subcategory": "Data Connectors", - "text": "Security Events - verify Azure computers are connected and sending data to the workspace" + "severity": "Medium", + "subcategory": "Governance", + "text": "Identify required Azure tags and use the 'append' policy mode to enforce usage via Azure Policy.", + "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": "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": [ - "Sentinel" + "AzurePolicy", + "RBAC" ], - "severity": "High", - "subcategory": "Data Connectors", - "text": "Security Events - verify non-Azure computers are connected and sending data to the workspace" + "severity": "Medium", + "subcategory": "Governance", + "text": "Map regulatory and compliance requirements to Azure Policy definitions and Azure role assignments.", + "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", + "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": [ - "Sentinel" + "AzurePolicy", + "Subscriptions" ], - "severity": "High", - "subcategory": "Data Connectors", - "text": "Connector for AWS" + "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": "Sentinel", - "checklist": "Azure Security Review Checklist", - "guid": "909ae28c-84c3-43b6-a780-8bafe6c42149", - "link": "https://learn.microsoft.com/azure/sentinel/data-connectors-reference", + "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": [ - "Sentinel" + "AzurePolicy" ], - "severity": "High", - "subcategory": "Data Connectors", - "text": "Connector for GCP" + "severity": "Medium", + "subcategory": "Governance", + "text": "Manage policy assignments at the highest appropriate level with exclusions at bottom levels, if required.", + "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": "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": [ - "Sentinel" + "AzurePolicy", + "Subscriptions" ], - "severity": "High", - "subcategory": "Analytics Rules", - "text": "Customer has enabled Analytics rules and configured Incidents " + "severity": "Low", + "subcategory": "Governance", + "text": "Use Azure Policy to control which services users can provision at the subscription/management group level", + "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": "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": [ - "Sentinel" + "AzurePolicy" ], "severity": "Medium", - "subcategory": "Settings", - "text": "Customer does not have a daily cap enabled" + "subcategory": "Governance", + "text": "Use built-in policies where possible to minimize operational overhead.", + "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": "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": [ - "Firewall" + "Subscriptions", + "AzurePolicy", + "RBAC", + "Entra" ], - "severity": "High", - "subcategory": "Configuration", - "text": "Azure Firewall Premium deployed" + "severity": "Medium", + "subcategory": "Governance", + "text": "Assign the built-in Resource Policy Contributor role at a particular scope to enable application-level governance.", + "waf": "Security" }, { - "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": "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": [ - "Firewall" + "AzurePolicy", + "Subscriptions" ], - "severity": "High", - "subcategory": "Configuration", - "text": "Quad zero/force tunning enabled through Azure Firewall" + "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" }, { - "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": "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": [ - "RBAC", - "Firewall" + "AzurePolicy" ], "severity": "Medium", - "subcategory": "Access Control", - "text": "RBAC set to enable only authorized users" + "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": "Azure Firewall", - "checklist": "Azure Security Review Checklist", - "guid": "8093dc9f-c9d1-4bb7-9b36-a5a67fbb9ed5", - "link": "https://learn.microsoft.com/azure/firewall/firewall-diagnostics", + "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": [ - "Monitor", - "Firewall" + "Cost", + "VM", + "TrafficManager" ], - "severity": "Medium", - "subcategory": "Diagnostic Settings", - "text": "Diagnostics enabled and sending metrics to a Log Analytics workspace " + "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": "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": "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": [ - "Firewall", - "VNet" + "VM" ], - "severity": "High", - "subcategory": "Firewall Manager", - "text": "Hubs and virtual networks are protected or connected through Firewall Premium" + "severity": "Medium", + "subcategory": "Scalability", + "text": "Leverage Azure Virtual Machine Scale sets to scale in and out based on the load.", + "waf": "Reliability" }, { - "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": "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": [ - "AzurePolicy", - "RBAC", - "Firewall" + "Cost", + "TrafficManager", + "Monitor" ], - "severity": "High", - "subcategory": "Firewall Manager", - "text": "Policy: Access controls are configured (RBAC)" + "severity": "Medium", + "subcategory": "Optimize your cloud investment", + "text": "Configure 'Actual' and 'Forecasted' Budget Alerts.", + "waf": "Cost" }, { - "category": "Azure Firewall", - "checklist": "Azure Security Review Checklist", - "guid": "5c3a87af-4a79-41f8-a39b-da47768e14c1", - "link": "https://learn.microsoft.com/azure/firewall-manager/policy-overview", + "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": [ - "AzurePolicy", - "Firewall" + "AppGW", + "WAF", + "FrontDoor" ], "severity": "High", - "subcategory": "Firewall Manager", - "text": "Policy: Parent policy is configured " + "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": "Azure Firewall", - "checklist": "Azure Security Review Checklist", - "guid": "15675c1e-a55b-446a-a48f-f8ae7d7e4b47", - "link": "https://learn.microsoft.com/azure/firewall/rule-processing", + "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": [ - "AzurePolicy", - "Firewall" + "AppGW", + "Sentinel", + "WAF", + "FrontDoor" ], - "severity": "High", - "subcategory": "Firewall Manager", - "text": "Policy: Rule collections are defined" + "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": "Azure Firewall", - "checklist": "Azure Security Review Checklist", - "guid": "5b6c8bcb-f59b-4ce6-9de8-a03f97879468", - "link": "https://learn.microsoft.com/azure/firewall/rule-processing", - "services": [ - "AzurePolicy", - "Firewall" - ], - "severity": "High", - "subcategory": "Firewall Manager", - "text": "Policy: DNAT policies are defined" + "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" }, { - "category": "Azure Firewall", - "checklist": "Azure Security Review Checklist", - "guid": "d66a786d-60e9-46c9-9ad8-855d04c2b39c", - "link": "https://learn.microsoft.com/azure/firewall/rule-processing", + "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": [ - "AzurePolicy", - "Firewall" + "Backup" ], - "severity": "High", - "subcategory": "Firewall Manager", - "text": "Policy: Network rules are defined" + "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" }, { - "category": "Azure Firewall", - "checklist": "Azure Security Review Checklist", - "guid": "986bb2c1-2149-4a11-9b5e-3df574ecccd9", - "link": "https://learn.microsoft.com/azure/firewall/features", + "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": [ "AzurePolicy", - "Firewall" + "RBAC", + "Entra", + "Monitor" ], - "severity": "High", - "subcategory": "Firewall Manager", - "text": "Policy: Application rules are defined" + "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" }, { - "category": "Azure Firewall", - "checklist": "Azure Security Review Checklist", - "guid": "793a6bcd-a3b5-40eb-8eb0-3dd95d58d7c8", - "link": "https://learn.microsoft.com/azure/firewall/dns-details", + "category": "Management", + "checklist": "Azure Landing Zone Review", + "guid": "e179b599-de0d-4597-9cd4-cd21b088137f", + "id": "F03.02", "services": [ - "Firewall", - "DNS" + "Monitor" ], "severity": "Medium", - "subcategory": "Firewall Manager", - "text": "DNS: Feature understood and applied or not applied" + "subcategory": "Monitoring", + "text": "Is the landing zone documented?", + "waf": "Operations" }, { - "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": "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": [ - "Firewall" + "Monitor", + "ARS" ], - "severity": "High", - "subcategory": "Firewall Manager", - "text": "Threat Intelligence: Set to Alert & Deny" + "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" }, { - "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": "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": [ - "Firewall" + "AzurePolicy", + "Monitor" ], - "severity": "High", - "subcategory": "Firewall Manager", - "text": "Threat Intelligence: Allowed list (justify if they are being used - ie performance)" + "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" }, { - "category": "Azure Firewall", - "checklist": "Azure Security Review Checklist", - "guid": "623b365a-917e-4cbe-98eb-d54cd7df2e8b", - "link": "https://learn.microsoft.com/azure/firewall/premium-certificates", + "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": [ - "Firewall" + "VM", + "AzurePolicy", + "Monitor" ], - "severity": "High", - "subcategory": "Firewall Manager", - "text": "TLS enabled" + "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" }, { - "category": "Azure Firewall", - "checklist": "Azure Security Review Checklist", - "guid": "bac35715-59ab-4915-9e99-08aed8c44ce3", - "link": "https://learn.microsoft.com/azure/firewall/rule-processing", + "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": [ - "Firewall" + "VM", + "Monitor" ], - "severity": "High", - "subcategory": "Firewall Manager", - "text": "IDPS enabled" + "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" }, { - "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": "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": [ - "Firewall" + "NetworkWatcher", + "Monitor" ], - "severity": "High", - "subcategory": "Firewall Manager", - "text": "SNAT: Configured " + "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" }, { - "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": "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": [ - "Firewall", - "DDoS" + "Monitor" ], "severity": "Medium", - "subcategory": "DDOS Protection", - "text": "Enabled for Firewall public IP's" + "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": "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": "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": [ - "Storage" + "AzurePolicy", + "RBAC", + "Monitor" ], - "severity": "Medium", - "subcategory": "Physical", - "text": "All planned storage pools should use direct-attached storage (SATA, SAS, NVMe)", - "waf": "Performance" + "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": "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": [ - "ACR", - "Storage" + "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": [ + "Monitor" ], "severity": "Medium", - "subcategory": "Physical", - "text": "Disks are symmetrical across all nodes", - "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": "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": "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": [ - "Backup", - "Storage" + "Monitor" ], "severity": "Medium", - "subcategory": "S2D", - "text": "Parity type disk redundancy should only be used for low I/O volumes (backup/archive)", - "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": "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": "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": [ - "Storage" + "Monitor" ], "severity": "Medium", - "subcategory": "S2D", - "text": "Ensure there at least 2 capacity disks with available capacity in the Storage Pool", - "waf": "Reliability" + "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": "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": "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": [ - "Storage" + "RBAC", + "Entra", + "Monitor" ], - "severity": "Low", - "subcategory": "S2D", - "text": "'Delimited allocation' has been considered to improve volume resiliency in a multi-node failure", - "waf": "Reliability" + "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" }, { - "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": "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": [ - "Storage" + "Monitor" ], "severity": "Medium", - "subcategory": "S2D", - "text": "CSVs are created in multiples of node count", - "waf": "Performance" + "subcategory": "Monitoring", + "text": "Use Azure Monitor Logs for insights and reporting.", + "waf": "Operations" }, { - "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": "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": [ - "Storage" + "Storage", + "Monitor" ], "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": "Monitoring", + "text": "When necessary, use shared storage accounts within the landing zone for Azure diagnostic extension log storage.", + "waf": "Operations" }, { - "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", + "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": [ - "Storage" + "Monitor" ], "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": "Monitoring", + "text": "Use Azure Monitor alerts for the generation of operational alerts.", + "waf": "Operations" }, { - "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", + "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": [ - "Storage" + "Monitor" ], - "severity": "Low", - "subcategory": "S2D", - "text": "VMFleet has been run prior to workload deployment to baseline storage performance", - "waf": "Performance" + "severity": "Medium", + "subcategory": "Monitoring", + "text": "Ensure that monitoring requirements have been assessed and that appropriate data collection and alerting configurations are applied", + "waf": "Operations" }, { - "category": "Storage", - "checklist": "Azure Stack HCI Review", - "guid": "13c12e2a-c938-4dd1-9223-507d5e17f9c5", - "id": "01.03.01", + "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": [ - "Storage" + "Monitor" ], "severity": "Medium", - "subcategory": "Host OS", - "text": "OS drives use a dedicated storage controller", - "waf": "Reliability" + "subcategory": "Monitoring", + "text": "Consider supported regions for linked Log Analytics workspace and automation accounts", + "waf": "Operations" }, { - "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", + "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": [ - "Storage" + "VM", + "AzurePolicy" ], "severity": "Medium", - "subcategory": "Host OS", - "text": "CSV in-memory read caching is enabled and properly configured", - "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": "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", + "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": [ - "ACR" + "VM", + "AzurePolicy", + "Monitor" ], "severity": "Medium", - "subcategory": "Host", - "text": "NICs are symmetrical across nodes", - "waf": "Reliability" + "subcategory": "Operational compliance", + "text": "Monitor VM security configuration drift via Azure Policy.", + "waf": "Security" }, { - "category": "Networking", - "checklist": "Azure Stack HCI Review", - "guid": "ea8054db-a558-4533-80c8-5d9cf447ba19", - "id": "02.01.02", + "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": [ - "Storage" + "ACR", + "VM", + "ASR" ], - "severity": "High", - "subcategory": "Host", - "text": "Storage networking is redundant", - "waf": "Reliability" + "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" }, { - "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": [], + "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": [ + "ASR" + ], "severity": "Medium", - "subcategory": "Host", - "text": "Host networking configuration is managed by Network ATC and intents are healthy", - "waf": "Reliability" + "subcategory": "Protect and Recover", + "text": "Ensure to use and test native PaaS service disaster recovery capabilities.", + "waf": "Operations" }, { - "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", + "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": [ - "Storage", - "VNet" + "Backup" ], "severity": "Medium", - "subcategory": "Host", - "text": "Storage NICs are assigned static IP addresses on separate subnets and VLANs", - "waf": "Reliability" + "subcategory": "Protect and Recover", + "text": "Use Azure-native backup capabilities, or an Azure-compatible, 3rd-party backup solution.", + "waf": "Operations" }, { - "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", + "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": [ + "VM" + ], + "severity": "High", + "subcategory": "Fault Tolerance", + "text": "Leverage Availability Zones for your VMs in regions where they are supported.", "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", + "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": [ - "Storage" + "VM" ], - "severity": "Medium", - "subcategory": "Host", - "text": "If the cluster is made up of more than 3 nodes, a switched storage network has been implemented", + "severity": "High", + "subcategory": "Fault Tolerance", + "text": "Avoid running a production workload on a single VM.", "waf": "Reliability" }, { - "category": "Networking", - "checklist": "Azure Stack HCI Review", - "guid": "603c6d71-59d2-419c-a312-8edc6e799c6a", - "id": "02.01.08", + "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": [ - "Storage" + "AppGW", + "ACR", + "LoadBalancer" ], - "severity": "High", - "subcategory": "Host", - "text": "RDMA is enabled on the Storage networking", - "waf": "Performance" + "severity": "Medium", + "subcategory": "Fault Tolerance", + "text": "Azure Load Balancer and Application Gateway distribute incoming network traffic across multiple resources.", + "waf": "Reliability" }, { - "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", + "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": "Host", - "text": "Test-RDMA.ps1 has been run to validate the RDMA configuration", - "waf": "Performance" + "subcategory": "Access control", + "text": "Determine the incident response plan for Azure services before allowing it into production.", + "waf": "Security" }, { - "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": [ - "VM" - ], + "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": "Host", - "text": "If a VMSwitch is shared for Compute and Management traffic, require that Management traffic is tagged with a VLAN ID", + "subcategory": "Access control", + "text": "Implement a zero-trust approach for access to the Azure platform, where appropriate.", "waf": "Security" }, { - "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", + "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": [ - "VM" + "AKV" ], - "severity": "Medium", - "subcategory": "SDN", - "text": "There are at least 3 Network Controller VMs deployed", - "waf": "Reliability" + "severity": "High", + "subcategory": "Encryption and keys", + "text": "Use Azure Key Vault to store your secrets and credentials", + "waf": "Security" }, { - "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": "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": [ - "Backup" + "AKV" ], - "severity": "High", - "subcategory": "SDN", - "text": "Backups of SDN infrastructure are configured and tested", - "waf": "Operations" + "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" }, { - "category": "Management and Monitoring", - "checklist": "Azure Stack HCI Review", - "guid": "51eaa4b6-b9a7-43e1-a7dc-634d3107bc6d", - "id": "03.01.01", + "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": [ - "Monitor" + "AKV", + "AzurePolicy" ], "severity": "Medium", - "subcategory": "Cluster", - "text": "SCOM Managed Instance has been considered for more complex monitoring and alerting scenarios", - "waf": "Operations" + "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": "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", + "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": [ - "Monitor" + "AKV", + "RBAC", + "Entra" ], - "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": "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" }, { - "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", + "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": [ - "Monitor" + "AKV" ], "severity": "Medium", - "subcategory": "Cluster", - "text": "Insights has been enabled at the cluster level and all nodes are reporting data", - "waf": "Operations" + "subcategory": "Encryption and keys", + "text": "Automate the certificate management and renewal process with public certificate authorities to ease administration.", + "waf": "Security" }, { - "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", + "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": [ - "Monitor" + "AKV" ], "severity": "Medium", - "subcategory": "Cluster", - "text": "Azure Monitoring Agent has been deployed to hosts and an appropriate Data Collection Rule has been configured", - "waf": "Operations" + "subcategory": "Encryption and keys", + "text": "Establish an automated process for key and certificate rotation.", + "waf": "Security" }, { - "category": "Management and Monitoring", - "checklist": "Azure Stack HCI Review", - "guid": "6143af1d-0d1a-4163-b1c9-662f7459bb98", - "id": "03.02.01", + "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": [ - "Monitor" + "VNet", + "PrivateLink", + "AKV" ], "severity": "Medium", - "subcategory": "Hardware", - "text": "Relevant hardware monitoring has been configured", - "waf": "Operations" + "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": "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", + "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": [ - "Monitor" + "AKV", + "Monitor", + "Entra" ], "severity": "Medium", - "subcategory": "Hardware", - "text": "Relevant hardware alerting has been configured", - "waf": "Operations" + "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": "Operations", - "checklist": "Azure Stack HCI Review", - "guid": "c0da5bbd-0f0d-4a26-98ec-38c9cc42b323", - "id": "04.01.01", + "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": [ - "VM" + "AKV", + "AzurePolicy" ], - "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" + "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" }, { - "category": "Networking", - "checklist": "Azure Stack HCI Review", - "guid": "a8ecf23c-c048-4fa9-b87b-51ebfb409863", - "id": "04.01.02", + "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": [ - "VM" + "AKV" ], - "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": "Medium", + "subcategory": "Encryption and keys", + "text": "Default to Microsoft-managed keys for principal encryption functionality and use customer-managed keys when required.", + "waf": "Security" }, { - "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": "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": [ - "Backup", - "VM", - "ASR" + "AKV" ], - "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" - }, - { - "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" + "subcategory": "Encryption and keys", + "text": "Use an Azure Key Vault per application per environment per region.", + "waf": "Security" }, { - "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": "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": [ - "VM" + "ACR", + "AKV", + "ASR" ], "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": "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": "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": "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": [ - "AzurePolicy" + "Entra" ], "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": "Operations", + "text": "Use Microsoft Entra ID reporting capabilities to generate access control audit reports.", + "waf": "Security" }, { - "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": "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": [ - "Entra" + "Storage", + "Monitor", + "ARS" ], "severity": "Medium", - "subcategory": "Stretch Clustering", - "text": "There is sub 5ms latency between each site if synchronous replication is being configured AAD", - "waf": "Performance" + "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" }, { - "category": "Networking", - "checklist": "Azure Stack HCI Review", - "guid": "3277558e-3155-4088-b49a-78594cb4ce1a", - "id": "07.01.02", + "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": [ - "Storage", - "VNet" + "Defender", + "Subscriptions" ], "severity": "High", - "subcategory": "Stretch Clustering", - "text": "Management, Replication and Storage networks excluded from stretched VLANs configurations, are routed, and in different subnets", - "waf": "Reliability" + "subcategory": "Operations", + "text": "Enable Defender Cloud Security Posture Management for all subscriptions.", + "waf": "Security" }, { - "category": "Operations", - "checklist": "Azure Stack HCI Review", - "guid": "baed6066-8531-44ba-bd94-38cbabbf4099", - "id": "07.02.01", - "services": [], + "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": [ + "Defender", + "Subscriptions" + ], "severity": "High", - "subcategory": "Stretch Clustering", - "text": "There is a plan detailed for site failure and recovery", - "waf": "Operations" + "subcategory": "Operations", + "text": "Enable a Defender Cloud Workload Protection Plan for Servers on all subscriptions.", + "waf": "Security" }, { - "category": "Networking", - "checklist": "Azure Stack HCI Review", - "guid": "8e62945f-b9ac-4a5c-a4e4-836f527010b4", - "id": "07.02.02", + "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": [ - "ACR" - ], - "severity": "Medium", - "subcategory": "Stretch Clustering", - "text": "Separate vLANs and networks are used for each replication network across both sites", - "waf": "Reliability" - }, - { - "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" + "Defender", + "Subscriptions" ], "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" + "subcategory": "Operations", + "text": "Enable Defender Cloud Workload Protection Plans for Azure Resources on all subscriptions.", + "waf": "Security" }, { - "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", + "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": "Stretch Clustering", - "text": "When using data deduplication, only enable it on the primary/source volumes", - "waf": "Reliability" + "subcategory": "Operations", + "text": "Enable Endpoint Protection on IaaS Servers.", + "waf": "Security" }, { - "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": "Security", + "checklist": "Azure Landing Zone Review", + "guid": "15833ee7-ad6c-46d3-9331-65c7acbe44ab", + "id": "G03.07", + "link": "https://learn.microsoft.com/azure/security-center/", "services": [ - "Storage" + "Defender", + "Monitor" ], - "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": "Medium", + "subcategory": "Operations", + "text": "Monitor base operating system patching drift via Azure Monitor Logs and Defender for Cloud.", + "waf": "Security" }, { - "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": "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": [ - "ASR", - "Backup" + "Monitor", + "Entra" ], "severity": "Medium", - "subcategory": "Disaster Recovery", - "text": "Azure Site Recovery has been considered for DR purposes", - "waf": "Operations" + "subcategory": "Operations", + "text": "Connect default resource configurations to a centralized Azure Monitor Log Analytics workspace.", + "waf": "Security" }, { + "ammp": true, "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", + "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": [ + "Storage" + ], + "severity": "High", + "subcategory": "Overview", + "text": "Secure transfer to storage accounts should be enabled", "waf": "Security" }, { + "ammp": true, "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", + "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": [ + "Storage" + ], + "severity": "High", + "subcategory": "Overview", + "text": "Enable container soft delete for the storage account to recover a deleted container and its contents.", "waf": "Security" }, { + "ammp": true, "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", + "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": [ - "Defender" + "Entra" ], - "severity": "Medium", - "subcategory": "Host", - "text": "Microsoft Defender Antivirus has been enabled on all nodes", + "severity": "High", + "subcategory": "Secure privileged access", + "text": "Separate privileged admin accounts for Azure administrative tasks.", "waf": "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", + "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": "Host", - "text": "Credential Guard has been configured, where appropriate", + "subcategory": "Service enablement framework", + "text": "Plan how new azure services will be implemented", "waf": "Security" }, { "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": [ - "EventHubs" - ], - "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": "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": [ - "EventHubs" - ], + "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": "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": "Service enablement framework", + "text": "Plan how service request will be fulfilled for Azure services", + "waf": "Security" }, { - "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": [ - "AzurePolicy", - "EventHubs", - "Entra", - "RBAC", - "TrafficManager" - ], - "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/" + "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": "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", - "services": [ - "VM", - "EventHubs", - "Entra", - "AKV", - "Storage" - ], - "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/" + "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": "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": "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": [ - "RBAC", - "Entra", - "EventHubs" + "RBAC" ], - "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": "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": "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", - "services": [ - "Monitor", - "VNet", - "EventHubs" - ], - "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/" + "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": "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", - "services": [ - "PrivateLink", - "VNet", - "EventHubs" - ], + "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": "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": "DevOps Team Topologies", + "text": "Include unit tests for IaC and application code as part of your build process.", + "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", + "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": [ - "EventHubs" + "AKV", + "VM" ], - "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/" + "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": "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": "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": [ "Storage" ], - "severity": "Medium", - "subcategory": " Overview", - "text": "Consider the 'Azure security baseline for storage'", - "waf": "Security" + "severity": "Low", + "subcategory": "DevOps Team Topologies", + "text": "Implement automation for File > New > Landing Zone for applications and workloads.", + "waf": "Operations" }, { - "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": [ - "PrivateLink", - "Storage" - ], + "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": "Networking", - "text": "Consider using private endpoints for Azure Storage", - "waf": "Security" + "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": "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": [ - "Subscriptions", - "RBAC", - "Storage" - ], + "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": "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": "Governance", - "text": "Ensure older storage accounts are not using 'classic deployment model'", - "waf": "Security" + "subcategory": "Development Lifecycle", + "text": "Adopt a pull request strategy to help keep control of code changes merged into branches.", + "waf": "Operations" }, { - "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": [ - "Defender", - "Storage" - ], + "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": "Governance", - "text": "Enable Microsoft Defender for all of your storage accounts", - "waf": "Security" + "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": "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", + "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": "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": [ - "Storage" + "Backup", + "AKV", + "SQL" ], "severity": "Medium", - "subcategory": "Data Availability", - "text": "Enable 'soft delete' for blobs", + "subcategory": "Azure Key Vault", + "text": "Protect your backup data with encryption and store keys safely in Azure Key Vault", "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": "3f1d5e87-2e52-4e36-81cc-58b4a4b1510e", - "id": "A05.01", - "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-blob-enable", + "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": [ - "Storage" + "Backup", + "Storage", + "SQL" ], "severity": "Medium", - "subcategory": "Confidentiality", - "text": "Disable 'soft delete' for blobs", + "subcategory": "Backup", + "text": "Configure Azure SQL Database automated backups", "waf": "Security" }, { - "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": "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": [ - "Storage" + "Backup", + "Storage", + "SQL" ], - "severity": "High", - "subcategory": "Data Availability", - "text": "Enable 'soft delete' for containers", + "severity": "Low", + "subcategory": "Backup", + "text": "Enable geo-redundant backup storage to protect against single region failure and data loss", "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": "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": "Confidentiality", - "text": "Disable 'soft delete' for containers", + "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": "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": "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": [ - "Storage" + "SQL" ], - "severity": "High", - "subcategory": "Data Availability", - "text": "Enable resource locks on storage accounts", + "severity": "Low", + "subcategory": "Data Discovery and Classification", + "text": "Plan and configure Data Discovery & Classification to protect the sensitive data", "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": "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": [ - "Subscriptions", - "Storage", - "AzurePolicy" + "SQL" ], - "severity": "High", - "subcategory": "Data Availability, Compliance", - "text": "Consider immutable blobs", + "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": "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": "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": [ - "Storage" + "EventHubs", + "SQL", + "Defender" ], "severity": "High", - "subcategory": "Networking", - "text": "Require HTTPS, i.e. disable port 80 on the storage account", + "subcategory": "Advanced Threat Protection", + "text": "Review and complete Advanced Threat Protection (ATP) configuration", "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": "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" + "Subscriptions", + "SQL", + "Defender" ], "severity": "High", - "subcategory": "Networking", - "text": "When enforcing HTTPS (disabling HTTP), check that you do not use custom domains (CNAME) for the storage account.", + "subcategory": "Defender for Azure SQL", + "text": "Enable Microsoft Defender for Azure SQL", "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": "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" + "SQL", + "Defender", + "Monitor" ], - "severity": "Medium", - "subcategory": "Networking", - "text": "Limit shared access signature (SAS) tokens to HTTPS connections only", + "severity": "High", + "subcategory": "Defender for Azure SQL", + "text": "Prepare a security response plan to promptly react to Microsoft Defender for Azure SQL alerts", "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": "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", - "Entra" + "SQL", + "Defender", + "Monitor" ], "severity": "High", - "subcategory": "Identity and Access Management", - "text": "Use Azure Active Directory (Azure AD) tokens for blob access", + "subcategory": "Vulnerability Assessment", + "text": "Configure Vulnerability Assessment (VA) findings and review recommendations", "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": "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": [ - "RBAC", - "Storage", - "Entra" + "SQL", + "Defender" ], - "severity": "Medium", - "subcategory": "Identity and Access Management", - "text": "Least privilege in IaM permissions", + "severity": "High", + "subcategory": "Vulnerability Assessment", + "text": "Regularly review of Vulnerability Assessment (VA) findings and recommendations and prepare a plan to fix", "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": "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": [ - "Storage", - "Entra" + "SQL" ], - "severity": "High", - "subcategory": "Identity and Access Management", - "text": "When using SAS, prefer 'user delegation SAS' over storage-account-key based SAS.", + "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": "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": "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": [ - "Monitor", "Storage", "AKV", - "Entra" + "SQL" ], - "severity": "High", - "subcategory": "Identity and Access Management", - "text": "Consider disabling storage account keys, so that only AAD access (and user delegation SAS) is supported.", + "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": "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": "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": [ - "AzurePolicy", - "Monitor", + "Backup", "Storage", - "AKV" + "SQL" ], "severity": "High", - "subcategory": "Monitoring", - "text": "Consider using Azure Monitor to audit control plane operations on the storage account", + "subcategory": "Transparent Data Encryption", + "text": "Ensure Transparent Data Encryption (TDE) is kept enabled", "waf": "Security" }, { - "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": "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": [ - "AzurePolicy", - "Storage", "AKV", - "Entra" + "SQL" ], "severity": "Medium", - "subcategory": "Identity and Access Management", - "text": "When using storage account keys, consider enabling a 'key expiration policy'", + "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": "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": "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": [ - "AzurePolicy", - "Storage", + "SQL" + ], + "severity": "High", + "subcategory": "Transport Layer Security", + "text": "Enforce minimum TLS version to the latest available", + "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", + "services": [ + "SQL", "Entra" ], "severity": "Medium", - "subcategory": "Identity and Access Management", - "text": "Consider configuring an SAS expiration policy", + "subcategory": "Azure Active Directory", + "text": "Leverage Azure AD authentication for connections to Azure SQL Databases", "waf": "Security" }, { - "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": "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": [ - "AzurePolicy", - "Storage", - "AKV", + "SQL", + "Monitor", "Entra" ], "severity": "Medium", - "subcategory": "Identity and Access Management", - "text": "Consider linking SAS to a stored access policy", + "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": "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": "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": [ - "Storage", - "AKV" + "SQL", + "Entra" ], "severity": "Medium", - "subcategory": "CI/CD", - "text": "Consider configuring your application's source code repository to detect checked-in connection strings and storage account keys.", + "subcategory": "Azure Active Directory", + "text": "Minimize the use of password-based authentication for applications", "waf": "Security" }, { - "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": "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": [ - "Storage", + "ACR", + "SQL", + "AKV", + "RBAC", "Entra" ], - "severity": "High", - "subcategory": "Identity and Access Management", - "text": "Consider storing connection strings in Azure KeyVault (in scenarios where managed identities are not possible)", + "severity": "Low", + "subcategory": "Managed Identities", + "text": "Assign Azure SQL Database a managed identity for outbound resource access", "waf": "Security" }, { - "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": "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": [ - "AzurePolicy", - "Storage", + "SQL", "Entra" ], - "severity": "High", - "subcategory": "Identity and Access Management", - "text": "Strive for short validity periods for ad-hoc SAS", + "severity": "Medium", + "subcategory": "Passwords", + "text": "Minimize the use of password-based authentication for users", "waf": "Security" }, { - "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": "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", - "Entra" + "SQL" ], "severity": "Medium", - "subcategory": "Identity and Access Management", - "text": "Apply a narrow scope to a SAS", + "subcategory": "Database Digest", + "text": "Use Azure Confidential Ledger to store database digests only if advanced security features are required", "waf": "Security" }, { - "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": "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", - "Entra" + "AzurePolicy", + "SQL" ], "severity": "Medium", - "subcategory": "Identity and Access Management", - "text": "Consider scoping SAS to a specific client IP address, wherever possible", + "subcategory": "Database Digest", + "text": "If Azure storage account is used to store database digests, ensure security is properly configured", "waf": "Security" }, { - "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": "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", - "Entra" + "SQL" ], - "severity": "Low", - "subcategory": "Identity and Access Management", - "text": "Consider checking uploaded data, after clients used a SAS to upload a file. ", + "severity": "Medium", + "subcategory": "Integrity", + "text": "Schedule the Ledger verification process regularly to verify data integrity", "waf": "Security" }, { - "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": "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": [ - "RBAC", - "Storage", - "Entra" + "SQL" ], - "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.", + "severity": "Medium", + "subcategory": "Ledger", + "text": "If cryptographic proof of data integrity is a critical requirement, Ledger feature should be considered", "waf": "Security" }, { - "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": "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": [ - "Storage", - "Entra" + "SQL" ], "severity": "Medium", - "subcategory": "Identity and Access Management", - "text": "SFTP: The SFTP endpoint does not support POSIX-like ACLs.", + "subcategory": "Recovery", + "text": "Prepare a response plan to investigate and repair a database after a tampering event", "waf": "Security" }, { - "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": "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": [ + "Storage", "AzurePolicy", - "Storage" + "SQL" ], - "severity": "High", - "subcategory": "Networking", - "text": "Avoid overly broad CORS policies", + "severity": "Medium", + "subcategory": "Auditing", + "text": "Ensure that Azure SQL Database Auditing is enabled at the server level", "waf": "Security" }, { - "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": "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": [ - "Storage" + "Storage", + "SQL", + "Monitor", + "Backup", + "EventHubs", + "Entra" ], - "severity": "High", - "subcategory": "Confidentiality and Encryption", - "text": "Determine how data at rest should be encrypted. Understand the thread model for data.", + "severity": "Low", + "subcategory": "Auditing", + "text": "Ensure that Azure SQL Database Auditing logs are backed up and secured in the selected repository type", "waf": "Security" }, { - "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": "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": [ - "Storage" + "Storage", + "SQL", + "Subscriptions", + "Monitor", + "EventHubs" ], "severity": "Medium", - "subcategory": "Confidentiality and Encryption", - "text": "Determine which/if platform encryption should be used.", + "subcategory": "Auditing", + "text": "Ensure that Azure SQL Database Activity Log is collected and integrated with Auditing logs", "waf": "Security" }, { - "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": "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": [ - "Storage" + "SQL", + "Monitor" ], "severity": "Medium", - "subcategory": "Confidentiality and Encryption", - "text": "Determine which/if client-side encryption should be used.", + "subcategory": "SIEM/SOAR", + "text": "Ensure that Azure SQL Database Auditing logs are being presented in to your organizations SIEM/SOAR", "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": [ - "Storage", - "Entra" + "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": [ + "SQL", + "Monitor" ], - "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. ", + "severity": "Medium", + "subcategory": "SIEM/SOAR", + "text": "Ensure that Azure SQL Database Activity Log data is presented in to your SIEM/SOAR", "waf": "Security" }, { - "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": "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": [ - "AppSvc", - "AKV" + "EventHubs", + "SQL" ], - "severity": "High", - "subcategory": "Data Protection", - "text": "Use Key Vault to store secrets", + "severity": "Medium", + "subcategory": "SIEM/SOAR", + "text": "Ensure that you have response plans for malicious or aberrant audit logging events", "waf": "Security" }, { - "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": "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": [ - "Entra", - "AppSvc", - "AKV" + "PrivateLink", + "SQL" ], "severity": "High", - "subcategory": "Data Protection", - "text": "Use Managed Identity to connect to Key Vault", + "subcategory": "Connectivity", + "text": "Review Public vs. Private Access connectivity methods and select the appropriate one for the workload", "waf": "Security" }, { - "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": "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": [ - "AppSvc", - "AKV" + "PrivateLink", + "AzurePolicy", + "SQL" + ], + "severity": "Low", + "subcategory": "Connectivity", + "text": "Keep default Azure SQL Database Connection Policy if not differently required and justified", + "waf": "Security" + }, + { + "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": [ + "SQL", + "Subscriptions" ], "severity": "High", - "subcategory": "Data Protection", - "text": "Use Key Vault to store TLS certificate.", + "subcategory": "Connectivity", + "text": "Ensure Allow Azure Services and Resources to Access this Server setting is disabled in Azure SQL Database firewall", "waf": "Security" }, { - "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": "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": [ - "Subscriptions", - "AppSvc" + "EventHubs", + "SQL", + "APIM" ], "severity": "Medium", - "subcategory": "Data Protection", - "text": "Isolate systems that process sensitive information", + "subcategory": "Outbound Control", + "text": "Block or restrict outbound REST API calls to external endpoints", "waf": "Security" }, { - "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": "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": [ - "TrafficManager", - "AppSvc" + "Storage", + "SQL" ], "severity": "Medium", - "subcategory": "Data Protection", - "text": "Do not store sensitive data on local disk", + "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": "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": "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": [ - "Entra", - "AppSvc" + "PrivateLink", + "SQL", + "Firewall", + "Monitor", + "VNet" ], "severity": "Medium", - "subcategory": "Identity and Access Control", - "text": "Use an established Identity Provider for authentication", + "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": "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": "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": [ - "Entra", - "AppSvc" + "PrivateLink", + "VNet", + "SQL" ], "severity": "High", - "subcategory": "Identity and Access Control", - "text": "Deploy from a trusted environment", + "subcategory": "Private Access", + "text": "If Private Endpoint (Private Access) is used, consider disabling Public Access connectivity", "waf": "Security" }, { - "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": "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": [ - "Entra" + "PrivateLink", + "VNet", + "SQL" ], - "severity": "High", - "subcategory": "Identity and Access Control", - "text": "Disable basic authentication", + "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": "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": "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": [ - "Entra", - "AKV" + "ExpressRoute", + "VNet", + "SQL" ], - "severity": "High", - "subcategory": "Identity and Access Control", - "text": "Use Managed Identity to connect to resources", + "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": "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": "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": [ - "ACR", - "Entra" + "AzurePolicy", + "VNet", + "SQL" ], "severity": "High", - "subcategory": "Identity and Access Control", - "text": "Pull containers using a Managed Identity", + "subcategory": "Public Access", + "text": "If Public Access connectivity is used, leverage Service Endpoint to restrict access from selected Azure Virtual Networks", "waf": "Security" }, { - "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": "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": [ - "Monitor", - "Entra", - "AppSvc" + "Storage", + "SQL" ], "severity": "Medium", - "subcategory": "Logging and Monitoring", - "text": "Send App Service runtime logs to Log Analytics", + "subcategory": "Public Access", + "text": "If Public Access connectivity is used, ensure that only specific known IPs are added to the firewall", "waf": "Security" }, { - "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": [ - "Monitor", - "Entra", - "AppSvc" - ], - "severity": "Medium", - "subcategory": "Logging and Monitoring", - "text": "Send App Service activity logs to Log Analytics", - "waf": "Security" - }, - { - "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": [ - "NVA", - "Firewall", - "VNet", - "Monitor" - ], - "severity": "Medium", - "subcategory": "Network Security", - "text": "Outbound network access should be controlled", - "waf": "Security" - }, - { - "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": "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": [ - "PrivateLink", - "Firewall", "Storage", - "VNet", - "NVA" + "SQL" ], "severity": "Low", - "subcategory": "Network Security", - "text": "Ensure a stable IP for outbound communications towards internet addresses", + "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": "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": "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": [ - "PrivateLink", - "AppSvc" + "VNet", + "AzurePolicy", + "SQL" ], "severity": "High", - "subcategory": "Network Security", - "text": "Inbound network access should be controlled", + "subcategory": "Public Access", + "text": "Do not enable Azure SQL Managed Instance public endpoint", "waf": "Security" }, { - "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": "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": [ - "WAF", - "Monitor", - "AppSvc", - "AppGW", - "FrontDoor" + "VNet", + "SQL" ], "severity": "High", - "subcategory": "Network Security", - "text": "Use a WAF in front of App Service", + "subcategory": "Public Access", + "text": "Restrict access if Azure SQL Managed Instance public endpoint is required", "waf": "Security" }, { - "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": "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": [ - "PrivateLink", - "WAF" + "SQL" ], - "severity": "High", - "subcategory": "Network Security", - "text": "Avoid for WAF to be bypassed", + "severity": "Low", + "subcategory": "Lockbox", + "text": "Review and enable Customer Lockbox for Azure SQL Database access by Microsoft personnel", "waf": "Security" }, { - "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": "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": [ - "AzurePolicy", - "AppSvc" + "SQL" ], "severity": "Medium", - "subcategory": "Network Security", - "text": "Set minimum TLS policy to 1.2", + "subcategory": "Permissions", + "text": "Ensure that users are assigned the minimum level of access necessarily to complete their job functions", "waf": "Security" }, { - "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", + "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": [ - "AppSvc", - "WAF" + "SQL", + "Entra" ], - "severity": "High", - "subcategory": "Network Security", - "text": "Use HTTPS only", + "severity": "Low", + "subcategory": "Permissions", + "text": "Ensure that distinct applications will be assigned different credentials with minimal permissions to access Azure SQL Database", "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", + "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": [ - "Storage" + "AKV", + "FrontDoor" ], - "severity": "High", - "subcategory": "Network Security", - "text": "Wildcards must not be used for CORS", - "waf": "Security" + "severity": "Medium", + "subcategory": "App delivery", + "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": "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", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery", + "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": "High", - "subcategory": "Network Security", - "text": "Turn off remote debugging", + "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": "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", + "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": [ - "Defender", - "AppSvc" + "AppGW" ], "severity": "Medium", - "subcategory": "Network Security", - "text": "Enable Defender for Cloud - Defender for App Service", + "subcategory": "App delivery", + "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": "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", + "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": [ - "DDoS", - "EventHubs", - "WAF", - "VNet", - "AppGW", - "NVA" + "LoadBalancer" ], "severity": "Medium", - "subcategory": "Network Security", - "text": "Enable DDOS Protection Standard on the WAF VNet", + "subcategory": "App delivery", + "text": "Ensure you are using the Standard SKU for your Azure Load Balancers", "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", + "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 | project id, subnetId = tostring(subnets.id), subnetPrefixLength = split(subnets.properties.addressPrefix, '/')[1]) on subnetId | extend compliant = (subnetPrefixLength <= 26) | 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": [ - "PrivateLink", - "ACR", + "AppGW", "VNet" ], "severity": "Medium", - "subcategory": "Network Security", - "text": "Pull containers over a Virtual Network", + "subcategory": "App delivery", + "text": "Your application gateways should be deployed in subnets with IP prefixes equal or larger than /26", + "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", + "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": [ + "Subscriptions", + "VNet", + "WAF", + "NVA", + "AppGW", + "Entra" + ], "severity": "Medium", - "subcategory": "Penetration Testing", - "text": "Conduct a penetration test", + "subcategory": "App delivery", + "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": "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": [], + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery", + "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": "Vulnerability Management", - "text": "Deploy validated code", + "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": "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", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery", + "guid": "e79d17b7-3b22-4a5a-97e7-a8ed4b30e38c", + "id": "A01.08", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "services": [ + "AzurePolicy", + "WAF", + "FrontDoor" + ], + "severity": "Medium", + "subcategory": "App delivery", + "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": "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 Application Delivery", + "guid": "3f29812b-2363-4cef-b179-b599de0d5973", + "id": "A01.09", + "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", "services": [ - "Cost", - "Monitor" + "AppGW", + "AzurePolicy", + "WAF", + "FrontDoor" ], - "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": "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": "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", + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery", + "guid": "cd4cd21b-0881-437f-9e6c-4cfd3e504547", + "id": "A01.10", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", "services": [ - "Backup", - "Cost" + "TrafficManager" ], - "subcategory": "Backup", - "text": "check backup instances with the underlying datasource not found" + "severity": "High", + "subcategory": "App delivery", + "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": "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 Application Delivery", + "guid": "3b4b3e88-a459-4ed5-a22f-644dfbc58204", + "id": "A01.11", + "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy#how-application-proxy-works", "services": [ - "Cost" + "AVD", + "Entra" ], - "subcategory": "delete/archive", - "text": "delete or archive unassociated services (disks, nics, ip addresses etc)" + "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" }, { - "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 Application Delivery", + "guid": "01ca7cf1-5754-442d-babb-8ba6772e5c30", + "id": "A01.12", + "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy#how-application-proxy-works", "services": [ - "Cost" + "Entra" ], - "subcategory": "delete/archive", - "text": "consider snooze and stop technique (snooze a service after x days, stop after 2x, delete/deallocate after 3x)" + "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" }, { - "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", + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery", + "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.13", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-policy-settings", "services": [ - "Backup", - "Cost", - "Storage" + "Storage", + "WAF", + "FrontDoor" ], - "subcategory": "delete/archive", - "text": "delete or archive unused resources (old backups, logs, storage accounts, etc...)" + "severity": "High", + "subcategory": "App delivery", + "text": "Deploy your WAF profiles for Front Door in 'Prevention' mode.", + "waf": "Security" }, { - "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", + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery", + "guid": "062d5839-4d36-402f-bfa4-02811eb936e9", + "id": "A01.14", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#avoid-combining-traffic-manager-and-front-door", "services": [ - "Backup", - "Cost", - "Storage", - "ASR" + "TrafficManager", + "FrontDoor" ], - "subcategory": "delete/archive", - "text": "consider a good balance between site recovery storage and backup for non mission critical applications" + "severity": "High", + "subcategory": "App delivery", + "text": "Avoid combining Azure Traffic Manager and Azure Front Door.", + "waf": "Security" }, { - "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", + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery", + "guid": "5efeb96a-003f-4b18-8fcd-b4d84459c2b2", + "id": "A01.15", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-the-same-domain-name-on-front-door-and-your-origin", "services": [ - "Cost", - "Monitor" + "FrontDoor" ], - "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": "High", + "subcategory": "App delivery", + "text": "Use the same domain name on Azure Front Door and your origin. Mismatched host names can cause subtle bugs.", + "waf": "Security" }, { - "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 Application Delivery", + "guid": "0b5a380c-4bfb-47bc-b1d7-dcfef363a61b", + "id": "A01.16", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#disable-health-probes-when-theres-only-one-origin-in-an-origin-group", "services": [ - "AzurePolicy", - "Cost", - "Storage" + "FrontDoor" ], - "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": "Low", + "subcategory": "App delivery", + "text": "Disable health probes when there is only one origin in an Azure Front Door origin group.", + "waf": "Performance" }, { - "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 Application Delivery", + "guid": "5567048e-e5d7-4206-9c55-b5ed45d2cc0c", + "id": "A01.17", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#select-good-health-probe-endpoints", "services": [ - "Cost" + "FrontDoor" ], - "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": "Medium", + "subcategory": "App delivery", + "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": "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 Application Delivery", + "guid": "a13f72f3-8f5c-4864-95e5-75bf37fbbeb1", + "id": "A01.18", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-head-health-probes", "services": [ - "Cost" + "FrontDoor" ], - "subcategory": "shutdown/deallocate", - "text": "shutdown underutilized instances", - "training": "https://learn.microsoft.com/azure/cost-management-billing/understand/analyze-unexpected-charges" + "severity": "Low", + "subcategory": "App delivery", + "text": "Use HEAD health probes with Azure Front Door, to reduce the traffic that Front Door sends to your application.", + "waf": "Performance" }, { - "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", + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery", + "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.19", + "link": "https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity", "services": [ - "Backup", - "Cost", - "Storage", - "VM" + "LoadBalancer" ], - "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": "High", + "subcategory": "App delivery", + "text": "Use Azure NAT Gateway instead of Load Balancer outbound rules for better SNAT scalability", + "waf": "Reliability" }, { - "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", + "ammp": true, + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery", + "guid": "af95c92d-d723-4f4a-98d7-8722324efd4d", + "id": "A01.20", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-managed-tls-certificates", "services": [ - "AzurePolicy", + "AKV", "Cost", - "Storage" + "FrontDoor" ], - "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": "High", + "subcategory": "App delivery", + "text": "Use managed TLS certificates with Azure Front Door. Reduce operational cost and risk of outages due to certificate renewals.", + "waf": "Operations" }, { - "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 Application Delivery", + "guid": "189ea962-3969-4863-8f5a-5ad808c2cf4b", + "id": "A01.21", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#define-your-waf-configuration-as-code", "services": [ - "Cost" + "WAF", + "FrontDoor" ], - "subcategory": "Tagging", - "text": "use specific tags for temporary items with 'delete by DATE' format - and automate monthly cleanup" + "severity": "Medium", + "subcategory": "App delivery", + "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": "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", + "ammp": true, + "category": "Network topology and connectivity", + "checklist": "Azure Application Delivery", + "guid": "2e30abab-5478-417c-81bf-bf1ad4ed1ed4", + "id": "A02.01", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-end-to-end-tls", "services": [ - "Cost" + "FrontDoor" ], - "subcategory": "db optimization", - "text": "plan for db optimization with the intent of downsizing the related services (and improve performance)" + "severity": "High", + "subcategory": "App delivery", + "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": "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 Application Delivery", + "guid": "10aa45af-166f-44c4-9f36-b6d592dac2ca", + "id": "A02.02", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-http-to-https-redirection", "services": [ - "Cost" + "FrontDoor" ], - "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": "App delivery", + "text": "Use HTTP to HTTPS redirection with Azure Front Door. Support older clients by redirecting them to an HTTPS request automatically.", + "waf": "Security" }, { - "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", + "ammp": true, + "category": "Network topology and connectivity", + "checklist": "Azure Application Delivery", + "guid": "28b9ee82-b2c7-45aa-bc98-6de6f59a095d", + "id": "A02.03", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#enable-the-waf", "services": [ - "Cost", - "Storage", - "VM" + "WAF", + "FrontDoor" ], - "subcategory": "db optimization", - "text": "optimizing the DB queries will increase performance and allow better right-sizing of storage and VMs" + "severity": "High", + "subcategory": "App delivery", + "text": "Enable the Azure Front Door WAF. Protect your application from a range of attacks.", + "waf": "Security" }, { - "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", + "ammp": true, + "category": "Network topology and connectivity", + "checklist": "Azure Application Delivery", + "guid": "2902d8cc-1b0c-4495-afad-624ab70f7bd6", + "id": "A02.04", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#tune-your-waf", "services": [ - "Cost" + "WAF", + "FrontDoor" ], - "subcategory": "demand shaping", - "text": "using demand shaping on PaaS services will optimize costs and performances" + "severity": "High", + "subcategory": "App delivery", + "text": "Tune the Azure Front Door WAF for your workload. Reduce false positive detections.", + "waf": "Security" }, { - "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", + "ammp": true, + "category": "Network topology and connectivity", + "checklist": "Azure Application Delivery", + "guid": "17ba124b-127d-42b6-9322-388d5b2bbcfc", + "id": "A02.05", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-prevention-mode", "services": [ - "Cost", - "Entra" + "WAF", + "FrontDoor" ], - "subcategory": "Advisor", - "text": "Start from the Azure Advisor page suggestions." + "severity": "High", + "subcategory": "App delivery", + "text": "Use prevention mode with the Azure Front Door WAF. Prevention mode ensures that the WAF blocks malicious requests.", + "waf": "Security" }, { - "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", + "ammp": true, + "category": "Network topology and connectivity", + "checklist": "Azure Application Delivery", + "guid": "49a98f2b-ec22-4a87-9415-6a10b00d6555", + "id": "A02.06", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#enable-default-rule-sets", "services": [ - "Cost", - "VM" + "WAF", + "FrontDoor" ], - "subcategory": "Advisor", - "text": "make sure advisor is configured for VM right sizing " + "severity": "High", + "subcategory": "App delivery", + "text": "Enable the Azure Front Door WAF default rule sets. The default rule sets detect and block common attacks.", + "waf": "Security" }, { - "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", + "ammp": true, + "category": "Network topology and connectivity", + "checklist": "Azure Application Delivery", + "guid": "147a13d4-2a2f-4824-a524-f5855b52b946", + "id": "A02.07", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#enable-bot-management-rules", "services": [ - "Cost" + "WAF", + "FrontDoor" ], - "subcategory": "Automation", - "text": "consider implementing IAC scripts or devops pipelines to match the cost governance process" + "severity": "High", + "subcategory": "App delivery", + "text": "Enable the Azure Front Door WAF bot management rules. The bot rules detect good and bad bots.", + "waf": "Security" }, { - "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 Application Delivery", + "guid": "d7dcdcb9-0d99-44b9-baab-ac7570ede79a", + "id": "A02.08", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-the-latest-ruleset-versions", "services": [ - "Cost", - "Monitor" + "WAF", + "FrontDoor" ], - "subcategory": "Automation", - "text": "set up cost alerts for applications that have variable costs (ideally for all of them)" + "severity": "Medium", + "subcategory": "App delivery", + "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": "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 Application Delivery", + "guid": "b9620385-1cde-418f-914b-a84a06982ffc", + "id": "A02.09", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#add-rate-limiting", "services": [ - "Cost" + "WAF", + "FrontDoor" ], - "subcategory": "Automation", - "text": "Use Azure Automation: Automate repetitive tasks can help you save time and resources, reducing costs in the process. " + "severity": "Medium", + "subcategory": "App delivery", + "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": "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 Application Delivery", + "guid": "6dc36c52-0124-4ffe-9eaf-23ec1282dedb", + "id": "A02.10", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-a-high-threshold-for-rate-limits", "services": [ - "Cost" + "WAF", + "FrontDoor" ], - "subcategory": "Automation", - "text": "run orphaned resources workbook" + "severity": "Medium", + "subcategory": "App delivery", + "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": "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 Application Delivery", + "guid": "388a3d0e-0a43-4367-90b2-3dd2aeece5ee", + "id": "A02.11", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#geo-filter-traffic", "services": [ - "Cost", - "Storage" + "WAF", + "FrontDoor" ], - "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": "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": [ - "AzurePolicy", - "Cost" - ], - "subcategory": "Baseline", - "text": "establish a cost optimization baseline by using a policy that tags every new resource as #NEW" + "severity": "Low", + "subcategory": "App delivery", + "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": "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 Application Delivery", + "guid": "00acd8a9-6975-414f-8491-2be6309893b8", + "id": "A02.12", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#specify-the-unknown-zz-location", "services": [ - "Cost" + "WAF", + "FrontDoor" ], - "subcategory": "Baseline", - "text": "Organize resources to maximize cost insights and accountability" + "severity": "Medium", + "subcategory": "App delivery", + "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": "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": "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": [ - "Cost" + "Storage" ], - "subcategory": "Budgets", - "text": "Create budgets" + "severity": "Medium", + "subcategory": "Physical", + "text": "All planned storage pools should use direct-attached storage (SATA, SAS, NVMe)", + "waf": "Performance" }, { - "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": "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": [ - "Cost" + "Storage", + "ACR" ], - "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": "Physical", + "text": "Disks are symmetrical across all nodes", + "waf": "Performance" }, { - "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": "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": [ - "Cost" + "Backup", + "Storage" ], - "subcategory": "Cost Analysis", - "text": "check daily for cost spikes and anomalies (ideally with automatic billing exports)" + "severity": "Medium", + "subcategory": "S2D", + "text": "Parity type disk redundancy should only be used for low I/O volumes (backup/archive)", + "waf": "Performance" }, { - "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": "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": [ - "Cost" + "Storage" ], - "subcategory": "Cost Analysis", - "text": "automate cost retrieval for deep analysis or integration" + "severity": "Medium", + "subcategory": "S2D", + "text": "Ensure there at least 2 capacity disks with available capacity in the Storage Pool", + "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", + "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": [ - "Cost", - "ACR" + "Storage" ], - "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": "Low", + "subcategory": "S2D", + "text": "'Delimited allocation' has been considered to improve volume resiliency in a multi-node failure", + "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", + "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": [ - "Cost" + "Storage" ], - "subcategory": "Tagging", - "text": "Tag shared resources" + "severity": "Medium", + "subcategory": "S2D", + "text": "CSVs are created in multiples of node count", + "waf": "Performance" }, { - "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": "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": [ - "Cost" + "Storage" ], - "subcategory": "Tagging", - "text": "consider using tags to all services for cost allocation" + "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" }, { - "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": "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": [ - "Cost" + "Storage" ], - "subcategory": "automation", - "text": "consider Reservation automation to track and promptly react to changes" + "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" }, { - "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": "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": [ - "AzurePolicy", - "Cost", - "SQL", - "VM" + "Storage" ], - "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": "Low", + "subcategory": "S2D", + "text": "VMFleet has been run prior to workload deployment to baseline storage performance", + "waf": "Performance" }, { - "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": "Storage", + "checklist": "Azure Stack HCI Review", + "guid": "13c12e2a-c938-4dd1-9223-507d5e17f9c5", + "id": "01.03.01", "services": [ - "Cost", - "LoadBalancer" + "Storage" ], - "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": "Host OS", + "text": "OS drives use a dedicated storage controller", + "waf": "Reliability" }, { - "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": "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": [ - "Cost", - "AppSvc" + "Storage" ], - "subcategory": "Functions", - "text": "saving plans will provide 17% on select app service plans" + "severity": "Medium", + "subcategory": "Host OS", + "text": "CSV in-memory read caching is enabled and properly configured", + "waf": "Performance" }, { - "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": "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": [ - "Cost", - "VM" + "ACR" ], - "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": "Host", + "text": "NICs are symmetrical across nodes", + "waf": "Reliability" + }, { - "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": "Networking", + "checklist": "Azure Stack HCI Review", + "guid": "ea8054db-a558-4533-80c8-5d9cf447ba19", + "id": "02.01.02", "services": [ - "Cost", - "ARS", - "VM" + "Storage" ], - "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": "High", + "subcategory": "Host", + "text": "Storage networking is redundant", + "waf": "Reliability" }, { - "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": [ - "Cost" - ], - "subcategory": "reservations/savings plans", - "text": "plan for Azure Savings Plans for all the workloads that are dynamic and need maximum flexibility" + "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" }, { - "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": "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": [ - "Cost" + "Storage", + "VNet" ], - "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": "Host", + "text": "Storage NICs are assigned static IP addresses on separate subnets and VLANs", + "waf": "Reliability" }, { - "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": "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": [ - "Cost", "Storage" ], - "subcategory": "reserve storage", - "text": "only larger disks can be reserved =>1TiB -" + "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" }, { - "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": "Networking", + "checklist": "Azure Stack HCI Review", + "guid": "603c6d71-59d2-419c-a312-8edc6e799c6a", + "id": "02.01.08", "services": [ - "Cost", - "VM" + "Storage" ], - "subcategory": "reserve VMs with normalized and rationalized sizes", - "text": "after the right-sizing optimization" + "severity": "High", + "subcategory": "Host", + "text": "RDMA is enabled on the Storage networking", + "waf": "Performance" }, { - "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": [ - "AzurePolicy", - "Cost", - "SQL" - ], - "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": "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" }, { - "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": "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": [ - "Cost", - "SQL", "VM" ], - "subcategory": "SQL Database Reservations", - "text": "the VM + licence part discount (ahub+3YRI) is around 70% discount" + "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" }, { - "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": "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": [ - "Cost" + "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": "Medium", + "subcategory": "SDN", + "text": "There are at least 3 Network Controller VMs deployed", + "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": "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", - "Cost" + "Backup" ], - "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": "High", + "subcategory": "SDN", + "text": "Backups of SDN infrastructure are configured and tested", + "waf": "Operations" }, { - "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": "Management and Monitoring", + "checklist": "Azure Stack HCI Review", + "guid": "51eaa4b6-b9a7-43e1-a7dc-634d3107bc6d", + "id": "03.01.01", "services": [ - "AzurePolicy", - "Cost" + "Monitor" ], - "subcategory": "Automation", - "text": "plan and enforce a ON/OFF policy for production services, where possible" + "severity": "Medium", + "subcategory": "Cluster", + "text": "SCOM Managed Instance has been considered for more complex monitoring and alerting scenarios", + "waf": "Operations" }, { - "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": "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": [ - "AzurePolicy", - "Cost" + "Monitor" ], - "subcategory": "Automation", - "text": "plan and enforce a ON-DEMAND policy with auto-shutdown for non-production services, where possible" + "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": "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": "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": [ - "Cost", - "VM" + "Monitor" ], - "subcategory": "Autoscale", - "text": "consider using a VMSS to match demand rather than flat sizing" + "severity": "Medium", + "subcategory": "Cluster", + "text": "Insights has been enabled at the cluster level and all nodes are reporting data", + "waf": "Operations" }, { - "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": "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": [ - "Cost", - "AKS" + "Monitor" ], - "subcategory": "Autoscale", - "text": "use AKS autoscaler to match your clusters usage (make sure the pods requirements match the scaler)" + "severity": "Medium", + "subcategory": "Cluster", + "text": "Azure Monitoring Agent has been deployed to hosts and an appropriate Data Collection Rule has been configured", + "waf": "Operations" }, { - "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": "Management and Monitoring", + "checklist": "Azure Stack HCI Review", + "guid": "6143af1d-0d1a-4163-b1c9-662f7459bb98", + "id": "03.02.01", "services": [ - "Cost" + "Monitor" ], - "subcategory": "Autoscale", - "text": "right-size PaaS service according to average use and accomodate spikes with auto or manual scaling" + "severity": "Medium", + "subcategory": "Hardware", + "text": "Relevant hardware monitoring has been configured", + "waf": "Operations" }, { - "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": "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": [ - "Cost" + "Monitor" ], - "subcategory": "Autoscale", - "text": "plan for demand shaping where applicable" + "severity": "Medium", + "subcategory": "Hardware", + "text": "Relevant hardware alerting has been configured", + "waf": "Operations" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "e2e8aaab-3571-4549-ab91-53d89f89dc7b", - "id": "E02.05", + "category": "Operations", + "checklist": "Azure Stack HCI Review", + "guid": "c0da5bbd-0f0d-4a26-98ec-38c9cc42b323", + "id": "04.01.01", "services": [ - "Cost" + "VM" ], - "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": "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": "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": "Networking", + "checklist": "Azure Stack HCI Review", + "guid": "a8ecf23c-c048-4fa9-b87b-51ebfb409863", + "id": "04.01.02", "services": [ - "Backup", - "Cost" + "VM" ], - "subcategory": "Backup", - "text": "Move recovery points to vault-archive where applicable (Validate)", - "training": "https://azure.microsoft.com/pricing/reservations/" + "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" }, { - "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": "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": [ - "Cost", - "LoadBalancer", - "VM" + "Backup", + "VM", + "ASR" ], - "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": "High", + "subcategory": "VM", + "text": "Backups of HCI VMs have been configured using MABS or a third-party solution", + "waf": "Operations" }, { - "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": [ - "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" + "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": "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": [ - "Cost" - ], - "subcategory": "Functions", - "text": "functions -Cache data locally", - "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-compute-resources/" + "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": "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": [ - "Cost", - "Storage" - ], - "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": "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": "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": [ - "Cost" - ], - "subcategory": "Functions", - "text": "Functions -Keep your functions warm", - "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/" + "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": "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": "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": [ - "Cost" + "VM" ], - "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": "Cluster Configuration", + "text": "Azure Benefits has been enabled at the cluster and VM levels", + "waf": "Cost" }, { - "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": [ - "Cost" - ], - "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": "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": "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": "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": [ - "Cost" + "AzurePolicy" ], - "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": "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": "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": [ - "Cost" - ], - "subcategory": "Networking", - "text": "evaluate your network topology against networking costs and where applicable reduce the egress and peering data" + "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": "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": "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": [ - "Cost", - "FrontDoor", - "EventHubs" + "Entra" ], - "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": "Stretch Clustering", + "text": "There is sub 5ms latency between each site if synchronous replication is being configured AAD", + "waf": "Performance" }, { - "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": "Networking", + "checklist": "Azure Stack HCI Review", + "guid": "3277558e-3155-4088-b49a-78594cb4ce1a", + "id": "07.01.02", "services": [ - "Cost", - "AppSvc", - "FrontDoor" + "Storage", + "VNet" ], - "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": "Stretch Clustering", + "text": "Management, Replication and Storage networks excluded from stretched VLANs configurations, are routed, and in different subnets", + "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", - "services": [ - "Cost" - ], - "subcategory": "PaaS", - "text": "consider using free tiers where applicable for all non-production environments" + "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": "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": "Networking", + "checklist": "Azure Stack HCI Review", + "guid": "8e62945f-b9ac-4a5c-a4e4-836f527010b4", + "id": "07.02.02", "services": [ - "Cost" + "ACR" ], - "subcategory": "serverless", - "text": "using serverless patterns for spikes can help keeping costs down" + "severity": "Medium", + "subcategory": "Stretch Clustering", + "text": "Separate vLANs and networks are used for each replication network across both sites", + "waf": "Reliability" }, { - "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": "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": [ - "Cost", "Storage" ], - "subcategory": "Storage", - "text": "consider archiving tiers for less used data" + "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": "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": [ - "Cost", - "Storage" - ], - "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": "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" }, { - "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": "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": [ - "Cost", "Storage" ], - "subcategory": "Storage", - "text": "consider using standard SSD rather than Premium or Ultra where possible" + "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": "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": "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": [ - "Cost", - "Storage" + "Backup", + "ASR" ], - "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": "Disaster Recovery", + "text": "Azure Site Recovery has been considered for DR purposes", + "waf": "Operations" }, { - "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": [ - "ASR", - "Cost", - "Storage" - ], - "subcategory": "Storage", - "text": "for ASR, consider using Standard SSD disks if the RPO/RTO and replication throughput allow it" + "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": "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": "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" + }, + { + "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": [ - "Cost", - "Storage" + "Defender" ], - "subcategory": "storage", - "text": "storage accounts: check hot tier and/or GRS necessary" + "severity": "Medium", + "subcategory": "Host", + "text": "Microsoft Defender Antivirus has been enabled on all nodes", + "waf": "Security" }, { - "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": "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": "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": [ - "Cost", + "Backup", + "AVS", "Storage" ], - "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": "Medium", + "subcategory": "Backup", + "text": "Ensure backups are not stored on vSAN as vSAN is a finite resource", + "waf": "Reliability" }, { - "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": "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": [ - "Cost", - "Monitor", - "EventHubs" + "Backup", + "AVS" ], - "subcategory": "Synapse", - "text": "Create budgets to manage costs and create alerts that automatically notify stakeholders of spending anomalies and overspending risks." + "severity": "Medium", + "subcategory": "Business Continuity", + "text": "Use MABS as your backup solution", + "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": "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": [ - "Cost", - "Storage" + "Backup", + "AVS", + "ASR" ], - "subcategory": "Synapse", - "text": "Export cost data to a storage account for additional data analysis." + "severity": "Medium", + "subcategory": "Business Continuity", + "text": "Deploy your backup solution in the same region as your Azure VMware Solution private cloud", + "waf": "Reliability" }, { - "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": "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": [ - "Cost", - "SQL" + "AVS" ], - "subcategory": "Synapse", - "text": "Control costs for a dedicated SQL pool by pausing the resource when it is not in use." + "severity": "Medium", + "subcategory": "Business Continuity", + "text": "Preferably deploy MABS outside of the SDDC as native Azure IaaS", + "waf": "Reliability" }, { - "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": "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": [ - "Cost" + "AVS" ], - "subcategory": "Synapse", - "text": "Enable the serverless Apache Spark automatic pause feature and set your timeout value accordingly." + "severity": "Medium", + "subcategory": "Business Continuity", + "text": "Escalation process with Microsoft in the event of a regional DR", + "waf": "Reliability" }, { - "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": "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": [ - "Cost" + "AVS", + "ASR" ], - "subcategory": "Synapse", - "text": "Create multiple Apache Spark pool definitions of various sizes." + "severity": "Medium", + "subcategory": "Disaster Recovery", + "text": "Use VMware Site Recovery Manager when both sites are Azure VMware Solution", + "waf": "Reliability" }, { - "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": "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": [ - "Cost" + "AVS", + "ASR" ], - "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": "Medium", + "subcategory": "Disaster Recovery", + "text": "Use Azure Site Recovery when the Disaster Recovery technology is native Azure IaaS", + "waf": "Reliability" }, { - "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": "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": [ - "Cost", - "VM" + "AVS", + "ASR" ], - "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": "Medium", + "subcategory": "Disaster Recovery", + "text": "Use Automated recovery plans with either of the Disaster solutions,", + "waf": "Reliability" }, { - "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": "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": [ - "Cost", - "VM" + "AVS", + "ASR" ], - "subcategory": "VM", - "text": "right-sizing all VMs" + "severity": "Medium", + "subcategory": "Disaster Recovery", + "text": "Configure a secondary disaster recovery environment", + "waf": "Reliability" }, { - "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": "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": [ - "Cost", - "VM" + "AVS", + "ASR" ], - "subcategory": "VM", - "text": "swap VM sized with normalized and most recent sizes", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/" + "severity": "Medium", + "subcategory": "Disaster Recovery", + "text": "Assign IP ranges unique to each region", + "waf": "Reliability" }, { - "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": "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": [ - "Cost", - "VM", - "Monitor" + "AVS", + "ExpressRoute", + "ASR", + "NVA" ], - "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": "Disaster Recovery", + "text": "Use Global Reach between DR regions", + "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": "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": [ - "Cost", - "VM" + "AVS", + "VWAN" ], - "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": "Medium", + "subcategory": "Direct (no vWAN, no H&S)", + "text": "Global Reach to ExR circuit - no Azure resources", + "waf": "Performance" }, { - "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": "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": [ - "Entra" + "AVS", + "ExpressRoute" ], "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" + "subcategory": "ExpressRoute", + "text": "Connect to Azure using ExR", + "waf": "Performance" }, { - "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": "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": [ - "Entra" + "AVS", + "ExpressRoute" ], - "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" + "severity": "Medium", + "subcategory": "ExpressRoute", + "text": "Bandwidth sizing", + "waf": "Performance" }, { - "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": "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": [ - "Entra" + "AVS", + "ExpressRoute" ], - "severity": "Low", - "subcategory": "Microsoft Entra ID Tenants", - "text": "Leverage Azure Lighthouse for Multi-Tenant Management", - "waf": "Operations" + "severity": "Medium", + "subcategory": "ExpressRoute", + "text": "Traffic routing ", + "waf": "Performance" }, { - "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": "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": [ - "Entra" + "AVS", + "ExpressRoute" ], "severity": "Medium", - "subcategory": "Cloud Solution Provider", - "text": "Ensure that Azure Lighthouse is used for administering the tenant by partner", - "waf": "Cost" + "subcategory": "ExpressRoute", + "text": "Global Reach ", + "waf": "Performance" }, { - "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": "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": [ - "Entra" + "AVS", + "VNet" ], - "severity": "Low", - "subcategory": "Cloud Solution Provider", - "text": "Discuss support request and escalation process with CSP partner", - "waf": "Cost" + "severity": "Medium", + "subcategory": "Hub & Spoke", + "text": "VNet name & address space", + "waf": "Performance" }, { - "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": "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": [ - "Cost", - "Entra" + "AVS", + "VNet", + "VPN", + "ExpressRoute" ], "severity": "Medium", - "subcategory": "Cloud Solution Provider", - "text": "Setup Cost Reporting and Views with Azure Cost Management", - "waf": "Cost" + "subcategory": "Hub & Spoke", + "text": "Gateway subnet", + "waf": "Performance" }, { - "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": "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": [ - "LoadBalancer", - "Entra" + "AVS", + "VNet", + "VPN", + "ExpressRoute" ], "severity": "Medium", - "subcategory": "Enterprise Agreement", - "text": "Configure Notification Contacts to a group mailbox", - "waf": "Cost" + "subcategory": "Hub & Spoke", + "text": "VPN Gateway", + "waf": "Performance" }, { - "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": "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": [ - "TrafficManager", - "Entra" + "AVS", + "VNet", + "VPN", + "ExpressRoute" ], - "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": "Hub & Spoke", + "text": "ExR Gateway", + "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": "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": [ - "Entra" + "AVS", + "NVA" ], - "severity": "High", - "subcategory": "Enterprise Agreement", - "text": "Ensure that Accounts are configured to be of the type 'Work or School Account", - "waf": "Security" + "severity": "Medium", + "subcategory": "Internet", + "text": "Egress point", + "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": "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": [ - "Cost", - "Entra" + "Bastion", + "AVS" ], "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" + "subcategory": "Jumpbox & Bastion", + "text": "Remote connectivity to AVS", + "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": "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": [ - "Subscriptions", - "Cost", - "Entra" + "Bastion", + "AVS", + "VNet" ], - "severity": "Low", - "subcategory": "Enterprise Agreement", - "text": "Make use of Enterprise Dev/Test Subscriptions to reduce costs for non-production workloads", - "waf": "Cost" + "severity": "Medium", + "subcategory": "Jumpbox & Bastion", + "text": "Configure a jumbox and Azure Bastion", + "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": "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": [ - "RBAC", - "Entra" + "Bastion", + "AVS", + "VM" ], "severity": "Medium", - "subcategory": "Enterprise Agreement", - "text": "Periodically audit the role assignments to review who has access to your Enterprise Agreement Enrollment", - "waf": "Cost" + "subcategory": "Jumpbox & Bastion", + "text": "Security measure allowing RDP access via the portal", + "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": "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": [ - "Entra" + "AVS", + "VPN" ], - "severity": "Low", - "subcategory": "Microsoft Customer Agreement", - "text": "Configure Agreement billing account notification contact email", - "waf": "Cost" + "severity": "Medium", + "subcategory": "VPN", + "text": "Connect to Azure using a VPN", + "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": "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": [ - "Cost", - "Storage", - "Entra" + "AVS", + "VPN" ], - "severity": "Low", - "subcategory": "Microsoft Customer Agreement", - "text": "Use Billing Profiles and Invoice sections to structure your agreements billing for effective cost management", - "waf": "Cost" + "severity": "Medium", + "subcategory": "VPN", + "text": "Bandwidth sizing", + "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": "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": [ - "Cost", - "Entra" + "AVS", + "VPN" ], - "severity": "Low", - "subcategory": "Microsoft Customer Agreement", - "text": "Make use of Azure Plan to reduce costs for non-production workloads", - "waf": "Cost" + "severity": "Medium", + "subcategory": "VPN", + "text": "Traffic routing ", + "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": "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": [ - "RBAC", - "Entra" + "AVS", + "VWAN" ], "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" + "subcategory": "vWAN hub", + "text": "vWAN name, hub name and address space", + "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": "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": [ - "Entra" + "AVS", + "VPN", + "VWAN" ], - "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" + "severity": "Medium", + "subcategory": "vWAN hub", + "text": "ExR and/or VPN gateway provisioned", + "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": "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": [ - "ASR", - "Entra" + "AVS", + "VWAN", + "Firewall" ], "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" + "subcategory": "vWAN hub", + "text": "Secure vWAN", + "waf": "Security" }, { - "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": "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": [ + "AVS", "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/", + "severity": "Medium", + "subcategory": "Access", + "text": "External Identity (user accounts)", "waf": "Security" }, { - "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": "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": [ - "Monitor", + "AVS", "Entra" ], "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.", + "subcategory": "Access", + "text": "If using AD domain, ensure Sites & Services has been configured", "waf": "Security" }, { - "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": "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": [ - "Subscriptions", - "ACR", - "Entra", - "RBAC" + "AVS", + "Entra" ], - "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/", + "severity": "Medium", + "subcategory": "Access", + "text": "Use LDAPS not ldap ( vCenter)", "waf": "Security" }, { - "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": "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": [ - "AzurePolicy", + "AVS", "Entra" ], - "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/", + "severity": "Medium", + "subcategory": "Access", + "text": "Use LDAPS not ldap (NSX-T)", "waf": "Security" }, { - "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": "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": [ + "AVS", "Entra" ], - "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/", + "severity": "Medium", + "subcategory": "Security", + "text": "Security certificate installed on LDAPS servers ", "waf": "Security" }, { - "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": "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": [ + "AVS", "RBAC", "Entra" ], "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/", + "subcategory": "Security", + "text": "RBAC applied to Azure roles", "waf": "Security" }, { - "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": "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": [ - "Entra" + "AVS", + "RBAC", + "Entra" ], "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/", + "subcategory": "Security", + "text": "RBAC model in vCenter", "waf": "Security" }, { - "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": "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": [ + "AVS", + "RBAC", "Entra" ], - "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/", + "severity": "Medium", + "subcategory": "Security", + "text": "CloudAdmin role usage", "waf": "Security" }, { - "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": "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": [ + "AVS", + "RBAC", "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/", + "subcategory": "Security ", + "text": "Is Privileged Identity Management implemented", "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", + "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": [ - "Subscriptions", + "AVS", "RBAC", "Entra" ], "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/", + "subcategory": "Security ", + "text": "Is Privileged Identity Management audit reporting implemented", "waf": "Security" }, { - "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/active-directory-domain-services/overview", + "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": [ - "Subscriptions", + "AVS", + "Monitor", "Entra" ], "severity": "Medium", - "subcategory": "Identity", - "text": "If Azure Active Directory Domains Services (AADDS) is in use, deploy AADDS within the primary region because this service can only be projected into one subscription", - "training": "https://learn.microsoft.com/learn/modules/azure-active-directory/", + "subcategory": "Security ", + "text": "Limit use of CloudAdmin account to emergency access only", "waf": "Security" }, { - "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": "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": [ + "AVS", "Entra" ], "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/", + "subcategory": "Security ", + "text": "Is a process defined to regularly rotate cloudadmin (vCenter) and admin (NSX) credentials", "waf": "Security" }, { - "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": "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": [ - "Entra" + "AVS", + "VM", + "Arc" ], "severity": "Medium", - "subcategory": "Identity", - "text": "If AD on Windows server in use, are the resources in Azure using the correct domain controller?", - "training": "https://learn.microsoft.com/learn/paths/implement-windows-server-iaas-virtual-machine-identity/", - "waf": "Security" + "subcategory": "Operations", + "text": "AVS VM Management (Azure Arc)", + "waf": "Operations" }, { - "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": "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": [ - "VPN", - "Entra" + "AVS", + "AzurePolicy", + "Monitor" ], "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": "Operations", + "text": "Azure policy", + "waf": "Operations" }, { - "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": "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": [ - "RBAC", - "Entra" + "AVS" ], "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": "Operations", + "text": "Resource locks", + "waf": "Operations" }, { - "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": "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": [ - "Entra", - "VNet" + "AVS" ], - "severity": "Low", - "subcategory": "Landing zones", - "text": "Configure Identity (ADDS) 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" + "severity": "Medium", + "subcategory": "Operations", + "text": "Run books", + "waf": "Operations" }, { - "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": "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": [ - "ACR", - "Entra", - "AKV", - "RBAC", - "Storage" + "AVS", + "AKV" ], "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": "Operations", + "text": "Naming conventions for auth keys", + "waf": "Operations" }, { - "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": "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": [ - "Entra" + "AVS", + "Monitor" ], "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": "Naming and tagging", - "text": "It is recommended to follow Microsoft Best Practice Naming Standards", - "waf": "Security" + "subcategory": "Alerts", + "text": "Create warning alerts for critical thresholds ", + "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) <= 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": [ - "Subscriptions" + "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": [ + "AVS", + "Monitor" ], "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" + "subcategory": "Alerts", + "text": "Create critical alert vSAN consumption", + "waf": "Operations" }, { - "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": "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": [ - "Subscriptions" + "AVS", + "Monitor" ], "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": "Alerts", + "text": "Configured for Azure Service Health alerts and notifications", + "waf": "Operations" }, { - "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": "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": [ - "Subscriptions", - "RBAC", + "AVS", + "Monitor", + "Backup", + "VM", "AzurePolicy" ], "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": "Backup", + "text": "Backup policy", + "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": "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": [ - "Subscriptions", - "VWAN", - "ExpressRoute", - "DNS" + "AVS", + "AzurePolicy", + "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": "Capacity", + "text": "Policy around ESXi host density and efficiency", + "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": "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": [ - "Subscriptions" + "AVS", + "Cost", + "Subscriptions", + "Monitor" ], "severity": "Medium", - "subcategory": "Subscriptions", - "text": "Enforce no subscriptions are placed under the root management group", - "waf": "Security" + "subcategory": "Costs", + "text": "Ensure a good cost management process is in place for Azure VMware Solution - ", + "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": "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": [ - "Subscriptions", - "RBAC" + "AVS", + "Monitor", + "NetworkWatcher" ], "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": "Dashboard", + "text": "Connection monitor dashboard", + "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": "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": [ - "Subscriptions" + "Storage", + "AVS", + "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": "Logs & Metrics", + "text": "Configure Azure VMware Solution logging ", + "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": "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": [ - "AzurePolicy", - "RBAC", - "Subscriptions", - "Cost" + "AVS", + "Monitor" ], - "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": "Medium", + "subcategory": "Logs & Metrics", + "text": "vRealize Operations", + "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": "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": [ - "Subscriptions" + "AVS", + "VM", + "Monitor" ], "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" + "subcategory": "Logs & Metrics", + "text": "AVS VM logging", + "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": "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": [ - "AzurePolicy", - "Cost", - "Subscriptions", - "VM" + "AVS", + "Monitor", + "NetworkWatcher", + "VPN", + "ExpressRoute" ], - "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" + "severity": "Medium", + "subcategory": "Network", + "text": "Monitor ExpressRoute and/or VPN connections ", + "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", + "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": [ - "Subscriptions", + "AVS", + "ExpressRoute", "Monitor" ], - "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" + "severity": "Medium", + "subcategory": "Network", + "text": "Monitor from an Azure native resource to an Azure VMware Solution VM", + "waf": "Operations" }, { - "category": "Resource Organization", - "checklist": "Azure Landing Zone Review", - "guid": "4c27d42e-8bba-4c75-9155-9ab9153e8908", - "id": "C02.12", - "link": "https://azure.microsoft.com/global-infrastructure/services/", + "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": [ - "Subscriptions" + "AVS", + "Monitor" ], "severity": "Medium", - "subcategory": "Subscriptions", - "text": "Ensure required services and features are available within the chosen deployment regions", - "training": "https://learn.microsoft.com/learn/modules/azure-architecture-fundamentals/", - "waf": "Security" - }, - { - "ammp": true, - "category": "Resource Organization", - "checklist": "Azure Landing Zone Review", - "guid": "ae28c84c-33b6-4b78-88b9-fe5c41049d40", - "id": "C02.13", - "link": "https://learn.microsoft.com/azure/cost-management-billing/cost-management-billing-overview", - "services": [ - "Subscriptions", - "Cost" - ], - "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": "Network", + "text": "Monitor from an on-premises resource to an Azure VMware Solution VM", + "waf": "Operations" }, { - "category": "Resource Organization", - "checklist": "Azure Landing Zone Review", - "guid": "3a923c34-74d0-4001-aac6-a9e01e6a83de", - "id": "C02.14", - "link": "https://learn.microsoft.com/azure/governance/management-groups/overview", + "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": [ - "Subscriptions", - "Entra" + "AVS", + "Monitor" ], "severity": "Medium", - "subcategory": "Subscriptions", - "text": "If AD on Windows Server, establish a dedicated identity subscription in the Indentity management group, to host Windows Server Active Directory domain controllers", - "training": "https://learn.microsoft.com/learn/paths/enterprise-scale-architecture/", - "waf": "Security" + "subcategory": "Security", + "text": "Auditing and logging is implemented for inbound internet ", + "waf": "Operations" }, { - "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.15", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/track-costs", + "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": [ - "Subscriptions", - "Cost" + "AVS", + "Monitor" ], "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": "Security", + "text": "Session monitoring ", + "waf": "Operations" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "f00a69de-7076-4734-a734-6e4552cad9e1", - "id": "D01.01", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-latest-version-for-customer-managed-certificates", + "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": [ - "FrontDoor", - "AKV" + "AVS", + "Monitor" ], "severity": "Medium", - "subcategory": "App delivery", - "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.", + "subcategory": "VMWare", + "text": "Logging and diagnostics", "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", - "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": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "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": "D01.03", - "link": "https://learn.microsoft.com/azure/application-gateway/overview-v2", + "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": [ - "AppGW" + "AVS", + "VM", + "Monitor" ], "severity": "Medium", - "subcategory": "App delivery", - "text": "Ensure you are using Application Gateway v2 SKU", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", - "waf": "Security" + "subcategory": "VMware", + "text": "Log Analytics Agents deployed on Azure VMware Solution guest VM workloads", + "waf": "Operations" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "graph": "resources | where type == 'microsoft.network/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard')", - "guid": "4e35fbf5-0ae2-48b2-97ce-753353edbd1a", - "id": "D01.04", - "link": "https://learn.microsoft.com/azure/load-balancer/load-balancer-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": [ - "LoadBalancer" + "AVS" ], "severity": "Medium", - "subcategory": "App delivery", - "text": "Ensure you are using the Standard SKU for your Azure Load Balancers", + "subcategory": "Hub & Spoke", + "text": "North/South routing through Az Firewall or 3rd party ", "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "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 | project id, subnetId = tostring(subnets.id), subnetPrefixLength = split(subnets.properties.addressPrefix, '/')[1]) on subnetId | extend compliant = (subnetPrefixLength <= 26) | distinct id,compliant", - "guid": "dfc50f87-3800-424c-937b-ed5f186e7c15", - "id": "D01.05", - "link": "https://learn.microsoft.com/azure/application-gateway/configuration-infrastructure#size-of-the-subnet", + "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": [ - "AppGW", - "VNet" + "AVS" ], "severity": "Medium", - "subcategory": "App delivery", - "text": "Your application gateways should be deployed in subnets with IP prefixes equal or larger than /26", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "subcategory": "Hub & Spoke", + "text": "East West (Internal to Azure)", "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "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": "D01.06", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "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": [ - "Subscriptions", - "Entra", - "WAF", - "VNet", - "AppGW", + "AVS", + "ARS", "NVA" ], "severity": "Medium", - "subcategory": "App delivery", - "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" + "subcategory": "Hub & Spoke", + "text": "ExR without Global Reach", + "waf": "Operations" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "143b16c3-1d7a-4a9b-9470-4489a8042d88", - "id": "D01.07", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-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": [ - "DDoS" + "AVS", + "ARS" ], "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" + "subcategory": "Hub & Spoke", + "text": "Route server ", + "waf": "Operations" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "e79d17b7-3b22-4a5a-97e7-a8ed4b30e38c", - "id": "D01.08", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-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": [ - "AzurePolicy", - "FrontDoor", - "WAF" + "AVS" ], "severity": "Medium", - "subcategory": "App delivery", - "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": "Internet", + "text": "Egress point(s)", "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "3f29812b-2363-4cef-b179-b599de0d5973", - "id": "D01.09", - "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-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": [ "AppGW", + "AVS", "FrontDoor", - "AzurePolicy", - "WAF" + "NVA" ], "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": "Internet", + "text": "Internet facing applications", "waf": "Security" }, { - "ammp": true, - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "cd4cd21b-0881-437f-9e6c-4cfd3e504547", - "id": "D01.10", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "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": [ - "TrafficManager" + "AVS", + "ARS" ], - "severity": "High", - "subcategory": "App delivery", - "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" + "severity": "Medium", + "subcategory": "Routing", + "text": "When route server Route limit understood? ", + "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "3b4b3e88-a459-4ed5-a22f-644dfbc58204", - "id": "D01.11", - "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy#how-application-proxy-works", + "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": [ - "Entra", - "AVD" + "AVS", + "VNet", + "VM", + "DDoS", + "VPN", + "AppGW", + "ExpressRoute", + "LoadBalancer", + "FrontDoor" ], - "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/", + "severity": "Medium", + "subcategory": "Security", + "text": "Is DDoS standard protection of public facing IP addresses? ", "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "01ca7cf1-5754-442d-babb-8ba6772e5c30", - "id": "D01.12", - "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy#how-application-proxy-works", + "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": [ - "Entra" + "AVS" ], "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/", + "subcategory": "Security", + "text": "Use a dedicated privileged access workstation (PAW)", "waf": "Security" }, { - "ammp": true, - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "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": "D01.13", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-policy-settings", + "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": [ - "Storage", - "FrontDoor", - "WAF" + "AVS" ], - "severity": "High", - "subcategory": "App delivery", - "text": "Deploy your WAF profiles for Front Door in 'Prevention' mode.", + "severity": "Medium", + "subcategory": "Traffic Inspection", + "text": "East West (Internal to AVS)", "waf": "Security" }, { - "ammp": true, - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "062d5839-4d36-402f-bfa4-02811eb936e9", - "id": "D01.14", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#avoid-combining-traffic-manager-and-front-door", + "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": [ - "TrafficManager", - "FrontDoor" + "AVS", + "Firewall", + "VWAN" ], - "severity": "High", - "subcategory": "App delivery", - "text": "Avoid combining Azure Traffic Manager and Azure Front Door.", + "severity": "Medium", + "subcategory": "Virtual WAN", + "text": "Use Secure Hub (Azure Firewall or 3rd party)", "waf": "Security" }, { - "ammp": true, - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "5efeb96a-003f-4b18-8fcd-b4d84459c2b2", - "id": "D01.15", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-the-same-domain-name-on-front-door-and-your-origin", + "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": [ - "FrontDoor" + "AVS", + "VWAN" ], - "severity": "High", - "subcategory": "App delivery", - "text": "Use the same domain name on Azure Front Door and your origin. Mismatched host names can cause subtle bugs.", + "severity": "Medium", + "subcategory": "Virtual WAN", + "text": "East West (Internal to Azure)", "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "0b5a380c-4bfb-47bc-b1d7-dcfef363a61b", - "id": "D01.16", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#disable-health-probes-when-theres-only-one-origin-in-an-origin-group", + "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": [ - "FrontDoor" + "AVS", + "Subscriptions" ], - "severity": "Low", - "subcategory": "App delivery", - "text": "Disable health probes when there is only one origin in an Azure Front Door origin group.", + "severity": "Medium", + "subcategory": "Automated Scale", + "text": "Scale out operations planning", "waf": "Performance" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "5567048e-e5d7-4206-9c55-b5ed45d2cc0c", - "id": "D01.17", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#select-good-health-probe-endpoints", + "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": [ - "FrontDoor" + "Storage", + "AVS", + "AzurePolicy" ], "severity": "Medium", - "subcategory": "App delivery", - "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": "Automated Scale", + "text": "Scale in operations planning", + "waf": "Performance" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "a13f72f3-8f5c-4864-95e5-75bf37fbbeb1", - "id": "D01.18", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-head-health-probes", + "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": [ - "FrontDoor" + "AVS" ], - "severity": "Low", - "subcategory": "App delivery", - "text": "Use HEAD health probes with Azure Front Door, to reduce the traffic that Front Door sends to your application.", + "severity": "Medium", + "subcategory": "Automated Scale", + "text": "Scale serialized operations planning", "waf": "Performance" }, { - "ammp": true, - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "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": "D01.19", - "link": "https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity", + "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": [ - "LoadBalancer" + "AVS" ], - "severity": "High", - "subcategory": "App delivery", - "text": "Use Azure NAT Gateway instead of Load Balancer outbound rules for better SNAT scalability", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "Automated Scale", + "text": "Scale rd operations planning", + "waf": "Performance" }, { - "ammp": true, - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "af95c92d-d723-4f4a-98d7-8722324efd4d", - "id": "D01.20", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-managed-tls-certificates", + "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": [ - "Cost", - "FrontDoor", - "AKV" + "AVS" ], - "severity": "High", - "subcategory": "App delivery", - "text": "Use managed TLS certificates with Azure Front Door. Reduce operational cost and risk of outages due to certificate renewals.", - "waf": "Operations" + "severity": "Medium", + "subcategory": "Automated Scale", + "text": "Scale maximum operations planning", + "waf": "Performance" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "189ea962-3969-4863-8f5a-5ad808c2cf4b", - "id": "D01.21", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#define-your-waf-configuration-as-code", + "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": [ - "FrontDoor", - "WAF" + "AVS", + "Monitor" ], "severity": "Medium", - "subcategory": "App delivery", - "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": "Automated Scale", + "text": "Monitor scaling operations ", + "waf": "Performance" }, { - "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": "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": [ - "ExpressRoute" + "AVS", + "PrivateLink" ], "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.", - "waf": "Security" + "subcategory": "Networking", + "text": "Private link", + "waf": "Performance" }, { - "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", + "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": [ - "VPN", - "ExpressRoute" + "AVS" ], - "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/", - "waf": "Security" + "severity": "Medium", + "subcategory": "Networking", + "text": "Provisioning Vmware VLANs", + "waf": "Performance" }, { - "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": "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": [ - "VNet" + "AVS" ], "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" + "subcategory": "Pre-deployment", + "text": "Region selected", + "waf": "Reliability" }, { - "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": "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": [ - "Entra", - "DNS", - "Firewall", - "VNet", - "VPN", - "NVA", - "ExpressRoute" + "AVS", + "AzurePolicy" ], - "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" + "severity": "Medium", + "subcategory": "Pre-deployment", + "text": "Data residency compliant with selected regions", + "waf": "Reliability" }, { - "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": "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": [ - "NVA" + "AVS" ], "severity": "Medium", - "subcategory": "Hub and spoke", - "text": "When deploying partner networking technologies or NVAs, follow the partner vendor's guidance", + "subcategory": "Pre-deployment", + "text": "Request for number of AVS hosts submitted ", "waf": "Reliability" }, { - "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": "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": [ - "VPN", - "ARS", - "ExpressRoute" + "AVS" ], - "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": "Medium", + "subcategory": "Pre-deployment", + "text": "Region and number of AVS nodes approved", + "waf": "Reliability" }, { - "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": "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": [ - "ARS", - "VNet" + "AVS", + "Subscriptions" ], - "severity": "Low", - "subcategory": "Hub and spoke", - "text": "If using Route Server, use a /27 prefix for the Route Server subnet.", - "waf": "Security" + "severity": "Medium", + "subcategory": "Pre-deployment", + "text": "Resource provider for AVS registered", + "waf": "Reliability" }, { - "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": "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": [ - "ACR", - "VNet" + "AVS", + "Subscriptions" ], "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": "Pre-deployment", + "text": "Landing zone architecture", + "waf": "Reliability" }, { - "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": "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": [ - "Monitor" + "AVS" ], "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": "Pre-deployment", + "text": "Resource group name selected", + "waf": "Reliability" }, { - "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": "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": [ - "Entra", - "VNet", - "ExpressRoute" + "AVS" ], "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)", + "subcategory": "Pre-deployment", + "text": "Deployment prefix selected", "waf": "Reliability" }, { - "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": "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": [ - "Storage" + "AVS" ], "severity": "Medium", - "subcategory": "Hub and spoke", - "text": "Consider the limit of routes per route table (400).", + "subcategory": "Pre-deployment", + "text": "Network space for AVS management layer", "waf": "Reliability" }, { - "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": "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": "High", - "subcategory": "Hub and spoke", - "text": "Use the setting 'Allow traffic to remote virtual network' when configuring VNet peerings", + "severity": "Medium", + "subcategory": "Pre-deployment", + "text": "Network space for AVS NSX-T segments", "waf": "Reliability" }, { - "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": "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": [ - "ExpressRoute" + "AVS" ], "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/", + "subcategory": "Pre-deployment", + "text": "AVS SKU (region dependent)", "waf": "Performance" }, { - "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", - "services": [ - "ExpressRoute" - ], - "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" - }, - { - "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": "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": [ - "VPN", - "ExpressRoute" + "AVS" ], "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/", + "subcategory": "Pre-deployment", + "text": "Number of hosts to be deployed", "waf": "Performance" }, { - "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": "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": [ - "Cost", - "ExpressRoute" + "AVS", + "Cost" ], - "severity": "High", - "subcategory": "Hybrid", - "text": "Ensure that you're using unlimited-data ExpressRoute circuits only if you reach the bandwidth that justifies their cost.", + "severity": "Medium", + "subcategory": "Pre-deployment", + "text": "Reserverd Instances", "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", + "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": [ - "Cost", - "ExpressRoute" + "AVS", + "ASR" ], - "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": "Pre-deployment", + "text": "Capacity ", + "waf": "Performance" }, { - "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": "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": [ - "ExpressRoute" + "AVS" ], "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/", + "subcategory": "Pre-deployment", + "text": "Networking & Connectivity See docs describing scenrario 1 through 5", "waf": "Reliability" }, { - "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": "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": [ - "ExpressRoute" + "AVS" ], "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": "Pre-deployment", + "text": "3rd party application compatibility ", + "waf": "Reliability" }, { - "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": "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": [ - "ExpressRoute" + "AVS", + "AKV" ], "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" + "subcategory": "Encryption", + "text": "Use Azure Key Vault with in-guest encryption ", + "waf": "Security" }, { - "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": "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": [ - "VPN" + "AVS", + "SQL" ], "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" + "subcategory": "Encryption", + "text": "Use in-guest encryption", + "waf": "Security" }, { - "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": "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": [ - "Cost", + "AVS", + "AKV", "ExpressRoute" ], - "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" + "severity": "Medium", + "subcategory": "Encryption", + "text": "Keyvault use for secrets", + "waf": "Security" }, { - "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": "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": [ - "ExpressRoute" + "AVS" ], "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/", + "subcategory": "Extended support", + "text": "Ensure extended security update support ", "waf": "Security" }, { - "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": "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": [ - "Monitor", - "ExpressRoute" + "AVS", + "Sentinel" ], "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": "Investigation", + "text": "Enable Azure Sentinel or 3rd party SIEM ", + "waf": "Security" }, { - "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": [ - "NetworkWatcher", - "ACR", - "Monitor" - ], - "severity": "Medium", - "subcategory": "Hybrid", - "text": "Use Connection Monitor for connectivity monitoring across the environment.", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", - "waf": "Operations" - }, - { - "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": "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": [ - "ExpressRoute" + "AVS", + "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" + "subcategory": "Security", + "text": "Enable Advanced Threat Detection ", + "waf": "Security" }, { - "ammp": true, - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "2df4930f-6a43-49a3-926b-309f02c302f0", - "id": "D04.15", - "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/identity/adds-extend-domain#vm-recommendations", + "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": [ - "VM" + "AVS", + "AzurePolicy" ], - "severity": "High", - "subcategory": "Hybrid", - "text": "If you are deploying at least two VMs running AD DS as domain controllers, add them to different Availability Zones. If not available in the region, deploy in an Availability Set.", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "Security", + "text": "Policy & Regulatory Compliance", + "waf": "Security" }, { - "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": "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": [ - "ACR", - "VNet" + "AVS" ], - "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/", + "severity": "Medium", + "subcategory": "Firewalls", + "text": "Azure / 3rd party firewall", "waf": "Security" }, { - "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": "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": [ - "VNet" + "AVS" ], - "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/", + "severity": "Medium", + "subcategory": "Firewalls", + "text": "Firewalls allow for East/West traffic inside AVS", "waf": "Security" }, { - "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": "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": [ - "VNet" + "AVS" ], - "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" + "severity": "Medium", + "subcategory": "Networking", + "text": "HCX and/or SRM", + "waf": "Reliability" }, { - "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": "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": [ - "VNet" + "AVS" ], - "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/", + "severity": "Medium", + "subcategory": "Networking", + "text": "Configuring and Managing the HCX Interconnect", "waf": "Reliability" }, { - "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": "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": [ - "VNet", - "DNS" + "AVS" ], "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": "Networking", + "text": "Restrictions and limitations for network extensions", + "waf": "Performance" }, { - "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": "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": [ - "ACR", - "VNet", - "DNS" + "AVS" ], "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" + "subcategory": "Networking", + "text": "Mobility optimized networking", + "waf": "Performance" }, { - "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": "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": [ - "VNet", - "DNS" + "AVS" ], - "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.", + "severity": "Medium", + "subcategory": "On-premises pre-requisites", + "text": "Support matrix (OS versions etc).", "waf": "Operations" }, { - "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": "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": [ - "VNet", - "VM", - "DNS" + "AVS" ], - "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/", + "severity": "Medium", + "subcategory": "On-premises pre-requisites", + "text": "Standard switches converted to dynamic switches", "waf": "Operations" }, { - "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": "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": [ - "Bastion" + "AVS" ], "severity": "Medium", - "subcategory": "Internet", - "text": "Consider using Azure Bastion to securely connect to your network.", - "waf": "Security" + "subcategory": "On-premises pre-requisites", + "text": "Capacity for HCX appliance", + "waf": "Performance" }, { - "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": "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": [ - "VNet", - "Bastion" + "AVS" ], "severity": "Medium", - "subcategory": "Internet", - "text": "Use Azure Bastion in a subnet /26 or larger.", - "waf": "Security" + "subcategory": "On-premises pre-requisites", + "text": "Hardware compatibility", + "waf": "Operations" }, { - "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": "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": [ - "Firewall" + "Storage", + "AVS" ], - "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" + "severity": "Medium", + "subcategory": "Storage", + "text": "VSAN RDM disks are converted - not supported.", + "waf": "Operations" }, { - "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": "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": [ - "AzurePolicy", - "Firewall", - "ACR", - "RBAC" + "Storage", + "AVS", + "VM" ], "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" + "subcategory": "Storage", + "text": "VM with SCSI shared bus are not supported", + "waf": "Operations" }, { - "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": "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": [ - "Firewall" + "Storage", + "AVS", + "VM" ], - "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": "Medium", + "subcategory": "Storage", + "text": "VM with Direct IO require removing DirectPath device", + "waf": "Operations" }, { - "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": "VMware", + "checklist": "Azure VMware Solution Implementation Checklist", + "description": "Cannot migrate clusters ", + "guid": "efc8a311-74f8-0252-c6a0-4bac7610e266", + "id": "J04.04", + "link": "Contact VMware", "services": [ - "AzurePolicy", - "ACR", - "FrontDoor", - "WAF" + "Storage", + "AVS" ], "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" + "subcategory": "Storage", + "text": "Shared VMDK files are not supported", + "waf": "Operations" }, { - "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": "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": [ - "AppGW", - "FrontDoor", - "AzurePolicy", - "WAF" + "Storage", + "AVS" ], - "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": "Medium", + "subcategory": "Storage", + "text": "RDM with 'physical compatibility mode' are not supported.", + "waf": "Operations" }, { - "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": "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": [ - "VNet", - "WAF" + "Storage", + "AVS", + "VM", + "AzurePolicy" ], - "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" + "severity": "Medium", + "subcategory": "Storage", + "text": "Default storage policy", + "waf": "Operations" }, { - "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": "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": [ - "VNet", - "DDoS" + "Storage", + "AVS", + "VM", + "AzurePolicy" ], - "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" + "severity": "Medium", + "subcategory": "Storage", + "text": "Ensure that the appropriate VM template storage policy is used", + "waf": "Operations" }, { - "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": "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": [ - "Firewall", - "DNS" + "Storage", + "AVS", + "AzurePolicy" ], - "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" + "severity": "Medium", + "subcategory": "Storage", + "text": "Failure to tolerate policy", + "waf": "Operations" }, { - "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": "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": [ - "Firewall" + "Storage", + "AVS" ], - "severity": "High", - "subcategory": "Internet", - "text": "Use Azure Firewall Premium for additional security and protection.", - "waf": "Security" + "severity": "Medium", + "subcategory": "Storage", + "text": "Use ANF for external storage", + "waf": "Operations" }, { - "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": "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", "services": [ - "Firewall" + "ACR" ], "severity": "High", - "subcategory": "Internet", - "text": "Configure Azure Firewall Threat Intelligence mode to Alert and Deny for additional protection.", + "subcategory": "Data Protection", + "text": "Disable Azure Container Registry image export", "waf": "Security" }, { - "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": "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", "services": [ - "Firewall" + "ACR", + "AzurePolicy" ], "severity": "High", - "subcategory": "Internet", - "text": "Configure Azure Firewall IDPS mode to Deny for additional protection.", + "subcategory": "Data Protection", + "text": "Enable Azure Policies for Azure Container Registry", "waf": "Security" }, { - "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": "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", "services": [ - "Firewall", - "VWAN", - "Storage", - "VNet", - "NVA" + "ACR", + "AKV" ], "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", + "subcategory": "Data Protection", + "text": "Sign and Verify containers with notation (Notary v2)", "waf": "Security" }, { - "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": "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", "services": [ - "VNet" + "ACR", + "AKV" ], - "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", + "severity": "Medium", + "subcategory": "Data Protection", + "text": "Encrypt registry with a customer managed key", "waf": "Security" }, { - "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": "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": [ - "PrivateLink" + "ACR", + "RBAC", + "Entra" ], - "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/", + "severity": "High", + "subcategory": "Identity and Access Control", + "text": "Use Managed Identities to connect instead of Service Principals", "waf": "Security" }, { - "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": "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": [ - "PrivateLink", - "ExpressRoute" + "ACR", + "RBAC", + "Entra" ], - "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/", + "severity": "High", + "subcategory": "Identity and Access Control", + "text": "Disable local authentication for management plane access", "waf": "Security" }, { - "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": "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": [ - "VNet" + "ACR", + "RBAC", + "Entra" ], - "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", + "severity": "High", + "subcategory": "Identity and Access Control", + "text": "Assign AcrPull & AcrPush RBAC roles rather than granting Administrative access to identity principals", "waf": "Security" }, { - "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": "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": [ - "PrivateLink", - "NVA", - "Firewall", - "DNS" + "ACR", + "Entra" ], "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", + "subcategory": "Identity and Access Control", + "text": "Disable Anonymous pull access", "waf": "Security" }, { - "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": "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": [ - "Firewall", - "VNet" + "ACR", + "Entra" ], "severity": "High", - "subcategory": "Segmentation", - "text": "Use a /26 prefix for your Azure Firewall subnets.", + "subcategory": "Identity and Access Control", + "text": "Disable repository-scoped access tokens", "waf": "Security" }, { - "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": "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": [ - "VPN", - "VNet", - "ExpressRoute" + "ACR", + "PrivateLink", + "Entra", + "EventHubs" ], "severity": "High", - "subcategory": "Segmentation", - "text": "Use at least a /27 prefix for your Gateway subnets", + "subcategory": "Identity and Access Control", + "text": "Deploy images from a trusted environment", "waf": "Security" }, { - "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": "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": [ - "VNet" + "ACR", + "AzurePolicy", + "Entra" ], "severity": "Medium", - "subcategory": "Segmentation", - "text": "Don't rely on the NSG inbound default rules using the VirtualNetwork service tag to limit connectivity.", + "subcategory": "Identity and Access Control", + "text": "Disable Azure ARM audience tokens for authentication", "waf": "Security" }, { - "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": "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": [ - "VNet" + "ACR", + "Monitor", + "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/", + "subcategory": "Logging and Monitoring", + "text": "Enable diagnostics logging", "waf": "Security" }, { - "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": "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": [ "ACR", - "VNet" + "VNet", + "PrivateLink", + "Firewall" ], "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/", + "subcategory": "Network Security", + "text": "Control inbound network access with Private Link", "waf": "Security" }, { - "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": "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": [ - "VNet", - "VM" + "ACR", + "PrivateLink" ], "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/", + "subcategory": "Network Security", + "text": "Disable Public Network access", "waf": "Security" }, { - "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": "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": [ - "NVA", - "Entra", - "VNet" + "ACR", + "PrivateLink" ], "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/", + "subcategory": "Network Security", + "text": "Use an Azure Container Registry SKU that supports Private Link (Premium SKU)", "waf": "Security" }, { - "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": "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": [ - "NetworkWatcher", - "VNet" + "ACR", + "Defender" ], - "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/", + "severity": "Low", + "subcategory": "Network Security", + "text": "Enable Defender for Containers to scan Azure Container Registry for vulnerabilities", "waf": "Security" }, { - "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": "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": [ - "VWAN" + "ACR" ], "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" + "subcategory": "Vulnerability Management", + "text": "Deploy validated container images", + "waf": "Security" }, { - "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": "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": [ - "ACR", - "VWAN" + "ACR" ], - "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" + "severity": "High", + "subcategory": "Vulnerability Management", + "text": "Use up-to-date platforms, languages, protocols and frameworks", + "waf": "Security" }, { - "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": "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": [ - "ACR", - "VWAN" + "EventHubs" ], "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" + "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": "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": "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": [ - "Firewall", - "VWAN" + "EventHubs" ], "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" + "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": "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": "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": [ - "VWAN" + "TrafficManager", + "AzurePolicy", + "EventHubs", + "RBAC", + "Entra" ], "severity": "Medium", - "subcategory": "Virtual WAN", - "text": "Ensure that the network architecture is within the Azure Virtual WAN limits.", - "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": "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": "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", "services": [ - "Monitor", - "VWAN" + "Storage", + "AKV", + "VM", + "EventHubs", + "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" + "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": "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": "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", "services": [ - "VWAN" + "EventHubs", + "RBAC", + "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": "Identity and Access Management", + "text": "Use least privilege data plane RBAC", + "training": "https://learn.microsoft.com/learn/modules/explore-basic-services-identity-types/" }, { - "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": "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", "services": [ - "VPN", - "VWAN", - "ExpressRoute" + "EventHubs", + "VNet", + "Monitor" ], "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": "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": "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": "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", "services": [ - "VWAN" + "EventHubs", + "VNet", + "PrivateLink" ], "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": "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/" }, { - "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": "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", "services": [ - "VWAN" + "EventHubs" ], - "severity": "High", - "subcategory": "Virtual WAN", - "text": "Assign enough IP space to virtual hubs, ideally a /23 prefix.", - "waf": "Reliability" + "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/" }, { - "ammp": true, - "category": "Network topology and connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "2e30abab-5478-417c-81bf-bf1ad4ed1ed4", - "id": "D10.01", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-end-to-end-tls", + "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": [ - "FrontDoor" + "RBAC", + "Entra" ], "severity": "High", - "subcategory": "App delivery", - "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.", + "subcategory": "Identity", + "text": "Create a service principal and its role assignments before creating the ARO clusters.", "waf": "Security" }, { - "category": "Network topology and connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "10aa45af-166f-44c4-9f36-b6d592dac2ca", - "id": "D10.02", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-http-to-https-redirection", + "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": [ - "FrontDoor" + "Entra" ], - "severity": "Medium", - "subcategory": "App delivery", - "text": "Use HTTP to HTTPS redirection with Azure Front Door. Support older clients by redirecting them to an HTTPS request automatically.", + "severity": "High", + "subcategory": "Identity", + "text": "Use AAD to authenticate users in your ARO cluster.", "waf": "Security" }, { - "ammp": true, - "category": "Network topology and connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "28b9ee82-b2c7-45aa-bc98-6de6f59a095d", - "id": "D10.03", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#enable-the-waf", + "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.03", + "link": "https://docs.openshift.com/container-platform/4.13/applications/projects/working-with-projects.html", "services": [ - "FrontDoor", - "WAF" + "RBAC", + "Entra" ], "severity": "High", - "subcategory": "App delivery", - "text": "Enable the Azure Front Door WAF. Protect your application from a range of attacks.", + "subcategory": "Identity", + "text": "Define OpenShift projects to restrict RBAC privilege and isolate workloads in your cluster.", "waf": "Security" }, { - "ammp": true, - "category": "Network topology and connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "2902d8cc-1b0c-4495-afad-624ab70f7bd6", - "id": "D10.04", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#tune-your-waf", + "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.04", + "link": "https://docs.openshift.com/container-platform/4.13/authentication/using-rbac.html", "services": [ - "FrontDoor", - "WAF" + "RBAC", + "Entra" ], - "severity": "High", - "subcategory": "App delivery", - "text": "Tune the Azure Front Door WAF for your workload. Reduce false positive detections.", + "severity": "Medium", + "subcategory": "Identity", + "text": "Define the required RBAC roles in OpenShift are scoped to either a project or a cluster.", "waf": "Security" }, { - "ammp": true, - "category": "Network topology and connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "17ba124b-127d-42b6-9322-388d5b2bbcfc", - "id": "D10.05", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-prevention-mode", + "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.05", + "link": "https://learn.microsoft.com/azure/cost-management-billing/manage/direct-ea-administration#manage-notification-contacts", "services": [ - "FrontDoor", - "WAF" + "AKV", + "Entra" ], - "severity": "High", - "subcategory": "App delivery", - "text": "Use prevention mode with the Azure Front Door WAF. Prevention mode ensures that the WAF blocks malicious requests.", + "severity": "Medium", + "subcategory": "Identity", + "text": "Minimize the number of users who have administrator rights and secrets access.", "waf": "Security" }, { - "ammp": true, - "category": "Network topology and connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "49a98f2b-ec22-4a87-9415-6a10b00d6555", - "id": "D10.06", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#enable-default-rule-sets", + "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.06", + "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-configure", "services": [ - "FrontDoor", - "WAF" + "RBAC", + "Entra" ], - "severity": "High", - "subcategory": "App delivery", - "text": "Enable the Azure Front Door WAF default rule sets. The default rule sets detect and block common attacks.", + "severity": "Medium", + "subcategory": "Identity", + "text": "Use Privileged Identity Management in AAD for ARO users with privileged roles.", "waf": "Security" }, { - "ammp": true, "category": "Network topology and connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "147a13d4-2a2f-4824-a524-f5855b52b946", - "id": "D10.07", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#enable-bot-management-rules", + "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": [ - "FrontDoor", - "WAF" + "Firewall", + "Subscriptions", + "VNet", + "WAF", + "DDoS", + "Entra" ], + "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": "App delivery", - "text": "Enable the Azure Front Door WAF bot management rules. The bot rules detect good and bad bots.", + "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": "Network topology and connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "d7dcdcb9-0d99-44b9-baab-ac7570ede79a", - "id": "D10.08", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-the-latest-ruleset-versions", + "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": [ - "FrontDoor", - "WAF" + "WAF", + "FrontDoor" ], "severity": "Medium", - "subcategory": "App delivery", - "text": "Use the latest Azure Front Door WAF ruleset versions. Ruleset updates are regularly updated to take account of the current threat landscape.", + "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": "Network topology and connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "b9620385-1cde-418f-914b-a84a06982ffc", - "id": "D10.09", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#add-rate-limiting", + "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": [ - "FrontDoor", - "WAF" + "PrivateLink", + "FrontDoor" ], "severity": "Medium", - "subcategory": "App delivery", - "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.", + "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": "Network topology and connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "6dc36c52-0124-4ffe-9eaf-23ec1282dedb", - "id": "D10.10", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-a-high-threshold-for-rate-limits", + "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": [ - "FrontDoor", - "WAF" + "Firewall", + "AzurePolicy", + "NVA" ], "severity": "Medium", - "subcategory": "App delivery", - "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. ", + "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": "Network topology and connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "388a3d0e-0a43-4367-90b2-3dd2aeece5ee", - "id": "D10.11", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#geo-filter-traffic", + "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": [ - "FrontDoor", - "WAF" + "AzurePolicy" ], - "severity": "Low", - "subcategory": "App delivery", - "text": "Geo-filter traffic by using the Azure Front Door WAF. Allow traffic only from expected regions, and block traffic from other regions.", + "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" }, { "category": "Network topology and connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "00acd8a9-6975-414f-8491-2be6309893b8", - "id": "D10.12", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#specify-the-unknown-zz-location", + "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": [ - "FrontDoor", - "WAF" + "ACR", + "PrivateLink" ], "severity": "Medium", - "subcategory": "App delivery", - "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.", + "subcategory": "Private access", + "text": "Use Azure Private Link to secure network connections to managed Azure services, including to Azure Container Registry.", "waf": "Security" }, { - "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": "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": [ - "AzurePolicy" + "Monitor" ], "severity": "High", - "subcategory": "Governance", - "text": "Leverage Azure Policy strategically, define controls for your environment, using Policy Initiatives to group related policies.", - "waf": "Security" + "subcategory": "Operations", + "text": "Establish a monitoring process using the inbuilt Prometheus, OpenShift Logging or Container Insights integration.", + "waf": "Operations" }, { - "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": [ - "AzurePolicy" - ], + "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": "Governance", - "text": "Identify required Azure tags and use the 'append' policy mode to enforce usage via Azure Policy.", - "waf": "Security" + "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": "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": [ - "AzurePolicy", - "RBAC" - ], - "severity": "Medium", - "subcategory": "Governance", - "text": "Map regulatory and compliance requirements to Azure Policy definitions and Azure role assignments.", - "waf": "Security" + "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/active-directory-domain-services/overview", + "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": "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": "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": [ - "Subscriptions", - "AzurePolicy" + "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": "Governance", - "text": "Establish Azure Policy definitions at the intermediate root management group so that they can be assigned at inherited scopes", - "waf": "Security" + "subcategory": "Performance", + "text": "Use pod requests and limits to manage the compute resources within a cluster.", + "waf": "Performance" }, { - "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": [ - "AzurePolicy" - ], + "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": "Governance", - "text": "Manage policy assignments at the highest appropriate level with exclusions at bottom levels, if required.", - "waf": "Security" + "subcategory": "Performance", + "text": "Enforce resource quotas on projects.", + "waf": "Performance" }, { - "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": "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": "Performance", + "text": "Define ClusterAutoScaler and MachineAutoScaler to scale machines when your cluster runs out of resources to support more deployments.", + "waf": "Performance" + }, + { + "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": [ - "Subscriptions", - "AzurePolicy" + "VM" ], - "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": "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": "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": "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": "Reliability", + "text": "Deploy machine health checks to automatically repair damaged machines in a machine pool.", + "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", "services": [ - "AzurePolicy" + "Monitor" ], - "severity": "Medium", - "subcategory": "Governance", - "text": "Use built-in policies where possible to minimize operational overhead.", - "waf": "Security" + "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.", + "waf": "Reliability" }, { - "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": "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": "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": "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": [ - "AzurePolicy", - "RBAC", - "Entra", - "Subscriptions" + "AKS" ], - "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": "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": "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": "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": [ - "Subscriptions", - "AzurePolicy" + "Backup" ], "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" + "subcategory": "Reliability", + "text": "Create application backup and plan for restore and include persistent volumes in the backup.", + "waf": "Reliability" }, { - "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": "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": "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": [ "AzurePolicy" ], - "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/", + "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" }, { - "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": "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": [ - "Cost", - "TrafficManager", - "VM" + "ACR" ], "severity": "Low", - "subcategory": "Optimize your cloud investment", - "text": "Consider using automation tags to start/stop VM's in your environment to save on cost.", + "subcategory": "Security", + "text": "Store your container images in Azure Container Registry and geo-replicate the registry to each region.", "waf": "Security" }, { - "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": [ - "VM" - ], - "severity": "Medium", - "subcategory": "Scalability", - "text": "Leverage Azure Virtual Machine Scale sets to scale in and out based on the load.", - "waf": "Reliability" + "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": "Workload", + "text": "Optimize the CPU and memory request values, and maximize the efficiency of the cluster resources using vertical pod autoscaler.", + "waf": "Performance" }, { - "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": "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": [ - "Monitor", - "TrafficManager", - "Cost" + "Monitor" ], "severity": "Medium", - "subcategory": "Optimize your cloud investment", - "text": "Configure 'Actual' and 'Forecasted' Budget Alerts.", - "waf": "Cost" + "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" }, { - "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": [ - "FrontDoor", - "WAF" - ], - "severity": "High", - "subcategory": "App delivery", - "text": "Add diagnostic settings to save your Azure Front Door WAF's logs. Regularly review the logs to check for attacks and for false positive detections.", - "waf": "Operations" + "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": "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": "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": [ - "FrontDoor", - "Sentinel" + "Cost" ], "severity": "Medium", - "subcategory": "App delivery", - "text": "Send Azure Front Door logs to Microsoft Sentinel. Detect attacks and integrate Front Door telemetry into your overall Azure environment.", - "waf": "Operations" + "subcategory": "Workload", + "text": "Use disruption budgets to ensure the required number of pod replicas exist to handle expected application load.", + "waf": "Reliability" }, { - "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", + "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": "Data Protection", - "text": "Consider cross-region replication in Azure for BCDR with paired regions", + "subcategory": "Workload", + "text": "Use pod topology constraints to automatically schedule pods on nodes throughout the cluster.", "waf": "Reliability" }, { - "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": "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": "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": "Control plane", + "text": "Keep your clusters on the latest OpenShift version to avoid potential security or upgrade issues.", + "waf": "Security" + }, + { + "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": [ - "Backup" + "AKS", + "Arc" ], - "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": "Control plane", + "text": "Connect Azure Red Hat OpenShift clusters to Azure Arc-enabled Kubernetes.", + "waf": "Security" }, { - "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": "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": "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": [ - "AzurePolicy", - "Monitor", - "Entra", - "RBAC" + "Defender", + "AKS", + "Arc" ], "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": "Posture", + "text": "Use Microsoft Defender for Containers supported via Arc-enabled Kubernetes to secure clusters, containers, and applications.", + "waf": "Security" }, { - "category": "Management", - "checklist": "Azure Landing Zone Review", - "guid": "e179b599-de0d-4597-9cd4-cd21b088137f", - "id": "F03.02", + "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": [ - "Monitor" + "AKV", + "AKS", + "Arc" ], "severity": "Medium", - "subcategory": "Monitoring", - "text": "Is the landing zone documented?", - "waf": "Operations" + "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": "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": [ - "Monitor", - "ARS" - ], + "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": "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": "Workload", + "text": "Secure pod access to resources. Provide the least number of permissions, and avoid using root or privileged escalation.", + "waf": "Security" }, { - "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": "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": [ "AzurePolicy", "Monitor" ], "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": "Workload", + "text": "Monitor and enforce configuration by using the Azure Policy Extension.", + "waf": "Security" }, { - "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": "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": [ - "AzurePolicy", - "Monitor", - "VM" + "Defender" ], - "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" + "severity": "High", + "subcategory": "Workload", + "text": "Scan your images for vulnerabilities with Microsoft Defender or any other image scanning solution.", + "waf": "Security" }, { - "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": "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": [ - "Monitor", - "VM" + "ACR", + "Subscriptions" ], - "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" + "severity": "Low", + "subcategory": "Workload", + "text": "Deploy a dedicated and private instance of Azure Container Registry to each landing zone subscription.", + "waf": "Security" }, { - "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": "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": [ - "NetworkWatcher", - "Monitor" + "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" + "severity": "Low", + "subcategory": "VM Scale Sets", + "text": "Enable automatic instance repairs for enhanced VM Scale Sets resiliency", + "waf": "Reliability" }, { - "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": "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": [ - "Monitor" + "Backup", + "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" + "severity": "High", + "subcategory": "Virtual Machines", + "text": "Consider Azure Backup to meet your resiliency requirements for Azure VMs", + "waf": "Reliability" }, { - "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": "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": [ - "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": "Virtual Machines", + "text": "Use Premium or Ultra disks for production VMs", + "waf": "Reliability" }, { - "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": "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": [ - "Monitor" + "VM" ], - "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": "Virtual Machines", + "text": "Ensure Managed Disks are used for all VMs", + "waf": "Reliability" }, { - "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": "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": [ - "Monitor" + "Storage", + "VM", + "SQL" ], "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" + "subcategory": "Virtual Machines", + "text": "Do not use the Temp disk for anything that is not acceptable to be lost", + "waf": "Reliability" }, { - "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": "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": [ - "Monitor" + "Storage", + "VM", + "ACR" ], "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": "Virtual Machines", + "text": "Leverage Availability Zones for your VMs in regions where they are supported", + "waf": "Reliability" }, { - "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": "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": [ - "Monitor", - "Entra", - "RBAC" + "VM" ], "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" + "subcategory": "Virtual Machines", + "text": "For regions that do not support Availability Zones deploy VMs into Availability Sets", + "waf": "Reliability" }, { - "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": "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": [ - "Monitor" + "VM", + "ASR" ], - "severity": "Medium", - "subcategory": "Monitoring", - "text": "Use Azure Monitor Logs for insights and reporting.", - "waf": "Operations" + "severity": "High", + "subcategory": "Virtual Machines", + "text": "Avoid running a production workload on a single VM", + "waf": "Reliability" }, { - "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": "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": [ - "Monitor", - "Storage" + "AVS", + "VM", + "ASR" ], - "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": "Virtual Machines", + "text": "For Azure and on-premises VMs (Hyper-V/Phyiscal/VMware) with low RTO requirements use Azure Site Recovery", + "waf": "Reliability" }, { - "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": "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": [ - "Monitor" + "VM" ], - "severity": "Medium", - "subcategory": "Monitoring", - "text": "Use Azure Monitor alerts for the generation of operational alerts.", - "waf": "Operations" + "severity": "Low", + "subcategory": "Virtual Machines", + "text": "Use Capacity Reservations for critical workloads that require guaranteed capacity", + "waf": "Reliability" }, { - "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": "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": [ - "Monitor" + "VM", + "ASR" ], "severity": "Medium", - "subcategory": "Monitoring", - "text": "Ensure that monitoring requirements have been assessed and that appropriate data collection and alerting configurations are applied", - "waf": "Operations" + "subcategory": "Virtual Machines", + "text": "Increase quotas in DR region before testing failover with ASR", + "waf": "Reliability" }, { - "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": "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": [ - "Monitor" + "VM" ], - "severity": "Medium", - "subcategory": "Monitoring", - "text": "Consider supported regions for linked Log Analytics workspace and automation accounts", - "waf": "Operations" + "severity": "Low", + "subcategory": "Virtual Machines", + "text": "Utilize Scheduled Events to prepare for VM maintenance", + "waf": "Reliability" }, { - "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": "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": [ - "AzurePolicy", - "VM" + "Storage" ], "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" + "subcategory": "Storage Accounts", + "text": "Choose the most appropriate data redundancy option for Azure Storage based on your requirements", + "waf": "Reliability" }, { - "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": "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": [ - "AzurePolicy", - "Monitor", - "VM" + "Storage" ], - "severity": "Medium", - "subcategory": "Operational compliance", - "text": "Monitor VM security configuration drift via Azure Policy.", - "waf": "Security" + "severity": "Low", + "subcategory": "Storage Accounts", + "text": "Apply a Delete lock to prevent accidental or malicious deletion of storage accounts", + "waf": "Reliability" }, { - "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": "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": [ - "ASR", - "ACR", - "VM" + "Storage" ], - "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": "Low", + "subcategory": "Storage Accounts", + "text": "Enable soft delete for Storage Account Containers", + "waf": "Reliability" }, { - "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": "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": [ - "ASR" + "Storage" ], - "severity": "Medium", - "subcategory": "Protect and Recover", - "text": "Ensure to use and test native PaaS service disaster recovery capabilities.", - "waf": "Operations" + "severity": "Low", + "subcategory": "Storage Accounts", + "text": "Enable soft delete for blobs", + "waf": "Reliability" }, { - "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": "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": [ "Backup" ], "severity": "Medium", - "subcategory": "Protect and Recover", - "text": "Use Azure-native backup capabilities, or an Azure-compatible, 3rd-party backup solution.", - "waf": "Operations" + "subcategory": "Backup", + "text": "Enable Azure Backup enhanced soft delete for improved data protection and recovery", + "waf": "Reliability" }, { - "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": "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": [ - "VM" + "Backup" ], - "severity": "High", - "subcategory": "Fault Tolerance", - "text": "Leverage Availability Zones for your VMs in regions where they are supported.", + "severity": "Low", + "subcategory": "Backup", + "text": "Implement multi-user authorization for Azure Backup to ensure secure and controlled access to backup resources", "waf": "Reliability" }, { - "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": "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": [ - "VM" + "Backup", + "Storage" ], - "severity": "High", - "subcategory": "Fault Tolerance", - "text": "Avoid running a production workload on a single VM.", + "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 ", - "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": "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": [ - "AppGW", - "ACR", - "LoadBalancer" + "ASR" ], - "severity": "Medium", - "subcategory": "Fault Tolerance", - "text": "Azure Load Balancer and Application Gateway distribute incoming network traffic across multiple resources.", + "severity": "High", + "subcategory": "Design", + "text": "Define business continuity and disaster recovery requirements", "waf": "Reliability" }, { - "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", + "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": "Medium", - "subcategory": "Access control", - "text": "Determine the incident response plan for Azure services before allowing it into production.", - "waf": "Security" + "severity": "High", + "subcategory": "Design", + "text": "Implement reliability best practices in Azure architectures", + "waf": "Reliability" }, { - "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": [], + "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": [ + "ASR", + "RBAC" + ], "severity": "Medium", - "subcategory": "Access control", - "text": "Implement a zero-trust approach for access to the Azure platform, where appropriate.", - "waf": "Security" + "subcategory": "DevOps", + "text": "Implement Infrastructure as Code (IaC) for Rapid Infrastructure Recovery", + "waf": "Reliability" }, { - "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": "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": [ - "AKV" + "ASR" ], - "severity": "High", - "subcategory": "Encryption and keys", - "text": "Use Azure Key Vault to store your secrets and credentials", - "waf": "Security" + "severity": "Medium", + "subcategory": "Multi-region", + "text": "Plan for cross-region recovery by leveraging region pairs", + "waf": "Reliability" }, { - "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": "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": [ - "AKV" + "AppGW" ], "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" - }, + "subcategory": "Application Gateways", + "text": "Deploy Application Gateways with a minimum instance count of 2 to avoid instance provisioning downtime", + "waf": "Reliability" + }, { - "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": "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": [ - "AzurePolicy", - "AKV" + "AppGW", + "Storage" ], - "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": "Application Gateways", + "text": "Deploy Azure Application Gateway v2 for zone redundancy support", + "waf": "Reliability" }, { - "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": "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": [ - "RBAC", - "Entra", - "AKV" + "FrontDoor" ], - "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": "Low", + "subcategory": "Azure Front Door", + "text": "Consider a redundant traffic management solution in conjunction with Azure Front Door", + "waf": "Reliability" }, { - "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": "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": [ - "AKV" + "DNS", + "TrafficManager", + "ASR", + "Monitor" ], - "severity": "Medium", - "subcategory": "Encryption and keys", - "text": "Automate the certificate management and renewal process with public certificate authorities to ease administration.", - "waf": "Security" + "severity": "Low", + "subcategory": "DNS", + "text": "Plan for automated failover using Traffic Manager for DNS Traffic", + "waf": "Reliability" }, { - "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": "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": [ - "AKV" + "DNS", + "ACR", + "ASR" ], - "severity": "Medium", - "subcategory": "Encryption and keys", - "text": "Establish an automated process for key and certificate rotation.", - "waf": "Security" + "severity": "Low", + "subcategory": "DNS", + "text": "Implement DNS Failover using Azure DNS Private Resolvers", + "waf": "Reliability" }, { - "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": "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": [ - "PrivateLink", - "VNet", - "AKV" + "ACR" ], "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" + "subcategory": "Data Gateways", + "text": "Use on-premises data gateway clusters to ensure high availability for business-critical data", + "waf": "Reliability" }, { - "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": "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": [ - "Monitor", - "Entra", - "AKV" + "ExpressRoute" ], "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" + "subcategory": "ExpressRoute", + "text": "Ensure redundancy within both the partner network and customer network when utilizing ExpressRoute for high availability", + "waf": "Reliability" }, { - "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": "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", - "AKV" + "Backup", + "ExpressRoute" ], "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" + "subcategory": "ExpressRoute", + "text": "When using multiple ExpressRoute circuits ensure that routing allows for a primary and backup", + "waf": "Reliability" }, { - "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": "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": [ - "AKV" + "Backup", + "ExpressRoute", + "Cost", + "VPN" ], - "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": "Low", + "subcategory": "ExpressRoute", + "text": "Consider deploying site-to-site VPN as a backup for your ExpressRoute private peering", + "waf": "Reliability" }, { - "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": "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": [ - "AKV" + "LoadBalancer" ], "severity": "Medium", - "subcategory": "Encryption and keys", - "text": "Use an Azure Key Vault per application per environment per region.", - "waf": "Security" + "subcategory": "Load Balancers", + "text": "Leverage the Standard SKU for Load Balancers that handle traffic to production applications", + "waf": "Reliability" }, { - "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": "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": [ - "ASR", - "ACR", - "AKV" + "LoadBalancer", + "VM" ], - "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": "Low", + "subcategory": "Load Balancers", + "text": "For load balancers, consider using a zone-redundant frontend with multiple zonal resources in the backend", + "waf": "Reliability" }, { - "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": "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": [ - "Entra" + "LoadBalancer", + "Monitor" ], - "severity": "Medium", - "subcategory": "Operations", - "text": "Use Microsoft Entra ID reporting capabilities to generate access control audit reports.", - "waf": "Security" + "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": "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": "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": [ - "Monitor", - "Storage", - "ARS" + "NVA" ], - "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" + "severity": "High", + "subcategory": "NVAs", + "text": "Deploy Network Virtual Appliances (NVAs) in a vendor supported configuration for High Availability", + "waf": "Reliability" + }, + { + "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": [ + "ACR", + "VPN" + ], + "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" + }, + { + "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": [ + "VPN" + ], + "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" }, { - "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", + "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": [ - "Subscriptions", - "Defender" + "Storage" ], - "severity": "High", - "subcategory": "Operations", - "text": "Enable Defender Cloud Security Posture Management for all subscriptions.", + "severity": "Medium", + "subcategory": " Overview", + "text": "Consider the 'Azure security baseline for storage'", "waf": "Security" }, { - "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", + "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": [ - "Subscriptions", - "Defender" + "Storage", + "PrivateLink" ], "severity": "High", - "subcategory": "Operations", - "text": "Enable a Defender Cloud Workload Protection Plan for Servers on all subscriptions.", + "subcategory": "Networking", + "text": "Consider using private endpoints for Azure Storage", "waf": "Security" }, { - "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", + "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": [ + "Storage", "Subscriptions", - "Defender" + "RBAC" ], - "severity": "High", - "subcategory": "Operations", - "text": "Enable Defender Cloud Workload Protection Plans for Azure Resources on all subscriptions.", + "severity": "Medium", + "subcategory": "Governance", + "text": "Ensure older storage accounts are not using 'classic deployment model'", "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": [], + "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": [ + "Storage", + "Defender" + ], "severity": "High", - "subcategory": "Operations", - "text": "Enable Endpoint Protection on IaaS Servers.", + "subcategory": "Governance", + "text": "Enable Microsoft Defender for all of your storage accounts", "waf": "Security" }, { "category": "Security", - "checklist": "Azure Landing Zone Review", - "guid": "15833ee7-ad6c-46d3-9331-65c7acbe44ab", - "id": "G03.07", - "link": "https://learn.microsoft.com/azure/security-center/", + "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": [ - "Defender", - "Monitor" + "Storage" ], "severity": "Medium", - "subcategory": "Operations", - "text": "Monitor base operating system patching drift via Azure Monitor Logs and Defender for Cloud.", + "subcategory": "Data Availability", + "text": "Enable 'soft delete' for blobs", "waf": "Security" }, { "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", + "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": [ - "Monitor", - "Entra" + "Storage" ], "severity": "Medium", - "subcategory": "Operations", - "text": "Connect default resource configurations to a centralized Azure Monitor Log Analytics workspace.", + "subcategory": "Confidentiality", + "text": "Disable 'soft delete' for blobs", "waf": "Security" }, { - "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", + "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": [ "Storage" ], "severity": "High", - "subcategory": "Overview", - "text": "Secure transfer to storage accounts should be enabled", + "subcategory": "Data Availability", + "text": "Enable 'soft delete' for containers", "waf": "Security" }, { - "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", + "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": [ "Storage" ], - "severity": "High", - "subcategory": "Overview", - "text": "Enable container soft delete for the storage account to recover a deleted container and its contents.", + "severity": "Medium", + "subcategory": "Confidentiality", + "text": "Disable 'soft delete' for containers", "waf": "Security" }, { - "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", + "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": [ - "Entra" + "Storage" ], "severity": "High", - "subcategory": "Secure privileged access", - "text": "Separate privileged admin accounts for Azure administrative tasks.", + "subcategory": "Data Availability", + "text": "Enable resource locks on storage accounts", "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", + "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": [ + "Storage", + "AzurePolicy", + "Subscriptions" + ], + "severity": "High", + "subcategory": "Data Availability, Compliance", + "text": "Consider immutable blobs", "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", + "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": [ + "Storage" + ], + "severity": "High", + "subcategory": "Networking", + "text": "Require HTTPS, i.e. disable port 80 on the storage account", "waf": "Security" }, { - "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": "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": [ + "Storage" + ], "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" + "subcategory": "Networking", + "text": "When enforcing HTTPS (disabling HTTP), check that you do not use custom domains (CNAME) for the storage account.", + "waf": "Security" }, { - "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": "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": [ + "Storage" + ], + "severity": "Medium", + "subcategory": "Networking", + "text": "Limit shared access signature (SAS) tokens to HTTPS connections only", + "waf": "Security" }, { - "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": "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": [ - "RBAC" + "Storage", + "Entra" ], - "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" + "severity": "High", + "subcategory": "Identity and Access Management", + "text": "Use Azure Active Directory (Azure AD) tokens for blob access", + "waf": "Security" }, { - "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": [], + "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": [ + "Storage", + "RBAC", + "Entra" + ], + "severity": "Medium", + "subcategory": "Identity and Access Management", + "text": "Least privilege in IaM permissions", + "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", + "services": [ + "Storage", + "Entra" + ], "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": "Identity and Access Management", + "text": "When using SAS, prefer 'user delegation SAS' over storage-account-key based SAS.", + "waf": "Security" }, { - "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": "DevOps Team Topologies", - "text": "Include unit tests for IaC and application code as part of your build process.", - "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", + "services": [ + "Storage", + "AKV", + "Monitor", + "Entra" + ], + "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" }, { - "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": "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": [ + "Storage", "AKV", - "VM" + "AzurePolicy", + "Monitor" ], "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" + "subcategory": "Monitoring", + "text": "Consider using Azure Monitor to audit control plane operations on the storage account", + "waf": "Security" }, { - "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": "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": [ - "Storage" + "Storage", + "AKV", + "AzurePolicy", + "Entra" ], - "severity": "Low", - "subcategory": "DevOps Team Topologies", - "text": "Implement automation for File > New > Landing Zone for applications and workloads.", - "waf": "Operations" + "severity": "Medium", + "subcategory": "Identity and Access Management", + "text": "When using storage account keys, consider enabling a 'key expiration policy'", + "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": [], + "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": [ + "Storage", + "AzurePolicy", + "Entra" + ], + "severity": "Medium", + "subcategory": "Identity and Access Management", + "text": "Consider configuring an SAS expiration policy", + "waf": "Security" + }, + { + "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": [ + "Storage", + "AKV", + "AzurePolicy", + "Entra" + ], + "severity": "Medium", + "subcategory": "Identity and Access Management", + "text": "Consider linking SAS to a stored access policy", + "waf": "Security" + }, + { + "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": [ + "Storage", + "AKV" + ], + "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" + }, + { + "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": [ + "Storage", + "Entra" + ], "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" + "subcategory": "Identity and Access Management", + "text": "Consider storing connection strings in Azure KeyVault (in scenarios where managed identities are not possible)", + "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": [], + "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": [ + "Storage", + "AzurePolicy", + "Entra" + ], + "severity": "High", + "subcategory": "Identity and Access Management", + "text": "Strive for short validity periods for ad-hoc SAS", + "waf": "Security" + }, + { + "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": [ + "Storage", + "Entra" + ], + "severity": "Medium", + "subcategory": "Identity and Access Management", + "text": "Apply a narrow scope to a SAS", + "waf": "Security" + }, + { + "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": [ + "Storage", + "Entra" + ], + "severity": "Medium", + "subcategory": "Identity and Access Management", + "text": "Consider scoping SAS to a specific client IP address, wherever possible", + "waf": "Security" + }, + { + "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": [ + "Storage", + "Entra" + ], "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" + "subcategory": "Identity and Access Management", + "text": "Consider checking uploaded data, after clients used a SAS to upload a file. ", + "waf": "Security" }, { - "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": [], + "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": [ + "Storage", + "RBAC", + "Entra" + ], + "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": "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": [ + "Storage", + "Entra" + ], "severity": "Medium", - "subcategory": "Development Lifecycle", - "text": "Adopt a pull request strategy to help keep control of code changes merged into branches.", - "waf": "Operations" + "subcategory": "Identity and Access Management", + "text": "SFTP: The SFTP endpoint does not support POSIX-like ACLs.", + "waf": "Security" }, { - "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": "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": [ + "Storage", + "AzurePolicy" + ], "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" + "subcategory": "Networking", + "text": "Avoid overly broad CORS policies", + "waf": "Security" + }, + { + "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": [ + "Storage" + ], + "severity": "High", + "subcategory": "Confidentiality and Encryption", + "text": "Determine how data at rest should be encrypted. Understand the thread model for data.", + "waf": "Security" + }, + { + "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": [ + "Storage" + ], + "severity": "Medium", + "subcategory": "Confidentiality and Encryption", + "text": "Determine which/if platform encryption should be used.", + "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": [], + "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": [ + "Storage", + "Entra" + ], "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" + "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": "Management", - "checklist": "Azure API Management Review", - "guid": "06862505-2d9a-4874-9491-2837b00a3475", - "link": "https://learn.microsoft.com/azure/api-management/backends", + "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": [ - "APIM" + "Cost", + "Monitor" ], - "severity": "Medium", - "subcategory": "Best practices", - "text": "Use Backends feature to eliminate redundant API backend configurations" + "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": "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": "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": [ - "AzurePolicy", - "APIM" + "Backup", + "Cost" ], - "severity": "Medium", - "subcategory": "Best practices", - "text": "Use Named Values to store common values that can be used in policies" + "subcategory": "Backup", + "text": "check backup instances with the underlying datasource not found" }, { - "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": "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": [ - "ASR", - "APIM" + "Cost" ], - "severity": "Medium", - "subcategory": "Business continuity and disaster recovery", - "text": "Deploy to multiple Azure regions" + "subcategory": "delete/archive", + "text": "delete or archive unassociated services (disks, nics, ip addresses etc)" }, { - "category": "Management", - "checklist": "Azure API Management Review", - "guid": "9c8d1664-dd9a-49d4-bd83-950af0af4044", - "link": "https://learn.microsoft.com/azure/api-management/high-availability", + "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": [ - "ASR", - "APIM" + "Cost" ], - "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" + "subcategory": "delete/archive", + "text": "consider snooze and stop technique (snooze a service after x days, stop after 2x, delete/deallocate after 3x)" }, { - "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": "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": [ "Backup", - "APIM", - "ASR" + "Storage", + "Cost" ], - "severity": "High", - "subcategory": "Business continuity and disaster recovery", - "text": "Ensure there is an automated backup routine" + "subcategory": "delete/archive", + "text": "delete or archive unused resources (old backups, logs, storage accounts, etc...)" }, { - "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": "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": [ - "AzurePolicy", - "APIM" + "Backup", + "Storage", + "Cost", + "ASR" ], - "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": "delete/archive", + "text": "consider a good balance between site recovery storage and backup for non mission critical applications" }, { - "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": "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": [ - "AzurePolicy", - "APIM", - "EventHubs" + "Cost", + "Monitor" ], - "severity": "Low", - "subcategory": "Performance and scalability", - "text": "If you need to log at high performance levels, consider Event Hubs policy" + "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": "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": "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": [ - "AzurePolicy", - "APIM" + "Storage", + "Cost", + "AzurePolicy" ], - "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": "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": "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": "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": [ - "APIM" + "Cost" ], - "severity": "Medium", - "subcategory": "Performance and scalability", - "text": "Configure autoscaling to scale out the number of instances when the load increases" + "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": "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": "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": [ - "APIM" + "Cost" ], - "severity": "Medium", - "subcategory": "Performance and scalability", - "text": "Deploy self-hosted gateways where Azure doesn't have a region close to the backend APIs." + "subcategory": "shutdown/deallocate", + "text": "shutdown underutilized instances", + "training": "https://learn.microsoft.com/azure/cost-management-billing/understand/analyze-unexpected-charges" }, { - "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": "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": [ - "AzurePolicy", - "APIM" + "Backup", + "Storage", + "Cost", + "VM" ], - "severity": "Medium", - "subcategory": "Development best practices", - "text": "Implement an error handling policy at the global level" + "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": "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": "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": [ - "AzurePolicy", - "APIM" + "Storage", + "Cost", + "AzurePolicy" ], - "severity": "Medium", - "subcategory": "Development best practices", - "text": "Ensure all APIs policies include a element." + "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": "Governance", - "checklist": "Azure API Management Review", - "guid": "a5c45b03-93b6-42fe-b16b-8fccb6a79902", - "link": "https://learn.microsoft.com/azure/api-management/policy-fragments", + "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": [ - "AzurePolicy", - "APIM", - "ACR" + "Cost" ], - "severity": "Medium", - "subcategory": "Development best practices", - "text": "Use Policy Fragments to avoid repeating same policies definitions across multiple APIs" + "subcategory": "Tagging", + "text": "use specific tags for temporary items with 'delete by DATE' format - and automate monthly cleanup" }, { - "category": "Governance", - "checklist": "Azure API Management Review", - "guid": "c3818a95-6ff3-4474-88dc-e809b46dad6a", - "link": "https://learn.microsoft.com/azure/api-management/monetization-support", + "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": [ - "APIM" + "Cost" ], - "severity": "Medium", - "subcategory": "Monetization", - "text": "If you are planning to monetize your APIs, review the 'monetization support' article for best practices" + "subcategory": "db optimization", + "text": "plan for db optimization with the intent of downsizing the related services (and improve performance)" }, { - "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": "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": [ - "APIM", - "Monitor" + "Cost" ], - "severity": "High", - "subcategory": "Monitoring", - "text": "Enable Diagnostics Settings to export logs to Azure Monitor" + "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": "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": "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": [ - "APIM", - "Monitor" + "Storage", + "Cost", + "VM" ], - "severity": "Medium", - "subcategory": "Monitoring", - "text": "Enable Application Insights for more detailed telemetry" + "subcategory": "db optimization", + "text": "optimizing the DB queries will increase performance and allow better right-sizing of storage and VMs" }, { - "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": "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": [ - "APIM", - "Monitor" + "Cost" ], - "severity": "High", - "subcategory": "Monitoring", - "text": "Configure alerts on the most critical metrics" + "subcategory": "demand shaping", + "text": "using demand shaping on PaaS services will optimize costs and performances" }, { - "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": "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": [ - "APIM", - "Entra", - "AKV" + "Cost", + "Entra" ], - "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": "Advisor", + "text": "Start from the Azure Advisor page suggestions." }, { - "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": "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": [ - "APIM", - "Entra" + "Cost", + "VM" ], - "severity": "High", - "subcategory": "Identity", - "text": "Protect incoming requests to APIs (data plane) with Azure AD" + "subcategory": "Advisor", + "text": "make sure advisor is configured for VM right sizing " }, { - "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": "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": [ - "APIM", - "Entra" + "Cost" ], - "severity": "Medium", - "subcategory": "Identity", - "text": "Use Azure AD to authenticate users in the Developer Portal" + "subcategory": "Automation", + "text": "consider implementing IAC scripts or devops pipelines to match the cost governance process" }, { - "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": "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": [ - "APIM", - "Entra" + "Cost", + "Monitor" ], - "severity": "Medium", - "subcategory": "Privileged access", - "text": "Create appropriate groups to control the visibility of the products" + "subcategory": "Automation", + "text": "set up cost alerts for applications that have variable costs (ideally for all of them)" }, { - "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": "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": [ - "APIM", - "VNet" + "Cost" ], - "severity": "Medium", - "subcategory": "Security", - "text": "Deploy the service within a Virtual Network (VNET)" + "subcategory": "Automation", + "text": "Use Azure Automation: Automate repetitive tasks can help you save time and resources, reducing costs in the process. " }, { - "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": "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": [ - "APIM", - "VNet", - "Monitor" + "Cost" ], - "severity": "Medium", - "subcategory": "Security", - "text": "Deploy network security groups (NSG) to your subnets to restrict or monitor traffic" + "subcategory": "Automation", + "text": "run orphaned resources workbook" }, { - "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": "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": [ - "PrivateLink", - "APIM", - "VNet" + "Storage", + "Cost" ], - "severity": "Medium", - "subcategory": "Security", - "text": "Deploy Private Endpoints to filter incoming traffic when VNET is not used" + "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": "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": "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": [ - "APIM" + "Cost", + "AzurePolicy" ], - "severity": "High", - "subcategory": "Security", - "text": "Disable Public Network Access" + "subcategory": "Baseline", + "text": "establish a cost optimization baseline by using a policy that tags every new resource as #NEW" }, { - "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": "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": [ - "APIM", - "FrontDoor" + "Cost" ], - "severity": "Medium", - "subcategory": "Connectivity", - "text": "Use Azure Front Door for multi-region deployment" + "subcategory": "Baseline", + "text": "Organize resources to maximize cost insights and accountability" }, { - "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": "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": [ - "APIM" + "Cost" ], - "severity": "Medium", - "subcategory": "Automation", - "text": "Simplify management with PowerShell automation scripts" + "subcategory": "Budgets", + "text": "Create budgets" }, { - "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": "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": [ - "APIM", - "Entra" + "Cost" ], - "severity": "Medium", - "subcategory": "Best practices", - "text": "Review DevOps best practices from the Cloud Adaption Framework APIM Landing Zone Accelerator" + "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": "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": "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": [ - "APIM", - "Entra" + "Cost" ], - "severity": "Medium", - "subcategory": "Best practices", - "text": "Promote usage of Visual Studio Code APIM extension for faster API development" + "subcategory": "Cost Analysis", + "text": "check daily for cost spikes and anomalies (ideally with automatic billing exports)" }, { - "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": "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": [ - "APIM" + "Cost" ], - "severity": "Medium", - "subcategory": "DevOps", - "text": "Implement DevOps and CI/CD in your workflow" + "subcategory": "Cost Analysis", + "text": "automate cost retrieval for deep analysis or integration" }, { - "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": "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": [ - "APIM" + "ACR", + "Cost" ], - "severity": "Medium", - "subcategory": "APIs", - "text": "Secure APIs using client certificate authentication" + "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": "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": "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": [ - "APIM" + "Cost" ], - "severity": "Medium", - "subcategory": "APIs", - "text": "Secure backend services using client certificate authentication" + "subcategory": "Tagging", + "text": "Tag shared resources" }, { - "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": "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": [ - "APIM" + "Cost" ], - "severity": "Medium", - "subcategory": "APIs", - "text": "Review 'Recommendations to mitigate OWASP API Security Top 10 threats' article and check what is applicable to your APIs" + "subcategory": "Tagging", + "text": "consider using tags to all services for cost allocation" }, { - "category": "Security", - "checklist": "Azure API Management Review", - "guid": "5507c4b8-a7f8-41d6-9661-418c987100c9", - "link": "https://learn.microsoft.com/azure/api-management/authorizations-overview", + "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": [ - "APIM" + "Cost" ], - "severity": "Medium", - "subcategory": "APIs", - "text": "Use Authorizations feature to simplify management of OAuth 2.0 token for your backend APIs" + "subcategory": "automation", + "text": "consider Reservation automation to track and promptly react to changes" }, { - "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": "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": [ - "APIM" + "Cost", + "AzurePolicy", + "SQL", + "VM" ], - "severity": "High", - "subcategory": "Ciphers", - "text": "Use the latest TLS version when encrypting information in transit. Disable outdated and unnecessary protocols and ciphers when possible." + "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": "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": "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": [ - "APIM", - "AKV" + "Cost", + "LoadBalancer" ], - "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" + "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": "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": "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": [ - "APIM", - "Entra" + "Cost", + "AppSvc" ], - "severity": "Medium", - "subcategory": "Identities", - "text": "Use managed identities to authenticate to other Azure resources whenever possible" + "subcategory": "Functions", + "text": "saving plans will provide 17% on select app service plans" }, { - "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": "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": [ - "AppGW", - "APIM", - "Entra", - "WAF" + "Cost", + "VM" ], - "severity": "High", - "subcategory": "Network", - "text": "Use web application firewall (WAF) by deploying Application Gateway in front of APIM" + "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": "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", + "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": [ - "Arc" + "Cost", + "VM", + "ARS" ], - "severity": "High", - "subcategory": "Capacity Planning", - "text": "One or more resource groups is required for onboarding servers into Azure", - "waf": "Operations" + "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": "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", + "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": [ - "Entra", - "Arc" + "Cost" ], - "severity": "Medium", - "subcategory": "Capacity Planning", - "text": "Take Azure Active Directory object limitations into account", - "waf": "Performance" + "subcategory": "reservations/savings plans", + "text": "plan for Azure Savings Plans for all the workloads that are dynamic and need maximum flexibility" }, { - "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", + "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": [ - "Subscriptions", - "Arc" + "Cost" ], - "severity": "High", - "subcategory": "General", - "text": "Has the Resource providers required been registered in all subscriptions", - "waf": "Operations" + "subcategory": "reservations/savings plans", + "text": "plan for Azure Reservations for all the workloads that are less dynamic and won't change much" }, { - "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/", + "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": [ - "Arc" + "Storage", + "Cost" ], - "severity": "Low", - "subcategory": "General", - "text": "Has a tagging strategy for Azure Arc-enabled servers been defined", - "waf": "Cost" + "subcategory": "reserve storage", + "text": "only larger disks can be reserved =>1TiB -" }, { - "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", + "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": [ - "Arc" + "Cost", + "VM" ], - "severity": "High", - "subcategory": "General", - "text": "What operating systems need to be Azure Arc-enabled", - "waf": "Operations" + "subcategory": "reserve VMs with normalized and rationalized sizes", + "text": "after the right-sizing optimization" }, { - "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", + "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": [ - "Arc" + "Cost", + "AzurePolicy", + "SQL" ], - "severity": "High", - "subcategory": "General", - "text": "Are required software installed on Windows and Linux servers to support the installation", - "waf": "Operations" + "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": "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", + "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": [ - "Arc" + "Cost", + "VM", + "SQL" ], - "severity": "High", - "subcategory": "General", - "text": "Make sure to use a supported Azure region", - "waf": "Reliability" + "subcategory": "SQL Database Reservations", + "text": "the VM + licence part discount (ahub+3YRI) is around 70% discount" }, { - "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": "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": [ - "Subscriptions", - "Arc" + "Cost" ], - "severity": "Low", - "subcategory": "Organization", - "text": "Define the structure for Azure management of resources", - "waf": "Performance" + "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": "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": "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": [ - "RBAC", - "Entra", - "Arc" + "Cost", + "AzurePolicy" ], - "severity": "Medium", - "subcategory": "Access", - "text": "Assign RBAC rights to Azure AD user/group access for managing Azure Arc-enabled servers", - "waf": "Security" + "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": "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": "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": [ - "Entra", - "Arc", - "AKV" + "Cost", + "AzurePolicy" ], - "severity": "Low", - "subcategory": "Access", - "text": "Consider using managed identities for applications to access Azure resources like Key Vault example in link", - "waf": "Security" + "subcategory": "Automation", + "text": "plan and enforce a ON/OFF policy for production services, where possible" }, { - "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": "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": [ - "Subscriptions", - "Entra", - "Arc" + "Cost", + "AzurePolicy" ], - "severity": "High", - "subcategory": "Requirements", - "text": "An Azure Active Directory tenant must be available with at least one subscription", - "waf": "Operations" + "subcategory": "Automation", + "text": "plan and enforce a ON-DEMAND policy with auto-shutdown for non-production services, where possible" }, { - "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", + "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": [ - "RBAC", - "Entra", - "Arc" + "Cost", + "VM" ], - "severity": "Medium", - "subcategory": "Requirements", - "text": "Define which users (AAD user/groups) has access to onboard Azure Arc-enabled servers", - "waf": "Security" + "subcategory": "Autoscale", + "text": "consider using a VMSS to match demand rather than flat sizing" }, { - "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", + "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": [ - "RBAC", - "Entra", - "Arc" + "Cost", + "AKS" ], - "severity": "Medium", - "subcategory": "Security", - "text": "Use the principle of least privileged", - "waf": "Security" + "subcategory": "Autoscale", + "text": "use AKS autoscaler to match your clusters usage (make sure the pods requirements match the scaler)" }, { - "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": "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": [ - "RBAC", - "Entra", - "Arc" + "Cost" ], - "severity": "Medium", - "subcategory": "Security", - "text": "How many Service Principals are needed for onboarding Arc-enabled servers into Azure", - "waf": "Security" + "subcategory": "Autoscale", + "text": "right-size PaaS service according to average use and accomodate spikes with auto or manual scaling" }, { - "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": "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": [ - "RBAC", - "Entra", - "Arc" + "Cost" ], - "severity": "Medium", - "subcategory": "Security", - "text": "Limit the rights to onboard Azure Arc-enabled servers to the desired resource groups", - "waf": "Security" + "subcategory": "Autoscale", + "text": "plan for demand shaping where applicable" }, { - "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": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "e2e8aaab-3571-4549-ab91-53d89f89dc7b", + "id": "E02.05", "services": [ - "Monitor", - "Arc" + "Cost" ], - "severity": "Medium", - "subcategory": "Management", - "text": "Define a strategy for agent provisioning", - "waf": "Operations" + "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": "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": "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": [ - "Monitor", - "Arc" + "Backup", + "Cost" ], - "severity": "High", - "subcategory": "Management", - "text": "Define a strategy for agent updates", - "waf": "Operations" + "subcategory": "Backup", + "text": "Move recovery points to vault-archive where applicable (Validate)", + "training": "https://azure.microsoft.com/pricing/reservations/" }, { - "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": "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": [ - "AzurePolicy", - "Monitor", - "Arc" + "Cost", + "LoadBalancer", + "VM" ], - "severity": "Medium", - "subcategory": "Management", - "text": "Define a strategy for extension installation", - "waf": "Operations" + "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": "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": "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": [ - "Monitor", - "Arc" + "Cost" ], - "severity": "High", - "subcategory": "Management", - "text": "Define a strategy for extension updates", - "waf": "Operations" + "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": "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": "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": [ - "Monitor", - "Arc" + "Cost" ], - "severity": "Medium", - "subcategory": "Management", - "text": "Consider using Azure Automanage to control settings and avoid configuration drift on servers", - "waf": "Operations" + "subcategory": "Functions", + "text": "functions -Cache data locally", + "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-compute-resources/" }, { - "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": "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": [ - "Monitor", - "Arc" + "Storage", + "Cost" ], - "severity": "High", - "subcategory": "Monitoring", - "text": "Monitor for unresponsive agents", - "waf": "Operations" + "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": "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": "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": [ - "Monitor", - "Arc" + "Cost" ], - "severity": "Medium", - "subcategory": "Monitoring", - "text": "Design a monitoring strategy to send metrics and logs to an Log Analytics workspace", - "waf": "Operations" + "subcategory": "Functions", + "text": "Functions -Keep your functions warm", + "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/" }, { - "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": "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": [ - "Monitor", - "Arc" + "Cost" ], - "severity": "Medium", - "subcategory": "Monitoring", - "text": "Use notification in Activity logs to receive notification on unexpected changes to the resources", - "waf": "Operations" + "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": "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": "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": [ - "Monitor", - "Arc" + "Cost" ], - "severity": "Medium", - "subcategory": "Monitoring", - "text": "Use Azure Monitor for compliance and operational monitoring", - "waf": "Operations" + "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": "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": "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": [ - "Monitor", - "Arc" + "Cost" ], - "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", - "waf": "Operations" + "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": "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": "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": [ - "Monitor", - "Arc" + "Cost" ], - "severity": "Low", - "subcategory": "Security", - "text": "Use Azure Arc-enabled servers to control software updates deployments to servers", - "waf": "Operations" + "subcategory": "Networking", + "text": "evaluate your network topology against networking costs and where applicable reduce the egress and peering data" }, { - "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": "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": [ - "Arc" + "EventHubs", + "Cost", + "FrontDoor" ], - "severity": "High", "subcategory": "Networking", - "text": "Define a connectivity method from the server to Azure", - "waf": "Operations" + "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": "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": "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": [ - "Arc" + "Cost", + "AppSvc", + "FrontDoor" ], - "severity": "Medium", "subcategory": "Networking", - "text": "Is a proxy server a required for communication over the Public Internet", - "waf": "Operations" + "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": "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", + "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": [ - "VPN", - "Arc", - "ExpressRoute", - "PrivateLink" + "Cost" ], - "severity": "Medium", - "subcategory": "Networking", - "text": "Is a private (not public Internet) connection required?", - "waf": "Operations" + "subcategory": "PaaS", + "text": "consider using free tiers where applicable for all non-production environments" }, { - "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", + "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": [ + "Cost" + ], + "subcategory": "serverless", + "text": "using serverless patterns for spikes can help keeping costs down" + }, + { + "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": [ - "Arc" + "Storage", + "Cost" ], - "severity": "High", - "subcategory": "Networking", - "text": "Will Firewall configurations be needed in order to ensure communication with Azure Services?", - "waf": "Security" + "subcategory": "Storage", + "text": "consider archiving tiers for less used data" }, { - "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": "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": [ - "Arc" + "Storage", + "Cost" ], - "severity": "Low", - "subcategory": "Networking", - "text": "Can the Firewall or Proxy rules be automated updated if Service Tags or IP addresses change", - "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": "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": "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": [ - "Arc" + "Storage", + "Cost" ], - "severity": "High", - "subcategory": "Networking", - "text": "Always use secure communication for Azure where possible", - "waf": "Security" + "subcategory": "Storage", + "text": "consider using standard SSD rather than Premium or Ultra where possible" }, { - "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": "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": [ - "PrivateLink", - "Monitor", - "Arc" + "Storage", + "Cost" ], - "severity": "Low", - "subcategory": "Networking", - "text": "Include communication for Azure Arc-enabled Servers extensions in the design (firewall/proxy/private link)", - "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, Governance and Compliance", - "checklist": "Azure Arc Review", - "guid": "ac6aae01-e6a8-44de-9df4-7d2d92881b1c", - "link": "https://learn.microsoft.com/azure/governance/policy/", + "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": [ - "AzurePolicy", - "Arc" + "Storage", + "Cost", + "ASR" ], - "severity": "Medium", - "subcategory": "Management", - "text": "Use Azure Policy to implement a governance model for hybrid connected servers", - "waf": "Security" + "subcategory": "Storage", + "text": "for ASR, consider using Standard SSD disks if the RPO/RTO and replication throughput allow it" }, { - "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": "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": [ - "Arc" + "Storage", + "Cost" ], - "severity": "Medium", - "subcategory": "Management", - "text": "Consider using Machine configurations for in guest OS configurations", - "waf": "Operations" + "subcategory": "storage", + "text": "storage accounts: check hot tier and/or GRS necessary" }, { - "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": "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": [ - "AzurePolicy", - "Arc" + "Storage", + "Cost" ], - "severity": "Medium", - "subcategory": "Management", - "text": "Evaluate the need for custom Guest Configuration policies", - "waf": "Operations" + "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, Governance and Compliance", - "checklist": "Azure Arc Review", - "guid": "49674c5e-d85b-4859-a773-3be2a1a27b77", - "link": "https://learn.microsoft.com/azure/automation/change-tracking/overview", + "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": [ - "Monitor", - "Arc" + "EventHubs", + "Cost", + "Monitor" ], - "severity": "Medium", - "subcategory": "Monitoring", - "text": "Consider using change tracking for tracking changes made on the servers", - "waf": "Operations" + "subcategory": "Synapse", + "text": "Create budgets to manage costs and create alerts that automatically notify stakeholders of spending anomalies and overspending risks." }, { - "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": "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": [ - "Arc" + "Storage", + "Cost" ], - "severity": "Medium", - "subcategory": "Requirements", - "text": "Make sure to use an Azure region for storing the metadata approved by the organization", - "waf": "Security" + "subcategory": "Synapse", + "text": "Export cost data to a storage account for additional data analysis." }, { - "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": "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": [ - "Arc", - "AKV" + "Cost", + "SQL" ], - "severity": "Medium", - "subcategory": "Secrets", - "text": "Use Azure Key Vault for certificate management on servers", - "waf": "Security" + "subcategory": "Synapse", + "text": "Control costs for a dedicated SQL pool by pausing the resource when it is not in use." }, { - "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": "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": [ - "Storage", - "Arc", - "AKV", - "Entra" + "Cost" ], - "severity": "High", - "subcategory": "Secrets", - "text": "What is the acceptable life time of the secret used by SP's", - "waf": "Security" + "subcategory": "Synapse", + "text": "Enable the serverless Apache Spark automatic pause feature and set your timeout value accordingly." }, { - "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": "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": [ - "Arc", - "AKV" + "Cost" ], - "severity": "Medium", - "subcategory": "Secrets", - "text": "Secure the public key for Azure Arc-enabled Servers", - "waf": "Security" + "subcategory": "Synapse", + "text": "Create multiple Apache Spark pool definitions of various sizes." }, { - "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": "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": [ - "Arc" + "Cost" ], - "severity": "High", - "subcategory": "Security", - "text": "Ensure there is local administrator access for executing the agent installation", - "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, 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": "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": [ - "Arc" + "Cost", + "VM" ], - "severity": "Medium", - "subcategory": "Security", - "text": "Limit the amount of users with local administrator rights to the servers", - "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, 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": "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": [ - "Entra", - "Arc" + "Cost", + "VM" ], - "severity": "Medium", - "subcategory": "Security", - "text": "Consider using and restricting access to managed identities for applications.", - "waf": "Security" + "subcategory": "VM", + "text": "right-sizing all VMs" }, { - "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": "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": [ - "Defender", - "Arc" + "Cost", + "VM" ], - "severity": "Medium", - "subcategory": "Security", - "text": "Enable Defender for Servers for all servers to secure hybrid workloads from threats", - "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, Governance and Compliance", - "checklist": "Azure Arc Review", - "guid": "cbafe6c4-6589-4d45-9a92-7c3974d1102c", + "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": [ - "Arc" + "Cost", + "VM", + "Monitor" ], - "severity": "Medium", - "subcategory": "Security", - "text": "Define controls to detect security misconfigurations and track compliance", - "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, 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": "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": [ - "Arc" + "Cost", + "VM" ], - "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": "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": "Identity", @@ -9768,8 +10524,8 @@ "guid": "32e42e36-11c8-418b-8a0b-c510e43a18a9", "id": "A01.01", "services": [ - "Subscriptions", "AVS", + "Subscriptions", "Entra" ], "severity": "High", @@ -9853,8 +10609,8 @@ "guid": "ae0e37ce-e297-411b-b352-caaab79b198d", "id": "A01.07", "services": [ - "RBAC", "AVS", + "RBAC", "Entra" ], "severity": "Medium", @@ -9868,8 +10624,8 @@ "guid": "ab81932c-9fc9-4d1b-a780-36f5e6bfbb9e", "id": "A01.08", "services": [ - "RBAC", "AVS", + "RBAC", "Entra" ], "severity": "Medium", @@ -9883,8 +10639,8 @@ "guid": "d503547c-c447-4e82-9128-a71f0f1cac6d", "id": "A01.09", "services": [ - "RBAC", "AVS", + "RBAC", "Entra" ], "severity": "High", @@ -9912,9 +10668,9 @@ "guid": "dbf590ce-65de-48e0-9f9c-cbd468266abc", "id": "B02.01", "services": [ - "NetworkWatcher", - "Monitor", "AVS", + "Monitor", + "NetworkWatcher", "VPN", "ExpressRoute" ], @@ -9929,10 +10685,10 @@ "guid": "e6a84de5-df43-4d19-a248-1718d5d1e5f6", "id": "B02.02", "services": [ - "VM", - "NetworkWatcher", - "Monitor", "AVS", + "Monitor", + "NetworkWatcher", + "VM", "ExpressRoute" ], "severity": "Medium", @@ -9946,10 +10702,10 @@ "guid": "25659d35-58fd-4772-99c9-31112d027fe4", "id": "B02.03", "services": [ - "NetworkWatcher", - "Monitor", "AVS", - "VM" + "VM", + "Monitor", + "NetworkWatcher" ], "severity": "Medium", "subcategory": "Monitoring", @@ -9976,8 +10732,8 @@ "guid": "6128a71f-0f1c-4ac6-b9ef-1d5e832e42e3", "id": "C01.01", "services": [ - "RBAC", "AVS", + "RBAC", "Entra" ], "severity": "High", @@ -9991,8 +10747,8 @@ "guid": "c4e2436b-b336-4d71-9f17-960eee0b9b5c", "id": "C01.02", "services": [ - "RBAC", "AVS", + "RBAC", "Entra" ], "severity": "High", @@ -10020,8 +10776,8 @@ "guid": "d329f798-bc17-48bd-a5a0-6ca7144351d1", "id": "C01.04", "services": [ - "RBAC", "AVS", + "RBAC", "Entra" ], "severity": "Medium", @@ -10078,8 +10834,8 @@ "id": "C02.02", "services": [ "AppGW", - "Firewall", - "AVS" + "AVS", + "Firewall" ], "severity": "High", "subcategory": "Security (network)", @@ -10105,8 +10861,8 @@ "guid": "29e3eec2-1836-487a-8077-a2b5945bda43", "id": "C02.04", "services": [ - "Monitor", - "AVS" + "AVS", + "Monitor" ], "severity": "Medium", "subcategory": "Security (network)", @@ -10119,10 +10875,10 @@ "guid": "334fdf91-c234-4182-a652-75269440b4be", "id": "C02.05", "services": [ - "DDoS", "AVS", "VNet", "VPN", + "DDoS", "ExpressRoute" ], "severity": "Medium", @@ -10149,8 +10905,8 @@ "guid": "9ccbd869-266a-4cca-874f-aa19bf39d95d", "id": "C03.01", "services": [ - "Defender", - "AVS" + "AVS", + "Defender" ], "severity": "Medium", "subcategory": "Security (guest/VM)", @@ -10218,10 +10974,10 @@ "guid": "3ef7ad7c-6d37-4331-95c7-acbe44bbe609", "id": "C04.01", "services": [ - "AzurePolicy", + "Storage", "AVS", "VM", - "Storage" + "AzurePolicy" ], "severity": "High", "subcategory": "Governance (platform)", @@ -10234,8 +10990,8 @@ "guid": "d89f2e87-7784-424d-9167-85c6fa95b96a", "id": "C04.02", "services": [ - "ASR", - "AVS" + "AVS", + "ASR" ], "severity": "Low", "subcategory": "Governance (platform)", @@ -10248,9 +11004,9 @@ "guid": "d88408f3-7273-44c8-96ba-280214590146", "id": "C04.03", "services": [ - "AzurePolicy", + "Storage", "AVS", - "Storage" + "AzurePolicy" ], "severity": "High", "subcategory": "Governance (platform)", @@ -10276,8 +11032,8 @@ "guid": "bf39d95d-44c7-4c89-89ca-1f6d5315ae52", "id": "C04.05", "services": [ - "AzurePolicy", - "AVS" + "AVS", + "AzurePolicy" ], "severity": "Low", "subcategory": "Governance (platform)", @@ -10290,8 +11046,8 @@ "guid": "4ba34d45-85e1-4213-abd7-bb012f7b95ef", "id": "C04.06", "services": [ - "Cost", - "AVS" + "AVS", + "Cost" ], "severity": "Medium", "subcategory": "Governance (platform)", @@ -10304,8 +11060,8 @@ "guid": "6e043e2a-a359-4271-ae6e-205172676ae4", "id": "C04.07", "services": [ - "Cost", - "AVS" + "AVS", + "Cost" ], "severity": "Low", "subcategory": "Governance (platform)", @@ -10331,9 +11087,9 @@ "guid": "48b262d6-cc5f-4512-a253-98e6db9d37da", "id": "C05.01", "services": [ - "Defender", "AVS", - "VM" + "VM", + "Defender" ], "severity": "Medium", "subcategory": "Governance (guest/VM)", @@ -10347,8 +11103,8 @@ "id": "C05.02", "services": [ "AVS", - "Arc", - "VM" + "VM", + "Arc" ], "severity": "Medium", "subcategory": "Governance (guest/VM)", @@ -10374,9 +11130,9 @@ "guid": "4ed90dae-2cc8-44c4-9b6b-781cbafe6c46", "id": "C05.04", "services": [ - "Monitor", "AVS", - "VM" + "VM", + "Monitor" ], "severity": "Medium", "subcategory": "Governance (guest/VM)", @@ -10391,8 +11147,8 @@ "services": [ "Backup", "AVS", - "AzurePolicy", - "VM" + "VM", + "AzurePolicy" ], "severity": "Medium", "subcategory": "Governance (guest/VM)", @@ -10405,8 +11161,8 @@ "guid": "ee29711b-d352-4caa-ab79-b198dab81932", "id": "C06.01", "services": [ - "Defender", "AVS", + "Defender", "Monitor" ], "severity": "Medium", @@ -10420,8 +11176,8 @@ "guid": "c9fc9d1b-b780-436f-9e6b-fbb9ed503547", "id": "C06.02", "services": [ - "Defender", - "AVS" + "AVS", + "Defender" ], "severity": "Medium", "subcategory": "Compliance", @@ -10460,8 +11216,8 @@ "guid": "e43a18a9-cd28-49ce-b6b1-7db8255461e2", "id": "D01.01", "services": [ - "Monitor", - "AVS" + "AVS", + "Monitor" ], "severity": "High", "subcategory": "Monitoring", @@ -10474,8 +11230,8 @@ "guid": "6b84ee5d-f47d-42d9-8881-b1cd5d1e54a2", "id": "D01.02", "services": [ - "Monitor", - "AVS" + "AVS", + "Monitor" ], "severity": "High", "subcategory": "Monitoring", @@ -10488,8 +11244,8 @@ "guid": "9659e396-80e7-4828-ac93-5657d02bff45", "id": "D01.03", "services": [ - "Monitor", - "AVS" + "AVS", + "Monitor" ], "severity": "High", "subcategory": "Monitoring", @@ -10502,8 +11258,8 @@ "guid": "64b0d934-a348-4726-be79-d6b5c3a36495", "id": "D01.04", "services": [ - "Monitor", - "AVS" + "AVS", + "Monitor" ], "severity": "High", "subcategory": "Monitoring", @@ -10516,9 +11272,9 @@ "guid": "b6abad38-aad5-43cc-99e1-d86667357c54", "id": "D01.05", "services": [ - "Monitor", + "Storage", "AVS", - "Storage" + "Monitor" ], "severity": "Medium", "subcategory": "Monitoring", @@ -10531,8 +11287,8 @@ "guid": "9674c5ed-85b8-459c-9733-be2b1a27b775", "id": "D01.06", "services": [ - "Monitor", - "AVS" + "AVS", + "Monitor" ], "severity": "Low", "subcategory": "Monitoring", @@ -10545,10 +11301,10 @@ "guid": "a91be1f3-88f0-43a4-b2cd-463cbbbc8682", "id": "D02.01", "services": [ - "AzurePolicy", + "Storage", "AVS", "VM", - "Storage" + "AzurePolicy" ], "severity": "High", "subcategory": "Operations", @@ -10603,8 +11359,8 @@ "guid": "925398e6-da9d-437d-ac43-bc6cd1d79a9b", "id": "D02.05", "services": [ - "Monitor", - "AVS" + "AVS", + "Monitor" ], "severity": "Medium", "subcategory": "Operations", @@ -10630,9 +11386,9 @@ "guid": "17e7a8d9-0ae0-4e27-aee2-9711bd352caa", "id": "D02.07", "services": [ + "AVS", "AzurePolicy", - "Monitor", - "AVS" + "Monitor" ], "severity": "Medium", "subcategory": "Operations", @@ -10645,9 +11401,9 @@ "guid": "ab79b188-dab8-4193-8c9f-c9d1bb77036f", "id": "D02.08", "services": [ + "Storage", "AVS", - "VM", - "Storage" + "VM" ], "severity": "High", "subcategory": "Operations", @@ -10660,8 +11416,8 @@ "guid": "aee3553a-fc83-4392-98b2-62d6cc5f5129", "id": "D03.01", "services": [ - "Defender", - "AVS" + "AVS", + "Defender" ], "severity": "Medium", "subcategory": "Security", @@ -10688,8 +11444,8 @@ "guid": "5e6bfbb9-ed50-4354-9cc4-47e826028a71", "id": "E02.01", "services": [ - "ASR", - "AVS" + "AVS", + "ASR" ], "severity": "Medium", "subcategory": "Disaster Recovery", @@ -10702,8 +11458,8 @@ "guid": "f0f1cac6-d9ef-41d5-b832-d42e3611c818", "id": "E02.02", "services": [ - "ASR", - "AVS" + "AVS", + "ASR" ], "severity": "Medium", "subcategory": "Disaster Recovery", @@ -10716,8 +11472,8 @@ "guid": "b0afbc51-0e43-4a18-a9cd-289bed6b17db", "id": "E02.03", "services": [ - "ASR", - "AVS" + "AVS", + "ASR" ], "severity": "High", "subcategory": "Disaster Recovery", @@ -10730,8 +11486,8 @@ "guid": "8255461e-2aee-4345-9aec-8339248b262d", "id": "E02.04", "services": [ - "ASR", - "AVS" + "AVS", + "ASR" ], "severity": "Medium", "subcategory": "Disaster Recovery", @@ -10744,8 +11500,8 @@ "guid": "6cc5f512-9253-498e-9da9-d37dac43bc6c", "id": "E02.05", "services": [ - "ASR", - "AVS" + "AVS", + "ASR" ], "severity": "High", "subcategory": "Disaster Recovery", @@ -10758,10 +11514,10 @@ "guid": "d1d79a9b-2460-4448-aa8f-42d78e78cb6a", "id": "E02.06", "services": [ - "ASR", - "NVA", "AVS", - "ExpressRoute" + "ASR", + "ExpressRoute", + "NVA" ], "severity": "Medium", "subcategory": "Disaster Recovery", @@ -10880,8 +11636,8 @@ "guid": "0f1cac6d-9ef1-4d5e-a32e-42e3611c818b", "id": "F02.03", "services": [ - "AzurePolicy", - "AVS" + "AVS", + "AzurePolicy" ], "severity": "Low", "subcategory": "Automated Deployment", @@ -10949,8 +11705,8 @@ "guid": "3bd2a0a1-7e7a-48d9-8ae0-e37cee29711b", "id": "F04.01", "services": [ - "Subscriptions", - "AVS" + "AVS", + "Subscriptions" ], "severity": "Medium", "subcategory": "Automated Scale", @@ -10963,9 +11719,9 @@ "guid": "d352caaa-b79b-4198-bab8-1932c9fc9d1b", "id": "F04.02", "services": [ - "AzurePolicy", + "Storage", "AVS", - "Storage" + "AzurePolicy" ], "severity": "Medium", "subcategory": "Automated Scale", @@ -11017,8 +11773,8 @@ "guid": "1dc15a1c-075e-4e9f-841a-cccd579376bc", "id": "F04.06", "services": [ - "Monitor", - "AVS" + "AVS", + "Monitor" ], "severity": "Medium", "subcategory": "Automated Scale", @@ -11026,9503 +11782,8927 @@ "waf": "Operations" }, { - "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", - "link": "https://learn.microsoft.com/azure/container-registry/data-loss-prevention", - "services": [ - "ACR" - ], - "severity": "High", - "subcategory": "Data Protection", - "text": "Disable Azure Container Registry image export" - }, - { - "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", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-azure-policy", - "services": [ - "AzurePolicy", - "ACR" - ], - "severity": "High", - "subcategory": "Data Protection", - "text": "Enable Azure Policies for Azure Container Registry" - }, - { - "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", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-tutorial-sign-build-push", - "services": [ - "ACR", - "AKV" - ], - "severity": "High", - "subcategory": "Data Protection", - "text": "Sign and Verify containers with notation (Notary v2)" - }, - { - "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", - "link": "https://learn.microsoft.com/azure/container-registry/tutorial-customer-managed-keys", - "services": [ - "ACR", - "AKV" - ], - "severity": "Medium", - "subcategory": "Data Protection", - "text": "Encrypt registry with a customer managed key" - }, - { - "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", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", - "services": [ - "ACR", - "Entra", - "RBAC" - ], - "severity": "High", - "subcategory": "Identity and Access Control", - "text": "Use Managed Identities to connect instead of Service Principals" - }, - { - "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", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", - "services": [ - "ACR", - "Entra", - "RBAC" - ], - "severity": "High", - "subcategory": "Identity and Access Control", - "text": "Disable local authentication for management plane access" - }, - { - "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", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-roles?tabs=azure-cli", - "services": [ - "ACR", - "Entra", - "RBAC" - ], - "severity": "High", - "subcategory": "Identity and Access Control", - "text": "Assign AcrPull & AcrPush RBAC roles rather than granting Administrative access to identity principals" - }, - { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "Disable anonymous pull/push access", - "guid": "e338997e-41c7-47d7-acf6-a62a1194956d", - "link": "https://learn.microsoft.com/azure/container-registry/anonymous-pull-access#configure-anonymous-pull-access", + "category": "Management", + "checklist": "Azure API Management Review", + "guid": "06862505-2d9a-4874-9491-2837b00a3475", + "link": "https://learn.microsoft.com/azure/api-management/backends", "services": [ - "ACR", - "Entra" + "APIM" ], "severity": "Medium", - "subcategory": "Identity and Access Control", - "text": "Disable Anonymous pull access" - }, - { - "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", - "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" - }, - { - "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", - "services": [ - "PrivateLink", - "ACR", - "Entra", - "EventHubs" - ], - "severity": "High", - "subcategory": "Identity and Access Control", - "text": "Deploy images from a trusted environment" + "subcategory": "Best practices", + "text": "Use Backends feature to eliminate redundant API backend configurations" }, { - "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", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-enable-conditional-access-policy", + "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": [ "AzurePolicy", - "ACR", - "Entra" - ], - "severity": "Medium", - "subcategory": "Identity and Access Control", - "text": "Disable Azure ARM audience tokens for authentication" - }, - { - "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", - "link": "https://learn.microsoft.com/azure/container-registry/monitor-service", - "services": [ - "ACR", - "Entra", - "Monitor" - ], - "severity": "Medium", - "subcategory": "Logging and Monitoring", - "text": "Enable diagnostics logging" - }, - { - "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", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-private-link", - "services": [ - "PrivateLink", - "ACR", - "Firewall", - "VNet" - ], - "severity": "Medium", - "subcategory": "Network Security", - "text": "Control inbound network access with Private Link" - }, - { - "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", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-access-selected-networks#disable-public-network-access", - "services": [ - "PrivateLink", - "ACR" - ], - "severity": "Medium", - "subcategory": "Network Security", - "text": "Disable Public Network access" - }, - { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "Only the ACR Premium SKU supports Private Link access", - "guid": "fc833934-8b26-42d6-ac5f-512925498f6d", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-skus", - "services": [ - "PrivateLink", - "ACR" + "APIM" ], "severity": "Medium", - "subcategory": "Network Security", - "text": "Use an Azure Container Registry SKU that supports Private Link (Premium SKU)" - }, - { - "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", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-introduction", - "services": [ - "ACR", - "Defender" - ], - "severity": "Low", - "subcategory": "Network Security", - "text": "Enable Defender for Containers to scan Azure Container Registry for vulnerabilities" + "subcategory": "Best practices", + "text": "Use Named Values to store common values that can be used in policies" }, { - "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", + "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": [ - "ACR" + "ASR", + "APIM" ], "severity": "Medium", - "subcategory": "Vulnerability Management", - "text": "Deploy validated container images" - }, - { - "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", - "services": [ - "ACR" - ], - "severity": "High", - "subcategory": "Vulnerability Management", - "text": "Use up-to-date platforms, languages, protocols and frameworks" + "subcategory": "Business continuity and disaster recovery", + "text": "Deploy to multiple Azure regions" }, { - "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": "Management", + "checklist": "Azure API Management Review", + "guid": "9c8d1664-dd9a-49d4-bd83-950af0af4044", + "link": "https://learn.microsoft.com/azure/api-management/high-availability", "services": [ - "ASR" + "ASR", + "APIM" ], "severity": "Medium", - "subcategory": " ", - "text": "Do not combine ASCS and Database cluster on to single/same VM" + "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": "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": "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": [ + "Backup", "ASR", - "LoadBalancer" + "APIM" ], - "severity": "Medium", - "subcategory": " ", - "text": "Make sure the Floating IP is enabled on the Load balancer" + "severity": "High", + "subcategory": "Business continuity and disaster recovery", + "text": "Ensure there is an automated backup routine" }, { - "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": "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": [ - "ASR", - "RBAC", - "Entra", - "VM" + "AzurePolicy", + "APIM" ], "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": "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": "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": "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": [ - "ASR", - "ACR", - "SAP" + "EventHubs", + "AzurePolicy", + "APIM" ], - "severity": "Medium", - "subcategory": " ", - "text": "Use one proximity placement group per SAP SID. Groups don't span across Availability Zones or Azure regions" + "severity": "Low", + "subcategory": "Performance and scalability", + "text": "If you need to log at high performance levels, consider Event Hubs policy" }, { - "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": "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": [ - "ASR", - "Entra", - "VM" + "AzurePolicy", + "APIM" ], "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": "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": "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": "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": [ - "ASR", - "LoadBalancer" + "APIM" ], "severity": "Medium", - "subcategory": " ", - "text": "Use a Standard Load Balancer SKU in front of ASCS and DB clusters" + "subcategory": "Performance and scalability", + "text": "Configure autoscaling to scale out the number of instances when the load increases" }, { - "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": "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": [ - "ASR", - "Storage", - "VM" + "APIM" ], "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": "Performance and scalability", + "text": "Deploy self-hosted gateways where Azure doesn't have a region close to the backend APIs." }, { - "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": "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": [ - "ASR" + "AzurePolicy", + "APIM" ], "severity": "Medium", - "subcategory": " ", - "text": "Native database replication technology should be used to synchronize the database in a HA pair." + "subcategory": "Development best practices", + "text": "Implement an error handling policy at the global level" }, { - "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", + "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": [ - "ASR", - "SAP" + "AzurePolicy", + "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": "Development best practices", + "text": "Ensure all APIs policies include a element." }, { - "category": "Business Continuity and Disaster Recovery", - "checklist": "Azure Landing Zone Review", - "guid": "81b12318-1a54-4174-8583-3fb4ae3c2df7", + "category": "Governance", + "checklist": "Azure API Management Review", + "guid": "a5c45b03-93b6-42fe-b16b-8fccb6a79902", + "link": "https://learn.microsoft.com/azure/api-management/policy-fragments", "services": [ - "ASR", - "VNet" + "ACR", + "AzurePolicy", + "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": "Development best practices", + "text": "Use Policy Fragments to avoid repeating same policies definitions across multiple APIs" }, { - "category": "Business Continuity and Disaster Recovery", - "checklist": "Azure Landing Zone Review", - "guid": "43165c3a-cbe0-45bb-b209-d490da477784", + "category": "Governance", + "checklist": "Azure API Management Review", + "guid": "c3818a95-6ff3-4474-88dc-e809b46dad6a", + "link": "https://learn.microsoft.com/azure/api-management/monetization-support", "services": [ - "ASR", - "Entra", - "VM" + "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": "Monetization", + "text": "If you are planning to monetize your APIs, review the 'monetization support' article for best practices" }, { - "category": "Business Continuity and Disaster Recovery", - "checklist": "Azure Landing Zone Review", - "guid": "24d11678-5d2f-4a56-a56a-d48408fe7273", + "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": [ - "ASR" + "Monitor", + "APIM" ], - "severity": "Medium", - "subcategory": " ", - "text": "Native database replication should be used to synchronize data to the DR site, rather than Azure Site Recovery" + "severity": "High", + "subcategory": "Monitoring", + "text": "Enable Diagnostics Settings to export logs to Azure Monitor" }, { - "category": "Compute", - "checklist": "Azure Landing Zone Review", - "guid": "2829e2ed-b217-4367-9aff-6691b4935ada", + "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": [ - "VM" + "Monitor", + "APIM" ], "severity": "Medium", - "subcategory": " ", - "text": "Make quota requests for correct VM SKU and Zones" + "subcategory": "Monitoring", + "text": "Enable Application Insights for more detailed telemetry" }, { - "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": "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": [ - "Subscriptions", - "RBAC", - "Entra" + "Monitor", + "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": "Monitoring", + "text": "Configure alerts on the most critical metrics" }, { - "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": "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": [ + "AKV", "Entra", - "SAP" + "APIM" ], - "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 custom SSL certificates 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": "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": [ + "Entra", + "APIM" + ], + "severity": "High", + "subcategory": "Identity", + "text": "Protect incoming requests to APIs (data plane) with Azure AD" + }, + { + "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": [ "Entra", - "SAP" + "APIM" ], "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." + "text": "Use Azure AD to authenticate users in the Developer Portal" }, { - "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": "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": [ "Entra", - "SAP" + "APIM" ], "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" + "subcategory": "Privileged access", + "text": "Create appropriate groups to control the visibility of the products" }, { - "category": "Identity and Access", - "checklist": "Azure Landing Zone Review", - "guid": "9eb54dad-7861-4e1c-973a-f3bb003fc9c1", + "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": [ - "Entra", - "SAP" + "VNet", + "APIM" ], "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" + "subcategory": "Security", + "text": "Deploy the service within a Virtual Network (VNET)" }, { - "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": "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": [ - "Entra", - "SAP" + "VNet", + "Monitor", + "APIM" ], "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" + "subcategory": "Security", + "text": "Deploy network security groups (NSG) to your subnets to restrict or monitor traffic" }, { - "category": "Identity and Access", - "checklist": "Azure Landing Zone Review", - "guid": "23181aa4-1742-4694-9ff8-ae7d7d474317", + "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": [ - "Entra", - "AKV", - "SAP" + "VNet", + "PrivateLink", + "APIM" ], "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" + "subcategory": "Security", + "text": "Deploy Private Endpoints to filter incoming traffic when VNET is not used" }, { - "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": "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": [ - "Entra", - "AKV", - "SAP" + "APIM" ], - "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": "Security", + "text": "Disable Public Network Access" }, { - "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": "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": [ - "Entra", - "SAP" + "FrontDoor", + "APIM" ], "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": "Connectivity", + "text": "Use Azure Front Door for multi-region deployment" }, { - "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": "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": [ - "Entra", - "SAP" + "APIM" ], "severity": "Medium", - "subcategory": "Identity", - "text": "Implement SSO to SAP HANA" + "subcategory": "Automation", + "text": "Simplify management with PowerShell automation scripts" }, { - "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": "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": [ "Entra", - "SAP" + "APIM" ], "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": "Best practices", + "text": "Review DevOps best practices from the Cloud Adaption Framework APIM Landing Zone Accelerator" }, { - "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": "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": [ "Entra", - "SAP" + "APIM" ], "severity": "Medium", - "subcategory": "Identity", - "text": "For applications that access SAP, you might want to use principal propagation to establish SSO." + "subcategory": "Best practices", + "text": "Promote usage of Visual Studio Code APIM extension for faster API development" }, { - "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": "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": [ - "Entra", - "SAP" + "APIM" ], "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." + "subcategory": "DevOps", + "text": "Implement DevOps and CI/CD in your workflow" }, { - "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": "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": [ - "Entra", - "SAP" + "APIM" ], "severity": "Medium", - "subcategory": "Identity", - "text": "Implement SSO to SAP BTP" + "subcategory": "APIs", + "text": "Secure APIs using client certificate authentication" }, { - "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": "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": [ - "Entra", - "SAP" + "APIM" ], "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": "APIs", + "text": "Secure backend services using client certificate authentication" }, { - "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": "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": [ - "Subscriptions", - "AzurePolicy", - "SAP" + "APIM" ], "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" + "subcategory": "APIs", + "text": "Review 'Recommendations to mitigate OWASP API Security Top 10 threats' article and check what is applicable to your APIs" }, { - "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": "Security", + "checklist": "Azure API Management Review", + "guid": "5507c4b8-a7f8-41d6-9661-418c987100c9", + "link": "https://learn.microsoft.com/azure/api-management/authorizations-overview", "services": [ - "Subscriptions", - "SAP" + "APIM" ], - "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": "APIs", + "text": "Use Authorizations feature to simplify management of OAuth 2.0 token for your backend APIs" }, { - "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": "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": [ - "Subscriptions" + "APIM" ], "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" + "subcategory": "Ciphers", + "text": "Use the latest TLS version when encrypting information in transit. Disable outdated and unnecessary protocols and ciphers when possible." }, { - "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": "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": [ - "Subscriptions", - "VM" + "AKV", + "APIM" ], "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" + "subcategory": "Data protection", + "text": "Ensure that secrets (Named values) are stored an Azure Key Vault so they can be securely accessed and updated" }, { - "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": "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": [ - "Subscriptions" + "Entra", + "APIM" ], - "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." + "severity": "Medium", + "subcategory": "Identities", + "text": "Use managed identities to authenticate to other Azure resources whenever possible" }, { - "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": "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": [ - "Subscriptions", - "VM" + "AppGW", + "WAF", + "Entra", + "APIM" ], "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." + "subcategory": "Network", + "text": "Use web application firewall (WAF) by deploying Application Gateway in front of APIM" }, { - "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": "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": [ - "Subscriptions" + "AKV", + "AppSvc" ], "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" + "subcategory": "Data Protection", + "text": "Use Key Vault to store secrets", + "waf": "Security" }, { - "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": "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": [ - "Subscriptions", - "Cost", - "TrafficManager" + "AKV", + "AppSvc", + "Entra" ], - "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": "High", + "subcategory": "Data Protection", + "text": "Use Managed Identity to connect to Key Vault", + "waf": "Security" }, { - "category": "Management and Monitoring", - "checklist": "Azure Landing Zone Review", - "guid": "14591147-5e39-4e53-89cc-cd979366bcda", + "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": [ - "Monitor", - "SQL", - "SAP" + "AKV", + "AppSvc" ], - "severity": "Medium", - "subcategory": "Monitoring", - "text": "Use SAP Solution Manager and Azure Monitor for SAP Solutions to monitor SAP HANA, high-availability SUSE clusters, and SQL systems" + "severity": "High", + "subcategory": "Data Protection", + "text": "Use Key Vault to store TLS certificate.", + "waf": "Security" }, { - "category": "Management and Monitoring", - "checklist": "Azure Landing Zone Review", - "guid": "2750ab1a-b039-4d95-b54c-7c8929cb107d", - "link": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", + "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": [ - "Monitor", - "Entra", - "VM", - "SAP" + "Subscriptions", + "AppSvc" ], "severity": "Medium", - "subcategory": "Monitoring", - "text": "Run a VM Extension for SAP check. VM Extension for SAP uses the assigned managed identity of a virtual machine to access VM monitoring and configuration data.", - "training": "https://learn.microsoft.com/learn/paths/architect-infrastructure-operations/" + "subcategory": "Data Protection", + "text": "Isolate systems that process sensitive information", + "waf": "Security" }, { - "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": "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": [ - "AzurePolicy", - "Monitor" + "TrafficManager", + "AppSvc" ], "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": "Data Protection", + "text": "Do not store sensitive data on local disk", + "waf": "Security" }, { - "category": "Management and Monitoring", - "checklist": "Azure Landing Zone Review", - "guid": "2f7c95f0-6e15-44e3-aa35-92829e6e2061", - "link": "https://learn.microsoft.com/azure/governance/policy/how-to/guest-configuration-create", + "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": [ - "Backup", - "Monitor", - "Storage" + "AppSvc", + "Entra" ], "severity": "Medium", - "subcategory": "Monitoring", - "text": "Protect your HANA database with Azure Backup service. If you deploy Azure NetApp Files (ANF) for your HANA database, use the Azure Application Consistent Snapshot tool (AzAcSnap) to take application-consistent snapshots", - "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/" + "subcategory": "Identity and Access Control", + "text": "Use an established Identity Provider for authentication", + "waf": "Security" }, { - "category": "Management and Monitoring", - "checklist": "Azure Landing Zone Review", - "guid": "73686af4-6791-4f89-95ad-a43324e13811", - "link": "https://learn.microsoft.com/azure/automation/update-management/overview", + "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": [ - "Monitor", - "VM", - "SAP" + "AppSvc", + "Entra" ], - "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.", - "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-compute-resources/" + "severity": "High", + "subcategory": "Identity and Access Control", + "text": "Deploy from a trusted environment", + "waf": "Security" }, { - "category": "Management and Monitoring", - "checklist": "Azure Landing Zone Review", - "guid": "523181aa-4174-4269-93ff-8ae7d7d47431", - "link": "https://learn.microsoft.com/azure/network-watcher/network-watcher-monitoring-overview", + "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": [ - "NetworkWatcher", - "Monitor", - "SAP" + "Entra" ], - "severity": "Medium", - "subcategory": "Monitoring", - "text": "Use Network Watcher Connection Monitor to monitor SAP database and application server latency metrics, or collect and display network latency measurements with Azure Monitor.", - "training": "https://learn.microsoft.com/learn/modules/configure-network-watcher/" + "severity": "High", + "subcategory": "Identity and Access Control", + "text": "Disable basic authentication", + "waf": "Security" }, { - "category": "Management and Monitoring", - "checklist": "Azure Landing Zone Review", - "guid": "76c8bcbf-45bb-4e60-ad8a-03e97778424d", - "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/lock-resources?tabs=json", + "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": [ - "Monitor", - "SAP" + "AKV", + "Entra" ], - "severity": "Medium", - "subcategory": "Monitoring", - "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/learn/paths/implement-resource-mgmt-security/" + "severity": "High", + "subcategory": "Identity and Access Control", + "text": "Use Managed Identity to connect to resources", + "waf": "Security" }, { - "category": "Management and Monitoring", - "checklist": "Azure Landing Zone Review", - "guid": "616785d6-fa96-4c96-ad88-518f482734c8", - "link": "https://learn.microsoft.com/azure/governance/policy/overview", + "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": [ - "Subscriptions", - "Monitor", - "SAP" + "ACR", + "Entra" ], - "severity": "Medium", - "subcategory": "Monitoring", - "text": "For each Azure subscription, run an Azure Availability Zone latency test before zonal deployment to choose low-latency zones for SAP on Azure deployment." + "severity": "High", + "subcategory": "Identity and Access Control", + "text": "Pull containers using a Managed Identity", + "waf": "Security" }, { - "category": "Management and Monitoring", - "checklist": "Azure Landing Zone Review", - "guid": "86ba2802-1459-4114-95e3-9e5309cccd97", - "link": "https://learn.microsoft.com/azure/sentinel/quickstart-onboard", + "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": [ + "Entra", "Monitor", - "Sentinel", - "SAP" + "AppSvc" ], "severity": "Medium", - "subcategory": "Monitoring", - "text": "Implement threat protection for SAP with Microsoft Sentinel." + "subcategory": "Logging and Monitoring", + "text": "Send App Service runtime logs to Log Analytics", + "waf": "Security" }, { - "category": "Management and Monitoring", - "checklist": "Azure Landing Zone Review", - "guid": "4d116785-d2fa-456c-96ad-48408fe72734", - "link": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", + "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": [ - "AzurePolicy", - "VM", - "ACR", "Entra", - "Monitor" + "Monitor", + "AppSvc" ], "severity": "Medium", - "subcategory": "Monitoring", - "text": "Enforcing configuration of update management through policy ensures all VMs are included in the patch management regimen, provides application teams with the ability to manage patch deployment for their VMs, and provides central IT with visibility and enforcement capabilities across all VMs" + "subcategory": "Logging and Monitoring", + "text": "Send App Service activity logs to Log Analytics", + "waf": "Security" }, { - "category": "Management and Monitoring", - "checklist": "Azure Landing Zone Review", - "guid": "c486ba28-0dc0-4591-af65-de8e1309cccd", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-setup-guide/monitoring-reporting?tabs=AzureMonitor", + "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": [ + "VNet", + "Firewall", "Monitor", - "VM", - "SAP" + "NVA" ], "severity": "Medium", - "subcategory": "Monitoring", - "text": "Enable VM Insights for VM's running SAP Workloads." + "subcategory": "Network Security", + "text": "Outbound network access should be controlled", + "waf": "Security" }, { - "category": "Management and Monitoring", - "checklist": "Azure Landing Zone Review", - "guid": "579266bc-ca27-45fa-a1ab-fe9d55d04c3c", - "link": "https://learn.microsoft.com/azure/architecture/framework/resiliency/backup-and-recovery", + "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": [ - "Cost", - "Monitor" + "Storage", + "Firewall", + "PrivateLink", + "VNet", + "NVA" ], - "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." + "severity": "Low", + "subcategory": "Network Security", + "text": "Ensure a stable IP for outbound communications towards internet addresses", + "waf": "Security" }, { - "category": "Management and Monitoring", - "checklist": "Azure Landing Zone Review", - "guid": "4919cb1b-3d13-425a-b124-ba34df685edd", - "link": "https://learn.microsoft.com/azure/backup/backup-center-overview", + "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": [ - "Monitor" + "PrivateLink", + "AppSvc" ], - "severity": "Medium", - "subcategory": "Monitoring", - "text": " " + "severity": "High", + "subcategory": "Network Security", + "text": "Inbound network access should be controlled", + "waf": "Security" }, { - "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", + "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": [ + "Monitor", + "WAF", + "AppSvc", "AppGW", - "AzurePolicy", - "WAF" + "FrontDoor" ], - "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/learn/paths/secure-application-delivery/" + "severity": "High", + "subcategory": "Network Security", + "text": "Use a WAF in front of App Service", + "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "a3592829-e6e2-4061-9368-6af46791f893", - "link": "https://learn.microsoft.com/azure/networking/", + "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": [ - "ACR", - "VNet", - "SAP" + "PrivateLink", + "WAF" ], - "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/learn/modules/design-implement-azure-expressroute/" + "severity": "High", + "subcategory": "Network Security", + "text": "Avoid for WAF to be bypassed", + "waf": "Security" }, { - "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", + "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": [ - "VNet", - "VM", - "SAP" + "AzurePolicy", + "AppSvc" ], "severity": "Medium", - "subcategory": "IP plan", - "text": "Public I.P assignment to VM running SAP Workload is not recommended.", - "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/" + "subcategory": "Network Security", + "text": "Set minimum TLS policy to 1.2", + "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "9cccd979-366b-4cda-8750-ab1ab039d95d", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing", + "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": [ - "ASR", - "VNet" + "WAF", + "AppSvc" ], - "severity": "Medium", - "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/" + "severity": "High", + "subcategory": "Network Security", + "text": "Use HTTPS only", + "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "54c7c892-9cb1-407d-9325-ae525ba34d46", - "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-name-resolution-for-vms-and-role-instances", + "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": [ - "VNet" + "Storage" ], - "severity": "Medium", - "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/" + "severity": "High", + "subcategory": "Network Security", + "text": "Wildcards must not be used for CORS", + "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "85e2213a-ce7b-4b12-8f7c-95f06e154e3a", - "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-name-resolution-for-vms-and-role-instances", - "services": [ - "VNet", - "VM" - ], - "severity": "Medium", - "subcategory": "IP plan", - "text": "Ensure Accelerated Networking is enable for all VM where it is applicable.", - "training": "https://learn.microsoft.com/learn/paths/az-104-manage-virtual-networks/" + "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", + "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "d8a03e97-7784-424d-9167-85d6fa96c96a", - "link": "https://learn.microsoft.com/azure/app-service/networking-features", + "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": [ - "Firewall" + "Defender", + "AppSvc" ], "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/learn/paths/secure-networking-infrastructure/" + "subcategory": "Network Security", + "text": "Enable Defender for Cloud - Defender for App Service", + "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "d88518f4-8273-44c8-a6ba-280214591147", - "link": "https://learn.microsoft.com/azure/firewall/", + "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": [ + "VNet", + "DDoS", + "WAF", + "NVA", "AppGW", - "SAP" + "EventHubs" ], "severity": "Medium", - "subcategory": "Internet", - "text": "Use SAP Web dispatcher or third party service like NetScaler in conjunction with Application gateway if necessary to overcome reverse proxy limitation for SAP web Apps.", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/" + "subcategory": "Network Security", + "text": "Enable DDOS Protection Standard on the WAF VNet", + "waf": "Security" }, { - "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", + "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": [ - "AzurePolicy", "ACR", - "FrontDoor", - "WAF" + "VNet", + "PrivateLink" ], "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/" + "subcategory": "Network Security", + "text": "Pull containers over a Virtual Network", + "waf": "Security" }, { - "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/ag/ag-overview", - "services": [ - "AppGW", - "FrontDoor", - "AzurePolicy", - "WAF" - ], + "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": "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/" + "subcategory": "Penetration Testing", + "text": "Conduct a penetration test", + "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "5ada4332-4e13-4811-9231-81aa41742694", - "link": "https://learn.microsoft.com/azure/virtual-network/vnet-integration-for-azure-services", - "services": [ - "AppGW", - "LoadBalancer", - "WAF" - ], + "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": "PaaS", - "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/learn/paths/implement-network-security/?source=learn" + "subcategory": "Vulnerability Management", + "text": "Deploy validated code", + "waf": "Security" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "3ff8ae7d-7d47-4431-96c8-bcbf45bbe609", - "services": [ - "LoadBalancer" - ], - "severity": "Medium", - "subcategory": "PaaS", - "text": "Ensure that internal deployments for Azure Load Balancer are set up to use Direct Server Return (DSR) for HA configuration on the DBMS layer" + "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 Landing Zone Review", - "guid": "6e154e3a-a359-4282-ae6e-206173686af4", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-setup-guide/organize-resources?tabs=AzureManagementGroupsAndHierarchy", + "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", "services": [ - "Storage", - "VNet", - "SAP" + "AKS" ], "severity": "Medium", - "subcategory": "Segmentation", - "text": "If Azure NetApp Files is used for SAP deployment , ensure that only one delegate subnet can exist in a Vnet for Azure NetAppFiles", - "training": "https://learn.microsoft.com/learn/paths/implement-network-security/" + "subcategory": "Development", + "text": "Use canary or blue/green deployments", + "waf": "Operations" }, { - "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", + "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", "services": [ - "VNet", - "SAP" + "AKS" ], - "severity": "Medium", - "subcategory": "Segmentation", - "text": "Use NSGs and application security groups to micro-segment traffic within SAP application layer, like App subnet, DB subnet and Web subnet etc.", - "training": "https://learn.microsoft.com/learn/paths/implement-network-security/" + "severity": "Low", + "subcategory": "Development", + "text": "If required for AKS Windows workloads HostProcess containers can be used", + "waf": "Reliability" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "41742694-3ff8-4ae7-b7d4-743176c8bcbf", - "link": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", + "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, "services": [ - "NVA", - "SAP" + "AKS" ], - "severity": "Medium", - "subcategory": "Segmentation", - "text": "It is not supported to deploy any NVA between SAP application and SAP Database server", - "training": "https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/" + "severity": "Low", + "simple": -1, + "subcategory": "Development", + "text": "Use KEDA if running event-driven workloads", + "waf": "Performance" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "45bbe609-d8a0-43e9-9778-424d616785d6", + "category": "Application Deployment", + "checklist": "Azure AKS Review", + "guid": "26886d20-b66c-457b-a591-19bf8e8f5c58", + "id": "01.01.04", + "link": "https://dapr.io/", "services": [ - "VNet", - "SAP" + "AKS" ], - "severity": "Medium", - "subcategory": "Segmentation", - "text": "Placing of the SAP application layer and SAP DBMS in different Azure VNets that aren't peered isn't supported" + "severity": "Low", + "simple": 1, + "subcategory": "Development", + "text": "Use Dapr to ease microservice development", + "waf": "Operations" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Landing Zone Review", - "guid": "fa96c96a-d885-418f-9827-34c886ba2802", + "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", "services": [ - "SAP" + "AKS" ], "severity": "Medium", - "subcategory": "Segmentation", - "text": "For optimal network latency with SAP applications, consider using Azure proximity placement groups." + "simple": -1, + "subcategory": "Infrastructure as Code", + "text": "Use automation through ARM/TF to create your Azure resources", + "waf": "Operations" }, { - "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", + "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", "services": [ - "Subscriptions", - "RBAC", - "SAP" + "AKS", + "ASR" ], "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": "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": [ - "PrivateLink", - "NVA", - "SAP" - ], - "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": "Disaster Recovery", + "text": "Schedule and perform DR tests regularly", + "waf": "Reliability" }, { - "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", + "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", "services": [ - "Backup", - "Storage", - "SQL", - "SAP" + "LoadBalancer", + "TrafficManager", + "AKS", + "FrontDoor" ], "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": "High Availability", + "text": "Use Azure Traffic Manager or Azure Front Door as a global load balancer for region failover", + "waf": "Reliability" }, { - "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", + "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": [ - "Storage" + "AKS" ], "severity": "Medium", - "subcategory": "Governance", - "text": "Azure Storage encryption is enabled by default" + "subcategory": "High Availability", + "text": "Use Availability Zones if they are supported in your Azure region", + "waf": "Reliability" }, { - "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": "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", + "services": [ + "AKS" + ], + "severity": "High", + "subcategory": "High Availability", + "text": "Use the SLA-backed AKS offering", + "waf": "Reliability" }, { - "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": "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", + "services": [ + "Cost", + "AKS" + ], + "severity": "Low", + "simple": -1, + "subcategory": "High Availability", + "text": "Use Disruption Budgets in your pod and deployment definitions", + "waf": "Reliability" }, { - "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", + "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", "services": [ - "AKV" + "ACR", + "AKS" ], "severity": "High", - "subcategory": "Secrets", - "text": "Use Azure Key Vault to store your secrets and credentials" + "subcategory": "High Availability", + "text": "If using a private registry, configure region replication to store images in multiple regions", + "waf": "Reliability" }, { - "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", + "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", "services": [ - "AKV" + "AKS" ], - "severity": "Medium", - "subcategory": "Secrets", - "text": "It is recommended to LOCK the Azure Resources post successful deployment to safeguard against unauthorized changes" + "severity": "High", + "subcategory": "Requirements", + "text": "Define non-functional requirements such as SLAs, RTO (Recovery Time Objective) and RPO (Recovery Point Objective).", + "waf": "Reliability" }, { - "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": "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", "services": [ - "AzurePolicy", - "AKV" + "Cost", + "AKS" ], - "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": "Low", + "subcategory": "Cost", + "text": "Use an external application such as kubecost to allocate costs to different users", + "waf": "Cost" }, { - "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", + "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", "services": [ - "AzurePolicy", - "RBAC", - "AKV" + "Cost", + "AKS" ], - "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" + "severity": "Low", + "subcategory": "Cost", + "text": "Use scale down mode to delete/delallocate nodes", + "waf": "Cost" }, { - "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", + "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", "services": [ - "AzurePolicy", - "Defender", - "AKV", - "SAP" + "Cost", + "AKS" ], "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." + "subcategory": "Cost", + "text": "When required use multi-instance partioning GPU on AKS Clusters", + "waf": "Cost" }, { - "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", + "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", "services": [ - "RBAC", - "AKV", - "SAP" + "Cost", + "AKS" ], - "severity": "Medium", - "subcategory": "Secrets", - "text": "Delegate an SAP admin custom role with just-in-time access." + "severity": "Low", + "subcategory": "Cost", + "text": "If running a Dev/Test cluster use NodePool Start/Stop", + "waf": "Cost" }, { - "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", + "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, "services": [ - "AKV", - "SAP" + "AzurePolicy", + "AKS" ], "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" + "simple": -1, + "subcategory": "Compliance", + "text": "Use Azure Policy for Kubernetes to ensure cluster compliance", + "waf": "Security" }, { - "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": "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, "services": [ - "Entra", - "AKV", - "SAP" + "AKS" ], "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" + "simple": -1, + "subcategory": "Compliance", + "text": "Separate applications from the control plane with user/system nodepools", + "waf": "Security" }, { - "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", + "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", "services": [ - "AKV", - "SAP" + "AKS" ], - "severity": "Medium", - "subcategory": "Secrets", - "text": "Make sure you harden the operating system to eradicate vulnerabilities that could lead to attacks on the SAP database." + "severity": "Low", + "simple": -1, + "subcategory": "Compliance", + "text": "Add taint to your system nodepool to make it dedicated", + "waf": "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": "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, "services": [ - "AKV" + "ACR", + "AKS" ], "severity": "Medium", - "subcategory": "Secrets", - "text": "Default to Microsoft-managed keys for principal encryption functionality and use customer-managed keys when required." + "simple": -1, + "subcategory": "Compliance", + "text": "Use a private registry for your images, such as ACR", + "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": "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, "services": [ - "AKV" + "AKS" ], "severity": "Medium", - "subcategory": "Secrets", - "text": "Use an Azure Key Vault per application per environment per region." + "subcategory": "Compliance", + "text": "Scan your images for vulnerabilities", + "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": "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, "services": [ - "AKV" + "Defender", + "AKS" ], "severity": "Medium", - "subcategory": "Secrets", - "text": " " + "subcategory": "Compliance", + "text": "Use Azure Security Center to detect security posture vulnerabilities", + "waf": "Security" }, { - "category": "Storage", - "checklist": "Azure Landing Zone Review", - "guid": "d579266b-cca2-475f-aa1a-bfe9d55d04c3", + "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, "services": [ - "Storage", - "SQL" + "AKS" ], - "severity": "Medium", - "subcategory": " ", - "text": "Disk config for Oracle, SQL, HANA" + "severity": "Low", + "subcategory": "Compliance", + "text": "If required configure FIPS", + "waf": "Security" }, { - "category": "Business", - "checklist": "Multitenant architecture", - "guid": "41177955-fe8f-430b-ae72-20dc5b6880da", - "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/overview", + "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, "services": [ - "Entra" + "AKS" ], "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": "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": "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": "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": "Business", - "text": "Based on your customers' requirements, decide on the tenancy models that are appropriate for various parts of your solution." + "subcategory": "Compliance", + "text": "Define app separation requirements (namespace/nodepool/cluster)", + "waf": "Security" }, { - "category": "Business", - "checklist": "Multitenant architecture", - "guid": "f5d76ae1-7048-4ff5-abba-f1ca799578b9", - "link": "https://learn.microsoft.com/azure/marketplace/plan-saas-offer", + "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, "services": [ - "Entra" + "AKV", + "AKS" ], "severity": "Medium", - "subcategory": "Business", - "text": "When you're ready, sell your B2B multitenant solution using the Microsoft Commercial Marketplace." - }, - { - "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." + "simple": -1, + "subcategory": "Secrets", + "text": "Store your secrets in Azure Key Vault with the CSI Secrets Store driver", + "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": [], + "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, + "services": [ + "AKV", + "AKS" + ], "severity": "High", - "subcategory": "Reliability", - "text": "Understand the Noisy Neighbor antipattern. Prevent individual tenants from impacting the system's availability for other tenants." - }, - { - "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": "Reliability", - "text": "Design your multitenant solution for the level of growth that you expect. But don't overengineer for unrealistic growth." + "subcategory": "Secrets", + "text": "If using Service Principals for the cluster, refresh credentials periodically (like quarterly)", + "waf": "Security" }, { - "category": "Reliability", - "checklist": "Multitenant architecture", - "guid": "7a634a0e-1c9d-42b1-aac2-5a5378f103f1", - "link": "https://learn.microsoft.com/azure/architecture/framework/resiliency/business-metrics", - "services": [], + "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, + "services": [ + "AKV", + "AKS" + ], "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": "Secrets", + "text": "If required add Key Management Service etcd encryption", + "waf": "Security" }, { - "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": "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, + "services": [ + "AKV", + "AKS" + ], + "severity": "Low", + "subcategory": "Secrets", + "text": "If required consider using Confidential Compute for AKS", + "waf": "Security" }, { - "category": "Reliability", - "checklist": "Multitenant architecture", - "guid": "2ff55551-984b-4606-95eb-bfb9c8b36761", - "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/approaches/compute", - "services": [], + "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, + "services": [ + "AKV", + "Defender", + "AKS" + ], "severity": "Medium", - "subcategory": "Reliability", - "text": "Apply chaos engineering principles to test the reliability of your solution." + "subcategory": "Secrets", + "text": "Consider using Defender for Containers", + "waf": "Security" }, { - "category": "Security", - "checklist": "Multitenant architecture", - "guid": "8238c038-8eb2-4a02-8bd5-4908c9442c1c", - "link": "https://learn.microsoft.com/security/zero-trust", - "services": [], + "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", + "services": [ + "AKS", + "Entra" + ], "severity": "High", - "subcategory": "Security", - "text": "Apply the Zero Trust and least privilege principles in all layers of your solution." + "simple": 1, + "subcategory": "Identity", + "text": "Use managed identities instead of Service Principals", + "waf": "Security" }, { - "category": "Security", - "checklist": "Multitenant architecture", - "guid": "92160e00-6894-4102-97e0-615d4ed93c01", - "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/considerations/map-requests", + "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", "services": [ + "AKS", "Entra" ], - "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", + "simple": 1, + "subcategory": "Identity", + "text": "Integrate authentication with AAD (using the managed integration)", + "waf": "Security" }, { - "category": "Security", - "checklist": "Multitenant architecture", - "guid": "3c1538b4-5676-4b85-b451-432befb37b4f", - "link": "https://learn.microsoft.com/azure/security/fundamentals/pen-testing", - "services": [], + "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, + "services": [ + "AKS", + "Entra" + ], "severity": "Medium", - "subcategory": "Security", - "text": "Perform ongoing penetration testing and security code reviews." + "simple": -1, + "subcategory": "Identity", + "text": "Limit access to admin kubeconfig (get-credentials --admin)", + "waf": "Security" }, { - "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": "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, + "services": [ + "AKS", + "RBAC", + "Entra" + ], + "severity": "Medium", + "simple": -1, + "subcategory": "Identity", + "text": "Integrate authorization with AAD RBAC", + "waf": "Security" }, { - "category": "Security", - "checklist": "Multitenant architecture", - "guid": "30adb90d-83d4-4a2e-986e-327ffe04e7a5", - "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/considerations/domain-names", + "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, "services": [ - "DNS" + "AKS", + "RBAC", + "Entra" ], "severity": "High", - "subcategory": "Security", - "text": "Correctly manage domain names and avoid vulnerabilities like dangling DNS and subdomain takeover attacks." - }, - { - "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": "Security", - "text": "Follow service-specific guidance for multitenancy." + "simple": -1, + "subcategory": "Identity", + "text": "Use namespaces for restricting RBAC privilege in Kubernetes", + "waf": "Security" }, { - "category": "Cost Optimization", - "checklist": "Multitenant architecture", - "guid": "db30a9fc-9b1d-40f3-ab90-01f6a3e87fc8", - "link": "https://learn.microsoft.com/azure/architecture/framework/cost/design-checklist", + "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, "services": [ - "Cost" + "AKS", + "Entra" ], "severity": "Medium", - "subcategory": "Cost Optimization", - "text": "Review the Azure Well-Architected Operational Excellence checklist, which is applicable to all workloads." + "simple": -1, + "subcategory": "Identity", + "text": "For POD Identity Access Management use Azure AD Workload Identity (preview)", + "waf": "Security" }, { - "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": "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, "services": [ - "Cost" + "AKS", + "Entra" ], - "severity": "High", - "subcategory": "Cost Optimization", - "text": "Ensure you can adequately measure per-tenant consumption and correlate it with your infrastructure costs." + "severity": "Medium", + "simple": -1, + "subcategory": "Identity", + "text": "For AKS non-interactive logins use kubelogin (preview)", + "waf": "Security" }, { - "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": "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, "services": [ - "Monitor", - "Cost" + "AKS", + "Entra" ], "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." + "simple": -1, + "subcategory": "Identity", + "text": "Disable AKS local accounts", + "waf": "Security" }, { - "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": "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, + "services": [ + "AKS", + "Entra" + ], + "severity": "Low", + "simple": -1, + "subcategory": "Identity", + "text": "Configure if required Just-in-time cluster access", + "waf": "Security" }, { - "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": "Operational Excellence", - "text": "Use automation to manage the tenant lifecycle, such as onboarding, deployment, provisioning, and configuration." + "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, + "services": [ + "AKS", + "Entra" + ], + "severity": "Low", + "simple": -1, + "subcategory": "Identity", + "text": "Configure if required AAD conditional access for AKS", + "waf": "Security" }, { - "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": "Operational Excellence", - "text": "Find the right balance for deploying service updates. Consider both your tenants' requirements and your own operational requirements." + "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, + "services": [ + "AKS", + "Entra" + ], + "severity": "Low", + "simple": -1, + "subcategory": "Identity", + "text": "If required for Windows AKS workloads configure gMSA ", + "waf": "Security" }, { - "category": "Operational Excellence", - "checklist": "Multitenant architecture", - "guid": "a3f80518-d428-4c02-b2cc-dfaef47db7e2", + "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, "services": [ - "Monitor" + "AKS", + "Entra" ], - "severity": "High", - "subcategory": "Operational Excellence", - "text": "Monitor the health of the overall system, as well as each tenant." + "severity": "Medium", + "simple": -1, + "subcategory": "Identity", + "text": "For finer control consider using a managed Kubelet Identity", + "waf": "Security" }, { - "category": "Operational Excellence", - "checklist": "Multitenant architecture", - "guid": "dfb42da5-f871-4953-9e5c-da6fda3f1411", + "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, "services": [ - "Monitor" + "AppGW", + "ACR", + "AKS" ], "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." + "simple": -1, + "subcategory": "Best practices", + "text": "If using AGIC, do not share an AppGW across clusters", + "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": [], + "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, + "services": [ + "AKS" + ], "severity": "High", - "subcategory": "Operational Excellence", - "text": "Organize your Azure resources for isolation and scale." + "simple": -1, + "subcategory": "Best practices", + "text": "Do not use AKS Application Routing Add-On", + "waf": "Reliability" }, { - "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": "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, + "services": [ + "AKS" + ], "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." + "simple": -1, + "subcategory": "Best practices", + "text": "For Windows workloads use Accelerated Networking", + "waf": "Performance" }, { - "category": "Performance Efficiency", - "checklist": "Multitenant architecture", - "guid": "f0b1fbd8-689c-4ab3-be1d-ad7607d2fbfd", - "link": "https://learn.microsoft.com/azure/architecture/framework/scalability/performance-efficiency", - "services": [], + "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, + "services": [ + "LoadBalancer", + "AKS" + ], "severity": "High", - "subcategory": "Performance Efficiency", - "text": "Review the Azure Well-Architected Performance Efficiency checklist, which is applicable to all workloads." + "subcategory": "Best practices", + "text": "Use the standard ALB (as opposed to the basic one)", + "waf": "Reliability" }, { - "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": "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, + "services": [ + "VNet", + "AKS" + ], + "severity": "Medium", + "simple": -2, + "subcategory": "Best practices", + "text": "If using Azure CNI, consider using different Subnets for NodePools", + "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": "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, "services": [ - "Storage" + "Cost", + "VNet", + "PrivateLink", + "AKS" ], "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." + "simple": -1, + "subcategory": "Cost", + "text": "Use Private Endpoints (preferred) or Virtual Network Service Endpoints to access PaaS services from the cluster", + "waf": "Security" }, { - "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": "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", + "services": [ + "VPN", + "AKS" + ], + "severity": "Medium", + "subcategory": "HA", + "text": "If hybrid connectivity is required, use 2xER or ER+VPN for better availability", + "waf": "Reliability" }, { - "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", - "link": "https://azure.microsoft.com/support/legal/sla/virtual-desktop/v1_0/", + "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", "services": [ - "ASR", - "Subscriptions", - "AVD", - "VM" + "AKS" ], "severity": "High", - "subcategory": "Compute", - "text": "Determine the expected High Availability SLA for applications/desktops published through AVD" + "simple": 1, + "subcategory": "IPAM", + "text": "Choose the best CNI network plugin for your requirements (Azure CNI recommended)", + "waf": "Reliability" }, { - "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/en-us/fslogix/concepts-container-recovery-business-continuity.", - "guid": "6acc076e-f9b1-441a-a989-579e76b897e7", - "link": "https://learn.microsoft.com/azure/architecture/example-scenario/wvd/azure-virtual-desktop-multi-region-bcdr", + "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": [ - "ASR", - "Storage", - "AVD", - "VM" + "VNet", + "AKS" ], - "severity": "Medium", - "subcategory": "Compute", - "text": "Assess Geo Disaster Recovery requirements for AVD Host Pools" + "severity": "High", + "subcategory": "IPAM", + "text": "If using Azure CNI, size your subnet accordingly considering the maximum number of pods per node", + "waf": "Performance" }, { - "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 are 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", - "link": "https://docs.microsoft.com/azure/virtual-desktop/disaster-recovery", + "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, "services": [ - "ASR", - "AVD" + "AKS" ], - "severity": "Low", - "subcategory": "Compute", - "text": "Separate critical applications in different AVD Host Pools" + "severity": "High", + "simple": -1, + "subcategory": "IPAM", + "text": "If using Azure CNI, check the maximum pods/node (default 30)", + "waf": "Performance" }, { - "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/en-us/azure/virtual-machines/availability.", - "guid": "25ab225c-6f4e-4168-9fdd-dea8a4b7cdeb", - "link": "https://techcommunity.microsoft.com/t5/azure-virtual-desktop-blog/announcing-general-availability-of-support-for-azure/ba-p/3636262", - "services": [ - "ASR", - "ACR", - "AVD" + "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": [ + "VNet", + "AKS" ], - "severity": "High", - "subcategory": "Compute", - "text": "Plan the best resiliency option for AVD Host Pool deployment" + "severity": "Low", + "simple": -1, + "subcategory": "IPAM", + "text": "If using private-IP LoadBalancer services, use a dedicated subnet (not the AKS subnet)", + "waf": "Security" }, { - "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", - "link": "https://docs.microsoft.com/azure/virtual-desktop/disaster-recovery", + "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": [ - "Backup", - "ASR", - "AVD", - "VM" + "AKS" ], - "severity": "Medium", - "subcategory": "Compute", - "text": "Assess the requirement to backup AVD Session Host VMs" + "severity": "High", + "subcategory": "IPAM", + "text": "Size the service IP address range accordingly (it is going to limit the cluster scalability)", + "waf": "Reliability" }, { - "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", - "link": "https://learn.microsoft.com/azure/site-recovery/azure-to-azure-how-to-enable-zone-to-zone-disaster-recovery", + "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": [ - "ASR", - "Cost", - "VM", - "Backup", - "AVD" + "AKS" ], - "severity": "Medium", - "subcategory": "Compute", - "text": "Prepare a local DR strategy for Personal Host Pool Session Hosts" + "severity": "Low", + "simple": -2, + "subcategory": "Operations", + "text": "If required add your own CNI plugin", + "waf": "Security" }, { - "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", - "link": "https://learn.microsoft.com/azure/virtual-machines/azure-compute-gallery", + "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": [ - "ASR", - "VM", - "ACR", - "Storage", - "AVD" + "AKS" ], "severity": "Low", - "subcategory": "Dependencies", - "text": "Plan for Golden Image cross-region availability" + "simple": -2, + "subcategory": "Operations", + "text": "If required configure Public IP per node in AKS", + "waf": "Performance" }, { - "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", - "link": "https://docs.microsoft.com/azure/virtual-desktop/disaster-recovery", + "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": [ - "ASR", - "AVD" + "AKS" ], "severity": "Medium", - "subcategory": "Dependencies", - "text": "Assess Infrastructure & Application dependencies " + "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": "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", - "link": "https://docs.microsoft.com/fslogix/manage-profile-content-cncpt", + "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": [ - "ASR", - "Storage", - "AVD" + "AKS" ], - "severity": "Medium", - "subcategory": "Storage", - "text": "Assess which data need to be protected in the Profile and Office Containers" + "severity": "Low", + "simple": -1, + "subcategory": "Scalability", + "text": "Use Azure NAT Gateway as outboundType for scaling egress traffic", + "waf": "Reliability" }, { - "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", - "link": "https://docs.microsoft.com/azure/virtual-desktop/disaster-recovery", + "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": [ - "AzurePolicy", - "ASR", - "Backup", - "Storage", - "AVD" + "AKS" ], "severity": "Medium", - "subcategory": "Storage", - "text": "Build a backup protection strategy for Profile and Office Containers" + "simple": -1, + "subcategory": "Scalability", + "text": "Use Dynamic allocations of IPs in order to avoid Azure CNI IP exhaustion", + "waf": "Reliability" }, { - "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", - "link": "https://docs.microsoft.com/azure/virtual-desktop/disaster-recovery", + "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": [ - "ASR", - "Storage", - "AVD" + "AKS", + "NVA" ], - "severity": "Medium", - "subcategory": "Storage", - "text": "Assess Profile Container storage replication requirements and resiliency for BCDR purpose" + "severity": "High", + "simple": -2, + "subcategory": "Security", + "text": "Filter egress traffic with AzFW/NVA if your security requirements mandate it", + "waf": "Security" }, { - "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", - "link": "https://docs.microsoft.com/azure/backup/backup-afs", + "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": [ - "ASR", - "Storage", - "AVD", - "Backup" + "AKS" ], "severity": "Medium", - "subcategory": "Storage", - "text": "Review Azure Files disaster recovery strategy" + "simple": -1, + "subcategory": "Security", + "text": "If using a public API endpoint, restrict the IP addresses that can access it", + "waf": "Security" }, { - "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", - "link": "https://learn.microsoft.com/azure/storage/files/files-redundancy#zone-redundant-storage", + "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": [ - "ASR", - "Storage", - "AVD" + "AKS" ], "severity": "High", - "subcategory": "Storage", - "text": "Use Zone Redundant Storage (ZRS) for Azure Files to maximize resiliency" + "simple": -1, + "subcategory": "Security", + "text": "Use private clusters if your requirements mandate it", + "waf": "Security" }, { - "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/en-us/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/en-us/azure/azure-netapp-files/manage-availability-zone-volume-placement.", - "guid": "23429db7-2281-4376-85cc-57b4a4b18142", - "link": "https://learn.microsoft.com/azure/azure-netapp-files/cross-region-replication-create-peering", + "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": [ - "ASR", - "ACR", - "Backup", - "Storage", - "AVD" + "AzurePolicy", + "AKS" ], "severity": "Medium", - "subcategory": "Storage", - "text": "Review Azure NetApp Files disaster recovery strategy" + "simple": -1, + "subcategory": "Security", + "text": "For Windows 2019 and 2022 AKS nodes Calico Network Policies can be used ", + "waf": "Security" }, { - "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/set-up-golden-image", + "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": [ - "AVD" + "AzurePolicy", + "AKS" ], "severity": "High", - "subcategory": "Golden Images", - "text": "Determine how applications will be deployed in AVD Host Pools" + "subcategory": "Security", + "text": "Enable a Kubernetes Network Policy option (Calico/Azure)", + "waf": "Security" }, { - "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/set-up-golden-image", + "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": [ - "AVD" + "AzurePolicy", + "AKS" ], - "severity": "Medium", - "subcategory": "Golden Images", - "text": "Estimate the number of golden images that will be required" + "severity": "High", + "simple": -1, + "subcategory": "Security", + "text": "Use Kubernetes network policies to increase intra-cluster security", + "waf": "Security" }, { - "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/prerequisites?tabs=portal#operating-systems-and-licenses", + "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": [ - "AVD" + "WAF", + "AKS" ], - "severity": "Medium", - "subcategory": "Golden Images", - "text": "Determine which OS image/s you will use for Host Pool deployment" + "severity": "High", + "simple": -1, + "subcategory": "Security", + "text": "Use a WAF for web workloads (UIs or APIs)", + "waf": "Security" }, { - "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", - "link": "https://learn.microsoft.com/azure/virtual-machines/shared-image-galleries", + "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", - "AVD", - "VM" + "VNet", + "DDoS", + "AKS" ], - "severity": "Low", - "subcategory": "Golden Images", - "text": "Select the proper store for custom images" + "severity": "Medium", + "subcategory": "Security", + "text": "Use DDoS Standard in the AKS Virtual Network", + "waf": "Security" }, { - "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/create-custom-image-templates", + "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": [ - "AVD" + "AKS" ], "severity": "Low", - "subcategory": "Golden Images", - "text": "Design your build process for custom images" + "subcategory": "Security", + "text": "If required add company HTTP Proxy", + "waf": "Security" }, { - "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/set-up-golden-image", + "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": [ - "AVD" + "AKS" ], "severity": "Medium", - "subcategory": "Golden Images", - "text": "If custom image will be used, check recommended best practices for AVD on how to build custom image" + "simple": -2, + "subcategory": "Security", + "text": "Consider using a service mesh for advanced microservice communication management", + "waf": "Security" }, { - "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", - "link": "https://learn.microsoft.com/fslogix/how-to-install-fslogix", + "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": [ - "AVD" + "AKS", + "Monitor" ], "severity": "High", - "subcategory": "Golden Images", - "text": "Include the latest version of FSLogix in the golden image update process" + "simple": -1, + "subcategory": "Alerting", + "text": "Configure alerts on the most critical metrics (see Container Insights for recommendations)", + "waf": "Operations" }, { - "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", - "link": "https://github.com/The-Virtual-Desktop-Team/Virtual-Desktop-Optimization-Tool", + "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": [ - "RBAC", - "AVD" + "AKS", + "Entra" ], "severity": "Low", - "subcategory": "Golden Images", - "text": "Evaluate the usage of Virtual-Desktop-Optimization-Tool" + "simple": -1, + "subcategory": "Compliance", + "text": "Check regularly Azure Advisor for recommendations on your cluster", + "waf": "Operations" }, { - "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/install-office-on-wvd-master-image#install-onedrive-in-per-machine-mode", + "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": [ - "Storage", - "AVD" + "AKS" ], "severity": "Low", - "subcategory": "Golden Images", - "text": "Determine if Microsoft OneDrive will be part of AVD deployment" + "simple": 1, + "subcategory": "Compliance", + "text": "Enable AKS auto-certificate rotation", + "waf": "Operations" }, { - "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/teams-on-AVD", + "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": [ - "AVD" + "AKS" ], - "severity": "Low", - "subcategory": "Golden Images", - "text": "Determine if Microsoft Teams will be part of AVD deployment" + "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" }, { - "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/windows-11-language-packs", + "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": [ - "AVD" + "AKS" ], - "severity": "Low", - "subcategory": "Golden Images", - "text": "Assess the requirement to support multiple languages" + "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": "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", - "link": "https://docs.microsoft.com/azure/virtual-desktop/app-attach-file-share", + "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": [ - "Cost", - "Storage", - "AVD" + "AKS" ], - "severity": "Medium", - "subcategory": "MSIX & AppAttach", - "text": "Do not use the same storage account/share as FSLogix profiles" + "severity": "High", + "simple": -1, + "subcategory": "Compliance", + "text": "Have a regular process to upgrade the cluster node images periodically (weekly, for example)", + "waf": "Operations" }, { - "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", - "link": "https://docs.microsoft.com/azure/virtual-desktop/app-attach-file-share", + "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": [ + "AKS" + ], + "severity": "Low", + "subcategory": "Compliance", + "text": "Consider gitops to deploy applications or cluster configuration to multiple clusters", + "waf": "Operations" + }, + { + "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": [ - "AVD" + "AKS" ], - "severity": "Medium", - "subcategory": "MSIX & AppAttach", - "text": "Review performance considerations for MSIX" + "severity": "Low", + "subcategory": "Compliance", + "text": "Consider using AKS command invoke on private clusters", + "waf": "Operations" }, { - "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", - "link": "https://docs.microsoft.com/azure/virtual-desktop/app-attach-file-share", + "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": [ - "RBAC", - "Storage", - "AVD", - "VM" + "AKS" ], - "severity": "Medium", - "subcategory": "MSIX & AppAttach", - "text": "Check proper session host permissions for MSIX share" + "severity": "Low", + "subcategory": "Compliance", + "text": "For planned events consider using Node Auto Drain", + "waf": "Operations" }, { - "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", - "link": "https://docs.microsoft.com/azure/virtual-desktop/app-attach-faq", + "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": [ - "AVD" + "AKS" ], - "severity": "Low", - "subcategory": "MSIX & AppAttach", - "text": "MSIX packages for 3rd-party applications" + "severity": "High", + "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": "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", - "link": "https://docs.microsoft.com/azure/virtual-desktop/app-attach-faq", + "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": [ - "AVD" + "AKS" ], "severity": "Low", - "subcategory": "MSIX & AppAttach", - "text": "Disable auto-update for MSIX packages" + "simple": 1, + "subcategory": "Compliance", + "text": "Use custom Node RG (aka 'Infra RG') name", + "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", - "link": "https://docs.microsoft.com/azure/virtual-desktop/app-attach-faq", + "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": [ - "AVD" + "AKS" ], "severity": "Medium", - "subcategory": "MSIX & AppAttach", - "text": "Review operating systems support" + "simple": -1, + "subcategory": "Compliance", + "text": "Do not use deprecated Kubernetes APIs in your YAML manifests", + "waf": "Operations" }, { - "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", - "link": "https://docs.microsoft.com/azure/virtual-machines/generation-2", + "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": [ - "AVD", - "VM" + "AKS" ], - "severity": "Medium", - "subcategory": "Session Host", - "text": "Evaluate the usage of Gen2 VM for Host Pool deployment" + "severity": "Low", + "simple": -1, + "subcategory": "Compliance", + "text": "Taint Windows nodes", + "waf": "Operations" }, { - "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/multimedia-redirection", + "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": [ - "AVD" + "AKS" ], "severity": "Low", - "subcategory": "Session Host", - "text": "Consider using MMR (MultiMedia Redirection) to get better video performance on browser" + "subcategory": "Compliance", + "text": "Keep windows containers patch level in sync with host patch level", + "waf": "Operations" }, { - "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/terminology#host-pools", + "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": [ - "AVD", - "VM" + "AKS", + "Monitor" ], - "severity": "High", - "subcategory": "Capacity Planning", - "text": "Determine the Host Pool type to use" + "severity": "Low", + "subcategory": "Compliance", + "text": "Send master logs (aka API logs) to Azure Monitor or your preferred log management solution", + "waf": "Operations" }, { - "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/terminology?WT.mc_id=Portal-fx#host-pools", + "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": [ - "AVD", - "VM" + "AKS" ], - "severity": "High", - "subcategory": "Capacity Planning", - "text": "Estimate the number of different Host Pools to deploy " + "severity": "Low", + "subcategory": "Compliance", + "text": "If required use nodePool snapshots", + "waf": "Cost" }, { - "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", - "link": "https://docs.microsoft.com/azure/virtual-desktop/configure-host-pool-personal-desktop-assignment-type", + "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": [ - "AVD" + "Cost", + "AKS" ], "severity": "Low", - "subcategory": "Capacity Planning", - "text": "For Personal Host Pool type, select the proper assignment type" + "simple": -1, + "subcategory": "Cost", + "text": "Consider spot node pools for non time-sensitive workloads", + "waf": "Operations" }, { - "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", - "link": "https://docs.microsoft.com/azure/virtual-desktop/host-pool-load-balancing", + "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": [ - "AVD" + "Cost", + "AKS" ], "severity": "Low", - "subcategory": "Capacity Planning", - "text": "For Pooled Host Pool type, select the best load balancing method" + "simple": -1, + "subcategory": "Cost", + "text": "Consider AKS virtual node for quick bursting", + "waf": "Operations" }, { - "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", - "link": "https://learn.microsoft.com/windows-server/remote/remote-desktop-services/virtual-machine-recs", + "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": [ - "AVD", - "VM" + "AKS", + "Monitor" ], - "severity": "Medium", - "subcategory": "Capacity Planning", - "text": "For Pooled Host Pool type, VMs shouldn't have more than 32 cores" + "severity": "High", + "simple": -1, + "subcategory": "Monitoring", + "text": "Monitor your cluster metrics with Container Insights (or other tools like Prometheus)", + "waf": "Operations" }, { - "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/terminology?WT.mc_id=Portal-fx#application-groups", + "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", - "AVD" + "AKS", + "Monitor" ], "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" + "simple": -1, + "subcategory": "Monitoring", + "text": "Store and analyze your cluster logs with Container Insights (or other tools like Telegraf/ElasticSearch)", + "waf": "Operations" }, { - "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", - "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits#azure-virtual-desktop-service-limits", + "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": [ - "ACR", - "Entra", - "AVD" + "AKS", + "Monitor" ], "severity": "Medium", - "subcategory": "Capacity Planning", - "text": "Estimate the number of Application Groups required across all Host Pools in the Microsoft Entra ID tenant" + "simple": -1, + "subcategory": "Monitoring", + "text": "Monitor CPU and memory utilization of the nodes", + "waf": "Operations" }, { - "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", - "link": "https://learn.microsoft.com/azure/architecture/example-scenario/wvd/windows-virtual-desktop#considerations", + "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": [ - "AVD" + "AKS", + "Monitor" ], - "severity": "Low", - "subcategory": "Capacity Planning", - "text": "Estimate the number of Applications for each Application Group" + "severity": "Medium", + "simple": -1, + "subcategory": "Monitoring", + "text": "If using Azure CNI, monitor % of pod IPs consumed per node", + "waf": "Operations" }, { - "category": "Foundation", - "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", - "link": "https://learn.microsoft.com/en-us/azure/virtual-desktop/configure-host-pool-personal-desktop-assignment-type?tabs=azure#reassign-a-personal-desktop", + "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": [ "Storage", - "AVD", - "VM" + "AKS", + "Monitor", + "ServiceBus", + "EventHubs" ], - "severity": "Low", - "subcategory": "Capacity Planning", - "text": "Evaluate the usage of FSLogix for Personal Host Pools" + "severity": "Medium", + "simple": -1, + "subcategory": "Monitoring", + "text": "Monitor OS disk queue depth in nodes", + "waf": "Operations" }, { - "category": "Foundation", - "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", - "link": "https://docs.microsoft.com/windows-server/remote/remote-desktop-services/virtual-machine-recs", + "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": [ - "AVD", - "VM" + "LoadBalancer", + "AKS", + "Monitor", + "NVA" ], - "severity": "High", - "subcategory": "Capacity Planning", - "text": "Run workload performance test to determine the best Azure VM SKU and size to use" + "severity": "Medium", + "simple": -1, + "subcategory": "Monitoring", + "text": "If not using egress filtering with AzFW/NVA, monitor standard ALB allocated SNAT ports", + "waf": "Operations" }, { - "category": "Foundation", - "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", - "link": "https://learn.microsoft.com/azure/architecture/example-scenario/wvd/windows-virtual-desktop#considerations", + "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": [ - "Storage", - "AVD" + "AKS", + "Monitor" ], - "severity": "High", - "subcategory": "Capacity Planning", - "text": "Verify AVD scalability limits for the environment" + "severity": "Medium", + "subcategory": "Monitoring", + "text": "Subscribe to resource health notifications for your AKS cluster", + "waf": "Operations" }, { - "category": "Foundation", - "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", - "link": "https://docs.microsoft.com/azure/virtual-desktop/configure-vm-gpu", + "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": [ - "AVD" + "AKS" ], - "severity": "Low", - "subcategory": "Capacity Planning", - "text": "Determine if Session Hosts will require GPU" + "severity": "High", + "simple": -1, + "subcategory": "Resources", + "text": "Configure requests and limits in your pod specs", + "waf": "Operations" }, { - "category": "Foundation", - "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", - "link": "https://learn.microsoft.com/azure/virtual-network/accelerated-networking-overview", + "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": [ - "AVD", - "VM" + "AKS" ], - "severity": "Low", - "subcategory": "Capacity Planning", - "text": "Use Azure VM SKUs able to leverage Accelerated Networking" + "severity": "Medium", + "simple": -1, + "subcategory": "Resources", + "text": "Enforce resource quotas for namespaces", + "waf": "Operations" }, { - "category": "Foundation", - "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/overview", + "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": [ - "AVD" + "Subscriptions", + "AKS" ], - "severity": "Medium", - "subcategory": "Clients & Users", - "text": "Assess how many users will connect to AVD and from which regions" + "severity": "High", + "subcategory": "Resources", + "text": "Ensure your subscription has enough quota to scale out your nodepools", + "waf": "Operations" }, { - "category": "Foundation", - "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", - "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", + "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": [ - "VPN", - "Storage", - "ExpressRoute", - "AVD" + "AKS" ], "severity": "Medium", - "subcategory": "Clients & Users", - "text": "Assess external dependencies for each Host Pool" + "subcategory": "Scalability", + "text": "Use the Cluster Autoscaler", + "waf": "Performance" }, { - "category": "Foundation", - "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", - "link": "https://learn.microsoft.com/en-us/azure/virtual-desktop/users/connect-windows", + "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": [ - "AVD" + "AKS" ], "severity": "Low", - "subcategory": "Clients & Users", - "text": "Review user client OS used and AVD client type" + "subcategory": "Scalability", + "text": "Customize node configuration for AKS node pools", + "waf": "Performance" }, { - "category": "Foundation", - "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", - "link": "https://azure.microsoft.com/services/virtual-desktop/assessment/", + "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": [ + "AKS" + ], + "severity": "Medium", + "simple": -1, + "subcategory": "Scalability", + "text": "Use the Horizontal Pod Autoscaler when required", + "waf": "Performance" + }, + { + "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": [ - "AVD" + "AKS" ], "severity": "High", - "subcategory": "Clients & Users", - "text": "Run a PoC to validate end-to-end user experience and impact of network latency" + "subcategory": "Scalability", + "text": "Consider an appropriate node size, not too large or too small", + "waf": "Performance" }, { - "category": "Foundation", - "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", - "link": "https://docs.microsoft.com/azure/virtual-desktop/customize-rdp-properties", + "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": [ - "AVD" + "AKS" ], "severity": "Low", - "subcategory": "Clients & Users", - "text": "Assess and document RDP settings for all user groups" + "subcategory": "Scalability", + "text": "If more than 5000 nodes are required for scalability then consider using an additional AKS cluster", + "waf": "Performance" }, { - "category": "Foundation", - "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", - "link": "https://azure.microsoft.com/global-infrastructure/services/?products=virtual-desktop", + "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": [ - "AVD" + "AKS" ], - "severity": "High", - "subcategory": "General", - "text": "Determine in which Azure regions AVD Host Pools will be deployed." + "severity": "Low", + "subcategory": "Scalability", + "text": "Consider subscribing to EventGrid Events for AKS automation", + "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", - "link": "https://docs.microsoft.com/azure/virtual-desktop/data-locations", + "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": [ - "AVD" + "AKS" ], - "severity": "Medium", - "subcategory": "General", - "text": "Determine metadata location for AVD service" + "severity": "Low", + "subcategory": "Scalability", + "text": "For long running operation on an AKS cluster consider event termination", + "waf": "Performance" }, { - "category": "Foundation", - "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", - "link": "https://docs.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits", + "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": [ - "Storage", - "AVD", - "VM" + "AKS" ], "severity": "Low", - "subcategory": "General", - "text": "Check Azure quotas and availability for specific VM sizes and types in the selected regions" + "subcategory": "Scalability", + "text": "If required consider using Azure Dedicated Hosts for AKS nodes", + "waf": "Performance" }, { - "category": "Identity", - "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", - "link": "https://docs.microsoft.com/azure/architecture/reference-architectures/identity/adds-extend-domain", + "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": [ - "Entra", - "VNet", - "AVD", - "Storage" + "Storage", + "AKS" ], - "severity": "Medium", - "subcategory": "Active Directory", - "text": "Create at least two Active Directory Domain Controllers (DCs) in Azure VNet environment close to AVD Host Pool" + "severity": "High", + "subcategory": "Storage", + "text": "Use ephemeral OS disks", + "waf": "Performance" }, { - "category": "Identity", - "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", - "link": "https://docs.microsoft.com/azure/virtual-desktop/create-host-pools-azure-marketplace", + "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", - "AVD" + "Storage", + "AKS" ], - "severity": "Medium", - "subcategory": "Active Directory", - "text": "Create a specific OU in Active Directory for each Host Pool" + "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" }, { - "category": "Identity", - "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", - "link": "https://docs.microsoft.com/previous-versions/windows/desktop/Policy/group-policy-hierarchy", + "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": [ - "Entra", - "AVD" + "Storage", + "AKS" ], - "severity": "Medium", - "subcategory": "Active Directory", - "text": "Review Domain GPOs that will be applied to OU and impacting Host Pool Session Hosts functionalities" + "severity": "Low", + "subcategory": "Storage", + "text": "For hyper performance storage option use Ultra Disks on AKS", + "waf": "Performance" }, { - "category": "Identity", - "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", - "link": "https://learn.microsoft.com/fslogix/how-to-use-group-policy-templates", + "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", - "AVD" + "Storage", + "SQL", + "AKS" ], "severity": "Medium", - "subcategory": "Active Directory", - "text": "Configure FSLogix settings using the built-in provided GPO ADMX template" + "simple": -1, + "subcategory": "Storage", + "text": "Avoid keeping state in the cluster, and store data outside (AzStorage, AzSQL, Cosmos, etc)", + "waf": "Performance" }, { - "category": "Identity", - "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/prerequisites?tabs=portal#session-hosts", + "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": [ - "Entra", - "AVD", - "VM" + "Storage", + "AKS" ], "severity": "Medium", - "subcategory": "Active Directory", - "text": "Create a dedicated user account with only permissions to join VM to the domain" + "subcategory": "Storage", + "text": "If using AzFiles Standard, consider AzFiles Premium and/or ANF for performance reasons", + "waf": "Performance" }, { - "category": "Identity", - "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", - "link": "https://docs.microsoft.com/azure/virtual-desktop/manage-app-groups", + "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": [ - "Entra", - "AVD" + "Storage", + "AKS" ], "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)" + "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", - "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", - "link": "https://docs.microsoft.com/azure/storage/files/storage-files-identity-ad-ds-enable", + "category": "Business", + "checklist": "Multitenant architecture", + "guid": "41177955-fe8f-430b-ae72-20dc5b6880da", + "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/overview", "services": [ - "AzurePolicy", - "Storage", - "AVD", "Entra" ], "severity": "High", - "subcategory": "Active Directory", - "text": "Review your organization password expiration policy for accounts used by Azure Files AD integration" + "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": "Identity", - "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/prerequisites?tabs=portal#identity", - "services": [ - "Entra", - "AVD" - ], + "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": "Active Directory", - "text": "A Windows Server Active Directory forest/domain must be in sync with Microsoft Entra ID" + "subcategory": "Business", + "text": "Define your pricing model and ensure it aligns with your tenants' consumption of Azure resources." }, { - "category": "Identity", - "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", - "link": "https://learn.microsoft.com/azure/storage/files/storage-files-identity-auth-hybrid-identities-enable", + "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": "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": "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": "Business", + "text": "Based on your customers' requirements, decide on the tenancy models that are appropriate for various parts of your solution." + }, + { + "category": "Business", + "checklist": "Multitenant architecture", + "guid": "f5d76ae1-7048-4ff5-abba-f1ca799578b9", + "link": "https://learn.microsoft.com/azure/marketplace/plan-saas-offer", "services": [ - "Storage", - "AVD", "Entra" ], "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": "Business", + "text": "When you're ready, sell your B2B multitenant solution using the Microsoft Commercial Marketplace." }, { - "category": "Identity", - "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/prerequisites?tabs=portal#identity", - "services": [ - "Subscriptions", - "Entra", - "VNet", - "AVD" - ], + "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": "Requirements", - "text": "A Microsoft Entra ID tenant must be available with at least one subscription linked" + "subcategory": "Reliability", + "text": "Review the Azure Well-Architected Reliability checklist, which is applicable to all workloads." }, { - "category": "Identity", - "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/en-us/azure/virtual-desktop/prerequisites?tabs=portal#supported-identity-scenarios.", - "guid": "b4ce4781-7557-4a1f-8043-332ae199d44c", - "link": "https://learn.microsoft.com/azure/virtual-desktop/authentication", - "services": [ - "Entra", - "AVD" - ], + "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": "Requirements", - "text": "Review and document your identity scenario" + "subcategory": "Reliability", + "text": "Understand the Noisy Neighbor antipattern. Prevent individual tenants from impacting the system's availability for other tenants." }, { - "category": "Identity", - "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/prerequisites?tabs=portal#supported-identity-scenarios", - "services": [ - "Entra", - "AVD" - ], + "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": "Requirements", - "text": "Assess User Account types and requirements" + "subcategory": "Reliability", + "text": "Design your multitenant solution for the level of growth that you expect. But don't overengineer for unrealistic growth." }, { - "category": "Identity", - "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/authentication#single-sign-on-sso", - "services": [ - "Entra", - "AVD" - ], + "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": "Requirements", - "text": "If Single-Sign On (SSO) is a requirement, review the supported scenarios and prerequisites" + "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": "Identity", - "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/prerequisites?tabs=portal#supported-identity-scenarios", - "services": [ - "Entra", - "AVD", - "VM" - ], + "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": "Requirements", - "text": "Select the proper AVD Session Host domain join type" + "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": "Identity", - "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", - "link": "https://docs.microsoft.com/azure/active-directory-domain-services/compare-identity-solutions", - "services": [ - "Entra", - "AVD" - ], - "severity": "Low", - "subcategory": "Requirements", - "text": "Before using Azure AD Domain Services (AAD-DS) for AVD, be sure to review the limitations." + "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": "Reliability", + "text": "Apply chaos engineering principles to test the reliability of your solution." }, { - "category": "Monitoring and Management", - "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/administrative-template", - "services": [ - "Monitor", - "Entra", - "AVD" - ], - "severity": "Low", - "subcategory": "Management", - "text": "Use built-in provided administrative templates for AVD settings configuration" + "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": "Monitoring and Management", - "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/management", + "category": "Security", + "checklist": "Multitenant architecture", + "guid": "92160e00-6894-4102-97e0-615d4ed93c01", + "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/considerations/map-requests", "services": [ - "Monitor", - "AVD", - "VM" + "Entra" ], - "severity": "Low", - "subcategory": "Management", - "text": "Plan AVD Session Hosts configuration management strategy" + "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": "Monitoring and Management", - "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/en-us/mem/intune/fundamentals/windows-virtual-desktop and multi-session https://learn.microsoft.com/en-us/mem/intune/fundamentals/windows-virtual-desktop-multi-session AVD.", - "guid": "63a08be1-6004-4b4a-a79b-f3239faae113", - "link": "https://learn.microsoft.com/mem/intune/fundamentals/azure-virtual-desktop", - "services": [ - "Monitor", - "AVD" - ], + "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": "Management", - "text": "Evaluate Intune for AVD Session Hosts management" + "subcategory": "Security", + "text": "Perform ongoing penetration testing and security code reviews." }, { - "category": "Monitoring and Management", - "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/autoscale-scenarios", + "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": "Security", + "checklist": "Multitenant architecture", + "guid": "30adb90d-83d4-4a2e-986e-327ffe04e7a5", + "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/considerations/domain-names", "services": [ - "Monitor", - "Cost", - "AVD", - "VM" + "DNS" ], + "severity": "High", + "subcategory": "Security", + "text": "Correctly manage domain names and avoid vulnerabilities like dangling DNS and subdomain takeover attacks." + }, + { + "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": "Management", - "text": "Assess the requirements for host pool auto-scaling capability" + "subcategory": "Security", + "text": "Follow service-specific guidance for multitenancy." }, { - "category": "Monitoring and Management", - "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/start-virtual-machine-connect", + "category": "Cost Optimization", + "checklist": "Multitenant architecture", + "guid": "db30a9fc-9b1d-40f3-ab90-01f6a3e87fc8", + "link": "https://learn.microsoft.com/azure/architecture/framework/cost/design-checklist", "services": [ - "Monitor", - "Cost", - "AVD", - "VM" + "Cost" ], - "severity": "Low", - "subcategory": "Management", - "text": "Consider the usage of Start VM on Connect for Personal Host Pools" + "severity": "Medium", + "subcategory": "Cost Optimization", + "text": "Review the Azure Well-Architected Operational Excellence checklist, which is applicable to all workloads." }, { - "category": "Monitoring and Management", - "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/start-virtual-machine-connect-faq#are-vms-automatically-deallocated-when-a-user-stops-using-them", + "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": [ - "AzurePolicy", - "Cost", - "VM", - "Monitor", - "AVD" + "Cost" ], - "severity": "Low", - "subcategory": "Management", - "text": "Evaluate the implementation of an ad-hoc mechanism to shut down Personal AVD Session Hosts" + "severity": "High", + "subcategory": "Cost Optimization", + "text": "Ensure you can adequately measure per-tenant consumption and correlate it with your infrastructure costs." }, { - "category": "Monitoring and Management", - "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/tag-virtual-desktop-resources", + "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": [ "Cost", - "DNS", - "Monitor", - "Storage", - "VWAN", - "AVD", - "VPN", - "ExpressRoute" + "Monitor" ], - "severity": "Low", - "subcategory": "Management", - "text": "Review and adopt suggested Azure Tags for Azure Virtual Desktop" + "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." }, { - "category": "Monitoring and Management", - "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/azure-advisor-recommendations", + "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": "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": "Operational Excellence", + "text": "Use automation to manage the tenant lifecycle, such as onboarding, deployment, provisioning, and configuration." + }, + { + "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": "Operational Excellence", + "text": "Find the right balance for deploying service updates. Consider both your tenants' requirements and your own operational requirements." + }, + { + "category": "Operational Excellence", + "checklist": "Multitenant architecture", + "guid": "a3f80518-d428-4c02-b2cc-dfaef47db7e2", "services": [ - "Monitor", - "Entra", - "Cost", - "AVD" + "Monitor" ], - "severity": "Low", - "subcategory": "Management", - "text": "Periodically check Azure Advisor recommendations for AVD" + "severity": "High", + "subcategory": "Operational Excellence", + "text": "Monitor the health of the overall system, as well as each tenant." }, { - "category": "Monitoring and Management", - "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/en-us/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/en-us/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", - "link": "https://learn.microsoft.com/mem/intune/fundamentals/azure-virtual-desktop-multi-session", + "category": "Operational Excellence", + "checklist": "Multitenant architecture", + "guid": "dfb42da5-f871-4953-9e5c-da6fda3f1411", "services": [ - "Monitor", - "AVD" + "Monitor" ], "severity": "Medium", - "subcategory": "Management", - "text": "Plan for a Session Host emergency patching and update strategy" + "subcategory": "Operational Excellence", + "text": "Configure and test alerts to notify you when specific tenants are experiencing issues or are exceeding their consumption limits." }, { - "category": "Monitoring and Management", - "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/scheduled-agent-updates", + "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": "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": "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." + }, + { + "category": "Performance Efficiency", + "checklist": "Multitenant architecture", + "guid": "6acf7eb5-24a3-47c7-ae87-1196cd96048e", + "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/approaches/compute", "services": [ - "Monitor", - "AVD" + "Storage" ], - "severity": "Low", - "subcategory": "Management", - "text": "Configure the Scheduled Agent Updates feature" + "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": "Monitoring and Management", - "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", - "link": "https://docs.microsoft.com/azure/virtual-desktop/create-validation-host-pool", + "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 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": [ - "Monitor", - "AVD", - "VM" + "ServiceBus" ], - "severity": "Medium", - "subcategory": "Management", - "text": "Create a validation (canary) Host Pool" + "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": "Monitoring and Management", - "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", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/wvd/eslz-platform-automation-and-devops", + "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": [ - "Monitor", - "AVD", - "VM" + "ServiceBus" ], "severity": "Medium", - "subcategory": "Management", - "text": "Determine Host Pool deployment strategy" + "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": "Monitoring and Management", - "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", - "link": "https://docs.microsoft.com/azure/virtual-desktop/faq", + "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": [ - "Monitor", - "AVD", - "VM" + "TrafficManager", + "AzurePolicy", + "ServiceBus", + "RBAC", + "Entra" ], "severity": "Medium", - "subcategory": "Management", - "text": "Turn on Session Host VMs at least every 90 days for token refresh" + "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": "Monitoring and Management", - "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/insights", + "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": [ - "Monitor", - "AVD" + "Storage", + "AKV", + "VM", + "ServiceBus", + "AppSvc", + "Entra" ], - "severity": "High", - "subcategory": "Monitoring", - "text": "Enable monitoring for AVD" + "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/" }, { - "category": "Monitoring and Management", - "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", - "link": "https://docs.microsoft.com/azure/virtual-desktop/diagnostics-log-analytics", + "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": [ - "Monitor", - "AVD", - "VM" + "Storage", + "Subscriptions", + "ServiceBus", + "RBAC", + "Entra" ], - "severity": "Medium", - "subcategory": "Monitoring", - "text": "Enable diagnostic settings for Workspaces, Host Pools, Application Groups and Host VMs to Log Analytics workspace" + "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": "Monitoring and Management", - "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", - "link": "https://docs.microsoft.com/azure/storage/files/storage-files-monitoring?tabs=azure-portal", + "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": [ + "VNet", "Monitor", - "Storage", - "AVD" + "ServiceBus" ], "severity": "Medium", "subcategory": "Monitoring", - "text": "Create alerts on the profile storage to be alerted in case of high usage and throttling" + "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": "Monitoring and Management", - "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", - "link": "https://docs.microsoft.com/azure/virtual-desktop/set-up-service-alerts", + "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": [ - "Monitor", - "AVD" + "VNet", + "PrivateLink", + "ServiceBus" ], "severity": "Medium", - "subcategory": "Monitoring", - "text": "Configure Azure Service Health for AVD alerts " + "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": "Networking", - "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", - "link": "https://docs.microsoft.com/azure/architecture/reference-architectures/hybrid-networking/", + "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": [ - "VPN", - "NVA", - "ExpressRoute", - "AVD" + "ServiceBus" ], "severity": "Medium", "subcategory": "Networking", - "text": "Determine if hybrid connectivity is required to connect to on-premises environment" + "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": "Networking", + "category": "Business Continuity and Disaster Recovery", "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", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/wvd/eslz-network-topology-and-connectivity", + "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", + "link": "https://azure.microsoft.com/support/legal/sla/virtual-desktop/v1_0/", "services": [ - "VWAN", - "VNet", - "AVD" + "AVD", + "VM", + "ASR", + "Subscriptions" ], - "severity": "Medium", - "subcategory": "Networking", - "text": "Determine Azure Virtual Network (VNet) placement for each AVD Host Pool" + "severity": "High", + "subcategory": "Compute", + "text": "Determine the expected High Availability SLA for applications/desktops published through AVD" }, { - "category": "Networking", + "category": "Business Continuity and Disaster Recovery", "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", - "link": "https://docs.microsoft.com/azure/architecture/reference-architectures/hybrid-networking/", + "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/en-us/fslogix/concepts-container-recovery-business-continuity.", + "guid": "6acc076e-f9b1-441a-a989-579e76b897e7", + "link": "https://learn.microsoft.com/azure/architecture/example-scenario/wvd/azure-virtual-desktop-multi-region-bcdr", "services": [ - "VPN", - "AVD" + "Storage", + "AVD", + "VM", + "ASR" ], "severity": "Medium", - "subcategory": "Networking", - "text": "Assess which on-premises resources are required from AVD Host Pools" + "subcategory": "Compute", + "text": "Assess Geo Disaster Recovery requirements for AVD Host Pools" }, { - "category": "Networking", + "category": "Business Continuity and Disaster Recovery", "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", - "link": " https://docs.microsoft.com/azure/firewall/protect-windows-virtual-desktop", + "description": "Before approaching Azure Virtual Desktop BCDR planning and design, it is important to initially consider which applications are 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", + "link": "https://docs.microsoft.com/azure/virtual-desktop/disaster-recovery", "services": [ - "NVA", - "VNet", - "Firewall", - "AVD" + "AVD", + "ASR" ], - "severity": "Medium", - "subcategory": "Networking", - "text": "Need to control/restrict Internet outbound traffic for AVD hosts?" + "severity": "Low", + "subcategory": "Compute", + "text": "Separate critical applications in different AVD Host Pools" }, { - "category": "Networking", + "category": "Business Continuity and Disaster Recovery", "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", - "link": "https://docs.microsoft.com/azure/virtual-desktop/safe-url-list", + "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/en-us/azure/virtual-machines/availability.", + "guid": "25ab225c-6f4e-4168-9fdd-dea8a4b7cdeb", + "link": "https://techcommunity.microsoft.com/t5/azure-virtual-desktop-blog/announcing-general-availability-of-support-for-azure/ba-p/3636262", "services": [ - "AVD" + "AVD", + "ACR", + "ASR" ], "severity": "High", - "subcategory": "Networking", - "text": "Ensure AVD control plane endpoints are accessible" + "subcategory": "Compute", + "text": "Plan the best resiliency option for AVD Host Pool deployment" }, { - "category": "Networking", + "category": "Business Continuity and Disaster Recovery", "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", - "link": "https://learn.microsoft.com/microsoft-365/security/defender-endpoint/onboard-windows-multi-session-device?view=o365-worldwide", + "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", + "link": "https://docs.microsoft.com/azure/virtual-desktop/disaster-recovery", "services": [ - "Defender", - "AVD" + "Backup", + "AVD", + "VM", + "ASR" ], "severity": "Medium", - "subcategory": "Networking", - "text": "Need to control/restrict Internet outbound traffic only for users on AVD hosts? " + "subcategory": "Compute", + "text": "Assess the requirement to backup AVD Session Host VMs" }, { - "category": "Networking", + "category": "Business Continuity and Disaster Recovery", "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/en-us/azure/virtual-desktop/safe-url-list.", - "guid": "523181a9-4174-4158-93ff-7ae7c6d37431", - "link": "https://docs.microsoft.com/azure/firewall/protect-windows-virtual-desktop", + "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", + "link": "https://learn.microsoft.com/azure/site-recovery/azure-to-azure-how-to-enable-zone-to-zone-disaster-recovery", "services": [ - "NVA", - "Firewall", - "VNet", + "ASR", + "Backup", + "Cost", + "VM", "AVD" ], - "severity": "Low", - "subcategory": "Networking", - "text": "Review custom UDR and NSG for AVD Host Pool subnets" + "severity": "Medium", + "subcategory": "Compute", + "text": "Prepare a local DR strategy for Personal Host Pool Session Hosts" }, { - "category": "Networking", + "category": "Business Continuity and Disaster Recovery", "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/proxy-server-support", + "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", + "link": "https://learn.microsoft.com/azure/virtual-machines/azure-compute-gallery", "services": [ - "AVD", - "VM" + "Storage", + "ACR", + "ASR", + "VM", + "AVD" ], - "severity": "High", - "subcategory": "Networking", - "text": "Do not use Proxy servers, SSL termination and Deep Packet Inspection for AVD control plane traffic" + "severity": "Low", + "subcategory": "Dependencies", + "text": "Plan for Golden Image cross-region availability" }, { - "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/rdp-bandwidth", + "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", + "link": "https://docs.microsoft.com/azure/virtual-desktop/disaster-recovery", "services": [ "AVD", - "VM" + "ASR" ], - "severity": "Low", - "subcategory": "Networking", - "text": "Check the network bandwidth required for each user and in total for the VM SKU" + "severity": "Medium", + "subcategory": "Dependencies", + "text": "Assess Infrastructure & Application dependencies " }, { - "category": "Networking", + "category": "Business Continuity and Disaster Recovery", "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", - "link": "https://learn.microsoft.com/azure/storage/files/storage-files-networking-endpoints", + "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", + "link": "https://docs.microsoft.com/fslogix/manage-profile-content-cncpt", "services": [ - "Cost", - "PrivateLink", "Storage", - "VNet", - "AVD" + "AVD", + "ASR" ], "severity": "Medium", - "subcategory": "Networking", - "text": "Evaluate usage Private Endpoint for Azure Files share" + "subcategory": "Storage", + "text": "Assess which data need to be protected in the Profile and Office Containers" }, { - "category": "Networking", + "category": "Business Continuity and Disaster Recovery", "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/en-us/azure/virtual-desktop/rdp-shortpath?tabs=managed-networks#key-benefits.", - "guid": "b2074747-d01a-4f61-b1aa-92ad793d9ff4", - "link": "https://docs.microsoft.com/azure/virtual-desktop/shortpath", + "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", + "link": "https://docs.microsoft.com/azure/virtual-desktop/disaster-recovery", "services": [ - "VPN", + "Storage", + "ASR", + "Backup", + "AzurePolicy", "AVD" ], "severity": "Medium", - "subcategory": "Networking", - "text": "Evaluate usage of RDP ShortPath for clients connecting from managed internal networks" + "subcategory": "Storage", + "text": "Build a backup protection strategy for Profile and Office Containers" }, { - "category": "Security", + "category": "Business Continuity and Disaster Recovery", "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/security-guide#establish-maximum-inactive-time-and-disconnection-policies", + "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", + "link": "https://docs.microsoft.com/azure/virtual-desktop/disaster-recovery", "services": [ - "AVD" + "Storage", + "AVD", + "ASR" ], "severity": "Medium", - "subcategory": "Active Directory", - "text": "Review Active Directory GPO to secure RDP sessions" + "subcategory": "Storage", + "text": "Assess Profile Container storage replication requirements and resiliency for BCDR purpose" }, { - "category": "Security", + "category": "Business Continuity and Disaster Recovery", "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", - "link": "https://learn.microsoft.com/microsoft-365/security/defender-endpoint/deployment-vdi-microsoft-defender-antivirus", + "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", + "link": "https://docs.microsoft.com/azure/backup/backup-afs", "services": [ - "Defender", - "AVD" + "Storage", + "AVD", + "Backup", + "ASR" ], - "severity": "High", - "subcategory": "Host Configuration", - "text": "Ensure anti-virus and anti-malware solutions are used" + "severity": "Medium", + "subcategory": "Storage", + "text": "Review Azure Files disaster recovery strategy" }, { - "category": "Security", + "category": "Business Continuity and Disaster Recovery", "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", - "link": "https://learn.microsoft.com/azure/virtual-machines/disk-encryption-overview", + "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", + "link": "https://learn.microsoft.com/azure/storage/files/files-redundancy#zone-redundant-storage", "services": [ "Storage", - "AKV", "AVD", - "VM" + "ASR" ], - "severity": "Low", - "subcategory": "Host Configuration", - "text": "Assess disk encryption requirements for AVD Session Hosts" + "severity": "High", + "subcategory": "Storage", + "text": "Use Zone Redundant Storage (ZRS) for Azure Files to maximize resiliency" }, { - "category": "Security", + "category": "Business Continuity and Disaster Recovery", "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/security-guide#azure-virtual-desktop-support-for-trusted-launch", + "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/en-us/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/en-us/azure/azure-netapp-files/manage-availability-zone-volume-placement.", + "guid": "23429db7-2281-4376-85cc-57b4a4b18142", + "link": "https://learn.microsoft.com/azure/azure-netapp-files/cross-region-replication-create-peering", "services": [ - "Monitor", - "AVD", - "VM" + "Storage", + "ACR", + "ASR", + "Backup", + "AVD" ], "severity": "Medium", - "subcategory": "Host Configuration", - "text": "Enable Trusted launch in Azure Gen2 VM Session Hosts" + "subcategory": "Storage", + "text": "Review Azure NetApp Files disaster recovery strategy" }, { - "category": "Security", + "category": "Compute", "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", - "link": "https://learn.microsoft.com/windows/whats-new/windows-11-requirements", + "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/set-up-golden-image", "services": [ - "AVD", - "VM" + "AVD" ], "severity": "High", - "subcategory": "Host Configuration", - "text": "Enable Trusted Launch and use Gen2 image are system requirements for Windows 11" + "subcategory": "Golden Images", + "text": "Determine how applications will be deployed in AVD Host Pools" }, { - "category": "Security", + "category": "Compute", "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/screen-capture-protection", + "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/set-up-golden-image", "services": [ "AVD" ], - "severity": "Low", - "subcategory": "Host Configuration", - "text": "Consider enabling screen capture protection to prevent sensitive information from being captured" + "severity": "Medium", + "subcategory": "Golden Images", + "text": "Estimate the number of golden images that will be required" }, { - "category": "Security", + "category": "Compute", "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/security-guide#other-security-tips-for-session-hosts", + "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/prerequisites?tabs=portal#operating-systems-and-licenses", "services": [ "AVD" ], "severity": "Medium", - "subcategory": "Host Configuration", - "text": "Restrict device redirection and drive mapping" + "subcategory": "Golden Images", + "text": "Determine which OS image/s you will use for Host Pool deployment" }, { - "category": "Security", + "category": "Compute", "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", - "link": "https://learn.microsoft.com/microsoft-365/security/defender-endpoint/web-protection-overview", + "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", + "link": "https://learn.microsoft.com/azure/virtual-machines/shared-image-galleries", + "services": [ + "Storage", + "AVD", + "VM" + ], + "severity": "Low", + "subcategory": "Golden Images", + "text": "Select the proper store for custom images" + }, + { + "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/create-custom-image-templates", "services": [ "AVD" ], - "severity": "Medium", - "subcategory": "Management", - "text": "When possible, prefer Remote Apps over Full Desktops (DAG)" + "severity": "Low", + "subcategory": "Golden Images", + "text": "Design your build process for custom images" }, { - "category": "Security", + "category": "Compute", "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", - "link": "https://learn.microsoft.com/microsoft-365/security/defender-endpoint/web-protection-overview", + "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/set-up-golden-image", "services": [ - "Defender", "AVD" ], "severity": "Medium", - "subcategory": "Management", - "text": "Need to control/restrict user Internet navigation from AVD session hosts?" + "subcategory": "Golden Images", + "text": "If custom image will be used, check recommended best practices for AVD on how to build custom image" }, { - "category": "Security", + "category": "Compute", "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", - "link": "https://docs.microsoft.com/azure/virtual-desktop/security-guide", + "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", + "link": "https://learn.microsoft.com/fslogix/how-to-install-fslogix", "services": [ "AVD" ], "severity": "High", - "subcategory": "Management", - "text": "Ensure AVD users will not have local administrator privileges on AVD Hosts" + "subcategory": "Golden Images", + "text": "Include the latest version of FSLogix in the golden image update process" }, { - "category": "Security", + "category": "Compute", "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/en-us/azure/virtual-desktop/security-guide#improve-your-secure-score.", - "guid": "1814387e-5ca9-4c26-a9b3-2ab5bdfc6998", - "link": "https://learn.microsoft.com/azure/virtual-desktop/security-guide#enable-microsoft-defender-for-cloud", + "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", + "link": "https://github.com/The-Virtual-Desktop-Team/Virtual-Desktop-Optimization-Tool", "services": [ - "Defender", - "VM", - "Subscriptions", - "AKV", - "Storage", - "AVD" + "AVD", + "RBAC" ], - "severity": "Medium", - "subcategory": "Management", - "text": "Enable Microsoft Defender for Cloud to manage AVD Session Hosts security posture" + "severity": "Low", + "subcategory": "Golden Images", + "text": "Evaluate the usage of Virtual-Desktop-Optimization-Tool" }, { - "category": "Security", + "category": "Compute", "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/security-guide#collect-audit-logs", + "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/install-office-on-wvd-master-image#install-onedrive-in-per-machine-mode", "services": [ - "Monitor", - "Entra", + "Storage", "AVD" ], - "severity": "Medium", - "subcategory": "Management", - "text": "Enable diagnostic and audit logging" + "severity": "Low", + "subcategory": "Golden Images", + "text": "Determine if Microsoft OneDrive will be part of AVD deployment" }, { - "category": "Security", + "category": "Compute", "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", - "link": "https://docs.microsoft.com/azure/virtual-desktop/rbac", + "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/teams-on-AVD", "services": [ - "RBAC", - "Entra", "AVD" ], "severity": "Low", - "subcategory": "Management", - "text": "Assess the requirement to use custom RBAC roles for AVD management" + "subcategory": "Golden Images", + "text": "Determine if Microsoft Teams will be part of AVD deployment" }, { - "category": "Security", + "category": "Compute", "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/security-guide#windows-defender-application-control", + "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/windows-11-language-packs", "services": [ - "Defender", "AVD" ], - "severity": "Medium", - "subcategory": "Management", - "text": "Restrict users from installing un-authorized applications" + "severity": "Low", + "subcategory": "Golden Images", + "text": "Assess the requirement to support multiple languages" }, { - "category": "Security", + "category": "Compute", "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/set-up-mfa", + "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", + "link": "https://docs.microsoft.com/azure/virtual-desktop/app-attach-file-share", "services": [ - "Entra", - "AVD" + "Storage", + "AVD", + "Cost" ], "severity": "Medium", - "subcategory": "Microsoft Entra ID", - "text": "Evaluate the usage of Multi-Factor Authentication (MFA) and Conditional Access (CA) for AVD users" + "subcategory": "MSIX & AppAttach", + "text": "Do not use the same storage account/share as FSLogix profiles" }, { - "category": "Security", + "category": "Compute", "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", - "link": "https://learn.microsoft.com/security/zero-trust/azure-infrastructure-avd", + "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", + "link": "https://docs.microsoft.com/azure/virtual-desktop/app-attach-file-share", "services": [ "AVD" ], "severity": "Medium", - "subcategory": "Zero Trust", - "text": "Review and Apply Zero Trust principles and guidance" + "subcategory": "MSIX & AppAttach", + "text": "Review performance considerations for MSIX" }, { - "category": "Storage", + "category": "Compute", "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/fslogix-containers-azure-files#best-practices-for-azure-virtual-desktop", + "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", + "link": "https://docs.microsoft.com/azure/virtual-desktop/app-attach-file-share", "services": [ "Storage", - "AVD" + "AVD", + "VM", + "RBAC" ], "severity": "Medium", - "subcategory": "Azure Files", - "text": "Check best-practices for Azure Files" + "subcategory": "MSIX & AppAttach", + "text": "Check proper session host permissions for MSIX share" }, { - "category": "Storage", + "category": "Compute", "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", - "link": "https://learn.microsoft.com/azure/storage/files/storage-files-smb-multichannel-performance", + "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", + "link": "https://docs.microsoft.com/azure/virtual-desktop/app-attach-faq", "services": [ - "ACR", - "Storage", - "Cost", "AVD" ], "severity": "Low", - "subcategory": "Azure Files", - "text": "Enable SMB multichannel when using a premium file share to host FSLogix profile containers." + "subcategory": "MSIX & AppAttach", + "text": "MSIX packages for 3rd-party applications" }, { - "category": "Storage", + "category": "Compute", "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", - "link": "https://azure.microsoft.com/global-infrastructure/services/", + "description": "MSIX app attach doesn't support auto-update for MSIX applications, so they should be disabled.", + "guid": "bb88037f-5e6b-4fbb-aed5-03547cc447e8", + "link": "https://docs.microsoft.com/azure/virtual-desktop/app-attach-faq", "services": [ - "Storage", "AVD" ], - "severity": "Medium", - "subcategory": "Azure NetApp Files", - "text": "If NetApp Files storage is required, check storage service availability in your specific region." + "severity": "Low", + "subcategory": "MSIX & AppAttach", + "text": "Disable auto-update for MSIX packages" }, { - "category": "Storage", + "category": "Compute", "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/create-fslogix-profile-container", + "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", + "link": "https://docs.microsoft.com/azure/virtual-desktop/app-attach-faq", "services": [ - "Storage", "AVD" ], "severity": "Medium", - "subcategory": "Azure NetApp Files", - "text": "If NetApp Files storage is used enable CA (Continuous Availability) option to increase resiliency" + "subcategory": "MSIX & AppAttach", + "text": "Review operating systems support" }, { - "category": "Storage", + "category": "Compute", "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", - "link": "https://docs.microsoft.com/azure/azure-netapp-files/create-active-directory-connections", + "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", + "link": "https://docs.microsoft.com/azure/virtual-machines/generation-2", "services": [ - "Storage", - "VNet", - "AVD" + "AVD", + "VM" ], - "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" + "severity": "Medium", + "subcategory": "Session Host", + "text": "Evaluate the usage of Gen2 VM for Host Pool deployment" }, { - "category": "Storage", + "category": "Compute", "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", - "link": "https://docs.microsoft.com/azure/virtual-machines/disks-types", + "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/multimedia-redirection", "services": [ - "Storage", "AVD" ], - "severity": "Medium", - "subcategory": "Capacity Planning", - "text": "Determine which type of managed disk will be used for the Session Hosts" + "severity": "Low", + "subcategory": "Session Host", + "text": "Consider using MMR (MultiMedia Redirection) to get better video performance on browser" }, { - "category": "Storage", + "category": "Foundation", "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", - "link": "https://docs.microsoft.com/azure/virtual-desktop/store-fslogix-profile", + "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/terminology#host-pools", "services": [ - "Storage", "AVD", "VM" ], "severity": "High", "subcategory": "Capacity Planning", - "text": "Determine which storage backend solution will be used for FSLogix Profiles" + "text": "Determine the Host Pool type to use" }, { - "category": "Storage", + "category": "Foundation", "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/store-fslogix-profile", + "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/terminology?WT.mc_id=Portal-fx#host-pools", "services": [ - "Storage", - "AVD" + "AVD", + "VM" ], "severity": "High", "subcategory": "Capacity Planning", - "text": "Do not share storage and profiles between different Host Pools" + "text": "Estimate the number of different Host Pools to deploy " }, { - "category": "Storage", + "category": "Foundation", "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", - "link": "https://learn.microsoft.com/azure/virtual-desktop/faq#what-s-the-largest-profile-size-fslogix-can-handle-", + "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", + "link": "https://docs.microsoft.com/azure/virtual-desktop/configure-host-pool-personal-desktop-assignment-type", "services": [ - "Storage", "AVD" ], - "severity": "High", + "severity": "Low", "subcategory": "Capacity Planning", - "text": "Verify storage scalability limits and Host Pool requirements" + "text": "For Personal Host Pool type, select the proper assignment type" }, { - "category": "Storage", + "category": "Foundation", "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", - "link": "https://docs.microsoft.com/azure/virtual-desktop/fslogix-containers-azure-files", + "description": "Check which one to use and available options, autoscale ignores existing load-balancing algorithms.", + "guid": "cbd8682a-6abc-4a2a-9fda-1dbf3dc95d48", + "link": "https://docs.microsoft.com/azure/virtual-desktop/host-pool-load-balancing", "services": [ - "Cost", - "Storage", "AVD" ], - "severity": "High", + "severity": "Low", "subcategory": "Capacity Planning", - "text": "For optimal performance, the storage solution and the FSLogix profile container should be in the same Azure region." - }, - { - "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", - "link": "https://learn.microsoft.com/fslogix/concepts-container-types#when-to-use-profile-and-odfc-containers", - "services": [ - "ASR", - "Storage", - "AVD" - ], - "severity": "High", - "subcategory": "FSLogix", - "text": "Do not use Office Containers (ODFC) if not strictly required and justified" + "text": "For Pooled Host Pool type, select the best load balancing method" }, { - "category": "Storage", + "category": "Foundation", "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", - "link": "https://learn.microsoft.com/fslogix/overview-prerequisites#configure-antivirus-file-and-folder-exclusions", + "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", + "link": "https://learn.microsoft.com/windows-server/remote/remote-desktop-services/virtual-machine-recs", "services": [ - "Storage", - "AVD" + "AVD", + "VM" ], "severity": "Medium", - "subcategory": "FSLogix", - "text": "Configure the recommended antivirus exclusions for FSLogix (includes not scanning VHD(x) files on connect)." + "subcategory": "Capacity Planning", + "text": "For Pooled Host Pool type, VMs shouldn't have more than 32 cores" }, { - "category": "Storage", + "category": "Foundation", "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", - "link": "https://docs.microsoft.com/fslogix/profile-container-configuration-reference", + "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/terminology?WT.mc_id=Portal-fx#application-groups", "services": [ "Storage", "AVD" ], "severity": "High", - "subcategory": "FSLogix", - "text": "Review and confirm configured maximum profile size in FSLogix" + "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" }, { - "category": "Storage", + "category": "Foundation", "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", - "link": "https://learn.microsoft.com/fslogix/concepts-configuration-examples", + "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", + "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits#azure-virtual-desktop-service-limits", "services": [ - "ACR", - "Storage", - "AKV", - "AVD" + "AVD", + "ACR", + "Entra" ], - "severity": "High", - "subcategory": "FSLogix", - "text": "Review FSLogix registry keys and determine which ones to apply" + "severity": "Medium", + "subcategory": "Capacity Planning", + "text": "Estimate the number of Application Groups required across all Host Pools in the Microsoft Entra ID tenant" }, { - "category": "Storage", + "category": "Foundation", "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", - "link": "https://learn.microsoft.com/fslogix/concepts-multi-concurrent-connections", + "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", + "link": "https://learn.microsoft.com/azure/architecture/example-scenario/wvd/windows-virtual-desktop#considerations", "services": [ - "Storage", "AVD" ], - "severity": "High", - "subcategory": "FSLogix", - "text": "Avoid usage of concurrent or multiple connections" + "severity": "Low", + "subcategory": "Capacity Planning", + "text": "Estimate the number of Applications for each Application Group" }, { - "category": "Storage", + "category": "Foundation", "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/en-us/fslogix/concepts-fslogix-cloud-cache. ", - "guid": "b2d1215a-e114-4ba3-9df5-85ecdcd9bd3b", - "link": "https://docs.microsoft.com/fslogix/cloud-cache-configuration-reference", + "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", + "link": "https://learn.microsoft.com/en-us/azure/virtual-desktop/configure-host-pool-personal-desktop-assignment-type?tabs=azure#reassign-a-personal-desktop", "services": [ "Storage", "AVD", "VM" ], "severity": "Low", - "subcategory": "FSLogix", - "text": "If FSLogix Cloud Cache is used, consider moving the cache directory to the VM temporary drive." + "subcategory": "Capacity Planning", + "text": "Evaluate the usage of FSLogix for Personal Host Pools" }, { - "category": "Storage", + "category": "Foundation", "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", - "link": "https://docs.microsoft.com/fslogix/manage-profile-content-cncpt#redirectionsxml", - "services": [ - "Storage", - "AVD" - ], - "severity": "Medium", - "subcategory": "FSLogix", - "text": "Review the usage of FSLogix redirection." - }, - { - "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", + "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", + "link": "https://docs.microsoft.com/windows-server/remote/remote-desktop-services/virtual-machine-recs", "services": [ - "RBAC", - "Entra" + "AVD", + "VM" ], "severity": "High", - "subcategory": "Identity", - "text": "Create a service principal and its role assignments before creating the ARO clusters.", - "waf": "Security" + "subcategory": "Capacity Planning", + "text": "Run workload performance test to determine the best Azure VM SKU and size to use" }, { - "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": "Foundation", + "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", + "link": "https://learn.microsoft.com/azure/architecture/example-scenario/wvd/windows-virtual-desktop#considerations", "services": [ - "Entra" + "Storage", + "AVD" ], "severity": "High", - "subcategory": "Identity", - "text": "Use AAD to authenticate users in your ARO cluster.", - "waf": "Security" + "subcategory": "Capacity Planning", + "text": "Verify AVD scalability limits for the environment" }, { - "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.03", - "link": "https://docs.openshift.com/container-platform/4.13/applications/projects/working-with-projects.html", + "category": "Foundation", + "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", + "link": "https://docs.microsoft.com/azure/virtual-desktop/configure-vm-gpu", "services": [ - "RBAC", - "Entra" + "AVD" ], - "severity": "High", - "subcategory": "Identity", - "text": "Define OpenShift projects to restrict RBAC privilege and isolate workloads in your cluster.", - "waf": "Security" + "severity": "Low", + "subcategory": "Capacity Planning", + "text": "Determine if Session Hosts will require GPU" }, { - "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.04", - "link": "https://docs.openshift.com/container-platform/4.13/authentication/using-rbac.html", + "category": "Foundation", + "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", + "link": "https://learn.microsoft.com/azure/virtual-network/accelerated-networking-overview", "services": [ - "RBAC", - "Entra" + "AVD", + "VM" ], - "severity": "Medium", - "subcategory": "Identity", - "text": "Define the required RBAC roles in OpenShift are scoped to either a project or a cluster.", - "waf": "Security" + "severity": "Low", + "subcategory": "Capacity Planning", + "text": "Use Azure VM SKUs able to leverage Accelerated Networking" }, { - "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.05", - "link": "https://learn.microsoft.com/azure/cost-management-billing/manage/direct-ea-administration#manage-notification-contacts", + "category": "Foundation", + "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/overview", "services": [ - "Entra", - "AKV" + "AVD" ], "severity": "Medium", - "subcategory": "Identity", - "text": "Minimize the number of users who have administrator rights and secrets access.", - "waf": "Security" + "subcategory": "Clients & Users", + "text": "Assess how many users will connect to AVD and from which regions" }, { - "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.06", - "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-configure", + "category": "Foundation", + "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", + "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": [ - "RBAC", - "Entra" + "Storage", + "AVD", + "VPN", + "ExpressRoute" ], "severity": "Medium", - "subcategory": "Identity", - "text": "Use Privileged Identity Management in AAD for ARO users with privileged roles.", - "waf": "Security" + "subcategory": "Clients & Users", + "text": "Assess external dependencies for each Host Pool" }, { - "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": "Foundation", + "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", + "link": "https://learn.microsoft.com/en-us/azure/virtual-desktop/users/connect-windows", "services": [ - "DDoS", - "Subscriptions", - "Entra", - "WAF", - "Firewall", - "VNet" + "AVD" ], "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" + "subcategory": "Clients & Users", + "text": "Review user client OS used and AVD client type" }, { - "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": [], + "category": "Foundation", + "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", + "link": "https://azure.microsoft.com/services/virtual-desktop/assessment/", + "services": [ + "AVD" + ], "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": "Clients & Users", + "text": "Run a PoC to validate end-to-end user experience and impact of network latency" }, { - "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", + "category": "Foundation", + "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", + "link": "https://docs.microsoft.com/azure/virtual-desktop/customize-rdp-properties", "services": [ - "FrontDoor", - "WAF" + "AVD" ], - "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": "Low", + "subcategory": "Clients & Users", + "text": "Assess and document RDP settings for all user groups" }, { - "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", + "category": "Foundation", + "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", + "link": "https://azure.microsoft.com/global-infrastructure/services/?products=virtual-desktop", "services": [ - "PrivateLink", - "FrontDoor" + "AVD" ], - "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": "General", + "text": "Determine in which Azure regions AVD Host Pools will be deployed." }, { - "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", + "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", + "link": "https://docs.microsoft.com/azure/virtual-desktop/data-locations", "services": [ - "AzurePolicy", - "NVA", - "Firewall" + "AVD" ], "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" + "subcategory": "General", + "text": "Determine metadata location for AVD service" }, { - "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": "Foundation", + "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", + "link": "https://docs.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits", "services": [ - "AzurePolicy" + "Storage", + "AVD", + "VM" ], - "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": "Low", + "subcategory": "General", + "text": "Check Azure quotas and availability for specific VM sizes and types in the selected regions" }, { - "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": "Identity", + "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", + "link": "https://docs.microsoft.com/azure/architecture/reference-architectures/identity/adds-extend-domain", "services": [ - "PrivateLink", - "ACR" + "Storage", + "AVD", + "VNet", + "Entra" ], "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": "Active Directory", + "text": "Create at least two Active Directory Domain Controllers (DCs) in Azure VNet environment close to AVD Host Pool" }, { - "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": "Identity", + "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", + "link": "https://docs.microsoft.com/azure/virtual-desktop/create-host-pools-azure-marketplace", "services": [ - "Monitor" + "AVD", + "Entra" ], - "severity": "High", - "subcategory": "Operations", - "text": "Establish a monitoring process using the inbuilt Prometheus, OpenShift Logging or Container Insights integration.", - "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.", - "waf": "Operations" + "subcategory": "Active Directory", + "text": "Create a specific OU in Active Directory for each Host Pool" }, { - "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/active-directory-domain-services/overview", - "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": "Identity", + "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", + "link": "https://docs.microsoft.com/previous-versions/windows/desktop/Policy/group-policy-hierarchy", + "services": [ + "AVD", + "Entra" + ], + "severity": "Medium", + "subcategory": "Active Directory", + "text": "Review Domain GPOs that will be applied to OU and impacting Host Pool Session Hosts functionalities" }, { - "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": "Identity", + "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", + "link": "https://learn.microsoft.com/fslogix/how-to-use-group-policy-templates", "services": [ - "Storage" + "AVD", + "Entra" ], - "severity": "Low", - "subcategory": "Operations", - "text": "Use RWX storage with inbuilt Azure Files storage class.", - "waf": "Operations" + "severity": "Medium", + "subcategory": "Active Directory", + "text": "Configure FSLogix settings using the built-in provided GPO ADMX template" }, { - "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": [], + "category": "Identity", + "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/prerequisites?tabs=portal#session-hosts", + "services": [ + "AVD", + "VM", + "Entra" + ], "severity": "Medium", - "subcategory": "Performance", - "text": "Use pod requests and limits to manage the compute resources within a cluster.", - "waf": "Performance" + "subcategory": "Active Directory", + "text": "Create a dedicated user account with only permissions to join VM to the domain" }, { - "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": [], + "category": "Identity", + "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", + "link": "https://docs.microsoft.com/azure/virtual-desktop/manage-app-groups", + "services": [ + "AVD", + "Entra" + ], "severity": "Medium", - "subcategory": "Performance", - "text": "Enforce resource quotas on projects.", - "waf": "Performance" + "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)" }, { - "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": "Identity", + "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", + "link": "https://docs.microsoft.com/azure/storage/files/storage-files-identity-ad-ds-enable", + "services": [ + "Storage", + "AVD", + "AzurePolicy", + "Entra" + ], "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": "Active Directory", + "text": "Review your organization password expiration policy for accounts used by Azure Files AD integration" }, { - "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": "Identity", + "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/prerequisites?tabs=portal#identity", "services": [ - "VM" + "AVD", + "Entra" ], "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" + "subcategory": "Active Directory", + "text": "A Windows Server Active Directory forest/domain must be in sync with Microsoft Entra ID" }, { - "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": "Reliability", - "text": "Deploy machine health checks to automatically repair damaged machines in a machine pool.", - "waf": "Reliability" + "category": "Identity", + "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", + "link": "https://learn.microsoft.com/azure/storage/files/storage-files-identity-auth-hybrid-identities-enable", + "services": [ + "Storage", + "AVD", + "Entra" + ], + "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" }, { - "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": "Identity", + "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/prerequisites?tabs=portal#identity", "services": [ - "Monitor" + "AVD", + "VNet", + "Subscriptions", + "Entra" ], "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.", - "waf": "Reliability" + "subcategory": "Requirements", + "text": "A Microsoft Entra ID tenant must be available with at least one subscription linked" }, { - "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": "Identity", + "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/en-us/azure/virtual-desktop/prerequisites?tabs=portal#supported-identity-scenarios.", + "guid": "b4ce4781-7557-4a1f-8043-332ae199d44c", + "link": "https://learn.microsoft.com/azure/virtual-desktop/authentication", + "services": [ + "AVD", + "Entra" + ], "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": "Requirements", + "text": "Review and document your identity scenario" }, { - "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": "Identity", + "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/prerequisites?tabs=portal#supported-identity-scenarios", "services": [ - "AKS" + "AVD", + "Entra" ], - "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" + "severity": "Medium", + "subcategory": "Requirements", + "text": "Assess User Account types and requirements" }, { - "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": "Identity", + "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/authentication#single-sign-on-sso", "services": [ - "Backup" + "AVD", + "Entra" ], "severity": "Medium", - "subcategory": "Reliability", - "text": "Create application backup and plan for restore and include persistent volumes in the backup.", - "waf": "Reliability" + "subcategory": "Requirements", + "text": "If Single-Sign On (SSO) is a requirement, review the supported scenarios and prerequisites" }, { - "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": "Identity", + "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/prerequisites?tabs=portal#supported-identity-scenarios", + "services": [ + "AVD", + "VM", + "Entra" + ], + "severity": "High", + "subcategory": "Requirements", + "text": "Select the proper AVD Session Host domain join type" }, { - "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": "Identity", + "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", + "link": "https://docs.microsoft.com/azure/active-directory-domain-services/compare-identity-solutions", "services": [ - "AzurePolicy" + "AVD", + "Entra" ], "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": "Requirements", + "text": "Before using Azure AD Domain Services (AAD-DS) for AVD, be sure to review the limitations." }, { - "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": "Monitoring and Management", + "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/administrative-template", "services": [ - "ACR" + "AVD", + "Monitor", + "Entra" ], "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": "Workload", - "text": "Optimize the CPU and memory request values, and maximize the efficiency of the cluster resources using vertical pod autoscaler.", - "waf": "Performance" + "subcategory": "Management", + "text": "Use built-in provided administrative templates for AVD settings configuration" }, { - "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": "Monitoring and Management", + "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/management", "services": [ + "AVD", + "VM", "Monitor" ], - "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": "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" + "severity": "Low", + "subcategory": "Management", + "text": "Plan AVD Session Hosts configuration management strategy" }, { - "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": "Monitoring and Management", + "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/en-us/mem/intune/fundamentals/windows-virtual-desktop and multi-session https://learn.microsoft.com/en-us/mem/intune/fundamentals/windows-virtual-desktop-multi-session AVD.", + "guid": "63a08be1-6004-4b4a-a79b-f3239faae113", + "link": "https://learn.microsoft.com/mem/intune/fundamentals/azure-virtual-desktop", "services": [ - "Cost" + "AVD", + "Monitor" ], "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": "Management", + "text": "Evaluate Intune for AVD Session Hosts management" }, { - "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": "Monitoring and Management", + "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/autoscale-scenarios", + "services": [ + "AVD", + "Cost", + "VM", + "Monitor" + ], "severity": "Medium", - "subcategory": "Workload", - "text": "Use pod topology constraints to automatically schedule pods on nodes throughout the cluster.", - "waf": "Reliability" + "subcategory": "Management", + "text": "Assess the requirements for host pool auto-scaling capability" }, { - "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": [], + "category": "Monitoring and Management", + "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/start-virtual-machine-connect", + "services": [ + "AVD", + "Cost", + "VM", + "Monitor" + ], "severity": "Low", - "subcategory": "Workload", - "text": "Consider blue/green or canary strategies to deploy new releases of application.", - "waf": "Operations" + "subcategory": "Management", + "text": "Consider the usage of Start VM on Connect for Personal Host Pools" }, { - "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": [], + "category": "Monitoring and Management", + "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/start-virtual-machine-connect-faq#are-vms-automatically-deallocated-when-a-user-stops-using-them", + "services": [ + "Monitor", + "Cost", + "AzurePolicy", + "VM", + "AVD" + ], "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": "Control plane", - "text": "Keep your clusters on the latest OpenShift version to avoid potential security or upgrade issues.", - "waf": "Security" - }, - { - "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", + "subcategory": "Management", + "text": "Evaluate the implementation of an ad-hoc mechanism to shut down Personal AVD Session Hosts" + }, + { + "category": "Monitoring and Management", + "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/tag-virtual-desktop-resources", "services": [ - "AKS", - "Arc" + "Storage", + "DNS", + "Monitor", + "Cost", + "VPN", + "ExpressRoute", + "VWAN", + "AVD" ], - "severity": "High", - "subcategory": "Control plane", - "text": "Connect Azure Red Hat OpenShift clusters to Azure Arc-enabled Kubernetes.", - "waf": "Security" + "severity": "Low", + "subcategory": "Management", + "text": "Review and adopt suggested Azure Tags for Azure Virtual Desktop" }, { - "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": [], + "category": "Monitoring and Management", + "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/azure-advisor-recommendations", + "services": [ + "AVD", + "Cost", + "Monitor", + "Entra" + ], "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" + "subcategory": "Management", + "text": "Periodically check Azure Advisor recommendations for AVD" }, { - "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": "Monitoring and Management", + "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/en-us/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/en-us/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", + "link": "https://learn.microsoft.com/mem/intune/fundamentals/azure-virtual-desktop-multi-session", "services": [ - "Defender", - "AKS", - "Arc" + "AVD", + "Monitor" ], "severity": "Medium", - "subcategory": "Posture", - "text": "Use Microsoft Defender for Containers supported via Arc-enabled Kubernetes to secure clusters, containers, and applications.", - "waf": "Security" + "subcategory": "Management", + "text": "Plan for a Session Host emergency patching and update strategy" }, { - "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": "Monitoring and Management", + "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/scheduled-agent-updates", "services": [ - "AKS", - "AKV", - "Arc" + "AVD", + "Monitor" ], - "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" + "severity": "Low", + "subcategory": "Management", + "text": "Configure the Scheduled Agent Updates feature" }, { - "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": "Monitoring and Management", + "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", + "link": "https://docs.microsoft.com/azure/virtual-desktop/create-validation-host-pool", + "services": [ + "AVD", + "VM", + "Monitor" + ], "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": "Management", + "text": "Create a validation (canary) Host Pool" }, { - "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": "Monitoring and Management", + "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", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/wvd/eslz-platform-automation-and-devops", "services": [ - "AzurePolicy", + "AVD", + "VM", "Monitor" ], "severity": "Medium", - "subcategory": "Workload", - "text": "Monitor and enforce configuration by using the Azure Policy Extension.", - "waf": "Security" + "subcategory": "Management", + "text": "Determine Host Pool deployment strategy" }, { - "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": "Monitoring and Management", + "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", + "link": "https://docs.microsoft.com/azure/virtual-desktop/faq", "services": [ - "Defender" + "AVD", + "VM", + "Monitor" ], - "severity": "High", - "subcategory": "Workload", - "text": "Scan your images for vulnerabilities with Microsoft Defender or any other image scanning solution.", - "waf": "Security" + "severity": "Medium", + "subcategory": "Management", + "text": "Turn on Session Host VMs at least every 90 days for token refresh" }, { - "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": "Monitoring and Management", + "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/insights", "services": [ - "Subscriptions", - "ACR" + "AVD", + "Monitor" ], - "severity": "Low", - "subcategory": "Workload", - "text": "Deploy a dedicated and private instance of Azure Container Registry to each landing zone subscription.", - "waf": "Security" + "severity": "High", + "subcategory": "Monitoring", + "text": "Enable monitoring for AVD" }, { - "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": "Monitoring and Management", + "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", + "link": "https://docs.microsoft.com/azure/virtual-desktop/diagnostics-log-analytics", "services": [ - "AKS" + "AVD", + "VM", + "Monitor" ], "severity": "Medium", - "subcategory": "Development", - "text": "Use canary or blue/green deployments", - "waf": "Operations" + "subcategory": "Monitoring", + "text": "Enable diagnostic settings for Workspaces, Host Pools, Application Groups and Host VMs to Log Analytics workspace" }, { - "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": "Monitoring and Management", + "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", + "link": "https://docs.microsoft.com/azure/storage/files/storage-files-monitoring?tabs=azure-portal", "services": [ - "AKS" + "Storage", + "AVD", + "Monitor" ], - "severity": "Low", - "subcategory": "Development", - "text": "If required for AKS Windows workloads HostProcess containers can be used", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "Monitoring", + "text": "Create alerts on the profile storage to be alerted in case of high usage and throttling" }, { - "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, + "category": "Monitoring and Management", + "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", + "link": "https://docs.microsoft.com/azure/virtual-desktop/set-up-service-alerts", "services": [ - "AKS" + "AVD", + "Monitor" ], - "severity": "Low", - "simple": -1, - "subcategory": "Development", - "text": "Use KEDA if running event-driven workloads", - "waf": "Performance" + "severity": "Medium", + "subcategory": "Monitoring", + "text": "Configure Azure Service Health for AVD alerts " }, { - "category": "Application Deployment", - "checklist": "Azure AKS Review", - "guid": "26886d20-b66c-457b-a591-19bf8e8f5c58", - "id": "01.01.04", - "link": "https://dapr.io/", + "category": "Networking", + "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", + "link": "https://docs.microsoft.com/azure/architecture/reference-architectures/hybrid-networking/", "services": [ - "AKS" + "AVD", + "VPN", + "ExpressRoute", + "NVA" ], - "severity": "Low", - "simple": 1, - "subcategory": "Development", - "text": "Use Dapr to ease microservice development", - "waf": "Operations" + "severity": "Medium", + "subcategory": "Networking", + "text": "Determine if hybrid connectivity is required to connect to on-premises environment" }, { - "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": "Networking", + "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", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/wvd/eslz-network-topology-and-connectivity", "services": [ - "AKS" + "AVD", + "VNet", + "VWAN" ], "severity": "Medium", - "simple": -1, - "subcategory": "Infrastructure as Code", - "text": "Use automation through ARM/TF to create your Azure resources", - "waf": "Operations" + "subcategory": "Networking", + "text": "Determine Azure Virtual Network (VNet) placement for each AVD Host Pool" }, { - "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", + "category": "Networking", + "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", + "link": "https://docs.microsoft.com/azure/architecture/reference-architectures/hybrid-networking/", "services": [ - "ASR", - "AKS" + "AVD", + "VPN" ], - "severity": "High", - "subcategory": "Disaster Recovery", - "text": "Schedule and perform DR tests regularly", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "Networking", + "text": "Assess which on-premises resources are required from AVD Host Pools" }, { - "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", + "category": "Networking", + "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", + "link": " https://docs.microsoft.com/azure/firewall/protect-windows-virtual-desktop", "services": [ - "LoadBalancer", - "AKS", - "FrontDoor", - "TrafficManager" + "AVD", + "VNet", + "Firewall", + "NVA" ], "severity": "Medium", - "subcategory": "High Availability", - "text": "Use Azure Traffic Manager or Azure Front Door as a global load balancer for region failover", - "waf": "Reliability" + "subcategory": "Networking", + "text": "Need to control/restrict Internet outbound traffic for AVD hosts?" }, { - "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", + "category": "Networking", + "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", + "link": "https://docs.microsoft.com/azure/virtual-desktop/safe-url-list", "services": [ - "AKS" + "AVD" ], - "severity": "Medium", - "subcategory": "High Availability", - "text": "Use Availability Zones if they are supported in your Azure region", - "waf": "Reliability" + "severity": "High", + "subcategory": "Networking", + "text": "Ensure AVD control plane endpoints are accessible" }, { - "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", + "category": "Networking", + "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", + "link": "https://learn.microsoft.com/microsoft-365/security/defender-endpoint/onboard-windows-multi-session-device?view=o365-worldwide", "services": [ - "AKS" + "AVD", + "Defender" ], - "severity": "High", - "subcategory": "High Availability", - "text": "Use the SLA-backed AKS offering", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "Networking", + "text": "Need to control/restrict Internet outbound traffic only for users on AVD hosts? " }, { - "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": "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/en-us/azure/virtual-desktop/safe-url-list.", + "guid": "523181a9-4174-4158-93ff-7ae7c6d37431", + "link": "https://docs.microsoft.com/azure/firewall/protect-windows-virtual-desktop", "services": [ - "Cost", - "AKS" + "AVD", + "VNet", + "Firewall", + "NVA" ], "severity": "Low", - "simple": -1, - "subcategory": "High Availability", - "text": "Use Disruption Budgets in your pod and deployment definitions", - "waf": "Reliability" + "subcategory": "Networking", + "text": "Review custom UDR and NSG for AVD Host Pool subnets" }, { - "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": "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/proxy-server-support", "services": [ - "ACR", - "AKS" + "AVD", + "VM" ], "severity": "High", - "subcategory": "High Availability", - "text": "If using a private registry, configure region replication to store images in multiple regions", - "waf": "Reliability" + "subcategory": "Networking", + "text": "Do not use Proxy servers, SSL termination and Deep Packet Inspection for AVD control plane traffic" }, { - "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": "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/rdp-bandwidth", "services": [ - "AKS" + "AVD", + "VM" ], - "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": "Networking", + "text": "Check the network bandwidth required for each user and in total for the VM SKU" }, { - "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", + "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", + "link": "https://learn.microsoft.com/azure/storage/files/storage-files-networking-endpoints", "services": [ + "Storage", + "PrivateLink", + "VNet", "Cost", - "AKS" + "AVD" ], - "severity": "Low", - "subcategory": "Cost", - "text": "Use an external application such as kubecost to allocate costs to different users", - "waf": "Cost" + "severity": "Medium", + "subcategory": "Networking", + "text": "Evaluate usage Private Endpoint for Azure Files share" }, { - "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", + "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/en-us/azure/virtual-desktop/rdp-shortpath?tabs=managed-networks#key-benefits.", + "guid": "b2074747-d01a-4f61-b1aa-92ad793d9ff4", + "link": "https://docs.microsoft.com/azure/virtual-desktop/shortpath", "services": [ - "Cost", - "AKS" + "AVD", + "VPN" ], - "severity": "Low", - "subcategory": "Cost", - "text": "Use scale down mode to delete/delallocate nodes", - "waf": "Cost" + "severity": "Medium", + "subcategory": "Networking", + "text": "Evaluate usage of RDP ShortPath for clients connecting from managed internal networks" }, { - "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": "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/security-guide#establish-maximum-inactive-time-and-disconnection-policies", "services": [ - "Cost", - "AKS" + "AVD" ], "severity": "Medium", - "subcategory": "Cost", - "text": "When required use multi-instance partioning GPU on AKS Clusters", - "waf": "Cost" + "subcategory": "Active Directory", + "text": "Review Active Directory GPO to secure RDP sessions" }, { - "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", + "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", + "link": "https://learn.microsoft.com/microsoft-365/security/defender-endpoint/deployment-vdi-microsoft-defender-antivirus", + "services": [ + "AVD", + "Defender" + ], + "severity": "High", + "subcategory": "Host Configuration", + "text": "Ensure anti-virus and anti-malware solutions are used" + }, + { + "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", + "link": "https://learn.microsoft.com/azure/virtual-machines/disk-encryption-overview", "services": [ - "Cost", - "AKS" + "Storage", + "AVD", + "AKV", + "VM" ], "severity": "Low", - "subcategory": "Cost", - "text": "If running a Dev/Test cluster use NodePool Start/Stop", - "waf": "Cost" + "subcategory": "Host Configuration", + "text": "Assess disk encryption requirements for AVD Session Hosts" }, { - "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": "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/security-guide#azure-virtual-desktop-support-for-trusted-launch", "services": [ - "AzurePolicy", - "AKS" + "AVD", + "VM", + "Monitor" ], "severity": "Medium", - "simple": -1, - "subcategory": "Compliance", - "text": "Use Azure Policy for Kubernetes to ensure cluster compliance", - "waf": "Security" + "subcategory": "Host Configuration", + "text": "Enable Trusted launch in Azure Gen2 VM Session Hosts" }, { - "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, + "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", + "link": "https://learn.microsoft.com/windows/whats-new/windows-11-requirements", "services": [ - "AKS" + "AVD", + "VM" ], - "severity": "Medium", - "simple": -1, - "subcategory": "Compliance", - "text": "Separate applications from the control plane with user/system nodepools", - "waf": "Security" + "severity": "High", + "subcategory": "Host Configuration", + "text": "Enable Trusted Launch and use Gen2 image are system requirements for Windows 11" }, { - "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", + "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/screen-capture-protection", "services": [ - "AKS" + "AVD" ], "severity": "Low", - "simple": -1, - "subcategory": "Compliance", - "text": "Add taint to your system nodepool to make it dedicated", - "waf": "Security" + "subcategory": "Host Configuration", + "text": "Consider enabling screen capture protection to prevent sensitive information from being captured" }, { - "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, + "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/security-guide#other-security-tips-for-session-hosts", "services": [ - "ACR", - "AKS" + "AVD" ], "severity": "Medium", - "simple": -1, - "subcategory": "Compliance", - "text": "Use a private registry for your images, such as ACR", - "waf": "Security" + "subcategory": "Host Configuration", + "text": "Restrict device redirection and drive mapping" }, { - "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, + "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", + "link": "https://learn.microsoft.com/microsoft-365/security/defender-endpoint/web-protection-overview", "services": [ - "AKS" + "AVD" ], "severity": "Medium", - "subcategory": "Compliance", - "text": "Scan your images for vulnerabilities", - "waf": "Security" + "subcategory": "Management", + "text": "When possible, prefer Remote Apps over Full Desktops (DAG)" }, { - "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, + "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", + "link": "https://learn.microsoft.com/microsoft-365/security/defender-endpoint/web-protection-overview", "services": [ - "Defender", - "AKS" + "AVD", + "Defender" ], "severity": "Medium", - "subcategory": "Compliance", - "text": "Use Azure Security Center to detect security posture vulnerabilities", - "waf": "Security" + "subcategory": "Management", + "text": "Need to control/restrict user Internet navigation from AVD session hosts?" }, { - "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": "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", + "link": "https://docs.microsoft.com/azure/virtual-desktop/security-guide", "services": [ - "AKS" + "AVD" ], - "severity": "Low", - "subcategory": "Compliance", - "text": "If required configure FIPS", - "waf": "Security" + "severity": "High", + "subcategory": "Management", + "text": "Ensure AVD users will not have local administrator privileges on AVD Hosts" }, { - "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": "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/en-us/azure/virtual-desktop/security-guide#improve-your-secure-score.", + "guid": "1814387e-5ca9-4c26-a9b3-2ab5bdfc6998", + "link": "https://learn.microsoft.com/azure/virtual-desktop/security-guide#enable-microsoft-defender-for-cloud", "services": [ - "AKS" + "Storage", + "AKV", + "Defender", + "Subscriptions", + "VM", + "AVD" ], - "severity": "High", - "subcategory": "Compliance", - "text": "Define app separation requirements (namespace/nodepool/cluster)", - "waf": "Security" + "severity": "Medium", + "subcategory": "Management", + "text": "Enable Microsoft Defender for Cloud to manage AVD Session Hosts security posture" }, { - "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": "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/security-guide#collect-audit-logs", "services": [ - "AKS", - "AKV" + "AVD", + "Monitor", + "Entra" ], "severity": "Medium", - "simple": -1, - "subcategory": "Secrets", - "text": "Store your secrets in Azure Key Vault with the CSI Secrets Store driver", - "waf": "Security" + "subcategory": "Management", + "text": "Enable diagnostic and audit logging" }, { - "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": "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", + "link": "https://docs.microsoft.com/azure/virtual-desktop/rbac", "services": [ - "AKS", - "AKV" + "AVD", + "RBAC", + "Entra" ], - "severity": "High", - "subcategory": "Secrets", - "text": "If using Service Principals for the cluster, refresh credentials periodically (like quarterly)", - "waf": "Security" + "severity": "Low", + "subcategory": "Management", + "text": "Assess the requirement to use custom RBAC roles for AVD management" }, { - "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 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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/security-guide#windows-defender-application-control", + "services": [ + "AVD", + "Defender" + ], + "severity": "Medium", + "subcategory": "Management", + "text": "Restrict users from installing un-authorized applications" + }, + { + "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/set-up-mfa", "services": [ - "AKS", - "AKV" + "AVD", + "Entra" ], "severity": "Medium", - "subcategory": "Secrets", - "text": "If required add Key Management Service etcd encryption", - "waf": "Security" + "subcategory": "Microsoft Entra ID", + "text": "Evaluate the usage of Multi-Factor Authentication (MFA) and Conditional Access (CA) for AVD users" }, { - "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 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", + "link": "https://learn.microsoft.com/security/zero-trust/azure-infrastructure-avd", "services": [ - "AKS", - "AKV" + "AVD" ], - "severity": "Low", - "subcategory": "Secrets", - "text": "If required consider using Confidential Compute for AKS", - "waf": "Security" + "severity": "Medium", + "subcategory": "Zero Trust", + "text": "Review and Apply Zero Trust principles and guidance" }, { - "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": "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/fslogix-containers-azure-files#best-practices-for-azure-virtual-desktop", "services": [ - "Defender", - "AKS", - "AKV" + "Storage", + "AVD" ], "severity": "Medium", - "subcategory": "Secrets", - "text": "Consider using Defender for Containers", - "waf": "Security" + "subcategory": "Azure Files", + "text": "Check best-practices for Azure Files" }, { - "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": "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", + "link": "https://learn.microsoft.com/azure/storage/files/storage-files-smb-multichannel-performance", "services": [ - "Entra", - "AKS" + "Storage", + "AVD", + "Cost", + "ACR" ], - "severity": "High", - "simple": 1, - "subcategory": "Identity", - "text": "Use managed identities instead of Service Principals", - "waf": "Security" + "severity": "Low", + "subcategory": "Azure Files", + "text": "Enable SMB multichannel when using a premium file share to host FSLogix profile containers." }, { - "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": "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", + "link": "https://azure.microsoft.com/global-infrastructure/services/", "services": [ - "Entra", - "AKS" + "Storage", + "AVD" ], "severity": "Medium", - "simple": 1, - "subcategory": "Identity", - "text": "Integrate authentication with AAD (using the managed integration)", - "waf": "Security" + "subcategory": "Azure NetApp Files", + "text": "If NetApp Files storage is required, check storage service availability in your specific region." }, { - "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": "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/create-fslogix-profile-container", "services": [ - "Entra", - "AKS" + "Storage", + "AVD" ], "severity": "Medium", - "simple": -1, - "subcategory": "Identity", - "text": "Limit access to admin kubeconfig (get-credentials --admin)", - "waf": "Security" + "subcategory": "Azure NetApp Files", + "text": "If NetApp Files storage is used enable CA (Continuous Availability) option to increase resiliency" }, { - "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": "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", + "link": "https://docs.microsoft.com/azure/azure-netapp-files/create-active-directory-connections", "services": [ - "RBAC", - "Entra", - "AKS" + "Storage", + "AVD", + "VNet" + ], + "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" + }, + { + "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", + "link": "https://docs.microsoft.com/azure/virtual-machines/disks-types", + "services": [ + "Storage", + "AVD" ], "severity": "Medium", - "simple": -1, - "subcategory": "Identity", - "text": "Integrate authorization with AAD RBAC", - "waf": "Security" + "subcategory": "Capacity Planning", + "text": "Determine which type of managed disk will be used for the Session Hosts" }, { - "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": "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", + "link": "https://docs.microsoft.com/azure/virtual-desktop/store-fslogix-profile", "services": [ - "RBAC", - "Entra", - "AKS" + "Storage", + "AVD", + "VM" ], "severity": "High", - "simple": -1, - "subcategory": "Identity", - "text": "Use namespaces for restricting RBAC privilege in Kubernetes", - "waf": "Security" + "subcategory": "Capacity Planning", + "text": "Determine which storage backend solution will be used for FSLogix Profiles" }, { - "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": "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/store-fslogix-profile", "services": [ - "Entra", - "AKS" + "Storage", + "AVD" ], - "severity": "Medium", - "simple": -1, - "subcategory": "Identity", - "text": "For POD Identity Access Management use Azure AD Workload Identity (preview)", - "waf": "Security" + "severity": "High", + "subcategory": "Capacity Planning", + "text": "Do not share storage and profiles between different Host Pools" }, { - "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": "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", + "link": "https://learn.microsoft.com/azure/virtual-desktop/faq#what-s-the-largest-profile-size-fslogix-can-handle-", "services": [ - "Entra", - "AKS" + "Storage", + "AVD" ], - "severity": "Medium", - "simple": -1, - "subcategory": "Identity", - "text": "For AKS non-interactive logins use kubelogin (preview)", - "waf": "Security" + "severity": "High", + "subcategory": "Capacity Planning", + "text": "Verify storage scalability limits and Host Pool requirements" }, { - "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": "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", + "link": "https://docs.microsoft.com/azure/virtual-desktop/fslogix-containers-azure-files", "services": [ - "Entra", - "AKS" - ], - "severity": "Medium", - "simple": -1, - "subcategory": "Identity", - "text": "Disable AKS local accounts", - "waf": "Security" + "Storage", + "AVD", + "Cost" + ], + "severity": "High", + "subcategory": "Capacity Planning", + "text": "For optimal performance, the storage solution and the FSLogix profile container should be in the same Azure region." }, { - "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": "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", + "link": "https://learn.microsoft.com/fslogix/concepts-container-types#when-to-use-profile-and-odfc-containers", "services": [ - "Entra", - "AKS" + "Storage", + "AVD", + "ASR" ], - "severity": "Low", - "simple": -1, - "subcategory": "Identity", - "text": "Configure if required Just-in-time cluster access", - "waf": "Security" + "severity": "High", + "subcategory": "FSLogix", + "text": "Do not use Office Containers (ODFC) if not strictly required and justified" }, { - "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": "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", + "link": "https://learn.microsoft.com/fslogix/overview-prerequisites#configure-antivirus-file-and-folder-exclusions", "services": [ - "Entra", - "AKS" + "Storage", + "AVD" ], - "severity": "Low", - "simple": -1, - "subcategory": "Identity", - "text": "Configure if required AAD conditional access for AKS", - "waf": "Security" + "severity": "Medium", + "subcategory": "FSLogix", + "text": "Configure the recommended antivirus exclusions for FSLogix (includes not scanning VHD(x) files on connect)." }, { - "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": "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", + "link": "https://docs.microsoft.com/fslogix/profile-container-configuration-reference", "services": [ - "Entra", - "AKS" + "Storage", + "AVD" ], - "severity": "Low", - "simple": -1, - "subcategory": "Identity", - "text": "If required for Windows AKS workloads configure gMSA ", - "waf": "Security" + "severity": "High", + "subcategory": "FSLogix", + "text": "Review and confirm configured maximum profile size in FSLogix" }, { - "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": "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", + "link": "https://learn.microsoft.com/fslogix/concepts-configuration-examples", "services": [ - "Entra", - "AKS" + "Storage", + "AVD", + "AKV", + "ACR" ], - "severity": "Medium", - "simple": -1, - "subcategory": "Identity", - "text": "For finer control consider using a managed Kubelet Identity", - "waf": "Security" + "severity": "High", + "subcategory": "FSLogix", + "text": "Review FSLogix registry keys and determine which ones to apply" }, { - "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": "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", + "link": "https://learn.microsoft.com/fslogix/concepts-multi-concurrent-connections", "services": [ - "AppGW", - "ACR", - "AKS" + "Storage", + "AVD" ], - "severity": "Medium", - "simple": -1, - "subcategory": "Best practices", - "text": "If using AGIC, do not share an AppGW across clusters", - "waf": "Reliability" + "severity": "High", + "subcategory": "FSLogix", + "text": "Avoid usage of concurrent or multiple connections" }, { - "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": "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/en-us/fslogix/concepts-fslogix-cloud-cache. ", + "guid": "b2d1215a-e114-4ba3-9df5-85ecdcd9bd3b", + "link": "https://docs.microsoft.com/fslogix/cloud-cache-configuration-reference", "services": [ - "AKS" + "Storage", + "AVD", + "VM" ], - "severity": "High", - "simple": -1, - "subcategory": "Best practices", - "text": "Do not use AKS Application Routing Add-On", - "waf": "Reliability" + "severity": "Low", + "subcategory": "FSLogix", + "text": "If FSLogix Cloud Cache is used, consider moving the cache directory to the VM temporary drive." }, { - "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": "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", + "link": "https://docs.microsoft.com/fslogix/manage-profile-content-cncpt#redirectionsxml", "services": [ - "AKS" + "Storage", + "AVD" ], "severity": "Medium", - "simple": -1, - "subcategory": "Best practices", - "text": "For Windows workloads use Accelerated Networking", - "waf": "Performance" + "subcategory": "FSLogix", + "text": "Review the usage of FSLogix redirection." }, { - "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": "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": [ - "LoadBalancer", - "AKS" + "Arc" ], "severity": "High", - "subcategory": "Best practices", - "text": "Use the standard ALB (as opposed to the basic one)", - "waf": "Reliability" + "subcategory": "Capacity Planning", + "text": "One or more resource groups is required for onboarding servers into Azure", + "waf": "Operations" }, { - "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": "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": [ - "AKS", - "VNet" + "Entra", + "Arc" ], "severity": "Medium", - "simple": -2, - "subcategory": "Best practices", - "text": "If using Azure CNI, consider using different Subnets for NodePools", - "waf": "Security" + "subcategory": "Capacity Planning", + "text": "Take Azure Active Directory object limitations into account", + "waf": "Performance" }, { - "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": "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": [ - "PrivateLink", - "Cost", - "AKS", - "VNet" + "Subscriptions", + "Arc" ], - "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" + "severity": "High", + "subcategory": "General", + "text": "Has the Resource providers required been registered in all subscriptions", + "waf": "Operations" }, { - "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", - "services": [ - "VPN", - "AKS" - ], - "severity": "Medium", - "subcategory": "HA", - "text": "If hybrid connectivity is required, use 2xER or ER+VPN for better availability", - "waf": "Reliability" + "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": "General", + "text": "Has a tagging strategy for Azure Arc-enabled servers been defined", + "waf": "Cost" }, { - "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": "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": [ - "AKS" + "Arc" ], "severity": "High", - "simple": 1, - "subcategory": "IPAM", - "text": "Choose the best CNI network plugin for your requirements (Azure CNI recommended)", - "waf": "Reliability" + "subcategory": "General", + "text": "What operating systems need to be Azure Arc-enabled", + "waf": "Operations" }, { - "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": "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": [ - "AKS", - "VNet" + "Arc" ], "severity": "High", - "subcategory": "IPAM", - "text": "If using Azure CNI, size your subnet accordingly considering the maximum number of pods per node", - "waf": "Performance" + "subcategory": "General", + "text": "Are required software installed on Windows and Linux servers to support the installation", + "waf": "Operations" }, { - "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": "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": [ - "AKS" + "Arc" ], "severity": "High", - "simple": -1, - "subcategory": "IPAM", - "text": "If using Azure CNI, check the maximum pods/node (default 30)", - "waf": "Performance" + "subcategory": "General", + "text": "Make sure to use a supported Azure region", + "waf": "Reliability" }, { - "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": "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": [ - "AKS", - "VNet" + "Subscriptions", + "Arc" ], "severity": "Low", - "simple": -1, - "subcategory": "IPAM", - "text": "If using private-IP LoadBalancer services, use a dedicated subnet (not the AKS subnet)", - "waf": "Security" + "subcategory": "Organization", + "text": "Define the structure for Azure management of resources", + "waf": "Performance" }, { - "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": "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": [ - "AKS" + "Entra", + "RBAC", + "Arc" ], - "severity": "High", - "subcategory": "IPAM", - "text": "Size the service IP address range accordingly (it is going to limit the cluster scalability)", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "Access", + "text": "Assign RBAC rights to Azure AD user/group access for managing Azure Arc-enabled servers", + "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": "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": [ - "AKS" + "AKV", + "Entra", + "Arc" ], "severity": "Low", - "simple": -2, - "subcategory": "Operations", - "text": "If required add your own CNI plugin", + "subcategory": "Access", + "text": "Consider using managed identities for applications to access Azure resources like Key Vault example in link", "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": "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": [ - "AKS" + "Subscriptions", + "Entra", + "Arc" ], - "severity": "Low", - "simple": -2, - "subcategory": "Operations", - "text": "If required configure Public IP per node in AKS", - "waf": "Performance" + "severity": "High", + "subcategory": "Requirements", + "text": "An Azure Active Directory tenant must be available with at least one subscription", + "waf": "Operations" }, { - "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": "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": [ - "AKS" + "Entra", + "RBAC", + "Arc" ], "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" + "subcategory": "Requirements", + "text": "Define which users (AAD user/groups) has access to onboard Azure Arc-enabled servers", + "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": "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": [ - "AKS" + "Entra", + "RBAC", + "Arc" ], - "severity": "Low", - "simple": -1, - "subcategory": "Scalability", - "text": "Use Azure NAT Gateway as outboundType for scaling egress traffic", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "Security", + "text": "Use the principle of least privileged", + "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": "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": [ - "AKS" + "Entra", + "RBAC", + "Arc" ], "severity": "Medium", - "simple": -1, - "subcategory": "Scalability", - "text": "Use Dynamic allocations of IPs in order to avoid Azure CNI IP exhaustion", - "waf": "Reliability" + "subcategory": "Security", + "text": "How many Service Principals are needed for onboarding Arc-enabled servers into Azure", + "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": "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": [ - "NVA", - "AKS" + "Entra", + "RBAC", + "Arc" ], - "severity": "High", - "simple": -2, + "severity": "Medium", "subcategory": "Security", - "text": "Filter egress traffic with AzFW/NVA if your security requirements mandate it", + "text": "Limit the rights to onboard Azure Arc-enabled servers to the desired resource groups", "waf": "Security" }, { - "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, + "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": [ - "AKS" + "Monitor", + "Arc" ], "severity": "Medium", - "simple": -1, - "subcategory": "Security", - "text": "If using a public API endpoint, restrict the IP addresses that can access it", - "waf": "Security" + "subcategory": "Management", + "text": "Define a strategy for agent provisioning", + "waf": "Operations" }, { - "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, + "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": [ - "AKS" + "Monitor", + "Arc" ], "severity": "High", - "simple": -1, - "subcategory": "Security", - "text": "Use private clusters if your requirements mandate it", - "waf": "Security" + "subcategory": "Management", + "text": "Define a strategy for agent updates", + "waf": "Operations" }, { - "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, + "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": [ "AzurePolicy", - "AKS" + "Monitor", + "Arc" ], "severity": "Medium", - "simple": -1, - "subcategory": "Security", - "text": "For Windows 2019 and 2022 AKS nodes Calico Network Policies can be used ", - "waf": "Security" + "subcategory": "Management", + "text": "Define a strategy for extension installation", + "waf": "Operations" }, { - "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, + "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": [ - "AzurePolicy", - "AKS" + "Monitor", + "Arc" ], "severity": "High", - "subcategory": "Security", - "text": "Enable a Kubernetes Network Policy option (Calico/Azure)", - "waf": "Security" + "subcategory": "Management", + "text": "Define a strategy for extension updates", + "waf": "Operations" }, { - "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, + "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", - "AKS" + "Monitor", + "Arc" ], - "severity": "High", - "simple": -1, - "subcategory": "Security", - "text": "Use Kubernetes network policies to increase intra-cluster security", - "waf": "Security" + "severity": "Medium", + "subcategory": "Management", + "text": "Consider using Azure Automanage to control settings and avoid configuration drift on servers", + "waf": "Operations" }, { - "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, + "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": [ - "AKS", - "WAF" + "Monitor", + "Arc" ], "severity": "High", - "simple": -1, - "subcategory": "Security", - "text": "Use a WAF for web workloads (UIs or APIs)", - "waf": "Security" + "subcategory": "Monitoring", + "text": "Monitor for unresponsive agents", + "waf": "Operations" }, { - "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, + "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": [ - "AKS", - "DDoS", - "VNet" + "Monitor", + "Arc" ], "severity": "Medium", - "subcategory": "Security", - "text": "Use DDoS Standard in the AKS Virtual Network", - "waf": "Security" + "subcategory": "Monitoring", + "text": "Design a monitoring strategy to send metrics and logs to an Log Analytics workspace", + "waf": "Operations" }, { - "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, + "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": [ - "AKS" + "Monitor", + "Arc" ], - "severity": "Low", - "subcategory": "Security", - "text": "If required add company HTTP Proxy", - "waf": "Security" + "severity": "Medium", + "subcategory": "Monitoring", + "text": "Use notification in Activity logs to receive notification on unexpected changes to the resources", + "waf": "Operations" }, { - "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, + "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": [ - "AKS" + "Monitor", + "Arc" ], "severity": "Medium", - "simple": -2, - "subcategory": "Security", - "text": "Consider using a service mesh for advanced microservice communication management", - "waf": "Security" + "subcategory": "Monitoring", + "text": "Use Azure Monitor for compliance and operational monitoring", + "waf": "Operations" }, { - "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", + "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": [ "Monitor", - "AKS" + "Arc" ], - "severity": "High", - "simple": -1, - "subcategory": "Alerting", - "text": "Configure alerts on the most critical metrics (see Container Insights for recommendations)", + "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", "waf": "Operations" }, { - "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", + "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": [ - "Entra", - "AKS" + "Monitor", + "Arc" ], "severity": "Low", - "simple": -1, - "subcategory": "Compliance", - "text": "Check regularly Azure Advisor for recommendations on your cluster", + "subcategory": "Security", + "text": "Use Azure Arc-enabled servers to control software updates deployments to servers", "waf": "Operations" }, { - "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", + "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": [ - "AKS" + "Arc" ], - "severity": "Low", - "simple": 1, - "subcategory": "Compliance", - "text": "Enable AKS auto-certificate rotation", + "severity": "High", + "subcategory": "Networking", + "text": "Define a connectivity method from the server to Azure", "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, + "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": [ - "AKS" + "Arc" ], - "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", + "severity": "Medium", + "subcategory": "Networking", + "text": "Is a proxy server a required for communication over the Public Internet", "waf": "Operations" }, { - "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", + "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": [ - "AKS" + "ExpressRoute", + "VPN", + "PrivateLink", + "Arc" ], - "severity": "High", - "simple": -1, - "subcategory": "Compliance", - "text": "Use kured for Linux node upgrades in case you are not using node-image upgrade", + "severity": "Medium", + "subcategory": "Networking", + "text": "Is a private (not public Internet) connection required?", "waf": "Operations" }, { - "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, + "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": [ - "AKS" + "Arc" ], "severity": "High", - "simple": -1, - "subcategory": "Compliance", - "text": "Have a regular process to upgrade the cluster node images periodically (weekly, for example)", - "waf": "Operations" + "subcategory": "Networking", + "text": "Will Firewall configurations be needed in order to ensure communication with Azure Services?", + "waf": "Security" }, { - "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", + "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": [ - "AKS" + "Arc" ], "severity": "Low", - "subcategory": "Compliance", - "text": "Consider gitops to deploy applications or cluster configuration to multiple clusters", - "waf": "Operations" + "subcategory": "Networking", + "text": "Can the Firewall or Proxy rules be automated updated if Service Tags or IP addresses change", + "waf": "Security" }, { - "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", + "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": [ - "AKS" + "Arc" ], - "severity": "Low", - "subcategory": "Compliance", - "text": "Consider using AKS command invoke on private clusters", - "waf": "Operations" + "severity": "High", + "subcategory": "Networking", + "text": "Always use secure communication for Azure where possible", + "waf": "Security" }, { - "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, + "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": [ - "AKS" + "PrivateLink", + "Monitor", + "Arc" ], "severity": "Low", - "subcategory": "Compliance", - "text": "For planned events consider using Node Auto Drain", - "waf": "Operations" + "subcategory": "Networking", + "text": "Include communication for Azure Arc-enabled Servers extensions in the design (firewall/proxy/private link)", + "waf": "Security" }, { - "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, + "category": "Security, Governance and Compliance", + "checklist": "Azure Arc Review", + "guid": "ac6aae01-e6a8-44de-9df4-7d2d92881b1c", + "link": "https://learn.microsoft.com/azure/governance/policy/", "services": [ - "AKS" + "AzurePolicy", + "Arc" ], - "severity": "High", - "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" + "severity": "Medium", + "subcategory": "Management", + "text": "Use Azure Policy to implement a governance model for hybrid connected servers", + "waf": "Security" }, { - "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", + "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": [ - "AKS" + "Arc" ], - "severity": "Low", - "simple": 1, - "subcategory": "Compliance", - "text": "Use custom Node RG (aka 'Infra RG') name", + "severity": "Medium", + "subcategory": "Management", + "text": "Consider using Machine configurations for in guest OS configurations", "waf": "Operations" }, { - "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/", + "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": [ - "AKS" + "AzurePolicy", + "Arc" ], "severity": "Medium", - "simple": -1, - "subcategory": "Compliance", - "text": "Do not use deprecated Kubernetes APIs in your YAML manifests", + "subcategory": "Management", + "text": "Evaluate the need for custom Guest Configuration policies", "waf": "Operations" }, { - "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", + "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": [ - "AKS" + "Monitor", + "Arc" ], - "severity": "Low", - "simple": -1, - "subcategory": "Compliance", - "text": "Taint Windows nodes", + "severity": "Medium", + "subcategory": "Monitoring", + "text": "Consider using change tracking for tracking changes made on the servers", "waf": "Operations" }, { - "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", + "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": [ - "AKS" + "Arc" ], - "severity": "Low", - "subcategory": "Compliance", - "text": "Keep windows containers patch level in sync with host patch level", - "waf": "Operations" + "severity": "Medium", + "subcategory": "Requirements", + "text": "Make sure to use an Azure region for storing the metadata approved by the organization", + "waf": "Security" }, { - "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", + "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": [ - "Monitor", - "AKS" + "AKV", + "Arc" ], - "severity": "Low", - "subcategory": "Compliance", - "text": "Send master logs (aka API logs) to Azure Monitor or your preferred log management solution", - "waf": "Operations" + "severity": "Medium", + "subcategory": "Secrets", + "text": "Use Azure Key Vault for certificate management on servers", + "waf": "Security" }, { - "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", + "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": [ - "AKS" + "Storage", + "AKV", + "Entra", + "Arc" ], - "severity": "Low", - "subcategory": "Compliance", - "text": "If required use nodePool snapshots", - "waf": "Cost" + "severity": "High", + "subcategory": "Secrets", + "text": "What is the acceptable life time of the secret used by SP's", + "waf": "Security" }, { - "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", + "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": [ - "Cost", - "AKS" + "AKV", + "Arc" ], - "severity": "Low", - "simple": -1, - "subcategory": "Cost", - "text": "Consider spot node pools for non time-sensitive workloads", - "waf": "Operations" + "severity": "Medium", + "subcategory": "Secrets", + "text": "Secure the public key for Azure Arc-enabled Servers", + "waf": "Security" }, { - "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, + "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": [ - "Cost", - "AKS" + "Arc" ], - "severity": "Low", - "simple": -1, - "subcategory": "Cost", - "text": "Consider AKS virtual node for quick bursting", - "waf": "Operations" + "severity": "High", + "subcategory": "Security", + "text": "Ensure there is local administrator access for executing the agent installation", + "waf": "Security" }, { - "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", + "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": [ - "Monitor", - "AKS" + "Arc" ], - "severity": "High", - "simple": -1, - "subcategory": "Monitoring", - "text": "Monitor your cluster metrics with Container Insights (or other tools like Prometheus)", - "waf": "Operations" + "severity": "Medium", + "subcategory": "Security", + "text": "Limit the amount of users with local administrator rights to the servers", + "waf": "Security" }, { - "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", + "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": [ - "Monitor", - "AKS" + "Entra", + "Arc" ], - "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": "Medium", + "subcategory": "Security", + "text": "Consider using and restricting access to managed identities for applications.", + "waf": "Security" }, { - "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", + "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": [ - "Monitor", - "AKS" + "Defender", + "Arc" ], "severity": "Medium", - "simple": -1, - "subcategory": "Monitoring", - "text": "Monitor CPU and memory utilization of the nodes", - "waf": "Operations" + "subcategory": "Security", + "text": "Enable Defender for Servers for all servers to secure hybrid workloads from threats", + "waf": "Security" }, { - "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", + "category": "Security, Governance and Compliance", + "checklist": "Azure Arc Review", + "guid": "cbafe6c4-6589-4d45-9a92-7c3974d1102c", "services": [ - "Monitor", - "AKS" + "Arc" ], "severity": "Medium", - "simple": -1, - "subcategory": "Monitoring", - "text": "If using Azure CNI, monitor % of pod IPs consumed per node", - "waf": "Operations" + "subcategory": "Security", + "text": "Define controls to detect security misconfigurations and track compliance", + "waf": "Security" }, { - "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", + "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": [ - "AKS", - "EventHubs", - "ServiceBus", - "Monitor", - "Storage" + "Arc" ], "severity": "Medium", - "simple": -1, - "subcategory": "Monitoring", - "text": "Monitor OS disk queue depth in nodes", - "waf": "Operations" + "subcategory": "Security", + "text": "Use allow- or block-lists to control what extensions can be installed on the Azure Arc-enabled servers", + "waf": "Security" }, { - "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", + "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": [ - "NVA", - "LoadBalancer", - "AKS", - "Monitor" + "ASR" ], "severity": "Medium", - "simple": -1, - "subcategory": "Monitoring", - "text": "If not using egress filtering with AzFW/NVA, monitor standard ALB allocated SNAT ports", - "waf": "Operations" + "subcategory": " ", + "text": "Do not combine ASCS and Database cluster on to single/same VM" }, { - "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", + "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": [ - "Monitor", - "AKS" + "LoadBalancer", + "ASR" ], "severity": "Medium", - "subcategory": "Monitoring", - "text": "Subscribe to resource health notifications for your AKS cluster", - "waf": "Operations" + "subcategory": " ", + "text": "Make sure the Floating IP is enabled on the Load balancer" }, { - "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", + "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": [ - "AKS" + "VM", + "ASR", + "RBAC", + "Entra" ], - "severity": "High", - "simple": -1, - "subcategory": "Resources", - "text": "Configure requests and limits in your pod specs", - "waf": "Operations" + "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": "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", + "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": [ - "AKS" + "ACR", + "ASR", + "SAP" ], "severity": "Medium", - "simple": -1, - "subcategory": "Resources", - "text": "Enforce resource quotas for namespaces", - "waf": "Operations" + "subcategory": " ", + "text": "Use one proximity placement group per SAP SID. Groups don't span across Availability Zones or Azure regions" }, { - "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", + "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": [ - "Subscriptions", - "AKS" + "VM", + "ASR", + "Entra" ], - "severity": "High", - "subcategory": "Resources", - "text": "Ensure your subscription has enough quota to scale out your nodepools", - "waf": "Operations" + "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": "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", + "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": [ - "AKS" + "LoadBalancer", + "ASR" ], "severity": "Medium", - "subcategory": "Scalability", - "text": "Use the Cluster Autoscaler", - "waf": "Performance" + "subcategory": " ", + "text": "Use a Standard Load Balancer SKU in front of ASCS and DB clusters" }, { - "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", + "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": [ - "AKS" + "Storage", + "VM", + "ASR" ], - "severity": "Low", - "subcategory": "Scalability", - "text": "Customize node configuration for AKS node pools", - "waf": "Performance" + "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" }, { - "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, + "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": [ - "AKS" + "ASR" ], "severity": "Medium", - "simple": -1, - "subcategory": "Scalability", - "text": "Use the Horizontal Pod Autoscaler when required", - "waf": "Performance" + "subcategory": " ", + "text": "Native database replication technology should be used to synchronize the database in a HA pair." }, { - "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/", + "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": [ - "AKS" + "ASR", + "SAP" ], - "severity": "High", - "subcategory": "Scalability", - "text": "Consider an appropriate node size, not too large or too small", - "waf": "Performance" + "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" }, { - "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", + "category": "Business Continuity and Disaster Recovery", + "checklist": "Azure Landing Zone Review", + "guid": "81b12318-1a54-4174-8583-3fb4ae3c2df7", "services": [ - "AKS" + "VNet", + "ASR" ], - "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", + "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": "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", + "category": "Business Continuity and Disaster Recovery", + "checklist": "Azure Landing Zone Review", + "guid": "43165c3a-cbe0-45bb-b209-d490da477784", "services": [ - "AKS" + "VM", + "ASR", + "Entra" ], - "severity": "Low", - "subcategory": "Scalability", - "text": "Consider subscribing to EventGrid Events for AKS automation", - "waf": "Performance" + "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": "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", + "category": "Business Continuity and Disaster Recovery", + "checklist": "Azure Landing Zone Review", + "guid": "24d11678-5d2f-4a56-a56a-d48408fe7273", "services": [ - "AKS" + "ASR" ], - "severity": "Low", - "subcategory": "Scalability", - "text": "For long running operation on an AKS cluster consider event termination", - "waf": "Performance" + "severity": "Medium", + "subcategory": " ", + "text": "Native database replication should be used to synchronize data to the DR site, rather than Azure Site Recovery" }, { - "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", + "category": "Compute", + "checklist": "Azure Landing Zone Review", + "guid": "2829e2ed-b217-4367-9aff-6691b4935ada", "services": [ - "AKS" + "VM" ], - "severity": "Low", - "subcategory": "Scalability", - "text": "If required consider using Azure Dedicated Hosts for AKS nodes", - "waf": "Performance" + "severity": "Medium", + "subcategory": " ", + "text": "Make quota requests for correct VM SKU and Zones" }, { - "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, + "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": [ - "Storage", - "AKS" + "Subscriptions", + "RBAC", + "Entra" ], "severity": "High", - "subcategory": "Storage", - "text": "Use ephemeral OS disks", - "waf": "Performance" + "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": "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, + "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": [ - "Storage", - "AKS" + "Entra", + "SAP" ], - "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", + "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": "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, + "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": [ - "Storage", - "AKS" + "Entra", + "SAP" ], - "severity": "Low", - "subcategory": "Storage", - "text": "For hyper performance storage option use Ultra Disks on AKS", - "waf": "Performance" + "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." }, { - "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", + "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": [ - "SQL", - "Storage", - "AKS" + "Entra", + "SAP" ], "severity": "Medium", - "simple": -1, - "subcategory": "Storage", - "text": "Avoid keeping state in the cluster, and store data outside (AzStorage, AzSQL, Cosmos, etc)", - "waf": "Performance" + "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": "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, + "category": "Identity and Access", + "checklist": "Azure Landing Zone Review", + "guid": "9eb54dad-7861-4e1c-973a-f3bb003fc9c1", "services": [ - "Storage", - "AKS" + "Entra", + "SAP" ], "severity": "Medium", - "subcategory": "Storage", - "text": "If using AzFiles Standard, consider AzFiles Premium and/or ANF for performance reasons", - "waf": "Performance" + "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": "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", + "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": [ - "Storage", - "AKS" + "Entra", + "SAP" ], "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" + "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": "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": "Identity and Access", + "checklist": "Azure Landing Zone Review", + "guid": "23181aa4-1742-4694-9ff8-ae7d7d474317", "services": [ - "VM" + "AKV", + "Entra", + "SAP" ], - "severity": "Low", - "subcategory": "VM Scale Sets", - "text": "Enable automatic instance repairs for enhanced VM Scale Sets resiliency", - "waf": "Reliability" + "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": "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": "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": [ - "Backup", - "VM" + "AKV", + "Entra", + "SAP" ], - "severity": "High", - "subcategory": "Virtual Machines", - "text": "Consider Azure Backup to meet your resiliency requirements for Azure VMs", - "waf": "Reliability" + "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": "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": "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": [ - "VM" + "Entra", + "SAP" ], - "severity": "High", - "subcategory": "Virtual Machines", - "text": "Use Premium or Ultra disks for production VMs", - "waf": "Reliability" + "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." }, { - "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": "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": [ - "VM" + "Entra", + "SAP" ], - "severity": "High", - "subcategory": "Virtual Machines", - "text": "Ensure Managed Disks are used for all VMs", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "Identity", + "text": "Implement SSO to SAP HANA" }, { - "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": "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": [ - "Storage", - "SQL", - "VM" + "Entra", + "SAP" ], "severity": "Medium", - "subcategory": "Virtual Machines", - "text": "Do not use the Temp disk for anything that is not acceptable to be lost", - "waf": "Reliability" + "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": "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": "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": [ - "ACR", - "Storage", - "VM" + "Entra", + "SAP" ], "severity": "Medium", - "subcategory": "Virtual Machines", - "text": "Leverage Availability Zones for your VMs in regions where they are supported", - "waf": "Reliability" + "subcategory": "Identity", + "text": "For applications that access SAP, you might want to use principal propagation to establish SSO." }, { - "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": "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": [ - "VM" + "Entra", + "SAP" ], "severity": "Medium", - "subcategory": "Virtual Machines", - "text": "For regions that do not support Availability Zones deploy VMs into Availability Sets", - "waf": "Reliability" + "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": "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": "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": [ - "ASR", - "VM" + "Entra", + "SAP" ], - "severity": "High", - "subcategory": "Virtual Machines", - "text": "Avoid running a production workload on a single VM", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "Identity", + "text": "Implement SSO to SAP BTP" }, { - "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": "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": [ - "ASR", - "AVS", - "VM" + "Entra", + "SAP" ], - "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" + "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." }, { - "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": "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": [ - "VM" + "AzurePolicy", + "Subscriptions", + "SAP" ], - "severity": "Low", - "subcategory": "Virtual Machines", - "text": "Use Capacity Reservations for critical workloads that require guaranteed capacity", - "waf": "Reliability" + "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" }, { - "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": "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": [ - "ASR", - "VM" + "Subscriptions", + "SAP" ], - "severity": "Medium", - "subcategory": "Virtual Machines", - "text": "Increase quotas in DR region before testing failover with ASR", - "waf": "Reliability" + "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": "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": "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": [ - "VM" + "Subscriptions" ], - "severity": "Low", - "subcategory": "Virtual Machines", - "text": "Utilize Scheduled Events to prepare for VM maintenance", - "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": "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": "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": "Storage Accounts", - "text": "Choose the most appropriate data redundancy option for Azure Storage based on your requirements", - "waf": "Reliability" + "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": "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": "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": [ - "Storage" + "Subscriptions" ], "severity": "Low", - "subcategory": "Storage Accounts", - "text": "Apply a Delete lock to prevent accidental or malicious deletion of storage accounts", - "waf": "Reliability" + "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": "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": "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": "Low", - "subcategory": "Storage Accounts", - "text": "Enable soft delete for Storage Account Containers", - "waf": "Reliability" + "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." }, { - "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": "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": [ - "Storage" + "Subscriptions" ], - "severity": "Low", - "subcategory": "Storage Accounts", - "text": "Enable soft delete for blobs", - "waf": "Reliability" + "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": "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": "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": [ - "Backup" + "TrafficManager", + "Cost", + "Subscriptions" ], "severity": "Medium", - "subcategory": "Backup", - "text": "Enable Azure Backup enhanced soft delete for improved data protection and recovery", - "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": "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": "Management and Monitoring", + "checklist": "Azure Landing Zone Review", + "guid": "14591147-5e39-4e53-89cc-cd979366bcda", "services": [ - "Backup" + "SQL", + "Monitor", + "SAP" ], - "severity": "Low", - "subcategory": "Backup", - "text": "Implement multi-user authorization for Azure Backup to ensure secure and controlled access to backup resources", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "Monitoring", + "text": "Use SAP Solution Manager and Azure Monitor for SAP Solutions to monitor SAP HANA, high-availability SUSE clusters, and SQL systems" }, { - "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": "Management and Monitoring", + "checklist": "Azure Landing Zone Review", + "guid": "2750ab1a-b039-4d95-b54c-7c8929cb107d", + "link": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", "services": [ - "Backup", - "Storage" + "VM", + "Monitor", + "Entra", + "SAP" ], - "severity": "Low", - "subcategory": "Backup", - "text": "Implement Immutable Storage for your vaults to protect against ransomware and prevent unauthorized modifications to backups", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "Monitoring", + "text": "Run a VM Extension for SAP check. VM Extension for SAP uses the assigned managed identity of a virtual machine to access VM monitoring and configuration data.", + "training": "https://learn.microsoft.com/learn/paths/architect-infrastructure-operations/" }, { - "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": "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", "services": [ - "ASR" + "AzurePolicy", + "Monitor" ], - "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" + "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/" }, { - "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": "Management and Monitoring", + "checklist": "Azure Landing Zone Review", + "guid": "2f7c95f0-6e15-44e3-aa35-92829e6e2061", + "link": "https://learn.microsoft.com/azure/governance/policy/how-to/guest-configuration-create", "services": [ - "ASR", - "RBAC" + "Backup", + "Storage", + "Monitor" ], "severity": "Medium", - "subcategory": "DevOps", - "text": "Implement Infrastructure as Code (IaC) for Rapid Infrastructure Recovery", - "waf": "Reliability" + "subcategory": "Monitoring", + "text": "Protect your HANA database with Azure Backup service. If you deploy Azure NetApp Files (ANF) for your HANA database, use the Azure Application Consistent Snapshot tool (AzAcSnap) to take application-consistent snapshots", + "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/" }, { - "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": "Management and Monitoring", + "checklist": "Azure Landing Zone Review", + "guid": "73686af4-6791-4f89-95ad-a43324e13811", + "link": "https://learn.microsoft.com/azure/automation/update-management/overview", "services": [ - "ASR" + "VM", + "Monitor", + "SAP" ], "severity": "Medium", - "subcategory": "Multi-region", - "text": "Plan for cross-region recovery by leveraging region pairs", - "waf": "Reliability" + "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.", + "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-compute-resources/" }, { - "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": "Management and Monitoring", + "checklist": "Azure Landing Zone Review", + "guid": "523181aa-4174-4269-93ff-8ae7d7d47431", + "link": "https://learn.microsoft.com/azure/network-watcher/network-watcher-monitoring-overview", "services": [ - "AppGW" + "NetworkWatcher", + "Monitor", + "SAP" ], "severity": "Medium", - "subcategory": "Application Gateways", - "text": "Deploy Application Gateways with a minimum instance count of 2 to avoid instance provisioning downtime", - "waf": "Reliability" + "subcategory": "Monitoring", + "text": "Use Network Watcher Connection Monitor to monitor SAP database and application server latency metrics, or collect and display network latency measurements with Azure Monitor.", + "training": "https://learn.microsoft.com/learn/modules/configure-network-watcher/" }, { - "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": "Management and Monitoring", + "checklist": "Azure Landing Zone Review", + "guid": "76c8bcbf-45bb-4e60-ad8a-03e97778424d", + "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/lock-resources?tabs=json", "services": [ - "AppGW", - "Storage" + "Monitor", + "SAP" ], - "severity": "High", - "subcategory": "Application Gateways", - "text": "Deploy Azure Application Gateway v2 for zone redundancy support", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "Monitoring", + "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/learn/paths/implement-resource-mgmt-security/" }, { - "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": "Management and Monitoring", + "checklist": "Azure Landing Zone Review", + "guid": "616785d6-fa96-4c96-ad88-518f482734c8", + "link": "https://learn.microsoft.com/azure/governance/policy/overview", "services": [ - "FrontDoor" + "Subscriptions", + "Monitor", + "SAP" ], - "severity": "Low", - "subcategory": "Azure Front Door", - "text": "Consider a redundant traffic management solution in conjunction with Azure Front Door", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "Monitoring", + "text": "For each Azure subscription, run an Azure Availability Zone latency test before zonal deployment to choose low-latency zones for SAP on Azure deployment." }, { - "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": "Management and Monitoring", + "checklist": "Azure Landing Zone Review", + "guid": "86ba2802-1459-4114-95e3-9e5309cccd97", + "link": "https://learn.microsoft.com/azure/sentinel/quickstart-onboard", "services": [ - "ASR", + "Sentinel", "Monitor", - "TrafficManager", - "DNS" + "SAP" ], - "severity": "Low", - "subcategory": "DNS", - "text": "Plan for automated failover using Traffic Manager for DNS Traffic", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "Monitoring", + "text": "Implement threat protection for SAP with Microsoft Sentinel." }, { - "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": "Management and Monitoring", + "checklist": "Azure Landing Zone Review", + "guid": "4d116785-d2fa-456c-96ad-48408fe72734", + "link": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", "services": [ - "ASR", "ACR", - "DNS" + "Monitor", + "VM", + "AzurePolicy", + "Entra" ], - "severity": "Low", - "subcategory": "DNS", - "text": "Implement DNS Failover using Azure DNS Private Resolvers", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "Monitoring", + "text": "Enforcing configuration of update management through policy ensures all VMs are included in the patch management regimen, provides application teams with the ability to manage patch deployment for their VMs, and provides central IT with visibility and enforcement capabilities across all VMs" }, { - "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": "Management and Monitoring", + "checklist": "Azure Landing Zone Review", + "guid": "c486ba28-0dc0-4591-af65-de8e1309cccd", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-setup-guide/monitoring-reporting?tabs=AzureMonitor", "services": [ - "ACR" + "VM", + "Monitor", + "SAP" ], "severity": "Medium", - "subcategory": "Data Gateways", - "text": "Use on-premises data gateway clusters to ensure high availability for business-critical data", - "waf": "Reliability" + "subcategory": "Monitoring", + "text": "Enable VM Insights for VM's running SAP Workloads." }, { - "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": "Management and Monitoring", + "checklist": "Azure Landing Zone Review", + "guid": "579266bc-ca27-45fa-a1ab-fe9d55d04c3c", + "link": "https://learn.microsoft.com/azure/architecture/framework/resiliency/backup-and-recovery", "services": [ - "ExpressRoute" + "Cost", + "Monitor" ], "severity": "Medium", - "subcategory": "ExpressRoute", - "text": "Ensure redundancy within both the partner network and customer network when utilizing ExpressRoute for high availability", - "waf": "Reliability" + "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." }, { - "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": "Management and Monitoring", + "checklist": "Azure Landing Zone Review", + "guid": "4919cb1b-3d13-425a-b124-ba34df685edd", + "link": "https://learn.microsoft.com/azure/backup/backup-center-overview", "services": [ - "Backup", - "ExpressRoute" + "Monitor" ], "severity": "Medium", - "subcategory": "ExpressRoute", - "text": "When using multiple ExpressRoute circuits ensure that routing allows for a primary and backup", - "waf": "Reliability" + "subcategory": "Monitoring", + "text": " " }, { - "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": "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": [ - "VPN", - "Cost", - "ExpressRoute", - "Backup" + "AppGW", + "AzurePolicy", + "WAF" ], - "severity": "Low", - "subcategory": "ExpressRoute", - "text": "Consider deploying site-to-site VPN as a backup for your ExpressRoute private peering", - "waf": "Reliability" + "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/learn/paths/secure-application-delivery/" }, { - "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": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "a3592829-e6e2-4061-9368-6af46791f893", + "link": "https://learn.microsoft.com/azure/networking/", "services": [ - "LoadBalancer" + "ACR", + "VNet", + "SAP" ], "severity": "Medium", - "subcategory": "Load Balancers", - "text": "Leverage the Standard SKU for Load Balancers that handle traffic to production applications", - "waf": "Reliability" + "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/learn/modules/design-implement-azure-expressroute/" }, { - "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": "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": [ - "LoadBalancer", - "VM" + "VNet", + "VM", + "SAP" ], - "severity": "Low", - "subcategory": "Load Balancers", - "text": "For load balancers, consider using a zone-redundant frontend with multiple zonal resources in the backend", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "IP plan", + "text": "Public I.P assignment to VM running SAP Workload is not recommended.", + "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/" }, { - "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": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "9cccd979-366b-4cda-8750-ab1ab039d95d", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing", "services": [ - "Monitor", - "LoadBalancer" + "VNet", + "ASR" ], - "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" + "severity": "Medium", + "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": "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": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "54c7c892-9cb1-407d-9325-ae525ba34d46", + "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-name-resolution-for-vms-and-role-instances", "services": [ - "NVA" + "VNet" ], - "severity": "High", - "subcategory": "NVAs", - "text": "Deploy Network Virtual Appliances (NVAs) in a vendor supported configuration for High Availability", - "waf": "Reliability" + "severity": "Medium", + "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/" }, { - "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": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "85e2213a-ce7b-4b12-8f7c-95f06e154e3a", + "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-name-resolution-for-vms-and-role-instances", "services": [ - "VPN", - "ACR" + "VNet", + "VM" + ], + "severity": "Medium", + "subcategory": "IP plan", + "text": "Ensure Accelerated Networking is enable for all VM where it is applicable.", + "training": "https://learn.microsoft.com/learn/paths/az-104-manage-virtual-networks/" + }, + { + "category": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "d8a03e97-7784-424d-9167-85d6fa96c96a", + "link": "https://learn.microsoft.com/azure/app-service/networking-features", + "services": [ + "Firewall" ], "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": "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/" }, { - "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": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "d88518f4-8273-44c8-a6ba-280214591147", + "link": "https://learn.microsoft.com/azure/firewall/", "services": [ - "VPN" + "AppGW", + "SAP" ], "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": "Internet", + "text": "Use SAP Web dispatcher or third party service like NetScaler in conjunction with Application gateway if necessary to overcome reverse proxy limitation for SAP web Apps.", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/" }, { - "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", + "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": [ - "Backup", - "AVS", - "Storage" + "ACR", + "AzurePolicy", + "WAF", + "FrontDoor" ], "severity": "Medium", - "subcategory": "Backup", - "text": "Ensure backups are not stored on vSAN as vSAN is a finite resource", - "waf": "Reliability" + "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/" }, { - "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": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "b039d95d-54c7-4c89-89cb-107d5325ae52", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", "services": [ - "Backup", - "AVS" + "AppGW", + "AzurePolicy", + "WAF", + "FrontDoor" ], "severity": "Medium", - "subcategory": "Business Continuity", - "text": "Use MABS as your backup solution", - "waf": "Reliability" + "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/" }, { - "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": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "5ada4332-4e13-4811-9231-81aa41742694", + "link": "https://learn.microsoft.com/azure/virtual-network/vnet-integration-for-azure-services", "services": [ - "Backup", - "AVS", - "ASR" + "AppGW", + "LoadBalancer", + "WAF" ], "severity": "Medium", - "subcategory": "Business Continuity", - "text": "Deploy your backup solution in the same region as your Azure VMware Solution private cloud", - "waf": "Reliability" + "subcategory": "PaaS", + "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/learn/paths/implement-network-security/?source=learn" }, { - "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": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "3ff8ae7d-7d47-4431-96c8-bcbf45bbe609", "services": [ - "AVS" + "LoadBalancer" ], "severity": "Medium", - "subcategory": "Business Continuity", - "text": "Preferably deploy MABS outside of the SDDC as native Azure IaaS", - "waf": "Reliability" + "subcategory": "PaaS", + "text": "Ensure that internal deployments for Azure Load Balancer are set up to use Direct Server Return (DSR) for HA configuration on the DBMS layer" }, { - "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": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "6e154e3a-a359-4282-ae6e-206173686af4", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-setup-guide/organize-resources?tabs=AzureManagementGroupsAndHierarchy", "services": [ - "AVS" + "Storage", + "VNet", + "SAP" ], "severity": "Medium", - "subcategory": "Business Continuity", - "text": "Escalation process with Microsoft in the event of a regional DR", - "waf": "Reliability" + "subcategory": "Segmentation", + "text": "If Azure NetApp Files is used for SAP deployment , ensure that only one delegate subnet can exist in a Vnet for Azure NetAppFiles", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/" }, { - "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": "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": [ - "ASR", - "AVS" + "VNet", + "SAP" ], "severity": "Medium", - "subcategory": "Disaster Recovery", - "text": "Use VMware Site Recovery Manager when both sites are Azure VMware Solution", - "waf": "Reliability" + "subcategory": "Segmentation", + "text": "Use NSGs and application security groups to micro-segment traffic within SAP application layer, like App subnet, DB subnet and Web subnet etc.", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/" }, { - "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": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "41742694-3ff8-4ae7-b7d4-743176c8bcbf", + "link": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", "services": [ - "ASR", - "AVS" + "NVA", + "SAP" ], "severity": "Medium", - "subcategory": "Disaster Recovery", - "text": "Use Azure Site Recovery when the Disaster Recovery technology is native Azure IaaS", - "waf": "Reliability" + "subcategory": "Segmentation", + "text": "It is not supported to deploy any NVA between SAP application and SAP Database server", + "training": "https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/" }, { - "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": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "45bbe609-d8a0-43e9-9778-424d616785d6", "services": [ - "ASR", - "AVS" + "VNet", + "SAP" ], "severity": "Medium", - "subcategory": "Disaster Recovery", - "text": "Use Automated recovery plans with either of the Disaster solutions,", - "waf": "Reliability" + "subcategory": "Segmentation", + "text": "Placing of the SAP application layer and SAP DBMS in different Azure VNets that aren't peered isn't supported" }, { - "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": "Network Topology and Connectivity", + "checklist": "Azure Landing Zone Review", + "guid": "fa96c96a-d885-418f-9827-34c886ba2802", "services": [ - "ASR", - "AVS" + "SAP" ], "severity": "Medium", - "subcategory": "Disaster Recovery", - "text": "Configure a secondary disaster recovery environment", - "waf": "Reliability" + "subcategory": "Segmentation", + "text": "For optimal network latency with SAP applications, consider using Azure proximity placement groups." }, { - "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": "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": [ - "ASR", - "AVS" + "Subscriptions", + "RBAC", + "SAP" ], - "severity": "Medium", - "subcategory": "Disaster Recovery", - "text": "Assign IP ranges unique to each region", - "waf": "Reliability" + "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": "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": "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": [ - "ASR", "NVA", - "AVS", - "ExpressRoute" + "PrivateLink", + "SAP" ], "severity": "Medium", - "subcategory": "Disaster Recovery", - "text": "Use Global Reach between DR regions", - "waf": "Reliability" + "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": "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": "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": [ - "VWAN", - "AVS" + "Backup", + "Storage", + "SQL", + "SAP" ], "severity": "Medium", - "subcategory": "Direct (no vWAN, no H&S)", - "text": "Global Reach to ExR circuit - no Azure resources", - "waf": "Performance" + "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": "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": "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": [ - "AVS", - "ExpressRoute" + "Storage" ], "severity": "Medium", - "subcategory": "ExpressRoute", - "text": "Connect to Azure using ExR", - "waf": "Performance" + "subcategory": "Governance", + "text": "Azure Storage encryption is enabled by default" }, { - "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" - ], + "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": "ExpressRoute", - "text": "Bandwidth sizing", - "waf": "Performance" + "subcategory": "Governance", + "text": " " }, { - "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": "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": [ - "AVS", - "ExpressRoute" + "AKV" ], - "severity": "Medium", - "subcategory": "ExpressRoute", - "text": "Traffic routing ", - "waf": "Performance" + "severity": "High", + "subcategory": "Secrets", + "text": "Use Azure Key Vault to store your secrets and credentials" }, { - "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": "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": [ - "AVS", - "ExpressRoute" + "AKV" ], "severity": "Medium", - "subcategory": "ExpressRoute", - "text": "Global Reach ", - "waf": "Performance" + "subcategory": "Secrets", + "text": "It is recommended to LOCK the Azure Resources post successful deployment to safeguard against unauthorized changes" }, { - "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": "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": [ - "AVS", - "VNet" + "AKV", + "AzurePolicy" ], "severity": "Medium", - "subcategory": "Hub & Spoke", - "text": "VNet name & address space", - "waf": "Performance" + "subcategory": "Secrets", + "text": "Provision Azure Key Vault with the soft delete and purge policies enabled to allow retention protection for deleted objects." }, { - "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": "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": [ - "VPN", - "AVS", - "VNet", - "ExpressRoute" + "AKV", + "AzurePolicy", + "RBAC" ], "severity": "Medium", - "subcategory": "Hub & Spoke", - "text": "Gateway subnet", - "waf": "Performance" + "subcategory": "Secrets", + "text": "Based on existing requirements, regulatory and compliance controls (internal/external) - Determine what Azure Policies and Azure RBAC role are needed" }, { - "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": "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": [ - "VPN", - "AVS", - "VNet", - "ExpressRoute" + "AKV", + "AzurePolicy", + "Defender", + "SAP" ], "severity": "Medium", - "subcategory": "Hub & Spoke", - "text": "VPN Gateway", - "waf": "Performance" + "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": "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": "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": [ - "VPN", - "AVS", - "VNet", - "ExpressRoute" + "AKV", + "RBAC", + "SAP" ], "severity": "Medium", - "subcategory": "Hub & Spoke", - "text": "ExR Gateway", - "waf": "Performance" + "subcategory": "Secrets", + "text": "Delegate an SAP admin custom role with just-in-time access." }, { - "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": "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": [ - "NVA", - "AVS" + "AKV", + "SAP" ], "severity": "Medium", - "subcategory": "Internet", - "text": "Egress point", - "waf": "Performance" + "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": "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": "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": [ - "AVS", - "Bastion" + "AKV", + "Entra", + "SAP" ], "severity": "Medium", - "subcategory": "Jumpbox & Bastion", - "text": "Remote connectivity to AVS", - "waf": "Performance" + "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": "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": "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": [ - "AVS", - "VNet", - "Bastion" + "AKV", + "SAP" ], "severity": "Medium", - "subcategory": "Jumpbox & Bastion", - "text": "Configure a jumbox and Azure Bastion", - "waf": "Performance" + "subcategory": "Secrets", + "text": "Make sure you harden the operating system to eradicate vulnerabilities that could lead to attacks on the SAP database." }, { - "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": [ - "AVS", - "Bastion", - "VM" + "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": [ + "AKV" ], "severity": "Medium", - "subcategory": "Jumpbox & Bastion", - "text": "Security measure allowing RDP access via the portal", - "waf": "Performance" + "subcategory": "Secrets", + "text": "Default to Microsoft-managed keys for principal encryption functionality and use customer-managed keys when required." }, { - "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": "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": [ - "VPN", - "AVS" + "AKV" ], "severity": "Medium", - "subcategory": "VPN", - "text": "Connect to Azure using a VPN", - "waf": "Performance" + "subcategory": "Secrets", + "text": "Use an Azure Key Vault per application per environment per region." }, { - "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.", + "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": [ - "VPN", - "AVS" + "AKV" ], "severity": "Medium", - "subcategory": "VPN", - "text": "Bandwidth sizing", - "waf": "Performance" + "subcategory": "Secrets", + "text": " " }, { - "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", + "category": "Storage", + "checklist": "Azure Landing Zone Review", + "guid": "d579266b-cca2-475f-aa1a-bfe9d55d04c3", "services": [ - "VPN", - "AVS" + "Storage", + "SQL" ], "severity": "Medium", - "subcategory": "VPN", - "text": "Traffic routing ", - "waf": "Performance" + "subcategory": " ", + "text": "Disk config for Oracle, SQL, HANA" }, { - "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": "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": [ - "VWAN", - "AVS" + "Defender", + "Subscriptions" ], - "severity": "Medium", - "subcategory": "vWAN hub", - "text": "vWAN name, hub name and address space", - "waf": "Performance" + "severity": "High", + "subcategory": "Pricing & Settings", + "text": "Security Center/Defender enable in all subscriptions" }, { - "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", + "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", - "AVS", - "VWAN" + "Defender", + "Monitor" ], - "severity": "Medium", - "subcategory": "vWAN hub", - "text": "ExR and/or VPN gateway provisioned", - "waf": "Performance" + "severity": "High", + "subcategory": "Pricing & Settings", + "text": "Security Center/Defender enabled on all Log Analytics workspaces" }, { - "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", + "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": [ - "VWAN", - "Firewall", - "AVS" + "Defender" ], "severity": "Medium", - "subcategory": "vWAN hub", - "text": "Secure vWAN", - "waf": "Security" + "subcategory": "Pricing & Settings", + "text": "Data collection set to 'Common'" }, { - "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", + "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": [ - "AVS", - "Entra" + "Defender" ], - "severity": "Medium", - "subcategory": "Access", - "text": "External Identity (user accounts)", - "waf": "Security" + "severity": "High", + "subcategory": "Pricing & Settings", + "text": "Defender for Cloud enhanced security features are all enabled" }, { - "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": "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": [ - "AVS", - "Entra" + "AzurePolicy", + "Defender" ], "severity": "Medium", - "subcategory": "Access", - "text": "If using AD domain, ensure Sites & Services has been configured", - "waf": "Security" + "subcategory": "Pricing & Settings", + "text": "Auto-provisioning enabled as per company policy (policy must exist)" }, { - "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": "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": [ - "AVS", - "Entra" + "AzurePolicy", + "Defender" ], - "severity": "Medium", - "subcategory": "Access", - "text": "Use LDAPS not ldap ( vCenter)", - "waf": "Security" + "severity": "Low", + "subcategory": "Pricing & Settings", + "text": "Email notifications enabled as per company policy (policy must exist)" }, { - "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": "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": [ - "AVS", - "Entra" + "Defender" ], "severity": "Medium", - "subcategory": "Access", - "text": "Use LDAPS not ldap (NSX-T)", - "waf": "Security" + "subcategory": "Pricing & Settings", + "text": "Enable integrations options are selected " }, { - "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": "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": [ - "AVS", - "Entra" + "Defender" ], "severity": "Medium", - "subcategory": "Security", - "text": "Security certificate installed on LDAPS servers ", - "waf": "Security" + "subcategory": "Pricing & Settings", + "text": "CI/CD integration is configured" }, { - "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": "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": [ - "RBAC", - "AVS", - "Entra" + "EventHubs", + "Defender" ], - "severity": "Medium", - "subcategory": "Security", - "text": "RBAC applied to Azure roles", - "waf": "Security" + "severity": "High", + "subcategory": "Pricing & Settings", + "text": "Continuous export 'Event Hub' is enabled if using 3rd party SIEM" }, { - "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": "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": [ - "RBAC", - "AVS", - "Entra" + "Sentinel", + "Defender", + "Monitor" ], "severity": "Medium", - "subcategory": "Security", - "text": "RBAC model in vCenter", - "waf": "Security" + "subcategory": "Pricing & Settings", + "text": "Continuous export 'Log Analytics Workspace' is enabled if not using Azure Sentinel" }, { - "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": "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": [ - "RBAC", - "AVS", - "Entra" + "Defender" ], - "severity": "Medium", - "subcategory": "Security", - "text": "CloudAdmin role usage", - "waf": "Security" + "severity": "High", + "subcategory": "Pricing & Settings", + "text": "Cloud connector enabled for AWS" }, { - "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": "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": [ - "RBAC", - "AVS", - "Entra" + "Defender" ], - "severity": "Medium", - "subcategory": "Security ", - "text": "Is Privileged Identity Management implemented", - "waf": "Security" + "severity": "High", + "subcategory": "Pricing & Settings", + "text": "Cloud connector enabled for GCP" }, { - "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": "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": [ - "RBAC", - "AVS", + "Defender", + "Monitor", "Entra" ], - "severity": "Medium", - "subcategory": "Security ", - "text": "Is Privileged Identity Management audit reporting implemented", - "waf": "Security" + "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": "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": "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": [ - "Monitor", - "AVS", - "Entra" + "Defender" ], "severity": "Medium", - "subcategory": "Security ", - "text": "Limit use of CloudAdmin account to emergency access only", - "waf": "Security" + "subcategory": "Recommendations", + "text": "All recommendations remediated or disabled if not required." }, { - "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": "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": [ - "AVS", - "Entra" + "Defender" ], - "severity": "Medium", - "subcategory": "Security ", - "text": "Is a process defined to regularly rotate cloudadmin (vCenter) and admin (NSX) credentials", - "waf": "Security" + "severity": "High", + "subcategory": "Recommendations", + "text": "Security Score>70%" }, { - "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": "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": [ - "AVS", - "Arc", - "VM" + "Defender", + "Monitor" ], "severity": "Medium", - "subcategory": "Operations", - "text": "AVS VM Management (Azure Arc)", - "waf": "Operations" + "subcategory": "Security Alerts", + "text": "Security Alerts contain only those generated in the past 24 hours (remediate or disable older security alerts)" }, { - "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": "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": [ - "AzurePolicy", - "Monitor", - "AVS" + "Defender" ], "severity": "Medium", - "subcategory": "Operations", - "text": "Azure policy", - "waf": "Operations" + "subcategory": "Workbooks", + "text": "If continuous export is enabled, default workbooks published to custom security dashboard" }, { - "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": "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": [ - "AVS" + "Defender" ], "severity": "Medium", - "subcategory": "Operations", - "text": "Resource locks", - "waf": "Operations" + "subcategory": "Community", + "text": "Customer is aware of the value of the 'Community' page and has a regular cadence set up to review" }, { - "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.", + "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": [ - "AVS" + "Defender", + "Subscriptions" ], - "severity": "Medium", - "subcategory": "Operations", - "text": "Run books", - "waf": "Operations" + "severity": "High", + "subcategory": "Secure Score", + "text": "All subscriptions protected by Security Center are shown (no subscription filter set)" }, { - "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", + "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": [ - "AVS", - "AKV" + "Defender" ], - "severity": "Medium", - "subcategory": "Operations", - "text": "Naming conventions for auth keys", - "waf": "Operations" + "severity": "High", + "subcategory": "Regulatory Compliance", + "text": "Compliance controls are green for any required compliance requirements" }, { - "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", + "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": [ - "Monitor", - "AVS" + "VM", + "Defender" ], - "severity": "Medium", - "subcategory": "Alerts", - "text": "Create warning alerts for critical thresholds ", - "waf": "Operations" + "severity": "High", + "subcategory": "Azure Defender", + "text": "High severity VM vulnerabilities is zero (empty)" }, { - "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": "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": [ - "Monitor", - "AVS" + "Firewall", + "Defender" ], "severity": "Medium", - "subcategory": "Alerts", - "text": "Create critical alert vSAN consumption", - "waf": "Operations" + "subcategory": "Firewall Manager", + "text": "Hubs are protected by an Azure Firewall" }, { - "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": "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": [ - "Monitor", - "AVS" + "Firewall", + "VNet", + "Defender" ], "severity": "Medium", - "subcategory": "Alerts", - "text": "Configured for Azure Service Health alerts and notifications", - "waf": "Operations" + "subcategory": "Firewall Manager", + "text": "Virtual Networks are protected by a Firewall" }, { - "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": "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": [ - "AzurePolicy", - "VM", - "Backup", - "Monitor", - "AVS" + "Firewall", + "Defender", + "DDoS" ], "severity": "Medium", - "subcategory": "Backup", - "text": "Backup policy", - "waf": "Operations" + "subcategory": "Firewall Manager", + "text": "DDoS Standard enabled" }, { - "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": "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": [ - "AzurePolicy", - "Monitor", - "AVS" + "Subscriptions", + "Defender" ], - "severity": "Medium", - "subcategory": "Capacity", - "text": "Policy around ESXi host density and efficiency", - "waf": "Operations" + "severity": "High", + "subcategory": "Coverage", + "text": "Verify that all subscriptions are covered (see pricing and settings to modify)" }, { - "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", + "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": [ - "Subscriptions", - "Cost", - "AVS", - "Monitor" + "VNet", + "VM" ], - "severity": "Medium", - "subcategory": "Costs", - "text": "Ensure a good cost management process is in place for Azure VMware Solution - ", - "waf": "Operations" + "severity": "High", + "subcategory": "Public IPs", + "text": "VM's with public IPs should be protected by NSG " }, { - "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", + "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": [ - "NetworkWatcher", - "Monitor", - "AVS" + "EventHubs", + "VM", + "Firewall" ], - "severity": "Medium", - "subcategory": "Dashboard", - "text": "Connection monitor dashboard", - "waf": "Operations" + "severity": "High", + "subcategory": "Public IPs", + "text": "VMs with public IPs are moved behind Azure Firewall Premium" }, { - "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", + "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": [ - "Monitor", - "AVS", - "Storage" + "VM" ], - "severity": "Medium", - "subcategory": "Logs & Metrics", - "text": "Configure Azure VMware Solution logging ", - "waf": "Operations" + "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": "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? ", + "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": [ - "Monitor", - "AVS" + "VNet", + "RBAC" ], "severity": "Medium", - "subcategory": "Logs & Metrics", - "text": "vRealize Operations", - "waf": "Operations" + "subcategory": "NSG", + "text": "NSG RBAC is used to restrict access to network security team" }, { - "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", + "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": [ - "Monitor", - "AVS", - "VM" + "VNet" ], - "severity": "Medium", - "subcategory": "Logs & Metrics", - "text": "AVS VM logging", - "waf": "Operations" + "severity": "High", + "subcategory": "NSG", + "text": "NSG Inbound security rules do not contain a * (wildcard) in Source field" }, { - "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", + "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": [ - "NetworkWatcher", - "Monitor", - "AVS", - "VPN", - "ExpressRoute" + "VNet" ], "severity": "Medium", - "subcategory": "Network", - "text": "Monitor ExpressRoute and/or VPN connections ", - "waf": "Operations" + "subcategory": "NSG", + "text": "NSG outbound security rules are used to control traffic to specific IP addresses for traffic not routed through a Firewall" }, { - "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", + "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": [ - "Monitor", - "AVS", - "ExpressRoute" + "VNet" ], - "severity": "Medium", - "subcategory": "Network", - "text": "Monitor from an Azure native resource to an Azure VMware Solution VM", - "waf": "Operations" + "severity": "High", + "subcategory": "NSG", + "text": "NSG do not have Source as a * (wildcard) in place." }, { - "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": "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": [ - "Monitor", - "AVS" + "Sentinel", + "VNet" ], "severity": "Medium", - "subcategory": "Network", - "text": "Monitor from an on-premises resource to an Azure VMware Solution VM", - "waf": "Operations" + "subcategory": "NSG", + "text": "NSG Diagnostics send NetworkSecurityGroupEvent and NetworkSecurityGroupRuleCounter traffic to Sentinel LAW" }, { - "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)", + "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": [ - "Monitor", - "AVS" + "VNet", + "RBAC" ], "severity": "Medium", - "subcategory": "Security", - "text": "Auditing and logging is implemented for inbound internet ", - "waf": "Operations" + "subcategory": "UDR", + "text": "UDR RBAC is used to restrict access to the network security team" }, { - "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", + "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": [ - "Monitor", - "AVS" + "VNet", + "Firewall" ], - "severity": "Medium", - "subcategory": "Security", - "text": "Session monitoring ", - "waf": "Operations" + "severity": "High", + "subcategory": "UDR", + "text": "If Zero Trust, then UDR's are used to send all traffic to the Azure Firewall Premium" }, { - "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", + "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": [ - "Monitor", - "AVS" + "VNet" ], "severity": "Medium", - "subcategory": "VMWare", - "text": "Logging and diagnostics", - "waf": "Operations" + "subcategory": "UDR", + "text": "UDR's that do not send all traffic to AzureFirewallPremium are known and documented." }, { - "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": "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": [ - "Monitor", - "AVS", - "VM" + "VNet" ], - "severity": "Medium", - "subcategory": "VMware", - "text": "Log Analytics Agents deployed on Azure VMware Solution guest VM workloads", - "waf": "Operations" + "severity": "High", + "subcategory": "Virtual Networks", + "text": "Customer is familiar with Azure networking defaults / SDN default routing in Azure" }, { - "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", + "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": [ - "AVS" + "VNet", + "RBAC" ], "severity": "Medium", - "subcategory": "Hub & Spoke", - "text": "North/South routing through Az Firewall or 3rd party ", - "waf": "Security" + "subcategory": "Virtual Networks", + "text": "VNet RBAC is used to restrict access to the network security team" }, { - "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", + "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": [ - "AVS" + "VNet" ], - "severity": "Medium", - "subcategory": "Hub & Spoke", - "text": "East West (Internal to Azure)", - "waf": "Security" + "severity": "High", + "subcategory": "Virtual Networks", + "text": "VNet Security recommendations are remediated and there are no 'At-risk' VNets " }, { - "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", + "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": [ - "NVA", - "AVS", - "ARS" + "VNet" ], - "severity": "Medium", - "subcategory": "Hub & Spoke", - "text": "ExR without Global Reach", - "waf": "Operations" + "severity": "High", + "subcategory": "Virtual Networks", + "text": "VNet Peering connections are understood and expected traffic flows are documented" }, { - "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", + "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": [ - "AVS", - "ARS" + "VNet" ], - "severity": "Medium", - "subcategory": "Hub & Spoke", - "text": "Route server ", - "waf": "Operations" + "severity": "High", + "subcategory": "Virtual Networks", + "text": "VNet Service Endpoints are in use, no legacy Public Service Endpoints exist" }, { - "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", + "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": [ - "AVS" + "VNet", + "PrivateLink" ], - "severity": "Medium", - "subcategory": "Internet", - "text": "Egress point(s)", - "waf": "Security" + "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": "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": "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": [ - "AppGW", - "NVA", - "AVS", - "FrontDoor" + "VNet", + "Monitor" ], - "severity": "Medium", - "subcategory": "Internet", - "text": "Internet facing applications", - "waf": "Security" + "severity": "High", + "subcategory": "Virtual Networks", + "text": "VNet Monitoring enabled" }, { - "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", + "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": [ - "AVS", - "ARS" + "VNet", + "AzurePolicy", + "AKS" ], - "severity": "Medium", - "subcategory": "Routing", - "text": "When route server Route limit understood? ", - "waf": "Security" + "severity": "High", + "subcategory": "Virtual Networks", + "text": "Secure traffic between pods using network policies in Azure Kubernetes Service (AKS)" }, { - "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", + "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": [ - "VPN", - "DDoS", - "VM", - "FrontDoor", - "AVS", - "LoadBalancer", "VNet", - "AppGW", - "ExpressRoute" + "NVA" ], - "severity": "Medium", - "subcategory": "Security", - "text": "Is DDoS standard protection of public facing IP addresses? ", - "waf": "Security" + "severity": "High", + "subcategory": "Virtual Networks", + "text": "VNet NVA (appliances) customer follows published architecture pattern" }, { - "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": "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": [ - "AVS" + "Sentinel", + "VNet", + "Monitor" ], - "severity": "Medium", - "subcategory": "Security", - "text": "Use a dedicated privileged access workstation (PAW)", - "waf": "Security" + "severity": "High", + "subcategory": "Virtual Networks", + "text": "VNet Diagnostic settings are enabled and sending VMProtectionAlerts to the Azure Sentinel LAW" }, { - "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", + "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": [ - "AVS" + "ExpressRoute", + "VPN" ], - "severity": "Medium", - "subcategory": "Traffic Inspection", - "text": "East West (Internal to AVS)", - "waf": "Security" + "severity": "High", + "subcategory": "Connectivity", + "text": "Use ExpressRoute or VPN to access Azure resources from on-premises environments" }, { - "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", + "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": [ "VWAN", - "Firewall", - "AVS" + "RBAC" ], - "severity": "Medium", + "severity": "High", "subcategory": "Virtual WAN", - "text": "Use Secure Hub (Azure Firewall or 3rd party)", - "waf": "Security" + "text": "VWAN RBAC is used to restrict access to the network security team" }, { - "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", + "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": [ "VWAN", - "AVS" + "Monitor" ], - "severity": "Medium", + "severity": "High", "subcategory": "Virtual WAN", - "text": "East West (Internal to Azure)", - "waf": "Security" + "text": "VWAN Customer is using Secure Hub or external Firewall to route and monitor traffic." }, { - "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", + "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": [ - "Subscriptions", - "AVS" + "AppGW", + "RBAC" ], - "severity": "Medium", - "subcategory": "Automated Scale", - "text": "Scale out operations planning", - "waf": "Performance" + "severity": "High", + "subcategory": "Application Gateway", + "text": "AppGW RBAC is used to restrict access to the network security team" }, { - "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", + "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": [ - "AzurePolicy", - "AVS", - "Storage" + "AppGW", + "EventHubs", + "WAF" ], - "severity": "Medium", - "subcategory": "Automated Scale", - "text": "Scale in operations planning", - "waf": "Performance" + "severity": "High", + "subcategory": "Application Gateway", + "text": "AppGW All external facing web services are behind Application Gateways with WAF enabled " }, { - "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", + "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": [ - "AVS" + "AppGW", + "EventHubs", + "WAF" ], - "severity": "Medium", - "subcategory": "Automated Scale", - "text": "Scale serialized operations planning", - "waf": "Performance" + "severity": "High", + "subcategory": "Application Gateway", + "text": "AppGW All internal facing web services are behind Application Gateways with WAF enabled " }, { - "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)", + "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": [ - "AVS" + "AppGW" ], - "severity": "Medium", - "subcategory": "Automated Scale", - "text": "Scale rd operations planning", - "waf": "Performance" + "severity": "High", + "subcategory": "Application Gateway", + "text": "AppGW - External facing has TLS/SSL enabled and redirects all traffic to 443 (no port 80 traffic)" }, { - "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": "Azure Networking", + "checklist": "Azure Security Review Checklist", + "guid": "f2e8bbbc-4681-455a-ac91-64e9909aed8c", + "link": "https://learn.microsoft.com/azure/frontdoor/", "services": [ - "AVS" + "RBAC", + "FrontDoor" ], - "severity": "Medium", - "subcategory": "Automated Scale", - "text": "Scale maximum operations planning", - "waf": "Performance" + "severity": "High", + "subcategory": "FrontDoor", + "text": "Front Door RBAC is used to restrict access to the network security team" }, { - "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", + "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": [ - "Monitor", - "AVS" + "AzurePolicy", + "WAF", + "FrontDoor" ], - "severity": "Medium", - "subcategory": "Automated Scale", - "text": "Monitor scaling operations ", - "waf": "Performance" + "severity": "High", + "subcategory": "FrontDoor", + "text": "Front Door is associated with a WAF policy" }, { - "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", + "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": [ - "PrivateLink", - "AVS" + "AzurePolicy", + "FrontDoor" ], - "severity": "Medium", - "subcategory": "Networking", - "text": "Private link", - "waf": "Performance" + "severity": "High", + "subcategory": "FrontDoor", + "text": "Front Door TLS/SSL policy is configured" }, { - "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": "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": [ - "AVS" + "FrontDoor" ], - "severity": "Medium", - "subcategory": "Networking", - "text": "Provisioning Vmware VLANs", - "waf": "Performance" + "severity": "High", + "subcategory": "FrontDoor", + "text": "Front Door redirect port 80 to port 443 is configured (listeners)" }, { - "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", + "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": [ - "AVS" + "Sentinel", + "FrontDoor" ], - "severity": "Medium", - "subcategory": "Pre-deployment", - "text": "Region selected", - "waf": "Reliability" + "severity": "High", + "subcategory": "FrontDoor", + "text": "Front Door diagnostics logs send ApplicationGatewayAccessLog &ApplicationGateway FirewallLog to Sentinel LAW" }, { - "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": "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": [ - "AzurePolicy", - "AVS" + "DDoS" ], - "severity": "Medium", - "subcategory": "Pre-deployment", - "text": "Data residency compliant with selected regions", - "waf": "Reliability" + "severity": "High", + "subcategory": "DDOS Protection", + "text": "Enabled for Firewall public IP's (all public IPs)" }, - { - "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": "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": [ - "AVS" + "Entra" ], - "severity": "Medium", - "subcategory": "Pre-deployment", - "text": "Request for number of AVS hosts submitted ", - "waf": "Reliability" + "severity": "High", + "subcategory": "Tenant", + "text": "Establish a single enterprise directory for managing identities of full-time employees and enterprise resources." }, { - "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": "Identity", + "checklist": "Azure Security Review Checklist", + "guid": "a46108cd-6a76-4749-ae69-b7bf61410010", + "link": "https://learn.microsoft.com/security/compass/identity#synchronized-identity-systems", "services": [ - "AVS" + "Entra" ], - "severity": "Medium", - "subcategory": "Pre-deployment", - "text": "Region and number of AVS nodes approved", - "waf": "Reliability" + "severity": "High", + "subcategory": "Tenant", + "text": "Synchronize your cloud identity with your existing identity systems." }, { - "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", + "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": [ - "Subscriptions", - "AVS" + "Entra" ], - "severity": "Medium", - "subcategory": "Pre-deployment", - "text": "Resource provider for AVS registered", - "waf": "Reliability" + "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": "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", + "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": [ - "Subscriptions", - "AVS" + "Entra" ], - "severity": "Medium", - "subcategory": "Pre-deployment", - "text": "Landing zone architecture", - "waf": "Reliability" + "severity": "High", + "subcategory": "Tenant", + "text": "Disable insecure legacy protocols for internet-facing services." }, { - "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", + "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": [ - "AVS" + "Entra" ], - "severity": "Medium", - "subcategory": "Pre-deployment", - "text": "Resource group name selected", - "waf": "Reliability" + "severity": "High", + "subcategory": "Tenant", + "text": "Enable single sign-on" }, { - "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": "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": [ - "AVS" + "Entra" ], - "severity": "Medium", - "subcategory": "Pre-deployment", - "text": "Deployment prefix selected", - "waf": "Reliability" + "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": "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": "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": [ - "AVS" + "Entra" ], - "severity": "Medium", - "subcategory": "Pre-deployment", - "text": "Network space for AVS management layer", - "waf": "Reliability" + "severity": "High", + "subcategory": "Privileged administration", + "text": "Limit the number of Global Administrators to less than 5" }, { - "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", + "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": [ - "AVS", - "VNet" + "RBAC", + "Entra" ], - "severity": "Medium", - "subcategory": "Pre-deployment", - "text": "Network space for AVS NSX-T segments", - "waf": "Reliability" + "severity": "High", + "subcategory": "Privileged administration", + "text": "Use groups for Azure AD role assignments and delegate the role assignment" }, { - "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/", + "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": [ - "AVS" + "AzurePolicy", + "Entra" ], - "severity": "Medium", - "subcategory": "Pre-deployment", - "text": "AVS SKU (region dependent)", - "waf": "Performance" + "severity": "High", + "subcategory": "Privileged administration", + "text": "Ensure all critical impact admins are managed by enterprise directory to follow organizational policy enforcement." }, { - "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", + "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": [ - "AVS" + "Entra" ], - "severity": "Medium", - "subcategory": "Pre-deployment", - "text": "Number of hosts to be deployed", - "waf": "Performance" + "severity": "High", + "subcategory": "Privileged administration", + "text": "Configure recurring access reviews to revoke unneeded permissions over time" }, { - "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": "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": [ - "Cost", - "AVS" + "Monitor", + "Entra" ], "severity": "Medium", - "subcategory": "Pre-deployment", - "text": "Reserverd Instances", - "waf": "Cost" + "subcategory": "Privileged administration", + "text": "Ensure critical impact admins use a workstation with elevated security protections and monitoring" }, { - "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": "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": [ - "ASR", - "AVS" + "Entra" ], - "severity": "Medium", - "subcategory": "Pre-deployment", - "text": "Capacity ", - "waf": "Performance" + "severity": "High", + "subcategory": "External Identities", + "text": "Identity Providers: Verify external identity providers are known" }, { - "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": "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": [ - "AVS" + "Entra" ], - "severity": "Medium", - "subcategory": "Pre-deployment", - "text": "Networking & Connectivity See docs describing scenrario 1 through 5", - "waf": "Reliability" + "severity": "High", + "subcategory": "External Identities", + "text": "External Collaboration Settings: Guest user access set to 'Guest user access is restricted?'" }, { - "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": "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": [ - "AVS" + "RBAC", + "Entra" ], - "severity": "Medium", - "subcategory": "Pre-deployment", - "text": "3rd party application compatibility ", - "waf": "Reliability" + "severity": "High", + "subcategory": "External Identities", + "text": "External Collaboration Settings: Guest invite settings set to 'Only users assigned to specific admin roles'" }, { - "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.", + "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": [ - "AVS", - "AKV" + "Entra" ], - "severity": "Medium", - "subcategory": "Encryption", - "text": "Use Azure Key Vault with in-guest encryption ", - "waf": "Security" + "severity": "High", + "subcategory": "External Identities", + "text": "External Collaboration Settings: Enable guest self-service sign up via flows set to 'Disabled' " }, { - "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", + "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": [ - "AVS", - "SQL" + "Entra" ], - "severity": "Medium", - "subcategory": "Encryption", - "text": "Use in-guest encryption", - "waf": "Security" + "severity": "High", + "subcategory": "External Identities", + "text": "External Collaboration Settings: Collaboration restrictions set to 'Allow invitations to the specified domains'" }, { - "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", + "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": [ - "AVS", - "AKV", - "ExpressRoute" + "Entra" ], "severity": "Medium", - "subcategory": "Encryption", - "text": "Keyvault use for secrets", - "waf": "Security" + "subcategory": "External Identities", + "text": "Access Reviews: Enabled for all groups" }, { - "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", + "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": [ - "AVS" + "Entra" ], "severity": "Medium", - "subcategory": "Extended support", - "text": "Ensure extended security update support ", - "waf": "Security" + "subcategory": "Enterprise Applications", + "text": "Consent & Permissions: Allow user consent for apps from verified publishers" }, { - "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", + "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": [ - "AVS", - "Sentinel" + "Entra" ], "severity": "Medium", - "subcategory": "Investigation", - "text": "Enable Azure Sentinel or 3rd party SIEM ", - "waf": "Security" + "subcategory": "Enterprise Applications", + "text": "Consent & Permissions: Allow group owner consent for selected group owners " }, { - "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": "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": [ - "Defender", - "AVS" + "Entra" ], - "severity": "Medium", - "subcategory": "Security", - "text": "Enable Advanced Threat Detection ", - "waf": "Security" + "severity": "High", + "subcategory": "Custom Domains", + "text": "Only validated customer domains are registered" }, { - "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": "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", - "AVS" + "Entra" ], - "severity": "Medium", - "subcategory": "Security", - "text": "Policy & Regulatory Compliance", - "waf": "Security" + "severity": "High", + "subcategory": "Password Reset", + "text": "Self-service password reset policy requirement verified compliant." }, { - "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": "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": [ - "AVS" + "Entra" ], "severity": "Medium", - "subcategory": "Firewalls", - "text": "Azure / 3rd party firewall", - "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": "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": "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": [ - "AVS" + "Entra" ], - "severity": "Medium", - "subcategory": "Firewalls", - "text": "Firewalls allow for East/West traffic inside AVS", - "waf": "Security" + "severity": "High", + "subcategory": "Password Reset", + "text": "Set number of methods required to reset password are selected" }, { - "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": "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": [ - "AVS" + "Entra" ], - "severity": "Medium", - "subcategory": "Networking", - "text": "HCX and/or SRM", - "waf": "Reliability" + "severity": "High", + "subcategory": "User Setting", + "text": "Disable 'Users can register applications'" }, { - "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": "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": [ - "AVS" + "Entra" ], - "severity": "Medium", - "subcategory": "Networking", - "text": "Configuring and Managing the HCX Interconnect", - "waf": "Reliability" + "severity": "High", + "subcategory": "User Setting", + "text": "Restrict access to Administrative portal (portal.azure.com) to administrators only" }, { - "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": "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": [ - "AVS" + "Entra" ], - "severity": "Medium", - "subcategory": "Networking", - "text": "Restrictions and limitations for network extensions", - "waf": "Performance" + "severity": "High", + "subcategory": "User Setting", + "text": "Disable 'LinkedIn account connection'" }, { - "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": "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": [ + "Sentinel", + "Monitor", + "Entra" + ], + "severity": "High", + "subcategory": "Diagnostic Settings", + "text": "Enabled and send to Log Analytics workspace with Sentinel" + }, + { + "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": [ - "AVS" + "Entra" ], - "severity": "Medium", - "subcategory": "Networking", - "text": "Mobility optimized networking", - "waf": "Performance" + "severity": "High", + "subcategory": "PIM enabled", + "text": "Privileged Identity Management enabled" }, { - "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": "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": [ - "AVS" + "Entra" ], - "severity": "Medium", - "subcategory": "On-premises pre-requisites", - "text": "Support matrix (OS versions etc).", - "waf": "Operations" + "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": "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": "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": [ - "AVS" + "AzurePolicy", + "Entra" ], - "severity": "Medium", - "subcategory": "On-premises pre-requisites", - "text": "Standard switches converted to dynamic switches", - "waf": "Operations" + "severity": "High", + "subcategory": "Conditional Access Policies", + "text": "Configure conditional access policies / Access Controls" }, { - "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": "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": [ - "AVS" + "AzurePolicy", + "Entra" ], "severity": "Medium", - "subcategory": "On-premises pre-requisites", - "text": "Capacity for HCX appliance", - "waf": "Performance" + "subcategory": "Conditional Access Policies", + "text": "Conditions: Restricted Locations" }, { - "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": "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": [ - "AVS" + "AzurePolicy", + "Entra" ], - "severity": "Medium", - "subcategory": "On-premises pre-requisites", - "text": "Hardware compatibility", - "waf": "Operations" + "severity": "High", + "subcategory": "Conditional Access Policies", + "text": "Access Controls: MFA enabled for all users" }, { - "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": "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": [ - "AVS", - "Storage" + "AzurePolicy", + "Entra" ], "severity": "Medium", - "subcategory": "Storage", - "text": "VSAN RDM disks are converted - not supported.", - "waf": "Operations" + "subcategory": "Conditional Access Policies", + "text": "Access Controls: Require MFA for Administrators" }, { - "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": "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": [ - "AVS", - "VM", - "Storage" + "AzurePolicy", + "Entra" ], - "severity": "Medium", - "subcategory": "Storage", - "text": "VM with SCSI shared bus are not supported", - "waf": "Operations" + "severity": "High", + "subcategory": "Conditional Access Policies", + "text": "Access Controls: Require MFA for Azure Management " }, { - "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": "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": [ - "AVS", - "VM", - "Storage" + "AzurePolicy", + "Entra" ], - "severity": "Medium", - "subcategory": "Storage", - "text": "VM with Direct IO require removing DirectPath device", - "waf": "Operations" + "severity": "High", + "subcategory": "Conditional Access Policies", + "text": "Access Controls: Block Legacy Protocols" }, { - "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": "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": [ - "AVS", - "Storage" + "AzurePolicy", + "Entra" ], - "severity": "Medium", - "subcategory": "Storage", - "text": "Shared VMDK files are not supported", - "waf": "Operations" + "severity": "High", + "subcategory": "Conditional Access Policies", + "text": "Access Controls: Require devices to be marked as compliant" }, { - "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": "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": [ - "AVS", - "Storage" + "AzurePolicy", + "Entra" ], "severity": "Medium", - "subcategory": "Storage", - "text": "RDM with 'physical compatibility mode' are not supported.", - "waf": "Operations" + "subcategory": "Guest users", + "text": "Is there a policy to track guest user accounts (i.e. usage/delete/disable)?" }, { - "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", + "checklist": "Azure Security Review Checklist", + "guid": "c5bb4e4f-1814-4287-b5ca-8c26c9b32ab5", + "link": "https://learn.microsoft.com/azure/active-directory/fundamentals/identity-secure-score", "services": [ - "AzurePolicy", - "AVS", - "VM", - "Storage" + "Entra" ], - "severity": "Medium", - "subcategory": "Storage", - "text": "Default storage policy", - "waf": "Operations" + "severity": "High", + "subcategory": "Identity Secure Score", + "text": "Implement Identity Secure Score based on best practices in your industry" }, { - "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", + "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", - "AVS", - "VM", - "Storage" + "Entra" ], "severity": "Medium", - "subcategory": "Storage", - "text": "Ensure that the appropriate VM template storage policy is used", - "waf": "Operations" + "subcategory": "Break Glass Accounts", + "text": "At least two break glass accounts have been created and policy around their use exists" }, { - "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": "VM Security Checks", + "checklist": "Azure Security Review Checklist", + "guid": "0ac252b9-99a6-48af-a7c9-a8f821b8eb8c", + "link": "https://learn.microsoft.com/azure/governance/policy/overview", "services": [ - "AzurePolicy", - "AVS", - "Storage" + "VM", + "AzurePolicy" ], - "severity": "Medium", - "subcategory": "Storage", - "text": "Failure to tolerate policy", - "waf": "Operations" + "severity": "High", + "subcategory": "Access Control", + "text": "Control VM Access leveraging Azure Policy" }, { - "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": "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": [ - "AVS", - "Storage" + "VM" ], "severity": "Medium", - "subcategory": "Storage", - "text": "Use ANF for external storage", - "waf": "Operations" + "subcategory": "Access Control", + "text": "Reduce variability in your setup and deployment of VMs by leveraging templates" }, { - "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": "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": [ - "ServiceBus" + "VM" ], - "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": "Access Control", + "text": "Secure privileged access to deploy VMS by reducing who has access to Resources through Governance" }, { - "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": "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": [ - "ServiceBus" + "VM" ], "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": "High Availability ", + "text": "Use multiple VMs for your workloads for better availability " }, { - "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": "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": [ - "AzurePolicy", - "Entra", - "ServiceBus", - "RBAC", - "TrafficManager" + "VM", + "ASR" ], "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": "High Availability ", + "text": "Deploy and test a disaster recovery solution " }, { - "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": "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", - "Entra", - "AKV", - "ServiceBus", - "Storage", - "AppSvc" + "VM" ], "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": "High Availability ", + "text": "Availability sets" }, { - "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": "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": [ - "Subscriptions", - "Entra", - "ServiceBus", - "RBAC", - "Storage" + "VM" ], - "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": "High Availability ", + "text": "Availability Zones" }, { - "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": "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": [ - "ServiceBus", - "Monitor", - "VNet" + "VM" ], "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": "High Availability ", + "text": "Regional fault tolerance " }, { - "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": "VM Security Checks", + "checklist": "Azure Security Review Checklist", + "guid": "af225ca4-4e16-496f-bdde-ace4cb1deb4c", + "link": "https://learn.microsoft.com/azure/security/fundamentals/antimalware", "services": [ - "ServiceBus", - "VNet", - "PrivateLink" + "VM" ], - "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/" + "severity": "High", + "subcategory": "Protect against malware", + "text": "Install antimalware solutions" }, { - "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": "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": [ - "ServiceBus" + "VM", + "Defender" ], - "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/" + "severity": "High", + "subcategory": "Protect against malware", + "text": "Integrate antimalware solution with Security Center" }, { - "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", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/sql-database-security-baseline#br-2-encrypt-backup-data", + "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": [ - "Backup", - "SQL", - "AKV" + "VM" ], - "severity": "Medium", - "subcategory": "Azure Key Vault", - "text": "Protect your backup data with encryption and store keys safely in Azure Key Vault" + "severity": "High", + "subcategory": "Manage VM Updates", + "text": "Keep VMs up to date using Update Management with Azure Automation" }, { - "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", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/sql-database-security-baseline#br-1-ensure-regular-automated-backups", + "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": [ - "Backup", - "Storage", - "SQL" + "VM" ], "severity": "Medium", - "subcategory": "Backup", - "text": "Configure Azure SQL Database automated backups" + "subcategory": "Manage VM Updates", + "text": "Ensure Windows images for deployment have the most recent level of updates " }, { - "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", - "link": "https://learn.microsoft.com/azure/azure-sql/database/automated-backups-overview?tabs=single-database&view=azuresql#backup-storage-redundancy", + "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": [ - "Backup", - "Storage", - "SQL" + "VM", + "Defender" ], - "severity": "Low", - "subcategory": "Backup", - "text": "Enable geo-redundant backup storage to protect against single region failure and data loss" + "severity": "High", + "subcategory": "Manage VM Updates", + "text": "Rapidly apply security updates to VMs using Microsoft Defender for Cloud" }, { - "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", - "link": "https://learn.microsoft.com/azure/azure-sql/database/transparent-data-encryption-byok-create-server", + "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": [ - "SQL" + "VM" ], - "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": "Encrypt your VHDs", + "text": "Enable encryption on your VMs" }, { - "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", - "link": "https://learn.microsoft.com/azure/azure-sql/database/data-discovery-and-classification-overview?view=azuresql#faq---advanced-classification-capabilities", + "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": [ - "SQL" + "VM" ], - "severity": "Low", - "subcategory": "Data Discovery and Classification", - "text": "Plan and configure Data Discovery & Classification to protect the sensitive data" + "severity": "High", + "subcategory": "Encrypt your VHDs", + "text": "Add Key Encryption Key (KEK) for added layer of security for encryption " }, { - "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", - "link": "https://learn.microsoft.com/azure/azure-sql/database/dynamic-data-masking-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": [ - "SQL" + "LoadBalancer", + "VM" ], - "severity": "Low", - "subcategory": "Data Masking", - "text": "Use Data Masking to prevent unauthorized non-admin users data access if no encryption is possible" + "severity": "Medium", + "subcategory": "Encrypt your VHDs", + "text": "Take a snapshot of disks before encryption for rollback purposes" }, { - "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", - "link": "https://learn.microsoft.com/azure/azure-sql/database/threat-detection-configure", + "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": [ - "Defender", - "SQL", - "EventHubs" + "VM", + "Entra" ], "severity": "High", - "subcategory": "Advanced Threat Protection", - "text": "Review and complete Advanced Threat Protection (ATP) configuration" + "subcategory": "Restrict direct internet connection ", + "text": "Ensure only the central networking group has permissions to networking resources " }, { - "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", - "link": "https://learn.microsoft.com/azure/azure-sql/database/azure-defender-for-sql?view=azuresql#enable-microsoft-defender-for-sql ", + "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": [ - "Subscriptions", - "Defender", - "SQL" + "VM", + "Entra" ], "severity": "High", - "subcategory": "Defender for Azure SQL", - "text": "Enable Microsoft Defender for Azure SQL" + "subcategory": "Restrict direct internet connection ", + "text": "Identity and remediate exposed VMs that allow access from 'ANY' source IP address" }, { - "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", - "link": "https://learn.microsoft.com/azure/azure-sql/database/threat-detection-configure", + "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": [ - "Defender", - "SQL", - "Monitor" + "VM" ], "severity": "High", - "subcategory": "Defender for Azure SQL", - "text": "Prepare a security response plan to promptly react to Microsoft Defender for Azure SQL alerts" + "subcategory": "Restrict direct internet connection ", + "text": "Restrict management ports (RDP, SSH) using Just-in-Time Access" }, { - "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", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/sql-azure-vulnerability-assessment-overview", + "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": [ - "Defender", - "SQL", - "Monitor" + "VM" ], "severity": "High", - "subcategory": "Vulnerability Assessment", - "text": "Configure Vulnerability Assessment (VA) findings and review recommendations" + "subcategory": "Restrict direct internet connection ", + "text": "Remove internet access and implement jump servers for RDP" }, { - "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", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/sql-azure-vulnerability-assessment-find?view=azuresql", + "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": [ - "Defender", - "SQL" + "VM", + "VPN" ], "severity": "High", - "subcategory": "Vulnerability Assessment", - "text": "Regularly review of Vulnerability Assessment (VA) findings and recommendations and prepare a plan to fix" + "subcategory": "Restrict direct internet connection ", + "text": "Remove direct logging into servers using RDP/SSH from internet and implement VPN or express route" }, { - "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", - "link": "https://learn.microsoft.com/sql/relational-databases/security/encryption/always-encrypted-enclaves", + "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": [ - "SQL" + "Bastion", + "VM" ], - "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" + "severity": "High", + "subcategory": "Restrict direct internet connection ", + "text": "Leverage Azure Bastion as your RDP/SSH broker for added security and reduction in footprint" }, { - "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", - "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#control-access-of-application-users-to-sensitive-data-through-encryption", + "category": "Sentinel", + "checklist": "Azure Security Review Checklist", + "guid": "cd5d1e54-a297-459e-9968-0e78289c9356", + "link": "https://learn.microsoft.com/azure/sentinel/quickstart-onboard", "services": [ - "Storage", - "SQL", - "AKV" + "Sentinel", + "Monitor" ], - "severity": "Low", - "subcategory": "Column Encryption", - "text": "To protect sensitive PII data from non-admin users in specific table columns, consider using Column Encryption" + "severity": "High", + "subcategory": "Architecture ", + "text": "All tenants contain have Sentinel enabled on at least one Log Analytics workspace" }, { - "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", - "link": "https://learn.microsoft.com/azure/azure-sql/database/transparent-data-encryption-byok-create-server", + "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": [ - "Backup", - "Storage", - "SQL" + "Sentinel" ], "severity": "High", - "subcategory": "Transparent Data Encryption", - "text": "Ensure Transparent Data Encryption (TDE) is kept enabled" + "subcategory": "Architecture ", + "text": "Customer understands Sentinel architecture" }, { - "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", - "link": "https://learn.microsoft.com/azure/azure-sql/database/transparent-data-encryption-byok-overview", + "category": "Sentinel", + "checklist": "Azure Security Review Checklist", + "guid": "e8f5c586-c7d9-4cdc-86ac-c075ef9b141a", + "link": "https://learn.microsoft.com/azure/sentinel/multiple-workspace-view", "services": [ - "SQL", - "AKV" + "ACR", + "Sentinel", + "Monitor" ], "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": "Architecture ", + "text": "Customer knows how to monitor Incidents across multiple Sentinel instances" }, { - "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", - "link": "https://learn.microsoft.com/azure/azure-sql/database/connectivity-settings?source=recommendations&view=azuresql&tabs=azure-portal#minimal-tls-version", + "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": [ - "SQL" + "Sentinel" ], - "severity": "High", - "subcategory": "Transport Layer Security", - "text": "Enforce minimum TLS version to the latest available" + "severity": "Medium", + "subcategory": "Overview", + "text": "No Incidents open more than 24 hours" }, { - "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", - "link": "https://learn.microsoft.com/azure/azure-sql/database/authentication-aad-overview", + "category": "Sentinel", + "checklist": "Azure Security Review Checklist", + "guid": "5d3c4ada-97cb-43d1-925a-b225c6f4e068", + "link": "https://learn.microsoft.com/azure/sentinel/whats-new", "services": [ - "Entra", - "SQL" + "Sentinel" ], - "severity": "Medium", - "subcategory": "Azure Active Directory", - "text": "Leverage Azure AD authentication for connections to Azure SQL Databases" + "severity": "Low", + "subcategory": "News & Guides", + "text": "Customer have been shown the News & Guides tab" }, { - "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", - "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#central-management-for-identities", + "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": [ - "Monitor", - "Entra", - "SQL" + "Sentinel" ], "severity": "Medium", - "subcategory": "Azure Active Directory", - "text": "Create a separate Azure AD group with two admin accounts for each Azure SQL Database logical server" + "subcategory": "UEBA ", + "text": "UEBA Configured (Sentinel/Settings/Settings/Configure UEBA)" }, { - "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", - "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#minimize-the-use-of-password-based-authentication-for-applications", + "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": [ - "Entra", - "SQL" + "Sentinel", + "Entra" ], - "severity": "Medium", - "subcategory": "Azure Active Directory", - "text": "Minimize the use of password-based authentication for applications" + "severity": "High", + "subcategory": "Data Connectors", + "text": "Azure Active Directory in configured and 'Last Log Received' shows today" }, { - "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", - "link": "https://learn.microsoft.com/azure/active-directory/managed-identities-azure-resources/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": [ - "ACR", - "Entra", - "AKV", - "RBAC", - "SQL" + "Sentinel", + "Entra" ], - "severity": "Low", - "subcategory": "Managed Identities", - "text": "Assign Azure SQL Database a managed identity for outbound resource access" + "severity": "High", + "subcategory": "Data Connectors", + "text": "Azure Active Directory Identity Protection is configured and 'Last Log Received' shows today" }, { - "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", - "link": "https://learn.microsoft.com/azure/azure-sql/database/authentication-aad-configure?view=azuresql&tabs=azure-powershell#active-directory-integrated-authentication", + "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": [ - "Entra", - "SQL" + "Sentinel" ], - "severity": "Medium", - "subcategory": "Passwords", - "text": "Minimize the use of password-based authentication for users" + "severity": "High", + "subcategory": "Data Connectors", + "text": "Azure Activity is configured is configured and 'Last Log Received' shows today" }, { - "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", - "link": "https://learn.microsoft.com/azure/architecture/guide/technology-choices/multiparty-computing-service#confidential-ledger-and-azure-blob-storage", + "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": [ - "Storage", - "SQL" + "Sentinel", + "Defender" ], - "severity": "Medium", - "subcategory": "Database Digest", - "text": "Use Azure Confidential Ledger to store database digests only if advanced security features are required" + "severity": "High", + "subcategory": "Data Connectors", + "text": "Microsoft Defender for Cloud is configured and 'Last Log Received' shows today" }, { - "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", - "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-digest-management", + "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": [ - "AzurePolicy", - "Storage", - "SQL" + "Sentinel", + "Firewall" ], - "severity": "Medium", - "subcategory": "Database Digest", - "text": "If Azure storage account is used to store database digests, ensure security is properly configured" + "severity": "High", + "subcategory": "Data Connectors", + "text": "Azure Firewall is configured and 'Last Log Received' shows today" }, { - "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", - "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-database-verification", + "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": [ - "Storage", - "SQL" + "Sentinel" ], - "severity": "Medium", - "subcategory": "Integrity", - "text": "Schedule the Ledger verification process regularly to verify data integrity" + "severity": "High", + "subcategory": "Data Connectors", + "text": "Windows Firewall is configured and 'Last Log Received' shows today" }, { - "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", - "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-overview", + "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": [ - "SQL" + "Sentinel" ], - "severity": "Medium", - "subcategory": "Ledger", - "text": "If cryptographic proof of data integrity is a critical requirement, Ledger feature should be considered" + "severity": "High", + "subcategory": "Data Connectors", + "text": "Security Events is configured with AMA and 'Last Log Received' shows today" }, { - "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", - "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-how-to-recover-after-tampering", + "category": "Sentinel", + "checklist": "Azure Security Review Checklist", + "guid": "1a4834ac-9322-423e-ae80-b123081a5417", + "link": "https://learn.microsoft.com/azure/sentinel/data-connectors-reference", "services": [ - "SQL" + "Sentinel" ], - "severity": "Medium", - "subcategory": "Recovery", - "text": "Prepare a response plan to investigate and repair a database after a tampering event" + "severity": "High", + "subcategory": "Data Connectors", + "text": "Security Events - verify Azure computers are connected and sending data to the workspace" }, { - "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", - "link": "https://learn.microsoft.com/azure/azure-sql/database/auditing-overview", + "category": "Sentinel", + "checklist": "Azure Security Review Checklist", + "guid": "859c773e-7e26-4162-9b77-5a917e1f348e", + "link": "https://learn.microsoft.com/azure/sentinel/data-connectors-reference", "services": [ - "AzurePolicy", - "Storage", - "SQL" + "Sentinel" ], - "severity": "Medium", - "subcategory": "Auditing", - "text": "Ensure that Azure SQL Database Auditing is enabled at the server level" + "severity": "High", + "subcategory": "Data Connectors", + "text": "Security Events - verify non-Azure computers are connected and sending data to the workspace" }, { - "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", - "link": "https://learn.microsoft.com/azure/azure-sql/database/auditing-overview", + "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": [ - "EventHubs", - "Entra", - "Backup", - "Monitor", - "Storage", - "SQL" + "Sentinel" ], - "severity": "Low", - "subcategory": "Auditing", - "text": "Ensure that Azure SQL Database Auditing logs are backed up and secured in the selected repository type" + "severity": "High", + "subcategory": "Data Connectors", + "text": "Connector for AWS" }, { - "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", - "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", + "category": "Sentinel", + "checklist": "Azure Security Review Checklist", + "guid": "909ae28c-84c3-43b6-a780-8bafe6c42149", + "link": "https://learn.microsoft.com/azure/sentinel/data-connectors-reference", "services": [ - "EventHubs", - "Subscriptions", - "Monitor", - "Storage", - "SQL" + "Sentinel" ], - "severity": "Medium", - "subcategory": "Auditing", - "text": "Ensure that Azure SQL Database Activity Log is collected and integrated with Auditing logs" + "severity": "High", + "subcategory": "Data Connectors", + "text": "Connector for GCP" }, { - "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", - "link": "https://learn.microsoft.com/azure/azure-sql/database/auditing-overview", + "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": [ - "Monitor", - "SQL" + "Sentinel" ], - "severity": "Medium", - "subcategory": "SIEM/SOAR", - "text": "Ensure that Azure SQL Database Auditing logs are being presented in to your organizations SIEM/SOAR" + "severity": "High", + "subcategory": "Analytics Rules", + "text": "Customer has enabled Analytics rules and configured Incidents " }, { - "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", - "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", + "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": [ - "Monitor", - "SQL" + "Sentinel" ], "severity": "Medium", - "subcategory": "SIEM/SOAR", - "text": "Ensure that Azure SQL Database Activity Log data is presented in to your SIEM/SOAR" + "subcategory": "Settings", + "text": "Customer does not have a daily cap enabled" }, { - "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", - "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", + "category": "Azure Firewall", + "checklist": "Azure Security Review Checklist", + "guid": "9e3558fd-7724-49c9-9111-2d027fe412f7", + "link": "https://learn.microsoft.com/azure/firewall/premium-features", "services": [ - "SQL", - "EventHubs" + "Firewall" ], - "severity": "Medium", - "subcategory": "SIEM/SOAR", - "text": "Ensure that you have response plans for malicious or aberrant audit logging events" + "severity": "High", + "subcategory": "Configuration", + "text": "Azure Firewall Premium deployed" }, { - "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", - "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview", + "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": [ - "PrivateLink", - "SQL" + "Firewall" ], "severity": "High", - "subcategory": "Connectivity", - "text": "Review Public vs. Private Access connectivity methods and select the appropriate one for the workload" + "subcategory": "Configuration", + "text": "Quad zero/force tunning enabled through Azure Firewall" }, { - "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", - "link": "https://learn.microsoft.com/azure/azure-sql/database/connectivity-architecture", + "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": [ - "AzurePolicy", - "SQL", - "PrivateLink" + "Firewall", + "RBAC" ], - "severity": "Low", - "subcategory": "Connectivity", - "text": "Keep default Azure SQL Database Connection Policy if not differently required and justified" + "severity": "Medium", + "subcategory": "Access Control", + "text": "RBAC set to enable only authorized users" }, - { - "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", - "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview", + { + "category": "Azure Firewall", + "checklist": "Azure Security Review Checklist", + "guid": "8093dc9f-c9d1-4bb7-9b36-a5a67fbb9ed5", + "link": "https://learn.microsoft.com/azure/firewall/firewall-diagnostics", "services": [ - "Subscriptions", - "SQL" + "Firewall", + "Monitor" ], - "severity": "High", - "subcategory": "Connectivity", - "text": "Ensure Allow Azure Services and Resources to Access this Server setting is disabled in Azure SQL Database firewall" + "severity": "Medium", + "subcategory": "Diagnostic Settings", + "text": "Diagnostics enabled and sending metrics to a Log Analytics workspace " }, { - "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", - "link": "https://learn.microsoft.com/sql/relational-databases/system-stored-procedures/sp-invoke-external-rest-endpoint-transact-sql", + "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": [ - "APIM", - "SQL", - "EventHubs" + "VNet", + "Firewall" ], - "severity": "Medium", - "subcategory": "Outbound Control", - "text": "Block or restrict outbound REST API calls to external endpoints" + "severity": "High", + "subcategory": "Firewall Manager", + "text": "Hubs and virtual networks are protected or connected through Firewall Premium" }, { - "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", - "link": "https://learn.microsoft.com/azure/azure-sql/database/outbound-firewall-rule-overview", + "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": [ - "Storage", - "SQL" + "Firewall", + "AzurePolicy", + "RBAC" ], - "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" + "severity": "High", + "subcategory": "Firewall Manager", + "text": "Policy: Access controls are configured (RBAC)" }, { - "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", - "link": "https://learn.microsoft.com/azure/azure-sql/database/private-endpoint-overview?view=azuresql#disable-public-access-to-your-logical-server", + "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": [ - "PrivateLink", "Firewall", - "Monitor", - "SQL", - "VNet" + "AzurePolicy" ], - "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" + "severity": "High", + "subcategory": "Firewall Manager", + "text": "Policy: Parent policy is configured " }, { - "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", - "link": "https://learn.microsoft.com/azure/azure-sql/database/private-endpoint-overview?view=azuresql#disable-public-access-to-your-logical-server", + "category": "Azure Firewall", + "checklist": "Azure Security Review Checklist", + "guid": "15675c1e-a55b-446a-a48f-f8ae7d7e4b47", + "link": "https://learn.microsoft.com/azure/firewall/rule-processing", "services": [ - "PrivateLink", - "SQL", - "VNet" + "Firewall", + "AzurePolicy" ], "severity": "High", - "subcategory": "Private Access", - "text": "If Private Endpoint (Private Access) is used, consider disabling Public Access connectivity" + "subcategory": "Firewall Manager", + "text": "Policy: Rule collections are defined" }, { - "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", - "link": "https://learn.microsoft.com/azure/private-link/private-endpoint-overview#network-security-of-private-endpoints", + "category": "Azure Firewall", + "checklist": "Azure Security Review Checklist", + "guid": "5b6c8bcb-f59b-4ce6-9de8-a03f97879468", + "link": "https://learn.microsoft.com/azure/firewall/rule-processing", "services": [ - "PrivateLink", - "SQL", - "VNet" + "Firewall", + "AzurePolicy" ], - "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" + "severity": "High", + "subcategory": "Firewall Manager", + "text": "Policy: DNAT policies are defined" }, { - "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", - "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/connectivity-architecture-overview", + "category": "Azure Firewall", + "checklist": "Azure Security Review Checklist", + "guid": "d66a786d-60e9-46c9-9ad8-855d04c2b39c", + "link": "https://learn.microsoft.com/azure/firewall/rule-processing", "services": [ - "SQL", - "ExpressRoute", - "VNet" + "Firewall", + "AzurePolicy" ], - "severity": "Medium", - "subcategory": "Private Access", - "text": "Apply Network Security Groups (NSG) and firewall rules to restrict access to Azure SQL Managed Instance internal subnet" + "severity": "High", + "subcategory": "Firewall Manager", + "text": "Policy: Network rules are defined" }, { - "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", - "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview?view=azuresql#ip-vs-virtual-network-firewall-rules", + "category": "Azure Firewall", + "checklist": "Azure Security Review Checklist", + "guid": "986bb2c1-2149-4a11-9b5e-3df574ecccd9", + "link": "https://learn.microsoft.com/azure/firewall/features", "services": [ - "AzurePolicy", - "SQL", - "VNet" + "Firewall", + "AzurePolicy" ], "severity": "High", - "subcategory": "Public Access", - "text": "If Public Access connectivity is used, leverage Service Endpoint to restrict access from selected Azure Virtual Networks" + "subcategory": "Firewall Manager", + "text": "Policy: Application rules are defined" }, { - "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", - "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-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": [ - "Storage", - "SQL" + "DNS", + "Firewall" ], "severity": "Medium", - "subcategory": "Public Access", - "text": "If Public Access connectivity is used, ensure that only specific known IPs are added to the firewall" + "subcategory": "Firewall Manager", + "text": "DNS: Feature understood and applied or not applied" }, { - "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", - "link": "https://learn.microsoft.com/azure/azure-sql/database/firewall-configure", + "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", - "SQL" + "Firewall" ], - "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" + "severity": "High", + "subcategory": "Firewall Manager", + "text": "Threat Intelligence: Set to Alert & Deny" }, { - "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", - "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/public-endpoint-overview", + "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": [ - "AzurePolicy", - "SQL", - "VNet" + "Firewall" ], "severity": "High", - "subcategory": "Public Access", - "text": "Do not enable Azure SQL Managed Instance public endpoint" + "subcategory": "Firewall Manager", + "text": "Threat Intelligence: Allowed list (justify if they are being used - ie performance)" }, { - "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", - "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/public-endpoint-overview", + "category": "Azure Firewall", + "checklist": "Azure Security Review Checklist", + "guid": "623b365a-917e-4cbe-98eb-d54cd7df2e8b", + "link": "https://learn.microsoft.com/azure/firewall/premium-certificates", "services": [ - "SQL", - "VNet" + "Firewall" ], "severity": "High", - "subcategory": "Public Access", - "text": "Restrict access if Azure SQL Managed Instance public endpoint is required" + "subcategory": "Firewall Manager", + "text": "TLS enabled" }, { - "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", - "link": "https://learn.microsoft.com/azure/security/fundamentals/customer-lockbox-overview", + "category": "Azure Firewall", + "checklist": "Azure Security Review Checklist", + "guid": "bac35715-59ab-4915-9e99-08aed8c44ce3", + "link": "https://learn.microsoft.com/azure/firewall/rule-processing", "services": [ - "SQL" + "Firewall" ], - "severity": "Low", - "subcategory": "Lockbox", - "text": "Review and enable Customer Lockbox for Azure SQL Database access by Microsoft personnel" + "severity": "High", + "subcategory": "Firewall Manager", + "text": "IDPS enabled" }, { - "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", - "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#implement-principle-of-least-privilege", + "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": [ - "SQL" + "Firewall" ], - "severity": "Medium", - "subcategory": "Permissions", - "text": "Ensure that users are assigned the minimum level of access necessarily to complete their job functions" + "severity": "High", + "subcategory": "Firewall Manager", + "text": "SNAT: Configured " }, { - "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", - "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": "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": [ - "Entra", - "SQL" + "Firewall", + "DDoS" ], - "severity": "Low", - "subcategory": "Permissions", - "text": "Ensure that distinct applications will be assigned different credentials with minimal permissions to access Azure SQL Database" + "severity": "Medium", + "subcategory": "DDOS Protection", + "text": "Enabled for Firewall public IP's" } ], "metadata": { "name": "Master checklist", - "timestamp": "October 31, 2023" + "timestamp": "November 06, 2023" }, "severities": [ { diff --git a/checklists/network_appdelivery_checklist.en.json b/checklists/network_appdelivery_checklist.en.json index 93fbf72d7..71a85fc7d 100644 --- a/checklists/network_appdelivery_checklist.en.json +++ b/checklists/network_appdelivery_checklist.en.json @@ -446,6 +446,6 @@ "metadata": { "name": "Azure Application Delivery", "state": "GA", - "timestamp": "October 02, 2023" + "timestamp": "November 06, 2023" } -} +} \ No newline at end of file diff --git a/checklists/network_appdelivery_checklist.es.json b/checklists/network_appdelivery_checklist.es.json new file mode 100644 index 000000000..83e66f8a1 --- /dev/null +++ b/checklists/network_appdelivery_checklist.es.json @@ -0,0 +1,451 @@ +{ + "categories": [ + { + "name": "Inquilinos de Facturación de Azure y de Id. de Microsoft Entra" + }, + { + "name": "Gestión de identidades y accesos" + }, + { + "name": "Topología y conectividad de red" + }, + { + "name": "Seguridad" + }, + { + "name": "Administración" + }, + { + "name": "Organización de recursos" + }, + { + "name": "Automatización de plataformas y DevOps" + }, + { + "name": "Gobernanza" + } + ], + "items": [ + { + "category": "Topología y conectividad de red", + "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", + "severity": "Medio", + "subcategory": "Entrega de aplicaciones", + "text": "Si usa certificados TLS administrados por el cliente con Azure Front Door, use la versión de certificado \"más reciente\". Reduzca el riesgo de interrupciones causadas por la renovación manual de certificados.", + "waf": "Operaciones" + }, + { + "category": "Topología y conectividad de red", + "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", + "severity": "Medio", + "subcategory": "Entrega de aplicaciones", + "text": "Realice la entrega de aplicaciones dentro de las zonas de aterrizaje tanto para aplicaciones internas (corp) como externas (en línea).", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "Seguridad" + }, + { + "category": "Topología y conectividad de red", + "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", + "severity": "Medio", + "subcategory": "Entrega de aplicaciones", + "text": "Asegúrese de que usa la SKU de Application Gateway v2", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "Seguridad" + }, + { + "category": "Topología y conectividad de red", + "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", + "severity": "Medio", + "subcategory": "Entrega de aplicaciones", + "text": "Asegúrese de que usa la SKU estándar para Azure Load Balancers", + "waf": "Seguridad" + }, + { + "category": "Topología y conectividad de red", + "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 | project id, subnetId = tostring(subnets.id), subnetPrefixLength = split(subnets.properties.addressPrefix, '/')[1]) on subnetId | extend compliant = (subnetPrefixLength <= 26) | 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", + "severity": "Medio", + "subcategory": "Entrega de aplicaciones", + "text": "Las puertas de enlace de aplicaciones deben implementarse en subredes con prefijos IP iguales o mayores que /26", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "Seguridad" + }, + { + "category": "Topología y conectividad de red", + "description": "La administración de proxies inversos en general y de WAF en particular está más cerca de la aplicación que de la red, por lo que pertenecen a la misma suscripción que la aplicación. La centralización de Application Gateway y WAF en la suscripción de conectividad puede ser correcta si la administra un solo equipo.", + "guid": "48b662d6-d15f-4512-a654-98f6dfe237de", + "id": "A01.06", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "severity": "Medio", + "subcategory": "Entrega de aplicaciones", + "text": "Implemente Azure Application Gateway v2 o aplicaciones virtuales de red de asociados que se usan para proxy de conexiones HTTP(S) entrantes dentro de la red virtual de la zona de aterrizaje y con las aplicaciones que están protegiendo.", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "Seguridad" + }, + { + "category": "Topología y conectividad de red", + "guid": "143b16c3-1d7a-4a9b-9470-4489a8042d88", + "id": "A01.07", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "severity": "Medio", + "subcategory": "Entrega de aplicaciones", + "text": "Use una red DDoS o planes de protección IP para todas las direcciones IP públicas en las zonas de aterrizaje de la aplicación.", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "Seguridad" + }, + { + "category": "Topología y conectividad de red", + "guid": "e79d17b7-3b22-4a5a-97e7-a8ed4b30e38c", + "id": "A01.08", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "severity": "Medio", + "subcategory": "Entrega de aplicaciones", + "text": "Use Azure Front Door con directivas de WAF para entregar y ayudar a proteger aplicaciones HTTP/S globales que abarcan varias regiones de Azure.", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "Seguridad" + }, + { + "category": "Topología y conectividad de red", + "guid": "3f29812b-2363-4cef-b179-b599de0d5973", + "id": "A01.09", + "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", + "severity": "Medio", + "subcategory": "Entrega de aplicaciones", + "text": "Al usar Front Door y Application Gateway para ayudar a proteger las aplicaciones HTTP/S, use directivas de WAF en Front Door. Bloquee Application Gateway para recibir tráfico solo de Front Door.", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "Seguridad" + }, + { + "ammp": true, + "category": "Topología y conectividad de red", + "guid": "cd4cd21b-0881-437f-9e6c-4cfd3e504547", + "id": "A01.10", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "severity": "Alto", + "subcategory": "Entrega de aplicaciones", + "text": "Use el Administrador de tráfico para entregar aplicaciones globales que abarquen protocolos distintos de HTTP/S.", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "Fiabilidad" + }, + { + "category": "Topología y conectividad de red", + "guid": "3b4b3e88-a459-4ed5-a22f-644dfbc58204", + "id": "A01.11", + "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy#how-application-proxy-works", + "severity": "Bajo", + "subcategory": "Entrega de aplicaciones", + "text": "Si los usuarios solo necesitan acceso a aplicaciones internas, ¿se ha considerado Microsoft Entra ID Application Proxy como una alternativa a Azure Virtual Desktop (AVD)?", + "training": "https://learn.microsoft.com/learn/modules/configure-azure-ad-application-proxy/", + "waf": "Seguridad" + }, + { + "category": "Topología y conectividad de red", + "guid": "01ca7cf1-5754-442d-babb-8ba6772e5c30", + "id": "A01.12", + "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy#how-application-proxy-works", + "severity": "Medio", + "subcategory": "Entrega de aplicaciones", + "text": "Para reducir el número de puertos de firewall abiertos para las conexiones entrantes en la red, considere la posibilidad de usar Microsoft Entra ID Application Proxy para proporcionar a los usuarios remotos acceso seguro y autenticado a las aplicaciones internas.", + "training": "https://learn.microsoft.com/learn/paths/implement-applications-external-access-azure-ad/", + "waf": "Seguridad" + }, + { + "ammp": true, + "category": "Topología y conectividad de red", + "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.13", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-policy-settings", + "severity": "Alto", + "subcategory": "Entrega de aplicaciones", + "text": "Implemente los perfiles de WAF para Front Door en modo \"Prevención\".", + "waf": "Seguridad" + }, + { + "ammp": true, + "category": "Topología y conectividad de red", + "guid": "062d5839-4d36-402f-bfa4-02811eb936e9", + "id": "A01.14", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#avoid-combining-traffic-manager-and-front-door", + "severity": "Alto", + "subcategory": "Entrega de aplicaciones", + "text": "Evite combinar Azure Traffic Manager y Azure Front Door.", + "waf": "Seguridad" + }, + { + "ammp": true, + "category": "Topología y conectividad de red", + "guid": "5efeb96a-003f-4b18-8fcd-b4d84459c2b2", + "id": "A01.15", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-the-same-domain-name-on-front-door-and-your-origin", + "severity": "Alto", + "subcategory": "Entrega de aplicaciones", + "text": "Use el mismo nombre de dominio en Azure Front Door y en su origen. Los nombres de host no coincidentes pueden causar errores sutiles.", + "waf": "Seguridad" + }, + { + "category": "Topología y conectividad de red", + "guid": "0b5a380c-4bfb-47bc-b1d7-dcfef363a61b", + "id": "A01.16", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#disable-health-probes-when-theres-only-one-origin-in-an-origin-group", + "severity": "Bajo", + "subcategory": "Entrega de aplicaciones", + "text": "Deshabilite los sondeos de estado cuando solo haya un origen en un grupo de orígenes de Azure Front Door.", + "waf": "Rendimiento" + }, + { + "category": "Topología y conectividad de red", + "guid": "5567048e-e5d7-4206-9c55-b5ed45d2cc0c", + "id": "A01.17", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#select-good-health-probe-endpoints", + "severity": "Medio", + "subcategory": "Entrega de aplicaciones", + "text": "Seleccione puntos de conexión de sondeo de estado correctos para Azure Front Door. Considere la posibilidad de crear puntos de conexión de estado que comprueben todas las dependencias de la aplicación.", + "waf": "Fiabilidad" + }, + { + "category": "Topología y conectividad de red", + "guid": "a13f72f3-8f5c-4864-95e5-75bf37fbbeb1", + "id": "A01.18", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-head-health-probes", + "severity": "Bajo", + "subcategory": "Entrega de aplicaciones", + "text": "Use sondeos de estado de HEAD con Azure Front Door para reducir el tráfico que Front Door envía a la aplicación.", + "waf": "Rendimiento" + }, + { + "ammp": true, + "category": "Topología y conectividad de red", + "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.19", + "link": "https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity", + "severity": "Alto", + "subcategory": "Entrega de aplicaciones", + "text": "Use Azure NAT Gateway en lugar de reglas de salida de Load Balancer para mejorar la escalabilidad de SNAT", + "waf": "Fiabilidad" + }, + { + "ammp": true, + "category": "Topología y conectividad de red", + "guid": "af95c92d-d723-4f4a-98d7-8722324efd4d", + "id": "A01.20", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-managed-tls-certificates", + "severity": "Alto", + "subcategory": "Entrega de aplicaciones", + "text": "Use certificados TLS administrados con Azure Front Door. Reduzca los costos operativos y el riesgo de interrupciones debido a las renovaciones de certificados.", + "waf": "Operaciones" + }, + { + "category": "Topología y conectividad de red", + "guid": "189ea962-3969-4863-8f5a-5ad808c2cf4b", + "id": "A01.21", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#define-your-waf-configuration-as-code", + "severity": "Medio", + "subcategory": "Entrega de aplicaciones", + "text": "Defina la configuración de WAF de Azure Front Door como código. Mediante el uso de código, puede adoptar más fácilmente nuevas versiones del conjunto de reglas y obtener protección adicional.", + "waf": "Operaciones" + }, + { + "ammp": true, + "category": "Topología y conectividad de red", + "guid": "2e30abab-5478-417c-81bf-bf1ad4ed1ed4", + "id": "A02.01", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-end-to-end-tls", + "severity": "Alto", + "subcategory": "Entrega de aplicaciones", + "text": "Use TLS de un extremo a otro con Azure Front Door. Use TLS para las conexiones de los clientes a Front Door y de Front Door al origen.", + "waf": "Seguridad" + }, + { + "category": "Topología y conectividad de red", + "guid": "10aa45af-166f-44c4-9f36-b6d592dac2ca", + "id": "A02.02", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-http-to-https-redirection", + "severity": "Medio", + "subcategory": "Entrega de aplicaciones", + "text": "Use el redireccionamiento de HTTP a HTTPS con Azure Front Door. Apoye a los clientes más antiguos redirigiéndolos automáticamente a una solicitud HTTPS.", + "waf": "Seguridad" + }, + { + "ammp": true, + "category": "Topología y conectividad de red", + "guid": "28b9ee82-b2c7-45aa-bc98-6de6f59a095d", + "id": "A02.03", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#enable-the-waf", + "severity": "Alto", + "subcategory": "Entrega de aplicaciones", + "text": "Habilite el WAF de Azure Front Door. Proteja su aplicación de una variedad de ataques.", + "waf": "Seguridad" + }, + { + "ammp": true, + "category": "Topología y conectividad de red", + "guid": "2902d8cc-1b0c-4495-afad-624ab70f7bd6", + "id": "A02.04", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#tune-your-waf", + "severity": "Alto", + "subcategory": "Entrega de aplicaciones", + "text": "Ajuste el WAF de Azure Front Door para su carga de trabajo. Reduzca las detecciones de falsos positivos.", + "waf": "Seguridad" + }, + { + "ammp": true, + "category": "Topología y conectividad de red", + "guid": "17ba124b-127d-42b6-9322-388d5b2bbcfc", + "id": "A02.05", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-prevention-mode", + "severity": "Alto", + "subcategory": "Entrega de aplicaciones", + "text": "Use el modo de prevención con el WAF de Azure Front Door. El modo de prevención garantiza que el WAF bloquee las solicitudes malintencionadas.", + "waf": "Seguridad" + }, + { + "ammp": true, + "category": "Topología y conectividad de red", + "guid": "49a98f2b-ec22-4a87-9415-6a10b00d6555", + "id": "A02.06", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#enable-default-rule-sets", + "severity": "Alto", + "subcategory": "Entrega de aplicaciones", + "text": "Habilite los conjuntos de reglas predeterminados de WAF de Azure Front Door. Los conjuntos de reglas predeterminados detectan y bloquean los ataques comunes.", + "waf": "Seguridad" + }, + { + "ammp": true, + "category": "Topología y conectividad de red", + "guid": "147a13d4-2a2f-4824-a524-f5855b52b946", + "id": "A02.07", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#enable-bot-management-rules", + "severity": "Alto", + "subcategory": "Entrega de aplicaciones", + "text": "Habilite las reglas de administración de bots de WAF de Azure Front Door. Las reglas de bots detectan bots buenos y malos.", + "waf": "Seguridad" + }, + { + "category": "Topología y conectividad de red", + "guid": "d7dcdcb9-0d99-44b9-baab-ac7570ede79a", + "id": "A02.08", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-the-latest-ruleset-versions", + "severity": "Medio", + "subcategory": "Entrega de aplicaciones", + "text": "Use las versiones más recientes del conjunto de reglas de Azure Front Door WAF. Las actualizaciones del conjunto de reglas se actualizan periódicamente para tener en cuenta el panorama actual de amenazas.", + "waf": "Seguridad" + }, + { + "category": "Topología y conectividad de red", + "guid": "b9620385-1cde-418f-914b-a84a06982ffc", + "id": "A02.09", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#add-rate-limiting", + "severity": "Medio", + "subcategory": "Entrega de aplicaciones", + "text": "Agregue limitación de velocidad al WAF de Azure Front Door. La limitación de velocidad bloquea a los clientes que envían accidental o intencionadamente grandes cantidades de tráfico en un corto período de tiempo.", + "waf": "Seguridad" + }, + { + "category": "Topología y conectividad de red", + "guid": "6dc36c52-0124-4ffe-9eaf-23ec1282dedb", + "id": "A02.10", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-a-high-threshold-for-rate-limits", + "severity": "Medio", + "subcategory": "Entrega de aplicaciones", + "text": "Use un umbral alto para los límites de frecuencia de WAF de Azure Front Door. Los umbrales de límite de velocidad altos evitan el bloqueo del tráfico legítimo y, al mismo tiempo, brindan protección contra un número extremadamente alto de solicitudes que podrían abrumar su infraestructura. ", + "waf": "Seguridad" + }, + { + "category": "Topología y conectividad de red", + "guid": "388a3d0e-0a43-4367-90b2-3dd2aeece5ee", + "id": "A02.11", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#geo-filter-traffic", + "severity": "Bajo", + "subcategory": "Entrega de aplicaciones", + "text": "Filtre geográficamente el tráfico mediante el WAF de Azure Front Door. Permita el tráfico solo de las regiones esperadas y bloquee el tráfico de otras regiones.", + "waf": "Seguridad" + }, + { + "category": "Topología y conectividad de red", + "guid": "00acd8a9-6975-414f-8491-2be6309893b8", + "id": "A02.12", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#specify-the-unknown-zz-location", + "severity": "Medio", + "subcategory": "Entrega de aplicaciones", + "text": "Especifique la ubicación desconocida (ZZ) al filtrar geográficamente el tráfico con el WAF de Azure Front Door. Evite bloquear accidentalmente solicitudes legítimas cuando las direcciones IP no se puedan hacer coincidir geográficamente.", + "waf": "Seguridad" + } + ], + "metadata": { + "name": "Azure Application Delivery", + "state": "GA", + "timestamp": "November 06, 2023" + }, + "severities": [ + { + "name": "Alto" + }, + { + "name": "Medio" + }, + { + "name": "Bajo" + } + ], + "status": [ + { + "description": "Esta comprobación aún no se ha examinado", + "name": "No verificado" + }, + { + "description": "Hay un elemento de acción asociado a esta comprobación", + "name": "Abrir" + }, + { + "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" + }, + { + "description": "No aplicable para el diseño actual", + "name": "N/A" + } + ], + "waf": [ + { + "name": "Fiabilidad" + }, + { + "name": "Seguridad" + }, + { + "name": "Costar" + }, + { + "name": "Operaciones" + }, + { + "name": "Rendimiento" + } + ], + "yesno": [ + { + "name": "Sí" + }, + { + "name": "No" + } + ] +} \ No newline at end of file diff --git a/checklists/network_appdelivery_checklist.ja.json b/checklists/network_appdelivery_checklist.ja.json new file mode 100644 index 000000000..68965d3e5 --- /dev/null +++ b/checklists/network_appdelivery_checklist.ja.json @@ -0,0 +1,451 @@ +{ + "categories": [ + { + "name": "Azure 課金と Microsoft Entra ID テナント" + }, + { + "name": "IDおよびアクセス管理" + }, + { + "name": "ネットワークトポロジと接続性" + }, + { + "name": "安全" + }, + { + "name": "管理" + }, + { + "name": "リソース編成" + }, + { + "name": "プラットフォームの自動化とDevOps" + }, + { + "name": "統治" + } + ], + "items": [ + { + "category": "ネットワークトポロジと接続性", + "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", + "severity": "中程度", + "subcategory": "アプリ配信", + "text": "Azure Front Door でカスタマー マネージド TLS 証明書を使用する場合は、\"最新\" の証明書バージョンを使用します。証明書の手動更新によって引き起こされる停止のリスクを軽減します。", + "waf": "オペレーションズ" + }, + { + "category": "ネットワークトポロジと接続性", + "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", + "severity": "中程度", + "subcategory": "アプリ配信", + "text": "内部向けアプリ (corp) と外部向けアプリ (online) の両方のランディング ゾーン内でアプリ配信を実行します。", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "安全" + }, + { + "category": "ネットワークトポロジと接続性", + "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", + "severity": "中程度", + "subcategory": "アプリ配信", + "text": "Application Gateway v2 SKU を使用していることを確認する", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "安全" + }, + { + "category": "ネットワークトポロジと接続性", + "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", + "severity": "中程度", + "subcategory": "アプリ配信", + "text": "Azure Load Balancer に Standard SKU を使用していることを確認する", + "waf": "安全" + }, + { + "category": "ネットワークトポロジと接続性", + "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 | project id, subnetId = tostring(subnets.id), subnetPrefixLength = split(subnets.properties.addressPrefix, '/')[1]) on subnetId | extend compliant = (subnetPrefixLength <= 26) | 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", + "severity": "中程度", + "subcategory": "アプリ配信", + "text": "アプリケーション ゲートウェイは、IP プレフィックスが /26 以上のサブネットにデプロイする必要があります", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "安全" + }, + { + "category": "ネットワークトポロジと接続性", + "description": "リバースプロキシ全般、特にWAFの管理は、ネットワークよりもアプリケーションに近いため、アプリと同じサブスクリプションに属します。Application Gateway と WAF を接続サブスクリプションに一元化することは、1 つのチームによって管理されている場合は問題ない可能性があります。", + "guid": "48b662d6-d15f-4512-a654-98f6dfe237de", + "id": "A01.06", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "severity": "中程度", + "subcategory": "アプリ配信", + "text": "ランディング ゾーン仮想ネットワーク内およびそれらがセキュリティで保護しているアプリと共に、受信 HTTP(S) 接続のプロキシに使用される Azure Application Gateway v2 またはパートナーの NVA をデプロイします。", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "安全" + }, + { + "category": "ネットワークトポロジと接続性", + "guid": "143b16c3-1d7a-4a9b-9470-4489a8042d88", + "id": "A01.07", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "severity": "中程度", + "subcategory": "アプリ配信", + "text": "アプリケーション ランディング ゾーン内のすべてのパブリック IP アドレスに対して DDoS ネットワークまたは IP 保護プランを使用します。", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "安全" + }, + { + "category": "ネットワークトポロジと接続性", + "guid": "e79d17b7-3b22-4a5a-97e7-a8ed4b30e38c", + "id": "A01.08", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "severity": "中程度", + "subcategory": "アプリ配信", + "text": "Azure Front Door と WAF ポリシーを使用して、複数の Azure リージョンにまたがるグローバル HTTP/S アプリを配信し、保護します。", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "安全" + }, + { + "category": "ネットワークトポロジと接続性", + "guid": "3f29812b-2363-4cef-b179-b599de0d5973", + "id": "A01.09", + "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", + "severity": "中程度", + "subcategory": "アプリ配信", + "text": "Front Door と Application Gateway を使用して HTTP/S アプリを保護する場合は、Front Door で WAF ポリシーを使用します。Application Gateway をロックダウンして、Front Door からのトラフィックのみを受信します。", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "安全" + }, + { + "ammp": true, + "category": "ネットワークトポロジと接続性", + "guid": "cd4cd21b-0881-437f-9e6c-4cfd3e504547", + "id": "A01.10", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "severity": "高い", + "subcategory": "アプリ配信", + "text": "Traffic Manager を使用して、HTTP/S 以外のプロトコルにまたがるグローバル アプリを配信します。", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "確実" + }, + { + "category": "ネットワークトポロジと接続性", + "guid": "3b4b3e88-a459-4ed5-a22f-644dfbc58204", + "id": "A01.11", + "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy#how-application-proxy-works", + "severity": "低い", + "subcategory": "アプリ配信", + "text": "ユーザーが内部アプリケーションへのアクセスのみを必要とする場合、Microsoft Entra ID アプリケーション プロキシは Azure Virtual Desktop (AVD) の代替として検討されていますか?", + "training": "https://learn.microsoft.com/learn/modules/configure-azure-ad-application-proxy/", + "waf": "安全" + }, + { + "category": "ネットワークトポロジと接続性", + "guid": "01ca7cf1-5754-442d-babb-8ba6772e5c30", + "id": "A01.12", + "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy#how-application-proxy-works", + "severity": "中程度", + "subcategory": "アプリ配信", + "text": "ネットワーク内の着信接続用に開かれているファイアウォール ポートの数を減らすには、Microsoft Entra ID アプリケーション プロキシを使用して、リモート ユーザーに内部アプリケーションへの安全で認証されたアクセスを提供することを検討してください。", + "training": "https://learn.microsoft.com/learn/paths/implement-applications-external-access-azure-ad/", + "waf": "安全" + }, + { + "ammp": true, + "category": "ネットワークトポロジと接続性", + "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.13", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-policy-settings", + "severity": "高い", + "subcategory": "アプリ配信", + "text": "Front Door の WAF プロファイルを \"防止\" モードでデプロイします。", + "waf": "安全" + }, + { + "ammp": true, + "category": "ネットワークトポロジと接続性", + "guid": "062d5839-4d36-402f-bfa4-02811eb936e9", + "id": "A01.14", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#avoid-combining-traffic-manager-and-front-door", + "severity": "高い", + "subcategory": "アプリ配信", + "text": "Azure Traffic Manager と Azure Front Door の組み合わせは避けてください。", + "waf": "安全" + }, + { + "ammp": true, + "category": "ネットワークトポロジと接続性", + "guid": "5efeb96a-003f-4b18-8fcd-b4d84459c2b2", + "id": "A01.15", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-the-same-domain-name-on-front-door-and-your-origin", + "severity": "高い", + "subcategory": "アプリ配信", + "text": "Azure Front Door と配信元で同じドメイン名を使用します。ホスト名が一致しないと、微妙なバグが発生する可能性があります。", + "waf": "安全" + }, + { + "category": "ネットワークトポロジと接続性", + "guid": "0b5a380c-4bfb-47bc-b1d7-dcfef363a61b", + "id": "A01.16", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#disable-health-probes-when-theres-only-one-origin-in-an-origin-group", + "severity": "低い", + "subcategory": "アプリ配信", + "text": "Azure Front Door 配信元グループに配信元が 1 つしかない場合は、正常性プローブを無効にします。", + "waf": "パフォーマンス" + }, + { + "category": "ネットワークトポロジと接続性", + "guid": "5567048e-e5d7-4206-9c55-b5ed45d2cc0c", + "id": "A01.17", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#select-good-health-probe-endpoints", + "severity": "中程度", + "subcategory": "アプリ配信", + "text": "Azure Front Door に適した正常性プローブ エンドポイントを選択します。アプリケーションのすべての依存関係をチェックする正常性エンドポイントを構築することを検討してください。", + "waf": "確実" + }, + { + "category": "ネットワークトポロジと接続性", + "guid": "a13f72f3-8f5c-4864-95e5-75bf37fbbeb1", + "id": "A01.18", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-head-health-probes", + "severity": "低い", + "subcategory": "アプリ配信", + "text": "Azure Front Door で HEAD 正常性プローブを使用して、Front Door がアプリケーションに送信するトラフィックを減らします。", + "waf": "パフォーマンス" + }, + { + "ammp": true, + "category": "ネットワークトポロジと接続性", + "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.19", + "link": "https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity", + "severity": "高い", + "subcategory": "アプリ配信", + "text": "Load Balancer の送信規則の代わりに Azure NAT Gateway を使用して、SNAT のスケーラビリティを向上させる", + "waf": "確実" + }, + { + "ammp": true, + "category": "ネットワークトポロジと接続性", + "guid": "af95c92d-d723-4f4a-98d7-8722324efd4d", + "id": "A01.20", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-managed-tls-certificates", + "severity": "高い", + "subcategory": "アプリ配信", + "text": "Azure Front Door でマネージド TLS 証明書を使用します。運用コストと、証明書の更新による停止のリスクを軽減します。", + "waf": "オペレーションズ" + }, + { + "category": "ネットワークトポロジと接続性", + "guid": "189ea962-3969-4863-8f5a-5ad808c2cf4b", + "id": "A01.21", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#define-your-waf-configuration-as-code", + "severity": "中程度", + "subcategory": "アプリ配信", + "text": "Azure Front Door WAF の構成をコードとして定義します。コードを使用することで、新しいルールセット・バージョンをより簡単に採用し、保護を強化できます。", + "waf": "オペレーションズ" + }, + { + "ammp": true, + "category": "ネットワークトポロジと接続性", + "guid": "2e30abab-5478-417c-81bf-bf1ad4ed1ed4", + "id": "A02.01", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-end-to-end-tls", + "severity": "高い", + "subcategory": "アプリ配信", + "text": "Azure Front Door でエンド ツー エンドの TLS を使用します。クライアントから Front Door への接続、および Front Door から配信元への接続には TLS を使用します。", + "waf": "安全" + }, + { + "category": "ネットワークトポロジと接続性", + "guid": "10aa45af-166f-44c4-9f36-b6d592dac2ca", + "id": "A02.02", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-http-to-https-redirection", + "severity": "中程度", + "subcategory": "アプリ配信", + "text": "Azure Front Door で HTTP から HTTPS へのリダイレクトを使用します。古いクライアントをHTTPSリクエストに自動的にリダイレクトすることでサポートします。", + "waf": "安全" + }, + { + "ammp": true, + "category": "ネットワークトポロジと接続性", + "guid": "28b9ee82-b2c7-45aa-bc98-6de6f59a095d", + "id": "A02.03", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#enable-the-waf", + "severity": "高い", + "subcategory": "アプリ配信", + "text": "Azure Front Door WAF を有効にします。さまざまな攻撃からアプリケーションを保護します。", + "waf": "安全" + }, + { + "ammp": true, + "category": "ネットワークトポロジと接続性", + "guid": "2902d8cc-1b0c-4495-afad-624ab70f7bd6", + "id": "A02.04", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#tune-your-waf", + "severity": "高い", + "subcategory": "アプリ配信", + "text": "ワークロードに合わせて Azure Front Door WAF を調整します。誤検知を減らします。", + "waf": "安全" + }, + { + "ammp": true, + "category": "ネットワークトポロジと接続性", + "guid": "17ba124b-127d-42b6-9322-388d5b2bbcfc", + "id": "A02.05", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-prevention-mode", + "severity": "高い", + "subcategory": "アプリ配信", + "text": "Azure Front Door WAF で防止モードを使用します。防止モードにより、WAF は悪意のある要求を確実にブロックします。", + "waf": "安全" + }, + { + "ammp": true, + "category": "ネットワークトポロジと接続性", + "guid": "49a98f2b-ec22-4a87-9415-6a10b00d6555", + "id": "A02.06", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#enable-default-rule-sets", + "severity": "高い", + "subcategory": "アプリ配信", + "text": "Azure Front Door WAF の既定のルール セットを有効にします。既定のルール セットは、一般的な攻撃を検出してブロックします。", + "waf": "安全" + }, + { + "ammp": true, + "category": "ネットワークトポロジと接続性", + "guid": "147a13d4-2a2f-4824-a524-f5855b52b946", + "id": "A02.07", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#enable-bot-management-rules", + "severity": "高い", + "subcategory": "アプリ配信", + "text": "Azure Front Door WAF ボット管理ルールを有効にします。ボットルールは、良いボットと悪いボットを検出します。", + "waf": "安全" + }, + { + "category": "ネットワークトポロジと接続性", + "guid": "d7dcdcb9-0d99-44b9-baab-ac7570ede79a", + "id": "A02.08", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-the-latest-ruleset-versions", + "severity": "中程度", + "subcategory": "アプリ配信", + "text": "最新バージョンの Azure Front Door WAF ルールセットを使用します。ルールセットの更新は、現在の脅威の状況を考慮して定期的に更新されます。", + "waf": "安全" + }, + { + "category": "ネットワークトポロジと接続性", + "guid": "b9620385-1cde-418f-914b-a84a06982ffc", + "id": "A02.09", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#add-rate-limiting", + "severity": "中程度", + "subcategory": "アプリ配信", + "text": "Azure Front Door WAF にレート制限を追加します。レート制限は、クライアントが短期間に大量のトラフィックを誤ってまたは意図的に送信することをブロックします。", + "waf": "安全" + }, + { + "category": "ネットワークトポロジと接続性", + "guid": "6dc36c52-0124-4ffe-9eaf-23ec1282dedb", + "id": "A02.10", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-a-high-threshold-for-rate-limits", + "severity": "中程度", + "subcategory": "アプリ配信", + "text": "Azure Front Door WAF のレート制限には、高いしきい値を使用します。高いレート制限しきい値は、正当なトラフィックのブロックを回避しながら、インフラストラクチャを圧倒する可能性のある非常に多数の要求に対する保護を提供します。", + "waf": "安全" + }, + { + "category": "ネットワークトポロジと接続性", + "guid": "388a3d0e-0a43-4367-90b2-3dd2aeece5ee", + "id": "A02.11", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#geo-filter-traffic", + "severity": "低い", + "subcategory": "アプリ配信", + "text": "Azure Front Door WAF を使用してトラフィックを geo フィルター処理します。想定されるリージョンからのトラフィックのみを許可し、他のリージョンからのトラフィックをブロックします。", + "waf": "安全" + }, + { + "category": "ネットワークトポロジと接続性", + "guid": "00acd8a9-6975-414f-8491-2be6309893b8", + "id": "A02.12", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#specify-the-unknown-zz-location", + "severity": "中程度", + "subcategory": "アプリ配信", + "text": "Azure Front Door WAF を使用してトラフィックをジオフィルター処理するときに、不明な (ZZ) 場所を指定します。IP アドレスを地理的に一致させることができない場合に、正当な要求を誤ってブロックしないようにします。", + "waf": "安全" + } + ], + "metadata": { + "name": "Azure Application Delivery", + "state": "GA", + "timestamp": "November 06, 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/network_appdelivery_checklist.ko.json b/checklists/network_appdelivery_checklist.ko.json new file mode 100644 index 000000000..5456e8c06 --- /dev/null +++ b/checklists/network_appdelivery_checklist.ko.json @@ -0,0 +1,451 @@ +{ + "categories": [ + { + "name": "Azure 청구 및 Microsoft Entra ID 테넌트" + }, + { + "name": "ID 및 액세스 관리" + }, + { + "name": "네트워크 토폴로지 및 연결" + }, + { + "name": "안전" + }, + { + "name": "경영" + }, + { + "name": "자원 조직" + }, + { + "name": "플랫폼 자동화 및 DevOps" + }, + { + "name": "지배구조" + } + ], + "items": [ + { + "category": "네트워크 토폴로지 및 연결", + "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", + "severity": "보통", + "subcategory": "앱 제공", + "text": "Azure Front Door에서 고객 관리형 TLS 인증서를 사용하는 경우 '최신' 인증서 버전을 사용합니다. 수동 인증서 갱신으로 인한 중단 위험을 줄입니다.", + "waf": "작업" + }, + { + "category": "네트워크 토폴로지 및 연결", + "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", + "severity": "보통", + "subcategory": "앱 제공", + "text": "랜딩 존 내에서 내부 연결(corp) 및 외부 연결 앱(온라인) 모두에 대해 앱 배달을 수행합니다.", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "안전" + }, + { + "category": "네트워크 토폴로지 및 연결", + "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", + "severity": "보통", + "subcategory": "앱 제공", + "text": "Application Gateway v2 SKU를 사용하고 있는지 확인합니다.", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "안전" + }, + { + "category": "네트워크 토폴로지 및 연결", + "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", + "severity": "보통", + "subcategory": "앱 제공", + "text": "Azure Load Balancer에 표준 SKU를 사용하고 있는지 확인합니다.", + "waf": "안전" + }, + { + "category": "네트워크 토폴로지 및 연결", + "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 | project id, subnetId = tostring(subnets.id), subnetPrefixLength = split(subnets.properties.addressPrefix, '/')[1]) on subnetId | extend compliant = (subnetPrefixLength <= 26) | 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", + "severity": "보통", + "subcategory": "앱 제공", + "text": "응용 프로그램 게이트웨이는 IP 접두사가 /26보다 크거나 같은 서브넷에 배포해야 합니다", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "안전" + }, + { + "category": "네트워크 토폴로지 및 연결", + "description": "일반적으로 역방향 프록시 및 특히 WAF의 관리는 네트워킹보다 애플리케이션에 더 가깝기 때문에 앱과 동일한 구독에 속합니다. 연결 구독에서 Application Gateway 및 WAF를 중앙 집중화하는 것은 단일 팀에서 관리하는 경우 괜찮을 수 있습니다.", + "guid": "48b662d6-d15f-4512-a654-98f6dfe237de", + "id": "A01.06", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "severity": "보통", + "subcategory": "앱 제공", + "text": "랜딩 영역 가상 네트워크 내에서 그리고 보안 중인 앱을 사용하여 인바운드 HTTP(S) 연결을 프록시하는 데 사용되는 Azure Application Gateway v2 또는 파트너 NVA를 배포합니다.", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "안전" + }, + { + "category": "네트워크 토폴로지 및 연결", + "guid": "143b16c3-1d7a-4a9b-9470-4489a8042d88", + "id": "A01.07", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "severity": "보통", + "subcategory": "앱 제공", + "text": "애플리케이션 랜딩 존의 모든 공용 IP 주소에 대해 DDoS 네트워크 또는 IP 보호 계획을 사용합니다.", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "안전" + }, + { + "category": "네트워크 토폴로지 및 연결", + "guid": "e79d17b7-3b22-4a5a-97e7-a8ed4b30e38c", + "id": "A01.08", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "severity": "보통", + "subcategory": "앱 제공", + "text": "WAF 정책과 함께 Azure Front Door를 사용하여 여러 Azure 지역에 걸쳐 있는 글로벌 HTTP/S 앱을 제공하고 보호할 수 있습니다.", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "안전" + }, + { + "category": "네트워크 토폴로지 및 연결", + "guid": "3f29812b-2363-4cef-b179-b599de0d5973", + "id": "A01.09", + "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", + "severity": "보통", + "subcategory": "앱 제공", + "text": "Front Door 및 Application Gateway를 사용하여 HTTP/S 앱을 보호하는 경우 Front Door에서 WAF 정책을 사용합니다. Front Door에서만 트래픽을 수신하도록 Application Gateway를 잠급니다.", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "안전" + }, + { + "ammp": true, + "category": "네트워크 토폴로지 및 연결", + "guid": "cd4cd21b-0881-437f-9e6c-4cfd3e504547", + "id": "A01.10", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "severity": "높다", + "subcategory": "앱 제공", + "text": "Traffic Manager를 사용하여 HTTP/S 이외의 프로토콜에 걸쳐 있는 글로벌 앱을 제공합니다.", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "신뢰도" + }, + { + "category": "네트워크 토폴로지 및 연결", + "guid": "3b4b3e88-a459-4ed5-a22f-644dfbc58204", + "id": "A01.11", + "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy#how-application-proxy-works", + "severity": "낮다", + "subcategory": "앱 제공", + "text": "사용자가 내부 애플리케이션에만 액세스해야 하는 경우 Microsoft Entra ID 애플리케이션 프록시가 AVD(Azure Virtual Desktop)의 대안으로 고려되었나요?", + "training": "https://learn.microsoft.com/learn/modules/configure-azure-ad-application-proxy/", + "waf": "안전" + }, + { + "category": "네트워크 토폴로지 및 연결", + "guid": "01ca7cf1-5754-442d-babb-8ba6772e5c30", + "id": "A01.12", + "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy#how-application-proxy-works", + "severity": "보통", + "subcategory": "앱 제공", + "text": "네트워크에서 들어오는 연결에 대해 열려 있는 방화벽 포트 수를 줄이려면 Microsoft Entra ID 애플리케이션 프록시를 사용하여 원격 사용자에게 내부 애플리케이션에 대한 안전하고 인증된 액세스 권한을 부여하는 것이 좋습니다.", + "training": "https://learn.microsoft.com/learn/paths/implement-applications-external-access-azure-ad/", + "waf": "안전" + }, + { + "ammp": true, + "category": "네트워크 토폴로지 및 연결", + "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.13", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-policy-settings", + "severity": "높다", + "subcategory": "앱 제공", + "text": "'방지' 모드에서 Front Door에 대한 WAF 프로필을 배포합니다.", + "waf": "안전" + }, + { + "ammp": true, + "category": "네트워크 토폴로지 및 연결", + "guid": "062d5839-4d36-402f-bfa4-02811eb936e9", + "id": "A01.14", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#avoid-combining-traffic-manager-and-front-door", + "severity": "높다", + "subcategory": "앱 제공", + "text": "Azure Traffic Manager와 Azure Front Door를 결합하지 마세요.", + "waf": "안전" + }, + { + "ammp": true, + "category": "네트워크 토폴로지 및 연결", + "guid": "5efeb96a-003f-4b18-8fcd-b4d84459c2b2", + "id": "A01.15", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-the-same-domain-name-on-front-door-and-your-origin", + "severity": "높다", + "subcategory": "앱 제공", + "text": "Azure Front Door 및 원본에서 동일한 도메인 이름을 사용합니다. 호스트 이름이 일치하지 않으면 미묘한 버그가 발생할 수 있습니다.", + "waf": "안전" + }, + { + "category": "네트워크 토폴로지 및 연결", + "guid": "0b5a380c-4bfb-47bc-b1d7-dcfef363a61b", + "id": "A01.16", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#disable-health-probes-when-theres-only-one-origin-in-an-origin-group", + "severity": "낮다", + "subcategory": "앱 제공", + "text": "Azure Front Door 원본 그룹에 원본이 하나만 있는 경우 상태 프로브를 사용하지 않도록 설정합니다.", + "waf": "공연" + }, + { + "category": "네트워크 토폴로지 및 연결", + "guid": "5567048e-e5d7-4206-9c55-b5ed45d2cc0c", + "id": "A01.17", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#select-good-health-probe-endpoints", + "severity": "보통", + "subcategory": "앱 제공", + "text": "Azure Front Door에 대한 양호한 상태 프로브 엔드포인트를 선택합니다. 애플리케이션의 모든 종속성을 확인하는 상태 엔드포인트를 빌드하는 것이 좋습니다.", + "waf": "신뢰도" + }, + { + "category": "네트워크 토폴로지 및 연결", + "guid": "a13f72f3-8f5c-4864-95e5-75bf37fbbeb1", + "id": "A01.18", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-head-health-probes", + "severity": "낮다", + "subcategory": "앱 제공", + "text": "Azure Front Door와 함께 HEAD 상태 프로브를 사용하여 Front Door가 애플리케이션으로 보내는 트래픽을 줄입니다.", + "waf": "공연" + }, + { + "ammp": true, + "category": "네트워크 토폴로지 및 연결", + "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.19", + "link": "https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity", + "severity": "높다", + "subcategory": "앱 제공", + "text": "SNAT 확장성 향상을 위해 Load Balancer 아웃바운드 규칙 대신 Azure NAT Gateway 사용", + "waf": "신뢰도" + }, + { + "ammp": true, + "category": "네트워크 토폴로지 및 연결", + "guid": "af95c92d-d723-4f4a-98d7-8722324efd4d", + "id": "A01.20", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-managed-tls-certificates", + "severity": "높다", + "subcategory": "앱 제공", + "text": "Azure Front Door에서 관리형 TLS 인증서를 사용합니다. 운영 비용을 줄이고 인증서 갱신으로 인한 중단 위험을 줄입니다.", + "waf": "작업" + }, + { + "category": "네트워크 토폴로지 및 연결", + "guid": "189ea962-3969-4863-8f5a-5ad808c2cf4b", + "id": "A01.21", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#define-your-waf-configuration-as-code", + "severity": "보통", + "subcategory": "앱 제공", + "text": "Azure Front Door WAF 구성을 코드로 정의합니다. 코드를 사용하면 새 규칙 집합 버전을 보다 쉽게 채택하고 추가 보호를 얻을 수 있습니다.", + "waf": "작업" + }, + { + "ammp": true, + "category": "네트워크 토폴로지 및 연결", + "guid": "2e30abab-5478-417c-81bf-bf1ad4ed1ed4", + "id": "A02.01", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-end-to-end-tls", + "severity": "높다", + "subcategory": "앱 제공", + "text": "Azure Front Door에서 엔드투엔드 TLS를 사용합니다. 클라이언트에서 Front Door로, Front Door에서 원본으로 연결하는 데 TLS를 사용합니다.", + "waf": "안전" + }, + { + "category": "네트워크 토폴로지 및 연결", + "guid": "10aa45af-166f-44c4-9f36-b6d592dac2ca", + "id": "A02.02", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-http-to-https-redirection", + "severity": "보통", + "subcategory": "앱 제공", + "text": "Azure Front Door에서 HTTP에서 HTTPS로 리디렉션을 사용합니다. 이전 클라이언트를 HTTPS 요청으로 자동 리디렉션하여 지원합니다.", + "waf": "안전" + }, + { + "ammp": true, + "category": "네트워크 토폴로지 및 연결", + "guid": "28b9ee82-b2c7-45aa-bc98-6de6f59a095d", + "id": "A02.03", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#enable-the-waf", + "severity": "높다", + "subcategory": "앱 제공", + "text": "Azure Front Door WAF를 사용하도록 설정합니다. 다양한 공격으로부터 애플리케이션을 보호합니다.", + "waf": "안전" + }, + { + "ammp": true, + "category": "네트워크 토폴로지 및 연결", + "guid": "2902d8cc-1b0c-4495-afad-624ab70f7bd6", + "id": "A02.04", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#tune-your-waf", + "severity": "높다", + "subcategory": "앱 제공", + "text": "워크로드에 맞게 Azure Front Door WAF를 튜닝합니다. 가양성 탐지를 줄입니다.", + "waf": "안전" + }, + { + "ammp": true, + "category": "네트워크 토폴로지 및 연결", + "guid": "17ba124b-127d-42b6-9322-388d5b2bbcfc", + "id": "A02.05", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-prevention-mode", + "severity": "높다", + "subcategory": "앱 제공", + "text": "Azure Front Door WAF에서 방지 모드를 사용합니다. 방지 모드는 WAF가 악의적인 요청을 차단하도록 합니다.", + "waf": "안전" + }, + { + "ammp": true, + "category": "네트워크 토폴로지 및 연결", + "guid": "49a98f2b-ec22-4a87-9415-6a10b00d6555", + "id": "A02.06", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#enable-default-rule-sets", + "severity": "높다", + "subcategory": "앱 제공", + "text": "Azure Front Door WAF 기본 규칙 집합을 사용하도록 설정합니다. 기본 규칙 집합은 일반적인 공격을 탐지하고 차단합니다.", + "waf": "안전" + }, + { + "ammp": true, + "category": "네트워크 토폴로지 및 연결", + "guid": "147a13d4-2a2f-4824-a524-f5855b52b946", + "id": "A02.07", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#enable-bot-management-rules", + "severity": "높다", + "subcategory": "앱 제공", + "text": "Azure Front Door WAF 봇 관리 규칙을 사용하도록 설정합니다. 봇 규칙은 좋은 봇과 나쁜 봇을 감지합니다.", + "waf": "안전" + }, + { + "category": "네트워크 토폴로지 및 연결", + "guid": "d7dcdcb9-0d99-44b9-baab-ac7570ede79a", + "id": "A02.08", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-the-latest-ruleset-versions", + "severity": "보통", + "subcategory": "앱 제공", + "text": "최신 Azure Front Door WAF 규칙 집합 버전을 사용합니다. 규칙 집합 업데이트는 현재 위협 환경을 고려하기 위해 정기적으로 업데이트됩니다.", + "waf": "안전" + }, + { + "category": "네트워크 토폴로지 및 연결", + "guid": "b9620385-1cde-418f-914b-a84a06982ffc", + "id": "A02.09", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#add-rate-limiting", + "severity": "보통", + "subcategory": "앱 제공", + "text": "Azure Front Door WAF에 속도 제한을 추가합니다. 속도 제한은 클라이언트가 실수로 또는 의도적으로 짧은 시간에 많은 양의 트래픽을 보내는 것을 차단합니다.", + "waf": "안전" + }, + { + "category": "네트워크 토폴로지 및 연결", + "guid": "6dc36c52-0124-4ffe-9eaf-23ec1282dedb", + "id": "A02.10", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-a-high-threshold-for-rate-limits", + "severity": "보통", + "subcategory": "앱 제공", + "text": "Azure Front Door WAF 속도 제한에 높은 임계값을 사용합니다. 높은 속도 제한 임계값은 합법적인 트래픽 차단을 방지하는 동시에 인프라를 압도할 수 있는 매우 많은 수의 요청에 대한 보호 기능을 제공합니다. ", + "waf": "안전" + }, + { + "category": "네트워크 토폴로지 및 연결", + "guid": "388a3d0e-0a43-4367-90b2-3dd2aeece5ee", + "id": "A02.11", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#geo-filter-traffic", + "severity": "낮다", + "subcategory": "앱 제공", + "text": "Azure Front Door WAF를 사용하여 트래픽을 지역 필터링합니다. 예상 지역의 트래픽만 허용하고 다른 지역의 트래픽은 차단합니다.", + "waf": "안전" + }, + { + "category": "네트워크 토폴로지 및 연결", + "guid": "00acd8a9-6975-414f-8491-2be6309893b8", + "id": "A02.12", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#specify-the-unknown-zz-location", + "severity": "보통", + "subcategory": "앱 제공", + "text": "Azure Front Door WAF를 사용하여 트래픽을 지리적으로 필터링할 때 알 수 없는(ZZ) 위치를 지정합니다. IP 주소를 지리적으로 일치시킬 수 없는 경우 합법적인 요청을 실수로 차단하지 않도록 합니다.", + "waf": "안전" + } + ], + "metadata": { + "name": "Azure Application Delivery", + "state": "GA", + "timestamp": "November 06, 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/network_appdelivery_checklist.pt.json b/checklists/network_appdelivery_checklist.pt.json new file mode 100644 index 000000000..fa95c8055 --- /dev/null +++ b/checklists/network_appdelivery_checklist.pt.json @@ -0,0 +1,451 @@ +{ + "categories": [ + { + "name": "Locatários de Cobrança do Azure e ID do Microsoft Entra" + }, + { + "name": "Gerenciamento de identidades e acesso" + }, + { + "name": "Topologia de rede e conectividade" + }, + { + "name": "Segurança" + }, + { + "name": "Gestão" + }, + { + "name": "Organização de Recursos" + }, + { + "name": "Automação de Plataforma e DevOps" + }, + { + "name": "Governança" + } + ], + "items": [ + { + "category": "Topologia de rede e conectividade", + "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", + "severity": "Média", + "subcategory": "Entrega de aplicativos", + "text": "Se você usar certificados TLS gerenciados pelo cliente com o Azure Front Door, use a versão de certificado 'Mais recente'. Reduza o risco de paralisações causadas pela renovação manual de certificados.", + "waf": "Operações" + }, + { + "category": "Topologia de rede e conectividade", + "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", + "severity": "Média", + "subcategory": "Entrega de aplicativos", + "text": "Execute a entrega de aplicativos dentro das zonas de aterrissagem para aplicativos internos (corp) e externos (online).", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "Segurança" + }, + { + "category": "Topologia de rede e conectividade", + "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", + "severity": "Média", + "subcategory": "Entrega de aplicativos", + "text": "Verifique se você está usando o SKU do Application Gateway v2", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "Segurança" + }, + { + "category": "Topologia de rede e conectividade", + "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", + "severity": "Média", + "subcategory": "Entrega de aplicativos", + "text": "Verifique se você está usando a SKU padrão para seus Balanceadores de Carga do Azure", + "waf": "Segurança" + }, + { + "category": "Topologia de rede e conectividade", + "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 | project id, subnetId = tostring(subnets.id), subnetPrefixLength = split(subnets.properties.addressPrefix, '/')[1]) on subnetId | extend compliant = (subnetPrefixLength <= 26) | 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", + "severity": "Média", + "subcategory": "Entrega de aplicativos", + "text": "Seus gateways de aplicativo devem ser implantados em sub-redes com prefixos IP iguais ou maiores que /26", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "Segurança" + }, + { + "category": "Topologia de rede e conectividade", + "description": "A administração de proxies reversos em geral e do WAF em particular está mais próxima do aplicativo do que da rede, portanto, eles pertencem à mesma assinatura do aplicativo. Centralizar o Application Gateway e o WAF na assinatura de conectividade pode ser OK se for gerenciado por uma única equipe.", + "guid": "48b662d6-d15f-4512-a654-98f6dfe237de", + "id": "A01.06", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "severity": "Média", + "subcategory": "Entrega de aplicativos", + "text": "Implante o Gateway de Aplicativo do Azure v2 ou NVAs de parceiros usados para fazer proxy de conexões HTTP(S) de entrada na rede virtual da zona de aterrissagem e com os aplicativos que eles estão protegendo.", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "Segurança" + }, + { + "category": "Topologia de rede e conectividade", + "guid": "143b16c3-1d7a-4a9b-9470-4489a8042d88", + "id": "A01.07", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "severity": "Média", + "subcategory": "Entrega de aplicativos", + "text": "Use uma rede DDoS ou planos de proteção IP para todos os endereços IP públicos nas zonas de aterrissagem do aplicativo.", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "Segurança" + }, + { + "category": "Topologia de rede e conectividade", + "guid": "e79d17b7-3b22-4a5a-97e7-a8ed4b30e38c", + "id": "A01.08", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "severity": "Média", + "subcategory": "Entrega de aplicativos", + "text": "Use o Azure Front Door com políticas WAF para fornecer e ajudar a proteger aplicativos HTTP/S globais que abrangem várias regiões do Azure.", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "Segurança" + }, + { + "category": "Topologia de rede e conectividade", + "guid": "3f29812b-2363-4cef-b179-b599de0d5973", + "id": "A01.09", + "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", + "severity": "Média", + "subcategory": "Entrega de aplicativos", + "text": "Ao usar o Front Door e o Application Gateway para ajudar a proteger aplicativos HTTP/S, use políticas WAF no Front Door. Bloqueie o Application Gateway para receber tráfego somente do Front Door.", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "Segurança" + }, + { + "ammp": true, + "category": "Topologia de rede e conectividade", + "guid": "cd4cd21b-0881-437f-9e6c-4cfd3e504547", + "id": "A01.10", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "severity": "Alto", + "subcategory": "Entrega de aplicativos", + "text": "Use o Gerenciador de Tráfego para fornecer aplicativos globais que abrangem protocolos diferentes de HTTP/S.", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "Fiabilidade" + }, + { + "category": "Topologia de rede e conectividade", + "guid": "3b4b3e88-a459-4ed5-a22f-644dfbc58204", + "id": "A01.11", + "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy#how-application-proxy-works", + "severity": "Baixo", + "subcategory": "Entrega de aplicativos", + "text": "Se os usuários precisarem apenas de acesso a aplicativos internos, o Proxy de Aplicativo de ID do Microsoft Entra foi considerado uma alternativa à Área de Trabalho Virtual (AVD) do Azure?", + "training": "https://learn.microsoft.com/learn/modules/configure-azure-ad-application-proxy/", + "waf": "Segurança" + }, + { + "category": "Topologia de rede e conectividade", + "guid": "01ca7cf1-5754-442d-babb-8ba6772e5c30", + "id": "A01.12", + "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy#how-application-proxy-works", + "severity": "Média", + "subcategory": "Entrega de aplicativos", + "text": "Para reduzir o número de portas de firewall abertas para conexões de entrada em sua rede, considere o uso do Microsoft Entra ID Application Proxy para dar aos usuários remotos acesso seguro e autenticado a aplicativos internos.", + "training": "https://learn.microsoft.com/learn/paths/implement-applications-external-access-azure-ad/", + "waf": "Segurança" + }, + { + "ammp": true, + "category": "Topologia de rede e conectividade", + "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.13", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-policy-settings", + "severity": "Alto", + "subcategory": "Entrega de aplicativos", + "text": "Implante seus perfis WAF para Front Door no modo 'Prevenção'.", + "waf": "Segurança" + }, + { + "ammp": true, + "category": "Topologia de rede e conectividade", + "guid": "062d5839-4d36-402f-bfa4-02811eb936e9", + "id": "A01.14", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#avoid-combining-traffic-manager-and-front-door", + "severity": "Alto", + "subcategory": "Entrega de aplicativos", + "text": "Evite combinar o Gerenciador de Tráfego do Azure e o Azure Front Door.", + "waf": "Segurança" + }, + { + "ammp": true, + "category": "Topologia de rede e conectividade", + "guid": "5efeb96a-003f-4b18-8fcd-b4d84459c2b2", + "id": "A01.15", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-the-same-domain-name-on-front-door-and-your-origin", + "severity": "Alto", + "subcategory": "Entrega de aplicativos", + "text": "Use o mesmo nome de domínio no Azure Front Door e sua origem. Nomes de host incompatíveis podem causar bugs sutis.", + "waf": "Segurança" + }, + { + "category": "Topologia de rede e conectividade", + "guid": "0b5a380c-4bfb-47bc-b1d7-dcfef363a61b", + "id": "A01.16", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#disable-health-probes-when-theres-only-one-origin-in-an-origin-group", + "severity": "Baixo", + "subcategory": "Entrega de aplicativos", + "text": "Desabilite os testes de integridade quando houver apenas uma origem em um grupo de origem do Azure Front Door.", + "waf": "Desempenho" + }, + { + "category": "Topologia de rede e conectividade", + "guid": "5567048e-e5d7-4206-9c55-b5ed45d2cc0c", + "id": "A01.17", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#select-good-health-probe-endpoints", + "severity": "Média", + "subcategory": "Entrega de aplicativos", + "text": "Selecione bons pontos de extremidade de teste de integridade para o Azure Front Door. Considere a criação de pontos de extremidade de integridade que verifiquem todas as dependências do seu aplicativo.", + "waf": "Fiabilidade" + }, + { + "category": "Topologia de rede e conectividade", + "guid": "a13f72f3-8f5c-4864-95e5-75bf37fbbeb1", + "id": "A01.18", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-head-health-probes", + "severity": "Baixo", + "subcategory": "Entrega de aplicativos", + "text": "Use testes de integridade do HEAD com o Azure Front Door para reduzir o tráfego que o Front Door envia para seu aplicativo.", + "waf": "Desempenho" + }, + { + "ammp": true, + "category": "Topologia de rede e conectividade", + "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.19", + "link": "https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity", + "severity": "Alto", + "subcategory": "Entrega de aplicativos", + "text": "Usar o Gateway NAT do Azure em vez das regras de saída do Load Balancer para melhor escalabilidade do SNAT", + "waf": "Fiabilidade" + }, + { + "ammp": true, + "category": "Topologia de rede e conectividade", + "guid": "af95c92d-d723-4f4a-98d7-8722324efd4d", + "id": "A01.20", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-managed-tls-certificates", + "severity": "Alto", + "subcategory": "Entrega de aplicativos", + "text": "Use certificados TLS gerenciados com o Azure Front Door. Reduza o custo operacional e o risco de paralisações devido a renovações de certificados.", + "waf": "Operações" + }, + { + "category": "Topologia de rede e conectividade", + "guid": "189ea962-3969-4863-8f5a-5ad808c2cf4b", + "id": "A01.21", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#define-your-waf-configuration-as-code", + "severity": "Média", + "subcategory": "Entrega de aplicativos", + "text": "Defina sua configuração do WAF do Azure Front Door como código. Usando o código, você pode adotar mais facilmente novas versões do conjunto de regras e obter proteção adicional.", + "waf": "Operações" + }, + { + "ammp": true, + "category": "Topologia de rede e conectividade", + "guid": "2e30abab-5478-417c-81bf-bf1ad4ed1ed4", + "id": "A02.01", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-end-to-end-tls", + "severity": "Alto", + "subcategory": "Entrega de aplicativos", + "text": "Use o TLS de ponta a ponta com o Azure Front Door. Use o TLS para conexões de seus clientes com o Front Door e do Front Door com sua origem.", + "waf": "Segurança" + }, + { + "category": "Topologia de rede e conectividade", + "guid": "10aa45af-166f-44c4-9f36-b6d592dac2ca", + "id": "A02.02", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-http-to-https-redirection", + "severity": "Média", + "subcategory": "Entrega de aplicativos", + "text": "Use o redirecionamento HTTP para HTTPS com o Azure Front Door. Ofereça suporte a clientes mais antigos redirecionando-os para uma solicitação HTTPS automaticamente.", + "waf": "Segurança" + }, + { + "ammp": true, + "category": "Topologia de rede e conectividade", + "guid": "28b9ee82-b2c7-45aa-bc98-6de6f59a095d", + "id": "A02.03", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#enable-the-waf", + "severity": "Alto", + "subcategory": "Entrega de aplicativos", + "text": "Habilite o WAF do Azure Front Door. Proteja seu aplicativo contra uma série de ataques.", + "waf": "Segurança" + }, + { + "ammp": true, + "category": "Topologia de rede e conectividade", + "guid": "2902d8cc-1b0c-4495-afad-624ab70f7bd6", + "id": "A02.04", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#tune-your-waf", + "severity": "Alto", + "subcategory": "Entrega de aplicativos", + "text": "Ajuste o WAF do Azure Front Door para sua carga de trabalho. Reduza as detecções de falsos positivos.", + "waf": "Segurança" + }, + { + "ammp": true, + "category": "Topologia de rede e conectividade", + "guid": "17ba124b-127d-42b6-9322-388d5b2bbcfc", + "id": "A02.05", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-prevention-mode", + "severity": "Alto", + "subcategory": "Entrega de aplicativos", + "text": "Use o modo de prevenção com o WAF do Azure Front Door. O modo de prevenção garante que o WAF bloqueie solicitações maliciosas.", + "waf": "Segurança" + }, + { + "ammp": true, + "category": "Topologia de rede e conectividade", + "guid": "49a98f2b-ec22-4a87-9415-6a10b00d6555", + "id": "A02.06", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#enable-default-rule-sets", + "severity": "Alto", + "subcategory": "Entrega de aplicativos", + "text": "Habilite os conjuntos de regras padrão do WAF do Azure Front Door. Os conjuntos de regras padrão detectam e bloqueiam ataques comuns.", + "waf": "Segurança" + }, + { + "ammp": true, + "category": "Topologia de rede e conectividade", + "guid": "147a13d4-2a2f-4824-a524-f5855b52b946", + "id": "A02.07", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#enable-bot-management-rules", + "severity": "Alto", + "subcategory": "Entrega de aplicativos", + "text": "Habilite as regras de gerenciamento de bot do WAF do Azure Front Door. As regras de bot detectam bots bons e ruins.", + "waf": "Segurança" + }, + { + "category": "Topologia de rede e conectividade", + "guid": "d7dcdcb9-0d99-44b9-baab-ac7570ede79a", + "id": "A02.08", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-the-latest-ruleset-versions", + "severity": "Média", + "subcategory": "Entrega de aplicativos", + "text": "Use as versões mais recentes do conjunto de regras do WAF do Azure Front Door. As atualizações do conjunto de regras são atualizadas regularmente para levar em conta o cenário atual de ameaças.", + "waf": "Segurança" + }, + { + "category": "Topologia de rede e conectividade", + "guid": "b9620385-1cde-418f-914b-a84a06982ffc", + "id": "A02.09", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#add-rate-limiting", + "severity": "Média", + "subcategory": "Entrega de aplicativos", + "text": "Adicione o limite de taxa ao WAF do Azure Front Door. A limitação de taxa bloqueia clientes que enviam acidentalmente ou intencionalmente grandes quantidades de tráfego em um curto período de tempo.", + "waf": "Segurança" + }, + { + "category": "Topologia de rede e conectividade", + "guid": "6dc36c52-0124-4ffe-9eaf-23ec1282dedb", + "id": "A02.10", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-a-high-threshold-for-rate-limits", + "severity": "Média", + "subcategory": "Entrega de aplicativos", + "text": "Use um limite alto para os limites de taxa do WAF do Azure Front Door. Limites de limite de taxa alta evitam o bloqueio de tráfego legítimo, ao mesmo tempo em que fornecem proteção contra um número extremamente alto de solicitações que podem sobrecarregar sua infraestrutura. ", + "waf": "Segurança" + }, + { + "category": "Topologia de rede e conectividade", + "guid": "388a3d0e-0a43-4367-90b2-3dd2aeece5ee", + "id": "A02.11", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#geo-filter-traffic", + "severity": "Baixo", + "subcategory": "Entrega de aplicativos", + "text": "Filtre geograficamente o tráfego usando o WAF do Azure Front Door. Permita o tráfego apenas de regiões esperadas e bloqueie o tráfego de outras regiões.", + "waf": "Segurança" + }, + { + "category": "Topologia de rede e conectividade", + "guid": "00acd8a9-6975-414f-8491-2be6309893b8", + "id": "A02.12", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#specify-the-unknown-zz-location", + "severity": "Média", + "subcategory": "Entrega de aplicativos", + "text": "Especifique o local desconhecido (ZZ) ao filtrar geograficamente o tráfego com o WAF do Azure Front Door. Evite bloquear acidentalmente solicitações legítimas quando os endereços IP não puderem ser correspondidos geograficamente.", + "waf": "Segurança" + } + ], + "metadata": { + "name": "Azure Application Delivery", + "state": "GA", + "timestamp": "November 06, 2023" + }, + "severities": [ + { + "name": "Alto" + }, + { + "name": "Média" + }, + { + "name": "Baixo" + } + ], + "status": [ + { + "description": "Esta verificação ainda não foi analisada", + "name": "Não verificado" + }, + { + "description": "Há um item de ação associado a essa verificação", + "name": "Abrir" + }, + { + "description": "Essa verificação foi verificada e não há outros itens de ação associados a ela", + "name": "Cumprido" + }, + { + "description": "Recomendação compreendida, mas não necessária pelos requisitos atuais", + "name": "Não é necessário" + }, + { + "description": "Não aplicável ao projeto atual", + "name": "N/A" + } + ], + "waf": [ + { + "name": "Fiabilidade" + }, + { + "name": "Segurança" + }, + { + "name": "Custar" + }, + { + "name": "Operações" + }, + { + "name": "Desempenho" + } + ], + "yesno": [ + { + "name": "Sim" + }, + { + "name": "Não" + } + ] +} \ No newline at end of file diff --git a/spreadsheet/macrofree/alz_checklist.en.xlsx b/spreadsheet/macrofree/alz_checklist.en.xlsx index 420e692e6..50e983eb2 100644 Binary files a/spreadsheet/macrofree/alz_checklist.en.xlsx and b/spreadsheet/macrofree/alz_checklist.en.xlsx differ diff --git a/spreadsheet/macrofree/alz_checklist.es.xlsx b/spreadsheet/macrofree/alz_checklist.es.xlsx index 728cf25b2..941fff93e 100644 Binary files a/spreadsheet/macrofree/alz_checklist.es.xlsx and b/spreadsheet/macrofree/alz_checklist.es.xlsx differ diff --git a/spreadsheet/macrofree/alz_checklist.ja.xlsx b/spreadsheet/macrofree/alz_checklist.ja.xlsx index 9caf632ed..30539c7d6 100644 Binary files a/spreadsheet/macrofree/alz_checklist.ja.xlsx and b/spreadsheet/macrofree/alz_checklist.ja.xlsx differ diff --git a/spreadsheet/macrofree/alz_checklist.ko.xlsx b/spreadsheet/macrofree/alz_checklist.ko.xlsx index 76179aa29..ba6833f8b 100644 Binary files a/spreadsheet/macrofree/alz_checklist.ko.xlsx and b/spreadsheet/macrofree/alz_checklist.ko.xlsx differ diff --git a/spreadsheet/macrofree/alz_checklist.pt.xlsx b/spreadsheet/macrofree/alz_checklist.pt.xlsx index d88961e6a..6bf2b3541 100644 Binary files a/spreadsheet/macrofree/alz_checklist.pt.xlsx and b/spreadsheet/macrofree/alz_checklist.pt.xlsx differ diff --git a/spreadsheet/macrofree/checklist.en.master.xlsx b/spreadsheet/macrofree/checklist.en.master.xlsx index eff96dca4..dfb3f4588 100644 Binary files a/spreadsheet/macrofree/checklist.en.master.xlsx and b/spreadsheet/macrofree/checklist.en.master.xlsx differ diff --git a/spreadsheet/macrofree/network_appdelivery_checklist.en.xlsx b/spreadsheet/macrofree/network_appdelivery_checklist.en.xlsx new file mode 100644 index 000000000..0aac3435c Binary files /dev/null and b/spreadsheet/macrofree/network_appdelivery_checklist.en.xlsx differ diff --git a/spreadsheet/macrofree/network_appdelivery_checklist.es.xlsx b/spreadsheet/macrofree/network_appdelivery_checklist.es.xlsx new file mode 100644 index 000000000..e2a034d78 Binary files /dev/null and b/spreadsheet/macrofree/network_appdelivery_checklist.es.xlsx differ diff --git a/spreadsheet/macrofree/network_appdelivery_checklist.ja.xlsx b/spreadsheet/macrofree/network_appdelivery_checklist.ja.xlsx new file mode 100644 index 000000000..6a66c5f07 Binary files /dev/null and b/spreadsheet/macrofree/network_appdelivery_checklist.ja.xlsx differ diff --git a/spreadsheet/macrofree/network_appdelivery_checklist.ko.xlsx b/spreadsheet/macrofree/network_appdelivery_checklist.ko.xlsx new file mode 100644 index 000000000..7d8fd1eb3 Binary files /dev/null and b/spreadsheet/macrofree/network_appdelivery_checklist.ko.xlsx differ diff --git a/spreadsheet/macrofree/network_appdelivery_checklist.pt.xlsx b/spreadsheet/macrofree/network_appdelivery_checklist.pt.xlsx new file mode 100644 index 000000000..39d511443 Binary files /dev/null and b/spreadsheet/macrofree/network_appdelivery_checklist.pt.xlsx differ diff --git a/workbooks/alz_checklist.en_counters_workbook.json b/workbooks/alz_checklist.en_counters_workbook.json index e0c4ad6b5..586398c17 100644 --- a/workbooks/alz_checklist.en_counters_workbook.json +++ b/workbooks/alz_checklist.en_counters_workbook.json @@ -152,7 +152,7 @@ "version": "KqlParameterItem/1.0", "name": "Query3Stats", "type": 1, - "query": "resources | where type == 'microsoft.network/applicationgateways' | project id, compliant = properties.sku.name in ('Standard_v2', 'WAF_v2') | 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/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}" ], @@ -180,7 +180,7 @@ "version": "KqlParameterItem/1.0", "name": "Query4Stats", "type": 1, - "query": "resources | where type == 'microsoft.network/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard')| 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}" ], @@ -208,7 +208,7 @@ "version": "KqlParameterItem/1.0", "name": "Query5Stats", "type": 1, - "query": "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 | project id, subnetId = tostring(subnets.id), subnetPrefixLength = split(subnets.properties.addressPrefix, '/')[1]) on subnetId | 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/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}" ], @@ -236,7 +236,7 @@ "version": "KqlParameterItem/1.0", "name": "Query6Stats", "type": 1, - "query": "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| 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}" ], @@ -264,7 +264,7 @@ "version": "KqlParameterItem/1.0", "name": "Query7Stats", "type": 1, - "query": "resources | where type=='microsoft.network/loadbalancers' | extend countOutRules=array_length(properties.outboundRules) | extend compliant = (countOutRules == 0) | 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}" ], @@ -292,7 +292,7 @@ "version": "KqlParameterItem/1.0", "name": "Query8Stats", "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())", + "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}" ], @@ -320,7 +320,7 @@ "version": "KqlParameterItem/1.0", "name": "Query9Stats", "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())", + "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}" ], @@ -348,7 +348,7 @@ "version": "KqlParameterItem/1.0", "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/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}" ], @@ -376,7 +376,7 @@ "version": "KqlParameterItem/1.0", "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/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}" ], @@ -404,7 +404,7 @@ "version": "KqlParameterItem/1.0", "name": "Query12Stats", "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())", + "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}" ], @@ -432,7 +432,7 @@ "version": "KqlParameterItem/1.0", "name": "Query13Stats", "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())", + "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}" ], @@ -460,7 +460,7 @@ "version": "KqlParameterItem/1.0", "name": "Query14Stats", "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 == '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}" ], @@ -488,7 +488,7 @@ "version": "KqlParameterItem/1.0", "name": "Query15Stats", "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/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}" ], @@ -516,7 +516,7 @@ "version": "KqlParameterItem/1.0", "name": "Query16Stats", "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/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}" ], @@ -544,7 +544,7 @@ "version": "KqlParameterItem/1.0", "name": "Query17Stats", "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())", + "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}" ], @@ -572,7 +572,7 @@ "version": "KqlParameterItem/1.0", "name": "Query18Stats", "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())", + "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}" ], @@ -600,7 +600,7 @@ "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 == '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/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}" ], @@ -628,7 +628,7 @@ "version": "KqlParameterItem/1.0", "name": "Query20Stats", "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/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}" ], @@ -656,7 +656,7 @@ "version": "KqlParameterItem/1.0", "name": "Query21Stats", "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/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}" ], @@ -684,7 +684,7 @@ "version": "KqlParameterItem/1.0", "name": "Query22Stats", "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/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}" ], @@ -712,7 +712,7 @@ "version": "KqlParameterItem/1.0", "name": "Query23Stats", "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/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}" ], @@ -740,7 +740,7 @@ "version": "KqlParameterItem/1.0", "name": "Query24Stats", "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,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}" ], @@ -768,7 +768,7 @@ "version": "KqlParameterItem/1.0", "name": "Query25Stats", "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/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())", "crossComponentResources": [ "{Subscription}" ], @@ -796,7 +796,7 @@ "version": "KqlParameterItem/1.0", "name": "Query26Stats", "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": "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)| 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}" ], @@ -819,146 +819,6 @@ }, "queryType": 8 }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query27Stats", - "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())", - "crossComponentResources": [ - "{Subscription}" - ], - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources" - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query27FullyCompliant", - "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query27Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 8 - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query28Stats", - "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": "Query28FullyCompliant", - "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query28Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 8 - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query29Stats", - "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": "Query29FullyCompliant", - "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query29Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 8 - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query30Stats", - "type": 1, - "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())", - "crossComponentResources": [ - "{Subscription}" - ], - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources" - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query30FullyCompliant", - "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query30Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 8 - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query31Stats", - "type": 1, - "query": "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)| 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": "Query31FullyCompliant", - "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query31Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 8 - }, { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", @@ -973,7 +833,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query3Stats:$.Success}+{Query4Stats:$.Success}+{Query5Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}+{Query9Stats:$.Success}+{Query10Stats:$.Success}+{Query11Stats:$.Success}+{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query16Stats:$.Success}+{Query17Stats:$.Success}+{Query18Stats:$.Success}+{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}+{Query22Stats:$.Success}+{Query23Stats:$.Success}+{Query24Stats:$.Success}+{Query25Stats:$.Success}+{Query26Stats:$.Success}+{Query27Stats:$.Success}+{Query28Stats:$.Success}+{Query29Stats:$.Success}+{Query30Stats:$.Success}" + "resultVal": "{Query3Stats:$.Success}+{Query4Stats:$.Success}+{Query5Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}+{Query9Stats:$.Success}+{Query10Stats:$.Success}+{Query11Stats:$.Success}+{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query16Stats:$.Success}+{Query17Stats:$.Success}+{Query18Stats:$.Success}+{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}+{Query22Stats:$.Success}+{Query23Stats:$.Success}+{Query24Stats:$.Success}+{Query25Stats:$.Success}" } } ] @@ -992,7 +852,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query3Stats:$.Total}+{Query4Stats:$.Total}+{Query5Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}+{Query9Stats:$.Total}+{Query10Stats:$.Total}+{Query11Stats:$.Total}+{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query16Stats:$.Total}+{Query17Stats:$.Total}+{Query18Stats:$.Total}+{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}+{Query22Stats:$.Total}+{Query23Stats:$.Total}+{Query24Stats:$.Total}+{Query25Stats:$.Total}+{Query26Stats:$.Total}+{Query27Stats:$.Total}+{Query28Stats:$.Total}+{Query29Stats:$.Total}+{Query30Stats:$.Total}" + "resultVal": "{Query3Stats:$.Total}+{Query4Stats:$.Total}+{Query5Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}+{Query9Stats:$.Total}+{Query10Stats:$.Total}+{Query11Stats:$.Total}+{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query16Stats:$.Total}+{Query17Stats:$.Total}+{Query18Stats:$.Total}+{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}+{Query22Stats:$.Total}+{Query23Stats:$.Total}+{Query24Stats:$.Total}+{Query25Stats:$.Total}" } } ] @@ -1030,7 +890,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query31Stats:$.Success}" + "resultVal": "{Query26Stats:$.Success}" } } ] @@ -1049,7 +909,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query31Stats:$.Total}" + "resultVal": "{Query26Stats:$.Total}" } } ] @@ -1144,7 +1004,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query3Stats:$.Total}+{Query4Stats:$.Total}+{Query5Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}+{Query9Stats:$.Total}+{Query10Stats:$.Total}+{Query11Stats:$.Total}+{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query16Stats:$.Total}+{Query17Stats:$.Total}+{Query18Stats:$.Total}+{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}+{Query22Stats:$.Total}+{Query23Stats:$.Total}+{Query24Stats:$.Total}+{Query25Stats:$.Total}+{Query26Stats:$.Total}+{Query27Stats:$.Total}+{Query28Stats:$.Total}+{Query29Stats:$.Total}+{Query30Stats:$.Total}+{Query31Stats:$.Total}+{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}" + "resultVal": "{Query3Stats:$.Total}+{Query4Stats:$.Total}+{Query5Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}+{Query9Stats:$.Total}+{Query10Stats:$.Total}+{Query11Stats:$.Total}+{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query16Stats:$.Total}+{Query17Stats:$.Total}+{Query18Stats:$.Total}+{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}+{Query22Stats:$.Total}+{Query23Stats:$.Total}+{Query24Stats:$.Total}+{Query25Stats:$.Total}+{Query26Stats:$.Total}+{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}" } } ] @@ -1163,7 +1023,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query3Stats:$.Success}+{Query4Stats:$.Success}+{Query5Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}+{Query9Stats:$.Success}+{Query10Stats:$.Success}+{Query11Stats:$.Success}+{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query16Stats:$.Success}+{Query17Stats:$.Success}+{Query18Stats:$.Success}+{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}+{Query22Stats:$.Success}+{Query23Stats:$.Success}+{Query24Stats:$.Success}+{Query25Stats:$.Success}+{Query26Stats:$.Success}+{Query27Stats:$.Success}+{Query28Stats:$.Success}+{Query29Stats:$.Success}+{Query30Stats:$.Success}+{Query31Stats:$.Success}+{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}" + "resultVal": "{Query3Stats:$.Success}+{Query4Stats:$.Success}+{Query5Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}+{Query9Stats:$.Success}+{Query10Stats:$.Success}+{Query11Stats:$.Success}+{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query16Stats:$.Success}+{Query17Stats:$.Success}+{Query18Stats:$.Success}+{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}+{Query22Stats:$.Success}+{Query23Stats:$.Success}+{Query24Stats:$.Success}+{Query25Stats:$.Success}+{Query26Stats:$.Success}+{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}" } } ] @@ -1237,7 +1097,7 @@ "style": "tabs", "links": [ { - "id": "d3f80a33-d623-4861-8245-de3d80c6352c", + "id": "87e8891d-3a58-4a0b-a374-b5f65799eaef", "cellValue": "VisibleTab", "linkTarget": "parameter", "linkLabel": "Network Topology and Connectivity ({Tab0Success:value}/{Tab0Total:value})", @@ -1246,7 +1106,7 @@ "style": "primary" }, { - "id": "87279a04-2a5f-4a5c-900e-68ab3d835628", + "id": "718abedf-47df-4514-981d-dfbf99522df3", "cellValue": "VisibleTab", "linkTarget": "parameter", "linkLabel": "Security ({Tab1Success:value}/{Tab1Total:value})", @@ -1255,7 +1115,7 @@ "style": "primary" }, { - "id": "cb4b1867-afed-488f-8301-a94ebf959e6c", + "id": "6c1d5831-929b-4559-b62c-f9edd5a8314a", "cellValue": "VisibleTab", "linkTarget": "parameter", "linkLabel": "Resource Organization ({Tab2Success:value}/{Tab2Total:value})", @@ -1283,7 +1143,7 @@ { "type": 1, "content": { - "json": "Ensure you are using Application Gateway v2 SKU. Check [this link](https://learn.microsoft.com/azure/application-gateway/overview-v2) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) 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": "querytext3" }, @@ -1291,7 +1151,7 @@ "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/applicationgateways' | project id, compliant = properties.sku.name in ('Standard_v2', 'WAF_v2') | 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 == 'RouteServerSubnet' | 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", @@ -1345,7 +1205,7 @@ { "type": 1, "content": { - "json": "Ensure you are using the Standard SKU for your Azure Load Balancers. Check [this link](https://learn.microsoft.com/azure/load-balancer/load-balancer-overview) 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": "querytext4" }, @@ -1353,7 +1213,7 @@ "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard') | 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": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1407,7 +1267,7 @@ { "type": 1, "content": { - "json": "Your application gateways should be deployed in subnets with IP prefixes equal or larger than /26. Check [this link](https://learn.microsoft.com/azure/application-gateway/configuration-infrastructure#size-of-the-subnet) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this." + "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": "querytext5" }, @@ -1415,7 +1275,7 @@ "type": 3, "content": { "version": "KqlItem/1.0", - "query": "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 | project id, subnetId = tostring(subnets.id), subnetPrefixLength = split(subnets.properties.addressPrefix, '/')[1]) on subnetId | 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/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": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1469,7 +1329,7 @@ { "type": 1, "content": { - "json": "Deploy your WAF profiles for Front Door in 'Prevention' mode. Check [this link](https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-policy-settings) 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": "querytext6" }, @@ -1477,7 +1337,7 @@ "type": 3, "content": { "version": "KqlItem/1.0", - "query": "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 | 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": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1531,7 +1391,7 @@ { "type": 1, "content": { - "json": "Use Azure NAT Gateway instead of Load Balancer outbound rules for better SNAT scalability. Check [this link](https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity) 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": "querytext7" }, @@ -1539,7 +1399,7 @@ "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/loadbalancers' | extend countOutRules=array_length(properties.outboundRules) | extend compliant = (countOutRules == 0) | 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", @@ -1593,7 +1453,7 @@ { "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": "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": "querytext8" }, @@ -1601,7 +1461,7 @@ "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/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", @@ -1655,7 +1515,7 @@ { "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": "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": "querytext9" }, @@ -1663,7 +1523,7 @@ "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/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", @@ -1717,7 +1577,7 @@ { "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": "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": "querytext10" }, @@ -1725,7 +1585,7 @@ "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/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", @@ -1779,7 +1639,7 @@ { "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 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": "querytext11" }, @@ -1787,7 +1647,7 @@ "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/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", @@ -1841,7 +1701,7 @@ { "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 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": "querytext12" }, @@ -1849,7 +1709,7 @@ "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' | 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": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1903,7 +1763,7 @@ { "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": "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": "querytext13" }, @@ -1911,7 +1771,7 @@ "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' | 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": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1965,7 +1825,7 @@ { "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": "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": "querytext14" }, @@ -1973,7 +1833,7 @@ "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/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", @@ -2027,7 +1887,7 @@ { "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 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": "querytext15" }, @@ -2035,7 +1895,7 @@ "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.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", @@ -2089,7 +1949,7 @@ { "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": "Use Azure Firewall Premium for additional security and protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information." }, "name": "querytext16" }, @@ -2097,7 +1957,7 @@ "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/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", @@ -2151,7 +2011,7 @@ { "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 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": "querytext17" }, @@ -2159,7 +2019,7 @@ "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.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", @@ -2213,7 +2073,7 @@ { "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": "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": "querytext18" }, @@ -2221,7 +2081,7 @@ "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/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", @@ -2275,7 +2135,7 @@ { "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 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": "querytext19" }, @@ -2283,7 +2143,7 @@ "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,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", @@ -2337,7 +2197,7 @@ { "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 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": "querytext20" }, @@ -2345,7 +2205,7 @@ "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,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", @@ -2399,7 +2259,7 @@ { "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": "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": "querytext21" }, @@ -2407,7 +2267,7 @@ "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,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", @@ -2461,7 +2321,7 @@ { "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": "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": "querytext22" }, @@ -2469,7 +2329,7 @@ "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/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", @@ -2523,7 +2383,7 @@ { "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": "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": "querytext23" }, @@ -2531,7 +2391,7 @@ "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/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", @@ -2585,7 +2445,7 @@ { "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": "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": "querytext24" }, @@ -2593,7 +2453,7 @@ "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,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", @@ -2647,7 +2507,7 @@ { "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": "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": "querytext25" }, @@ -2655,7 +2515,7 @@ "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/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", @@ -2705,316 +2565,6 @@ } }, "name": "query25" - }, - { - "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." - }, - "name": "querytext26" - }, - { - "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", - "size": 0, - "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": "query26" - }, - { - "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": "querytext27" - }, - { - "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": 0, - "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": "query27" - }, - { - "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": "querytext28" - }, - { - "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": 0, - "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": "query28" - }, - { - "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": "querytext29" - }, - { - "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": 0, - "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": "query29" - }, - { - "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." - }, - "name": "querytext30" - }, - { - "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", - "size": 0, - "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": "query30" } ] }, @@ -3043,7 +2593,7 @@ "content": { "json": "Use different Azure Key Vaults for different applications and regions to avoid transaction scale limits and restrict access to secrets. Check [this link](https://learn.microsoft.com/azure/key-vault/general/overview-throttling) for further information." }, - "name": "querytext31" + "name": "querytext26" }, { "type": 3, @@ -3098,7 +2648,7 @@ ] } }, - "name": "query31" + "name": "query26" } ] }, diff --git a/workbooks/alz_checklist.en_counters_workbook_template.json b/workbooks/alz_checklist.en_counters_workbook_template.json index 97ed8a717..da62535a7 100644 --- a/workbooks/alz_checklist.en_counters_workbook_template.json +++ b/workbooks/alz_checklist.en_counters_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\": 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\": \"resourcecontainers| where type == 'microsoft.resources/subscriptions'| extend ManagementGroup = tostring(tags),mgmtChain = properties.managementGroupAncestorsChain| extend compliant =( array_length(mgmtChain) <= 4 and array_length(mgmtChain) > 1)| 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\": \"resourcecontainers| where type == 'microsoft.resources/subscriptions'| extend ManagementGroup = tostring(tags),mgmtChain = properties.managementGroupAncestorsChain| extend compliant = (array_length(mgmtChain) > 1)| 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 | extend compliant = isnotnull(['tags']) | project name, id, subscriptionId, resourceGroup, tags, 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/applicationgateways' | project id, compliant = properties.sku.name in ('Standard_v2', 'WAF_v2') | 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\": \"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/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard')| 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/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 | project id, subnetId = tostring(subnets.id), subnetPrefixLength = split(subnets.properties.addressPrefix, '/')[1]) on subnetId | 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\": \"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/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| 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/loadbalancers' | extend countOutRules=array_length(properties.outboundRules) | extend compliant = (countOutRules == 0) | 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\": \"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/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\": \"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' | 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\": \"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/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\": \"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' | 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\": \"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/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\": \"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/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\": \"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/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\": \"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/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\": \"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/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\": \"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' | 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\": \"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' | 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\": \"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 == '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\": \"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/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\": \"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/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\": \"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/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\": \"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/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\": \"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\": \"Query24Stats\",\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\": \"Query24FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query24Stats:$.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\": \"Query25Stats\",\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\": \"Query25FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query25Stats:$.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\": \"Query26Stats\",\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\": \"Query26FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query26Stats:$.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\": \"Query27Stats\",\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\": \"Query27FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query27Stats:$.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\": \"Query28Stats\",\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\": \"Query28FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query28Stats:$.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\": \"Query29Stats\",\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\": \"Query29FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query29Stats:$.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\": \"Query30Stats\",\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\": \"Query30FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query30Stats:$.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\": \"Query31Stats\",\n \"type\": 1,\n \"query\": \"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)| 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\": \"Query31FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query31Stats:$.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\": \"{Query3Stats:$.Success}+{Query4Stats:$.Success}+{Query5Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}+{Query9Stats:$.Success}+{Query10Stats:$.Success}+{Query11Stats:$.Success}+{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query16Stats:$.Success}+{Query17Stats:$.Success}+{Query18Stats:$.Success}+{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}+{Query22Stats:$.Success}+{Query23Stats:$.Success}+{Query24Stats:$.Success}+{Query25Stats:$.Success}+{Query26Stats:$.Success}+{Query27Stats:$.Success}+{Query28Stats:$.Success}+{Query29Stats:$.Success}+{Query30Stats:$.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\": \"{Query3Stats:$.Total}+{Query4Stats:$.Total}+{Query5Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}+{Query9Stats:$.Total}+{Query10Stats:$.Total}+{Query11Stats:$.Total}+{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query16Stats:$.Total}+{Query17Stats:$.Total}+{Query18Stats:$.Total}+{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}+{Query22Stats:$.Total}+{Query23Stats:$.Total}+{Query24Stats:$.Total}+{Query25Stats:$.Total}+{Query26Stats:$.Total}+{Query27Stats:$.Total}+{Query28Stats:$.Total}+{Query29Stats:$.Total}+{Query30Stats:$.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\": \"{Query31Stats:$.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\": \"{Query31Stats:$.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}\"\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}\"\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\": \"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\": \"{Query3Stats:$.Total}+{Query4Stats:$.Total}+{Query5Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}+{Query9Stats:$.Total}+{Query10Stats:$.Total}+{Query11Stats:$.Total}+{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query16Stats:$.Total}+{Query17Stats:$.Total}+{Query18Stats:$.Total}+{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}+{Query22Stats:$.Total}+{Query23Stats:$.Total}+{Query24Stats:$.Total}+{Query25Stats:$.Total}+{Query26Stats:$.Total}+{Query27Stats:$.Total}+{Query28Stats:$.Total}+{Query29Stats:$.Total}+{Query30Stats:$.Total}+{Query31Stats:$.Total}+{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.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\": \"{Query3Stats:$.Success}+{Query4Stats:$.Success}+{Query5Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}+{Query9Stats:$.Success}+{Query10Stats:$.Success}+{Query11Stats:$.Success}+{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query16Stats:$.Success}+{Query17Stats:$.Success}+{Query18Stats:$.Success}+{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}+{Query22Stats:$.Success}+{Query23Stats:$.Success}+{Query24Stats:$.Success}+{Query25Stats:$.Success}+{Query26Stats:$.Success}+{Query27Stats:$.Success}+{Query28Stats:$.Success}+{Query29Stats:$.Success}+{Query30Stats:$.Success}+{Query31Stats:$.Success}+{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.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\\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\": \"d3f80a33-d623-4861-8245-de3d80c6352c\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Network Topology and Connectivity ({Tab0Success:value}/{Tab0Total:value})\",\n \"subTarget\": \"tab0\",\n \"preText\": \"Network Topology and Connectivity\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"87279a04-2a5f-4a5c-900e-68ab3d835628\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Security ({Tab1Success:value}/{Tab1Total:value})\",\n \"subTarget\": \"tab1\",\n \"preText\": \"Security\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"cb4b1867-afed-488f-8301-a94ebf959e6c\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Resource Organization ({Tab2Success:value}/{Tab2Total:value})\",\n \"subTarget\": \"tab2\",\n \"preText\": \"Resource Organization\",\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\": \"## Network Topology and Connectivity\"\n },\n \"name\": \"tab0title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure you are using Application Gateway v2 SKU. Check [this link](https://learn.microsoft.com/azure/application-gateway/overview-v2) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext3\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/applicationgateways' | project id, compliant = properties.sku.name in ('Standard_v2', 'WAF_v2') | 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\": \"query3\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure you are using the Standard SKU for your Azure Load Balancers. Check [this link](https://learn.microsoft.com/azure/load-balancer/load-balancer-overview) for further information.\"\n },\n \"name\": \"querytext4\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard') | 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\": \"Your application gateways should be deployed in subnets with IP prefixes equal or larger than /26. Check [this link](https://learn.microsoft.com/azure/application-gateway/configuration-infrastructure#size-of-the-subnet) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext5\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"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 | project id, subnetId = tostring(subnets.id), subnetPrefixLength = split(subnets.properties.addressPrefix, '/')[1]) on subnetId | 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\": \"query5\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Deploy your WAF profiles for Front Door in 'Prevention' mode. Check [this link](https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-policy-settings) 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/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 | 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\": \"Use Azure NAT Gateway instead of Load Balancer outbound rules for better SNAT scalability. Check [this link](https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity) for further information.\"\n },\n \"name\": \"querytext7\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/loadbalancers' | extend countOutRules=array_length(properties.outboundRules) | extend compliant = (countOutRules == 0) | 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\": \"query7\"\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\": \"querytext8\"\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\": \"query8\"\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\": \"querytext9\"\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\": \"query9\"\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\": \"querytext10\"\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\": \"query10\"\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\": \"querytext11\"\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\": \"query11\"\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\": \"querytext12\"\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\": \"query12\"\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\": \"querytext13\"\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\": \"query13\"\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\": \"querytext14\"\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\": \"query14\"\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\": \"querytext15\"\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\": \"query15\"\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\": \"querytext16\"\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\": \"query16\"\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\": \"querytext17\"\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\": \"query17\"\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\": \"querytext18\"\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\": \"query18\"\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\": \"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 == '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\": \"query19\"\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\": \"querytext20\"\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\": \"query20\"\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\": \"querytext21\"\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\": \"query21\"\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\": \"querytext22\"\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\": \"query22\"\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\": \"querytext23\"\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\": \"query23\"\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\": \"querytext24\"\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\": \"query24\"\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\": \"querytext25\"\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\": \"query25\"\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\": \"querytext26\"\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\": \"query26\"\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\": \"querytext27\"\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\": \"query27\"\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\": \"querytext28\"\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\": \"query28\"\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\": \"querytext29\"\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\": \"query29\"\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\": \"querytext30\"\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\": \"query30\"\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\": \"## Security\"\n },\n \"name\": \"tab1title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use different Azure Key Vaults for different applications and regions to avoid transaction scale limits and restrict access to secrets. Check [this link](https://learn.microsoft.com/azure/key-vault/general/overview-throttling) for further information.\"\n },\n \"name\": \"querytext31\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"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) | 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\": \"query31\"\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\": \"## Resource Organization\"\n },\n \"name\": \"tab2title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Enforce reasonably flat management group hierarchy with no more than four levels. Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/resource-org-management-groups) for further information.. [This training](https://learn.microsoft.com/learn/modules/azure-architecture-fundamentals/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext0\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resourcecontainers| where type == 'microsoft.resources/subscriptions'| extend ManagementGroup = tostring(tags),mgmtChain = properties.managementGroupAncestorsChain| extend compliant =( array_length(mgmtChain) <= 4 and array_length(mgmtChain) > 1) | 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\": \"Enforce no subscriptions are placed under the root management group. Check [this link](https://learn.microsoft.com/azure/governance/management-groups/how-to/protect-resource-hierarchy#setting---default-management-group) for further information.\"\n },\n \"name\": \"querytext1\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resourcecontainers| where type == 'microsoft.resources/subscriptions'| extend ManagementGroup = tostring(tags),mgmtChain = properties.managementGroupAncestorsChain| extend compliant = (array_length(mgmtChain) > 1) | 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\": \"Ensure tags are used for billing and cost management. Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/track-costs) for further information.. [This training](https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext2\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | extend compliant = isnotnull(['tags']) | project name, id, subscriptionId, resourceGroup, tags, 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 },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab2\"\n },\n \"name\": \"tab2\"\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\": \"resourcecontainers| where type == 'microsoft.resources/subscriptions'| extend ManagementGroup = tostring(tags),mgmtChain = properties.managementGroupAncestorsChain| extend compliant =( array_length(mgmtChain) <= 4 and array_length(mgmtChain) > 1)| 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\": \"resourcecontainers| where type == 'microsoft.resources/subscriptions'| extend ManagementGroup = tostring(tags),mgmtChain = properties.managementGroupAncestorsChain| extend compliant = (array_length(mgmtChain) > 1)| 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 | extend compliant = isnotnull(['tags']) | project name, id, subscriptionId, resourceGroup, tags, 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' | 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\": \"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/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\": \"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/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\": \"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/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\": \"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 !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\": \"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/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\": \"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/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\": \"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/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\": \"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/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\": \"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' | 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\": \"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/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\": \"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/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\": \"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.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\": \"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.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\": \"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/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\": \"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/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\": \"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,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\": \"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,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\": \"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/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\": \"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,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\": \"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/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\": \"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\": \"Query24Stats\",\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\": \"Query24FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query24Stats:$.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\": \"Query25Stats\",\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\": \"Query25FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query25Stats:$.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\": \"Query26Stats\",\n \"type\": 1,\n \"query\": \"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)| 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\": \"Query26FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query26Stats:$.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\": \"{Query3Stats:$.Success}+{Query4Stats:$.Success}+{Query5Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}+{Query9Stats:$.Success}+{Query10Stats:$.Success}+{Query11Stats:$.Success}+{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query16Stats:$.Success}+{Query17Stats:$.Success}+{Query18Stats:$.Success}+{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}+{Query22Stats:$.Success}+{Query23Stats:$.Success}+{Query24Stats:$.Success}+{Query25Stats:$.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\": \"{Query3Stats:$.Total}+{Query4Stats:$.Total}+{Query5Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}+{Query9Stats:$.Total}+{Query10Stats:$.Total}+{Query11Stats:$.Total}+{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query16Stats:$.Total}+{Query17Stats:$.Total}+{Query18Stats:$.Total}+{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}+{Query22Stats:$.Total}+{Query23Stats:$.Total}+{Query24Stats:$.Total}+{Query25Stats:$.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\": \"{Query26Stats:$.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\": \"{Query26Stats:$.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}\"\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}\"\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\": \"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\": \"{Query3Stats:$.Total}+{Query4Stats:$.Total}+{Query5Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}+{Query9Stats:$.Total}+{Query10Stats:$.Total}+{Query11Stats:$.Total}+{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query16Stats:$.Total}+{Query17Stats:$.Total}+{Query18Stats:$.Total}+{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}+{Query22Stats:$.Total}+{Query23Stats:$.Total}+{Query24Stats:$.Total}+{Query25Stats:$.Total}+{Query26Stats:$.Total}+{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.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\": \"{Query3Stats:$.Success}+{Query4Stats:$.Success}+{Query5Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}+{Query9Stats:$.Success}+{Query10Stats:$.Success}+{Query11Stats:$.Success}+{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query16Stats:$.Success}+{Query17Stats:$.Success}+{Query18Stats:$.Success}+{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}+{Query22Stats:$.Success}+{Query23Stats:$.Success}+{Query24Stats:$.Success}+{Query25Stats:$.Success}+{Query26Stats:$.Success}+{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.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\\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\": \"87e8891d-3a58-4a0b-a374-b5f65799eaef\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Network Topology and Connectivity ({Tab0Success:value}/{Tab0Total:value})\",\n \"subTarget\": \"tab0\",\n \"preText\": \"Network Topology and Connectivity\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"718abedf-47df-4514-981d-dfbf99522df3\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Security ({Tab1Success:value}/{Tab1Total:value})\",\n \"subTarget\": \"tab1\",\n \"preText\": \"Security\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"6c1d5831-929b-4559-b62c-f9edd5a8314a\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Resource Organization ({Tab2Success:value}/{Tab2Total:value})\",\n \"subTarget\": \"tab2\",\n \"preText\": \"Resource Organization\",\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\": \"## Network Topology and Connectivity\"\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\": \"querytext3\"\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\": \"query3\"\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\": \"querytext4\"\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\": \"query4\"\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\": \"querytext5\"\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\": \"query5\"\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\": \"querytext6\"\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\": \"query6\"\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\": \"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 !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\": \"query7\"\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\": \"querytext8\"\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\": \"query8\"\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\": \"querytext9\"\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\": \"query9\"\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\": \"querytext10\"\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\": \"query10\"\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\": \"querytext11\"\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\": \"query11\"\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\": \"querytext12\"\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\": \"query12\"\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\": \"querytext13\"\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\": \"query13\"\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\": \"querytext14\"\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\": \"query14\"\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\": \"querytext15\"\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\": \"query15\"\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\": \"querytext16\"\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\": \"query16\"\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\": \"querytext17\"\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\": \"query17\"\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\": \"querytext18\"\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\": \"query18\"\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\": \"querytext19\"\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\": \"query19\"\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\": \"querytext20\"\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\": \"query20\"\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\": \"querytext21\"\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\": \"query21\"\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\": \"querytext22\"\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\": \"query22\"\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\": \"querytext23\"\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\": \"query23\"\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\": \"querytext24\"\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\": \"query24\"\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\": \"querytext25\"\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\": \"query25\"\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\": \"## Security\"\n },\n \"name\": \"tab1title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use different Azure Key Vaults for different applications and regions to avoid transaction scale limits and restrict access to secrets. Check [this link](https://learn.microsoft.com/azure/key-vault/general/overview-throttling) for further information.\"\n },\n \"name\": \"querytext26\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"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) | 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\": \"query26\"\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\": \"## Resource Organization\"\n },\n \"name\": \"tab2title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Enforce reasonably flat management group hierarchy with no more than four levels. Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/resource-org-management-groups) for further information.. [This training](https://learn.microsoft.com/learn/modules/azure-architecture-fundamentals/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext0\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resourcecontainers| where type == 'microsoft.resources/subscriptions'| extend ManagementGroup = tostring(tags),mgmtChain = properties.managementGroupAncestorsChain| extend compliant =( array_length(mgmtChain) <= 4 and array_length(mgmtChain) > 1) | 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\": \"Enforce no subscriptions are placed under the root management group. Check [this link](https://learn.microsoft.com/azure/governance/management-groups/how-to/protect-resource-hierarchy#setting---default-management-group) for further information.\"\n },\n \"name\": \"querytext1\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resourcecontainers| where type == 'microsoft.resources/subscriptions'| extend ManagementGroup = tostring(tags),mgmtChain = properties.managementGroupAncestorsChain| extend compliant = (array_length(mgmtChain) > 1) | 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\": \"Ensure tags are used for billing and cost management. Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/track-costs) for further information.. [This training](https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext2\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | extend compliant = isnotnull(['tags']) | project name, id, subscriptionId, resourceGroup, tags, 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 },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab2\"\n },\n \"name\": \"tab2\"\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_counters.json b/workbooks/alz_checklist.en_network_counters.json index fc282eead..bd06ebae3 100644 --- a/workbooks/alz_checklist.en_network_counters.json +++ b/workbooks/alz_checklist.en_network_counters.json @@ -68,7 +68,7 @@ "version": "KqlParameterItem/1.0", "name": "Query0Stats", "type": 1, - "query": "resources | where type == 'microsoft.network/applicationgateways' | project id, compliant = properties.sku.name in ('Standard_v2', 'WAF_v2') | 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/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}" ], @@ -96,7 +96,7 @@ "version": "KqlParameterItem/1.0", "name": "Query1Stats", "type": 1, - "query": "resources | where type == 'microsoft.network/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard')| 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}" ], @@ -124,7 +124,7 @@ "version": "KqlParameterItem/1.0", "name": "Query2Stats", "type": 1, - "query": "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 | project id, subnetId = tostring(subnets.id), subnetPrefixLength = split(subnets.properties.addressPrefix, '/')[1]) on subnetId | 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/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}" ], @@ -152,7 +152,7 @@ "version": "KqlParameterItem/1.0", "name": "Query3Stats", "type": 1, - "query": "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| 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}" ], @@ -180,7 +180,7 @@ "version": "KqlParameterItem/1.0", "name": "Query4Stats", "type": 1, - "query": "resources | where type=='microsoft.network/loadbalancers' | extend countOutRules=array_length(properties.outboundRules) | extend compliant = (countOutRules == 0) | 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}" ], @@ -208,7 +208,7 @@ "version": "KqlParameterItem/1.0", "name": "Query5Stats", "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())", + "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}" ], @@ -236,7 +236,7 @@ "version": "KqlParameterItem/1.0", "name": "Query6Stats", "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())", + "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}" ], @@ -264,7 +264,7 @@ "version": "KqlParameterItem/1.0", "name": "Query7Stats", "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/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}" ], @@ -292,7 +292,7 @@ "version": "KqlParameterItem/1.0", "name": "Query8Stats", "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/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}" ], @@ -320,7 +320,7 @@ "version": "KqlParameterItem/1.0", "name": "Query9Stats", "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())", + "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}" ], @@ -348,7 +348,7 @@ "version": "KqlParameterItem/1.0", "name": "Query10Stats", "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())", + "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}" ], @@ -376,7 +376,7 @@ "version": "KqlParameterItem/1.0", "name": "Query11Stats", "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 == '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}" ], @@ -404,7 +404,7 @@ "version": "KqlParameterItem/1.0", "name": "Query12Stats", "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/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}" ], @@ -432,7 +432,7 @@ "version": "KqlParameterItem/1.0", "name": "Query13Stats", "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/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}" ], @@ -460,7 +460,7 @@ "version": "KqlParameterItem/1.0", "name": "Query14Stats", "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())", + "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}" ], @@ -488,7 +488,7 @@ "version": "KqlParameterItem/1.0", "name": "Query15Stats", "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())", + "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}" ], @@ -516,7 +516,7 @@ "version": "KqlParameterItem/1.0", "name": "Query16Stats", "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/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}" ], @@ -544,7 +544,7 @@ "version": "KqlParameterItem/1.0", "name": "Query17Stats", "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/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}" ], @@ -572,7 +572,7 @@ "version": "KqlParameterItem/1.0", "name": "Query18Stats", "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/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}" ], @@ -600,7 +600,7 @@ "version": "KqlParameterItem/1.0", "name": "Query19Stats", "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/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}" ], @@ -628,7 +628,7 @@ "version": "KqlParameterItem/1.0", "name": "Query20Stats", "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/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}" ], @@ -656,7 +656,7 @@ "version": "KqlParameterItem/1.0", "name": "Query21Stats", "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,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}" ], @@ -684,7 +684,7 @@ "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 = 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/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())", "crossComponentResources": [ "{Subscription}" ], @@ -707,146 +707,6 @@ }, "queryType": 8 }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query23Stats", - "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 - }, - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources" - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query23FullyCompliant", - "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query23Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 8 - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query24Stats", - "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())", - "crossComponentResources": [ - "{Subscription}" - ], - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources" - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query24FullyCompliant", - "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query24Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 8 - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query25Stats", - "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": "Query25FullyCompliant", - "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query25Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 8 - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query26Stats", - "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": "Query26FullyCompliant", - "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query26Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 8 - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query27Stats", - "type": 1, - "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())", - "crossComponentResources": [ - "{Subscription}" - ], - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources" - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query27FullyCompliant", - "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query27Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 8 - }, { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", @@ -861,7 +721,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query16Stats:$.Success}+{Query17Stats:$.Success}+{Query18Stats:$.Success}+{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}" + "resultVal": "{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}" } } ] @@ -880,7 +740,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query16Stats:$.Total}+{Query17Stats:$.Total}+{Query18Stats:$.Total}+{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}" + "resultVal": "{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}" } } ] @@ -918,7 +778,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query27Stats:$.Success}" + "resultVal": "{Query9Stats:$.Success}+{Query10Stats:$.Success}" } } ] @@ -937,7 +797,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query27Stats:$.Total}" + "resultVal": "{Query9Stats:$.Total}+{Query10Stats:$.Total}" } } ] @@ -975,7 +835,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query9Stats:$.Success}+{Query10Stats:$.Success}+{Query11Stats:$.Success}+{Query12Stats:$.Success}+{Query13Stats:$.Success}" + "resultVal": "{Query22Stats:$.Success}" } } ] @@ -994,7 +854,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query9Stats:$.Total}+{Query10Stats:$.Total}+{Query11Stats:$.Total}+{Query12Stats:$.Total}+{Query13Stats:$.Total}" + "resultVal": "{Query22Stats:$.Total}" } } ] @@ -1032,7 +892,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query22Stats:$.Success}" + "resultVal": "{Query18Stats:$.Success}+{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}" } } ] @@ -1051,7 +911,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query22Stats:$.Total}" + "resultVal": "{Query18Stats:$.Total}+{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}" } } ] @@ -1089,7 +949,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query23Stats:$.Success}+{Query24Stats:$.Success}+{Query25Stats:$.Success}+{Query26Stats:$.Success}" + "resultVal": "{Query4Stats:$.Success}+{Query5Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}" } } ] @@ -1108,7 +968,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query23Stats:$.Total}+{Query24Stats:$.Total}+{Query25Stats:$.Total}+{Query26Stats:$.Total}" + "resultVal": "{Query4Stats:$.Total}+{Query5Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}" } } ] @@ -1146,7 +1006,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}+{Query4Stats:$.Success}" + "resultVal": "{Query11Stats:$.Success}+{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query16Stats:$.Success}" } } ] @@ -1165,7 +1025,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}+{Query4Stats:$.Total}" + "resultVal": "{Query11Stats:$.Total}+{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query16Stats:$.Total}" } } ] @@ -1203,7 +1063,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query14Stats:$.Success}+{Query15Stats:$.Success}" + "resultVal": "{Query17Stats:$.Success}" } } ] @@ -1222,7 +1082,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query14Stats:$.Total}+{Query15Stats:$.Total}" + "resultVal": "{Query17Stats:$.Total}" } } ] @@ -1246,63 +1106,6 @@ } ] }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Tab7Success", - "type": 1, - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "criteriaData": [ - { - "criteriaContext": { - "operator": "Default", - "resultValType": "expression", - "resultVal": "{Query5Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}" - } - } - ] - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Tab7Total", - "type": 1, - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "criteriaData": [ - { - "criteriaContext": { - "operator": "Default", - "resultValType": "expression", - "resultVal": "{Query5Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}" - } - } - ] - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Tab7Percent", - "type": 1, - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "criteriaData": [ - { - "criteriaContext": { - "operator": "Default", - "resultValType": "expression", - "resultVal": "round(100*{Tab7Success}/{Tab7Total})" - } - } - ] - }, { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", @@ -1317,7 +1120,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query16Stats:$.Total}+{Query17Stats:$.Total}+{Query18Stats:$.Total}+{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}+{Query27Stats:$.Total}+{Query9Stats:$.Total}+{Query10Stats:$.Total}+{Query11Stats:$.Total}+{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query22Stats:$.Total}+{Query23Stats:$.Total}+{Query24Stats:$.Total}+{Query25Stats:$.Total}+{Query26Stats:$.Total}+{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}+{Query4Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query5Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}" + "resultVal": "{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}+{Query9Stats:$.Total}+{Query10Stats:$.Total}+{Query22Stats:$.Total}+{Query18Stats:$.Total}+{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}+{Query4Stats:$.Total}+{Query5Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}+{Query11Stats:$.Total}+{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query16Stats:$.Total}+{Query17Stats:$.Total}" } } ] @@ -1336,7 +1139,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query16Stats:$.Success}+{Query17Stats:$.Success}+{Query18Stats:$.Success}+{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}+{Query27Stats:$.Success}+{Query9Stats:$.Success}+{Query10Stats:$.Success}+{Query11Stats:$.Success}+{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query22Stats:$.Success}+{Query23Stats:$.Success}+{Query24Stats:$.Success}+{Query25Stats:$.Success}+{Query26Stats:$.Success}+{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}+{Query4Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query5Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}" + "resultVal": "{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}+{Query9Stats:$.Success}+{Query10Stats:$.Success}+{Query22Stats:$.Success}+{Query18Stats:$.Success}+{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}+{Query4Stats:$.Success}+{Query5Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}+{Query11Stats:$.Success}+{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query16Stats:$.Success}+{Query17Stats:$.Success}" } } ] @@ -1410,75 +1213,66 @@ "style": "tabs", "links": [ { - "id": "8d60b129-67a0-4558-b6c3-52125fbd0617", + "id": "94d19852-737f-4f07-97a2-8a913f090208", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Internet ({Tab0Success:value}/{Tab0Total:value})", + "linkLabel": "Hub and spoke ({Tab0Success:value}/{Tab0Total:value})", "subTarget": "tab0", - "preText": "Internet", + "preText": "Hub and spoke", "style": "primary" }, { - "id": "e865c54b-3907-4a23-b779-240f4cc0a583", + "id": "aa648a6e-ba53-48e9-bab8-a9b69e3938b1", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Virtual WAN ({Tab1Success:value}/{Tab1Total:value})", + "linkLabel": "IP plan ({Tab1Success:value}/{Tab1Total:value})", "subTarget": "tab1", - "preText": "Virtual WAN", + "preText": "IP plan", "style": "primary" }, { - "id": "01384aa5-f752-4f51-bf96-c5f9dae3ea99", + "id": "f22ad8ce-c4ab-4007-8efa-6725392b042c", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Hybrid ({Tab2Success:value}/{Tab2Total:value})", + "linkLabel": "Virtual WAN ({Tab2Success:value}/{Tab2Total:value})", "subTarget": "tab2", - "preText": "Hybrid", + "preText": "Virtual WAN", "style": "primary" }, { - "id": "a5489911-e231-4f26-b8d1-ee45618762c6", + "id": "8cd4f649-6e4d-4725-bf62-5eede2c458e1", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "PaaS ({Tab3Success:value}/{Tab3Total:value})", + "linkLabel": "Segmentation ({Tab3Success:value}/{Tab3Total:value})", "subTarget": "tab3", - "preText": "PaaS", + "preText": "Segmentation", "style": "primary" }, { - "id": "5461481a-6e46-4730-b105-71971fd4842b", + "id": "16f80b07-a3a3-462b-8f85-2e2c3666ce91", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Segmentation ({Tab4Success:value}/{Tab4Total:value})", + "linkLabel": "Hybrid ({Tab4Success:value}/{Tab4Total:value})", "subTarget": "tab4", - "preText": "Segmentation", + "preText": "Hybrid", "style": "primary" }, { - "id": "1276fa72-2660-49bb-b1bb-83b5fc392df5", + "id": "0c8faa13-cf82-43ab-9193-982acd0ef3c0", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "App delivery ({Tab5Success:value}/{Tab5Total:value})", + "linkLabel": "Internet ({Tab5Success:value}/{Tab5Total:value})", "subTarget": "tab5", - "preText": "App delivery", + "preText": "Internet", "style": "primary" }, { - "id": "2a7d66c0-9b24-418e-b3af-80bb85451ccb", + "id": "d873a0bb-76f6-4bf5-ad06-c32e1c10fd9a", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "IP plan ({Tab6Success:value}/{Tab6Total:value})", + "linkLabel": "PaaS ({Tab6Success:value}/{Tab6Total:value})", "subTarget": "tab6", - "preText": "IP plan", - "style": "primary" - }, - { - "id": "28a27454-f392-42a6-85af-6f3dfc3ddf2b", - "cellValue": "VisibleTab", - "linkTarget": "parameter", - "linkLabel": "Hub and spoke ({Tab7Success:value}/{Tab7Total:value})", - "subTarget": "tab7", - "preText": "Hub and spoke", + "preText": "PaaS", "style": "primary" } ] @@ -1494,22 +1288,22 @@ { "type": 1, "content": { - "json": "## Internet" + "json": "## Hub and spoke" }, "name": "tab0title" }, { "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": "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": "querytext16" + "name": "querytext0" }, { "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 == '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", @@ -1558,20 +1352,20 @@ ] } }, - "name": "query16" + "name": "query0" }, { "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": "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": "querytext17" + "name": "querytext1" }, { "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' | 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", @@ -1620,374 +1414,20 @@ ] } }, - "name": "query17" - }, - { - "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." - }, - "name": "querytext18" - }, - { - "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", - "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": "query18" - }, - { - "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." - }, - "name": "querytext19" - }, - { - "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", - "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": "query19" - }, - { - "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." - }, - "name": "querytext20" - }, - { - "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", - "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": "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": "querytext21" - }, - { - "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", - "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" - } - ] - }, - "conditionalVisibility": { - "parameterName": "VisibleTab", - "comparison": "isEqualTo", - "value": "tab0" - }, - "name": "tab0" - }, - { - "type": 12, - "content": { - "version": "NotebookGroup/1.0", - "groupType": "editable", - "items": [ - { - "type": 1, - "content": { - "json": "## Virtual WAN" - }, - "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." - }, - "name": "querytext27" - }, - { - "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", - "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": "query27" - } - ] - }, - "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": "query1" }, { "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": "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": "querytext9" + "name": "querytext2" }, { "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/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", @@ -2036,20 +1476,20 @@ ] } }, - "name": "query9" + "name": "query2" }, { "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 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": "querytext10" + "name": "querytext3" }, { "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 | 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", @@ -2098,82 +1538,42 @@ ] } }, - "name": "query10" - }, - { - "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." - }, - "name": "querytext11" - }, - { - "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", - "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": "query3" + } + ] + }, + "conditionalVisibility": { + "parameterName": "VisibleTab", + "comparison": "isEqualTo", + "value": "tab0" + }, + "name": "tab0" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## IP plan" }, - "name": "query11" + "name": "tab1title" }, { "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 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": "querytext12" + "name": "querytext9" }, { "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' | 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", @@ -2222,20 +1622,20 @@ ] } }, - "name": "query12" + "name": "query9" }, { "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": "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": "querytext13" + "name": "querytext10" }, { "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' | 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", @@ -2284,16 +1684,16 @@ ] } }, - "name": "query13" + "name": "query10" } ] }, "conditionalVisibility": { "parameterName": "VisibleTab", "comparison": "isEqualTo", - "value": "tab2" + "value": "tab1" }, - "name": "tab2" + "name": "tab1" }, { "type": 12, @@ -2304,14 +1704,14 @@ { "type": 1, "content": { - "json": "## PaaS" + "json": "## Virtual WAN" }, - "name": "tab3title" + "name": "tab2title" }, { "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": "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": "querytext22" }, @@ -2319,7 +1719,7 @@ "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/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", @@ -2375,9 +1775,9 @@ "conditionalVisibility": { "parameterName": "VisibleTab", "comparison": "isEqualTo", - "value": "tab3" + "value": "tab2" }, - "name": "tab3" + "name": "tab2" }, { "type": 12, @@ -2390,14 +1790,14 @@ "content": { "json": "## Segmentation" }, - "name": "tab4title" + "name": "tab3title" }, { "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." }, - "name": "querytext23" + "name": "querytext18" }, { "type": 3, @@ -2452,14 +1852,14 @@ ] } }, - "name": "query23" + "name": "query18" }, { "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": "querytext24" + "name": "querytext19" }, { "type": 3, @@ -2514,14 +1914,14 @@ ] } }, - "name": "query24" + "name": "query19" }, { "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": "querytext25" + "name": "querytext20" }, { "type": 3, @@ -2576,14 +1976,14 @@ ] } }, - "name": "query25" + "name": "query20" }, { "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": "querytext26" + "name": "querytext21" }, { "type": 3, @@ -2638,16 +2038,16 @@ ] } }, - "name": "query26" + "name": "query21" } ] }, "conditionalVisibility": { "parameterName": "VisibleTab", "comparison": "isEqualTo", - "value": "tab4" + "value": "tab3" }, - "name": "tab4" + "name": "tab3" }, { "type": 12, @@ -2658,22 +2058,22 @@ { "type": 1, "content": { - "json": "## App delivery" + "json": "## Hybrid" }, - "name": "tab5title" + "name": "tab4title" }, { "type": 1, "content": { - "json": "Ensure you are using Application Gateway v2 SKU. Check [this link](https://learn.microsoft.com/azure/application-gateway/overview-v2) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this." + "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": "querytext0" + "name": "querytext4" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/applicationgateways' | project id, compliant = properties.sku.name in ('Standard_v2', 'WAF_v2') | 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' 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", @@ -2722,20 +2122,20 @@ ] } }, - "name": "query0" + "name": "query4" }, { "type": 1, "content": { - "json": "Ensure you are using the Standard SKU for your Azure Load Balancers. Check [this link](https://learn.microsoft.com/azure/load-balancer/load-balancer-overview) 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": "querytext1" + "name": "querytext5" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard') | 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", @@ -2784,20 +2184,20 @@ ] } }, - "name": "query1" + "name": "query5" }, { "type": 1, "content": { - "json": "Your application gateways should be deployed in subnets with IP prefixes equal or larger than /26. Check [this link](https://learn.microsoft.com/azure/application-gateway/configuration-infrastructure#size-of-the-subnet) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) 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": "querytext2" + "name": "querytext6" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "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 | project id, subnetId = tostring(subnets.id), subnetPrefixLength = split(subnets.properties.addressPrefix, '/')[1]) on subnetId | 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/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", @@ -2846,20 +2246,20 @@ ] } }, - "name": "query2" + "name": "query6" }, { "type": 1, "content": { - "json": "Deploy your WAF profiles for Front Door in 'Prevention' mode. Check [this link](https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-policy-settings) 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": "querytext3" + "name": "querytext7" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "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 | 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", @@ -2908,20 +2308,20 @@ ] } }, - "name": "query3" + "name": "query7" }, { "type": 1, "content": { - "json": "Use Azure NAT Gateway instead of Load Balancer outbound rules for better SNAT scalability. Check [this link](https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity) 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": "querytext4" + "name": "querytext8" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/loadbalancers' | extend countOutRules=array_length(properties.outboundRules) | extend compliant = (countOutRules == 0) | 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", @@ -2970,16 +2370,16 @@ ] } }, - "name": "query4" + "name": "query8" } ] }, "conditionalVisibility": { "parameterName": "VisibleTab", "comparison": "isEqualTo", - "value": "tab5" + "value": "tab4" }, - "name": "tab5" + "name": "tab4" }, { "type": 12, @@ -2990,22 +2390,22 @@ { "type": 1, "content": { - "json": "## IP plan" + "json": "## Internet" }, - "name": "tab6title" + "name": "tab5title" }, { "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 Azure Bastion in a subnet /26 or larger. Check [this link](https://learn.microsoft.com/azure/bastion/bastion-faq#subnet) for further information." }, - "name": "querytext14" + "name": "querytext11" }, { "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 == '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", @@ -3054,20 +2454,20 @@ ] } }, - "name": "query14" + "name": "query11" }, { "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 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": "querytext15" + "name": "querytext12" }, { "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/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", @@ -3116,42 +2516,82 @@ ] } }, - "name": "query15" - } - ] - }, - "conditionalVisibility": { - "parameterName": "VisibleTab", - "comparison": "isEqualTo", - "value": "tab6" - }, - "name": "tab6" - }, - { - "type": 12, - "content": { - "version": "NotebookGroup/1.0", - "groupType": "editable", - "items": [ + "name": "query12" + }, { "type": 1, "content": { - "json": "## Hub and spoke" + "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": "querytext13" + }, + { + "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", + "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": "tab7title" + "name": "query13" }, { "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": "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": "querytext5" + "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 == '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/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", @@ -3200,20 +2640,20 @@ ] } }, - "name": "query5" + "name": "query14" }, { "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": "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": "querytext6" + "name": "querytext15" }, { "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/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", @@ -3262,20 +2702,20 @@ ] } }, - "name": "query6" + "name": "query15" }, { "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": "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": "querytext7" + "name": "querytext16" }, { "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,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", @@ -3324,20 +2764,42 @@ ] } }, - "name": "query7" + "name": "query16" + } + ] + }, + "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" }, { "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": "querytext8" + "name": "querytext17" }, { "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", @@ -3386,16 +2848,16 @@ ] } }, - "name": "query8" + "name": "query17" } ] }, "conditionalVisibility": { "parameterName": "VisibleTab", "comparison": "isEqualTo", - "value": "tab7" + "value": "tab6" }, - "name": "tab7" + "name": "tab6" } ], "$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json" diff --git a/workbooks/alz_checklist.en_network_counters_template.json b/workbooks/alz_checklist.en_network_counters_template.json index cf5699ec0..e4c8c0090 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/applicationgateways' | project id, compliant = properties.sku.name in ('Standard_v2', 'WAF_v2') | 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\": \"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/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard')| 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/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 | project id, subnetId = tostring(subnets.id), subnetPrefixLength = split(subnets.properties.addressPrefix, '/')[1]) on subnetId | 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\": \"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/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| 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/loadbalancers' | extend countOutRules=array_length(properties.outboundRules) | extend compliant = (countOutRules == 0) | 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\": \"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/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\": \"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/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\": \"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/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\": \"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/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\": \"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/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\": \"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/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\": \"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/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\": \"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/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\": \"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/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\": \"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/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\": \"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/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\": \"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/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\": \"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/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\": \"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/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\": \"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/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\": \"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/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\": \"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/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\": \"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 = 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\": \"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/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\": \"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\": \"Query24Stats\",\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\": \"Query24FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query24Stats:$.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\": \"Query25Stats\",\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\": \"Query25FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query25Stats:$.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\": \"Query26Stats\",\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\": \"Query26FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query26Stats:$.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\": \"Query27Stats\",\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\": \"Query27FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query27Stats:$.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\": \"{Query16Stats:$.Success}+{Query17Stats:$.Success}+{Query18Stats:$.Success}+{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.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\": \"{Query16Stats:$.Total}+{Query17Stats:$.Total}+{Query18Stats:$.Total}+{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.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\": \"{Query27Stats:$.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\": \"{Query27Stats:$.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\": \"{Query9Stats:$.Success}+{Query10Stats:$.Success}+{Query11Stats:$.Success}+{Query12Stats:$.Success}+{Query13Stats:$.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\": \"{Query9Stats:$.Total}+{Query10Stats:$.Total}+{Query11Stats:$.Total}+{Query12Stats:$.Total}+{Query13Stats:$.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\": \"{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\": \"{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 \"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}+{Query24Stats:$.Success}+{Query25Stats:$.Success}+{Query26Stats:$.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}+{Query24Stats:$.Total}+{Query25Stats:$.Total}+{Query26Stats:$.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}+{Query4Stats:$.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}+{Query4Stats:$.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\": \"{Query14Stats:$.Success}+{Query15Stats:$.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\": \"{Query14Stats:$.Total}+{Query15Stats:$.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\": \"Tab7Success\",\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\": \"{Query5Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab7Total\",\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\": \"{Query5Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab7Percent\",\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*{Tab7Success}/{Tab7Total})\"\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\": \"{Query16Stats:$.Total}+{Query17Stats:$.Total}+{Query18Stats:$.Total}+{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}+{Query27Stats:$.Total}+{Query9Stats:$.Total}+{Query10Stats:$.Total}+{Query11Stats:$.Total}+{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query22Stats:$.Total}+{Query23Stats:$.Total}+{Query24Stats:$.Total}+{Query25Stats:$.Total}+{Query26Stats:$.Total}+{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}+{Query4Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query5Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.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\": \"{Query16Stats:$.Success}+{Query17Stats:$.Success}+{Query18Stats:$.Success}+{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}+{Query27Stats:$.Success}+{Query9Stats:$.Success}+{Query10Stats:$.Success}+{Query11Stats:$.Success}+{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query22Stats:$.Success}+{Query23Stats:$.Success}+{Query24Stats:$.Success}+{Query25Stats:$.Success}+{Query26Stats:$.Success}+{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}+{Query4Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query5Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.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\": \"8d60b129-67a0-4558-b6c3-52125fbd0617\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Internet ({Tab0Success:value}/{Tab0Total:value})\",\n \"subTarget\": \"tab0\",\n \"preText\": \"Internet\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"e865c54b-3907-4a23-b779-240f4cc0a583\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Virtual WAN ({Tab1Success:value}/{Tab1Total:value})\",\n \"subTarget\": \"tab1\",\n \"preText\": \"Virtual WAN\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"01384aa5-f752-4f51-bf96-c5f9dae3ea99\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Hybrid ({Tab2Success:value}/{Tab2Total:value})\",\n \"subTarget\": \"tab2\",\n \"preText\": \"Hybrid\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"a5489911-e231-4f26-b8d1-ee45618762c6\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"PaaS ({Tab3Success:value}/{Tab3Total:value})\",\n \"subTarget\": \"tab3\",\n \"preText\": \"PaaS\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"5461481a-6e46-4730-b105-71971fd4842b\",\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\": \"1276fa72-2660-49bb-b1bb-83b5fc392df5\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"App delivery ({Tab5Success:value}/{Tab5Total:value})\",\n \"subTarget\": \"tab5\",\n \"preText\": \"App delivery\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"2a7d66c0-9b24-418e-b3af-80bb85451ccb\",\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 \"id\": \"28a27454-f392-42a6-85af-6f3dfc3ddf2b\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Hub and spoke ({Tab7Success:value}/{Tab7Total:value})\",\n \"subTarget\": \"tab7\",\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\": 1,\n \"content\": {\n \"json\": \"## Internet\"\n },\n \"name\": \"tab0title\"\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\": \"querytext16\"\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\": \"query16\"\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\": \"querytext17\"\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\": \"query17\"\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\": \"querytext18\"\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\": \"query18\"\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\": \"querytext19\"\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\": \"query19\"\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\": \"querytext20\"\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\": \"query20\"\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\": \"querytext21\"\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\": \"query21\"\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\": \"querytext27\"\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\": \"query27\"\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\": \"querytext9\"\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\": \"query9\"\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\": \"querytext10\"\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\": \"query10\"\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\": \"querytext11\"\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\": \"query11\"\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\": \"querytext12\"\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\": \"query12\"\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\": \"querytext13\"\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\": \"query13\"\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\": \"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 = 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\": \"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\": \"## 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\": \"querytext23\"\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\": \"query23\"\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\": \"querytext24\"\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\": \"query24\"\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\": \"querytext25\"\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\": \"query25\"\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\": \"querytext26\"\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\": \"query26\"\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\": \"## App delivery\"\n },\n \"name\": \"tab5title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure you are using Application Gateway v2 SKU. Check [this link](https://learn.microsoft.com/azure/application-gateway/overview-v2) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext0\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/applicationgateways' | project id, compliant = properties.sku.name in ('Standard_v2', 'WAF_v2') | 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\": \"query0\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure you are using the Standard SKU for your Azure Load Balancers. Check [this link](https://learn.microsoft.com/azure/load-balancer/load-balancer-overview) 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/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard') | 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\": \"Your application gateways should be deployed in subnets with IP prefixes equal or larger than /26. Check [this link](https://learn.microsoft.com/azure/application-gateway/configuration-infrastructure#size-of-the-subnet) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext2\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"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 | project id, subnetId = tostring(subnets.id), subnetPrefixLength = split(subnets.properties.addressPrefix, '/')[1]) on subnetId | 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\": \"query2\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Deploy your WAF profiles for Front Door in 'Prevention' mode. Check [this link](https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-policy-settings) 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/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 | 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 \"type\": 1,\n \"content\": {\n \"json\": \"Use Azure NAT Gateway instead of Load Balancer outbound rules for better SNAT scalability. Check [this link](https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity) for further information.\"\n },\n \"name\": \"querytext4\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/loadbalancers' | extend countOutRules=array_length(properties.outboundRules) | extend compliant = (countOutRules == 0) | 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\": \"query4\"\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\": \"querytext14\"\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\": \"query14\"\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\": \"querytext15\"\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\": \"query15\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab6\"\n },\n \"name\": \"tab6\"\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\": \"tab7title\"\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\": \"querytext5\"\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\": \"query5\"\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\": \"querytext6\"\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\": \"query6\"\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\": \"querytext7\"\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\": \"query7\"\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\": \"querytext8\"\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\": \"query8\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab7\"\n },\n \"name\": \"tab7\"\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' | 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\": \"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 | 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\": \"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' | 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\": \"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/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\": \"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.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\": \"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.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\": \"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.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\": \"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/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\": \"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 = 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\": \"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,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\": \"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 == '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\": \"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/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\": \"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/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\": \"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/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\": \"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\": \"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 \"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\": \"{Query9Stats:$.Success}+{Query10Stats:$.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\": \"{Query9Stats:$.Total}+{Query10Stats:$.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\": \"{Query22Stats:$.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\": \"{Query22Stats:$.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\": \"{Query18Stats:$.Success}+{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.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\": \"{Query18Stats:$.Total}+{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.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\": \"{Query4Stats:$.Success}+{Query5Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.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}\"\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\": \"{Query11Stats:$.Success}+{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query16Stats:$.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\": \"{Query11Stats:$.Total}+{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query16Stats:$.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\": \"{Query17Stats:$.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\": \"{Query17Stats:$.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\": \"{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}+{Query9Stats:$.Total}+{Query10Stats:$.Total}+{Query22Stats:$.Total}+{Query18Stats:$.Total}+{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}+{Query4Stats:$.Total}+{Query5Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}+{Query11Stats:$.Total}+{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\": \"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\": \"{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}+{Query9Stats:$.Success}+{Query10Stats:$.Success}+{Query22Stats:$.Success}+{Query18Stats:$.Success}+{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}+{Query4Stats:$.Success}+{Query5Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}+{Query11Stats:$.Success}+{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\": \"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\": \"94d19852-737f-4f07-97a2-8a913f090208\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Hub and spoke ({Tab0Success:value}/{Tab0Total:value})\",\n \"subTarget\": \"tab0\",\n \"preText\": \"Hub and spoke\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"aa648a6e-ba53-48e9-bab8-a9b69e3938b1\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"IP plan ({Tab1Success:value}/{Tab1Total:value})\",\n \"subTarget\": \"tab1\",\n \"preText\": \"IP plan\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"f22ad8ce-c4ab-4007-8efa-6725392b042c\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Virtual WAN ({Tab2Success:value}/{Tab2Total:value})\",\n \"subTarget\": \"tab2\",\n \"preText\": \"Virtual WAN\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"8cd4f649-6e4d-4725-bf62-5eede2c458e1\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Segmentation ({Tab3Success:value}/{Tab3Total:value})\",\n \"subTarget\": \"tab3\",\n \"preText\": \"Segmentation\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"16f80b07-a3a3-462b-8f85-2e2c3666ce91\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Hybrid ({Tab4Success:value}/{Tab4Total:value})\",\n \"subTarget\": \"tab4\",\n \"preText\": \"Hybrid\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"0c8faa13-cf82-43ab-9193-982acd0ef3c0\",\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\": \"d873a0bb-76f6-4bf5-ad06-c32e1c10fd9a\",\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\": \"## 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\": 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\": 1,\n \"content\": {\n \"json\": \"## IP plan\"\n },\n \"name\": \"tab1title\"\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\": \"querytext9\"\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\": \"query9\"\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\": \"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 | 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\": \"query10\"\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\": \"querytext22\"\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\": \"query22\"\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\": \"querytext18\"\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\": \"query18\"\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\": \"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 == '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\": \"query19\"\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\": \"querytext20\"\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\": \"query20\"\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\": \"querytext21\"\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\": \"query21\"\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\": 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 },\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\": \"querytext11\"\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\": \"query11\"\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\": \"querytext12\"\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\": \"query12\"\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\": \"querytext13\"\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\": \"query13\"\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\": \"querytext14\"\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\": \"query14\"\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\": \"querytext15\"\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\": \"query15\"\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\": \"querytext16\"\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\": \"query16\"\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\": \"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 = 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\": \"query17\"\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 6294c61ef..b952aeca5 100644 --- a/workbooks/alz_checklist.en_network_tabcounters.json +++ b/workbooks/alz_checklist.en_network_tabcounters.json @@ -70,75 +70,66 @@ "style": "tabs", "links": [ { - "id": "4faf8281-0b6a-4a91-9e78-00613f25277c", + "id": "74251644-5f78-479c-93ff-b7f35e6e44fe", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Internet", + "linkLabel": "Virtual WAN", "subTarget": "tab0", - "preText": "Internet", + "preText": "Virtual WAN", "style": "primary" }, { - "id": "2899ee3c-25d5-4ac1-be02-00481298af82", + "id": "c2454e4b-6c09-4565-9f21-6d21ff74fa99", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "PaaS", + "linkLabel": "Hub and spoke", "subTarget": "tab1", - "preText": "PaaS", + "preText": "Hub and spoke", "style": "primary" }, { - "id": "8ce79d07-63e7-47cb-bde8-dbabb9631cd6", + "id": "708118a0-f71c-41e9-96cf-bf5f702f6fa6", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "IP plan", + "linkLabel": "Hybrid", "subTarget": "tab2", - "preText": "IP plan", + "preText": "Hybrid", "style": "primary" }, { - "id": "e376fa23-ff33-40d6-ba9b-3a573f160dcb", + "id": "e73353bf-1ca0-472a-91ad-d493e32f4631", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Hybrid", + "linkLabel": "Internet", "subTarget": "tab3", - "preText": "Hybrid", + "preText": "Internet", "style": "primary" }, { - "id": "d42cf044-08bd-4117-b08b-7ac45a73db0a", + "id": "772b9526-386b-4ad6-a30d-30cf9b188afb", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Virtual WAN", + "linkLabel": "PaaS", "subTarget": "tab4", - "preText": "Virtual WAN", + "preText": "PaaS", "style": "primary" }, { - "id": "7cc3680b-c425-4a61-81ee-12fb427c87fa", + "id": "329cedec-47f7-4405-87ce-3b36382b96bd", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Segmentation", + "linkLabel": "IP plan", "subTarget": "tab5", - "preText": "Segmentation", + "preText": "IP plan", "style": "primary" }, { - "id": "94154802-2756-4434-bf32-a9c31beb64e8", + "id": "edb56912-4c88-4e05-93be-4e9cf75e7bc8", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Hub and spoke", + "linkLabel": "Segmentation", "subTarget": "tab6", - "preText": "Hub and spoke", - "style": "primary" - }, - { - "id": "5583239d-64f9-4966-a86c-ae1153be707a", - "cellValue": "VisibleTab", - "linkTarget": "parameter", - "linkLabel": "App delivery", - "subTarget": "tab7", - "preText": "App delivery", + "preText": "Segmentation", "style": "primary" } ] @@ -162,149 +153,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query16Stats", - "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())", - "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/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}" - ], - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources" - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query17FullyCompliant", - "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query17Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 8 - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query18Stats", - "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())", - "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": "Query19Stats", - "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": "Query19FullyCompliant", - "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query19Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 8 - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query20Stats", - "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": "Query20FullyCompliant", - "type": 1, - "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", + "name": "Query22Stats", "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/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())", "crossComponentResources": [ "{Subscription}" ], @@ -318,9 +169,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query21FullyCompliant", + "name": "Query22FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query21Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query22Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -341,7 +192,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query16Stats:$.Success}+{Query17Stats:$.Success}+{Query18Stats:$.Success}+{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}" + "resultVal": "{Query22Stats:$.Success}" } } ] @@ -360,7 +211,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query16Stats:$.Total}+{Query17Stats:$.Total}+{Query18Stats:$.Total}+{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}" + "resultVal": "{Query22Stats:$.Total}" } } ] @@ -394,544 +245,16 @@ { "type": 1, "content": { - "json": "## Internet" - }, - "customWidth": "50", - "name": "tab0title" - }, - { - "type": 3, - "content": { - "version": "KqlItem/1.0", - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"Column1\\\": \\\"{Tab0Percent}\\\", \\\"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" - }, - "numberFormat": { - "unit": 0, - "options": { - "style": "decimal" - } - } - }, - "subtitleContent": { - "columnMatch": "Column2" - }, - "showBorder": true - } - }, - "customWidth": "50", - "name": "TabPercentTile" - }, - { - "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." - }, - "name": "querytext16" - }, - { - "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", - "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": "query16" - }, - { - "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." - }, - "name": "querytext17" - }, - { - "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", - "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": "query17" - }, - { - "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." - }, - "name": "querytext18" - }, - { - "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", - "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": "query18" - }, - { - "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." - }, - "name": "querytext19" - }, - { - "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", - "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": "query19" - }, - { - "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." - }, - "name": "querytext20" - }, - { - "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", - "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": "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": "querytext21" - }, - { - "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", - "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" - } - ] - }, - "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": [ - { - "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 = 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": "Query22FullyCompliant", - "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query22Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 8 - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Tab1Success", - "type": 1, - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "criteriaData": [ - { - "criteriaContext": { - "operator": "Default", - "resultValType": "expression", - "resultVal": "{Query22Stats:$.Success}" - } - } - ] - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Tab1Total", - "type": 1, - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "criteriaData": [ - { - "criteriaContext": { - "operator": "Default", - "resultValType": "expression", - "resultVal": "{Query22Stats:$.Total}" - } - } - ] - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Tab1Percent", - "type": 1, - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "criteriaData": [ - { - "criteriaContext": { - "operator": "Default", - "resultValType": "expression", - "resultVal": "round(100*{Tab1Success}/{Tab1Total})" - } - } - ] - } - ], - "style": "pills", - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources" - }, - "name": "TabInvisibleParameters" - }, - { - "type": 1, - "content": { - "json": "## PaaS" + "json": "## Virtual WAN" }, "customWidth": "50", - "name": "tab1title" + "name": "tab0title" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"Column1\\\": \\\"{Tab1Percent}\\\", \\\"Column2\\\": \\\"Percent of successful checks\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"Column1\\\": \\\"{Tab0Percent}\\\", \\\"Column2\\\": \\\"Percent of successful checks\\\"}\",\"transformers\":null}", "size": 3, "queryType": 8, "visualization": "tiles", @@ -963,7 +286,7 @@ { "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": "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": "querytext22" }, @@ -971,7 +294,7 @@ "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/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", @@ -1027,9 +350,9 @@ "conditionalVisibility": { "parameterName": "VisibleTab", "comparison": "isEqualTo", - "value": "tab1" + "value": "tab0" }, - "name": "tab1" + "name": "tab0" }, { "type": 12, @@ -1048,9 +371,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query14Stats", + "name": "Query0Stats", "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())", + "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}" ], @@ -1064,9 +387,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query14FullyCompliant", + "name": "Query0FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query14Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query0Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -1076,9 +399,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query15Stats", + "name": "Query1Stats", "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())", + "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}" ], @@ -1092,9 +415,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query15FullyCompliant", + "name": "Query1FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query15Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query1Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -1104,7 +427,63 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Tab2Success", + "name": "Query2Stats", + "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())", + "crossComponentResources": [ + "{Subscription}" + ], + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query2FullyCompliant", + "type": 1, + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query2Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 8 + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query3Stats", + "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())", + "crossComponentResources": [ + "{Subscription}" + ], + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query3FullyCompliant", + "type": 1, + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query3Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 8 + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Tab1Success", "type": 1, "isHiddenWhenLocked": true, "timeContext": { @@ -1115,7 +494,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query14Stats:$.Success}+{Query15Stats:$.Success}" + "resultVal": "{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}" } } ] @@ -1123,7 +502,7 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Tab2Total", + "name": "Tab1Total", "type": 1, "isHiddenWhenLocked": true, "timeContext": { @@ -1134,7 +513,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query14Stats:$.Total}+{Query15Stats:$.Total}" + "resultVal": "{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}" } } ] @@ -1142,7 +521,7 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Tab2Percent", + "name": "Tab1Percent", "type": 1, "isHiddenWhenLocked": true, "timeContext": { @@ -1153,7 +532,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "round(100*{Tab2Success}/{Tab2Total})" + "resultVal": "round(100*{Tab1Success}/{Tab1Total})" } } ] @@ -1168,16 +547,16 @@ { "type": 1, "content": { - "json": "## IP plan" + "json": "## Hub and spoke" }, "customWidth": "50", - "name": "tab2title" + "name": "tab1title" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"Column1\\\": \\\"{Tab2Percent}\\\", \\\"Column2\\\": \\\"Percent of successful checks\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"Column1\\\": \\\"{Tab1Percent}\\\", \\\"Column2\\\": \\\"Percent of successful checks\\\"}\",\"transformers\":null}", "size": 3, "queryType": 8, "visualization": "tiles", @@ -1209,15 +588,15 @@ { "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": "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": "querytext14" + "name": "querytext0" }, { "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 == '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", @@ -1266,20 +645,20 @@ ] } }, - "name": "query14" + "name": "query0" }, { "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": "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": "querytext15" + "name": "querytext1" }, { "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' | 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", @@ -1328,16 +707,140 @@ ] } }, - "name": "query15" + "name": "query1" + }, + { + "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." + }, + "name": "querytext2" + }, + { + "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" + } + } + }, + { + "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": "query2" + }, + { + "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." + }, + "name": "querytext3" + }, + { + "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", + "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": "query3" } ] }, "conditionalVisibility": { "parameterName": "VisibleTab", "comparison": "isEqualTo", - "value": "tab2" + "value": "tab1" }, - "name": "tab2" + "name": "tab1" }, { "type": 12, @@ -1356,7 +859,7 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query9Stats", + "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": [ @@ -1372,9 +875,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query9FullyCompliant", + "name": "Query4FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query9Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query4Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -1384,7 +887,7 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query10Stats", + "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": [ @@ -1400,9 +903,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query10FullyCompliant", + "name": "Query5FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query10Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query5Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -1412,7 +915,7 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query11Stats", + "name": "Query6Stats", "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())", "crossComponentResources": [ @@ -1428,9 +931,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query11FullyCompliant", + "name": "Query6FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query11Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query6Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -1440,7 +943,7 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query12Stats", + "name": "Query7Stats", "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())", "crossComponentResources": [ @@ -1456,9 +959,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query12FullyCompliant", + "name": "Query7FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query12Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query7Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -1468,7 +971,7 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query13Stats", + "name": "Query8Stats", "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())", "crossComponentResources": [ @@ -1484,9 +987,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query13FullyCompliant", + "name": "Query8FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query13Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query8Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -1496,7 +999,7 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Tab3Success", + "name": "Tab2Success", "type": 1, "isHiddenWhenLocked": true, "timeContext": { @@ -1507,7 +1010,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query9Stats:$.Success}+{Query10Stats:$.Success}+{Query11Stats:$.Success}+{Query12Stats:$.Success}+{Query13Stats:$.Success}" + "resultVal": "{Query4Stats:$.Success}+{Query5Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}" } } ] @@ -1515,7 +1018,7 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Tab3Total", + "name": "Tab2Total", "type": 1, "isHiddenWhenLocked": true, "timeContext": { @@ -1526,7 +1029,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query9Stats:$.Total}+{Query10Stats:$.Total}+{Query11Stats:$.Total}+{Query12Stats:$.Total}+{Query13Stats:$.Total}" + "resultVal": "{Query4Stats:$.Total}+{Query5Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}" } } ] @@ -1534,7 +1037,7 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Tab3Percent", + "name": "Tab2Percent", "type": 1, "isHiddenWhenLocked": true, "timeContext": { @@ -1545,7 +1048,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "round(100*{Tab3Success}/{Tab3Total})" + "resultVal": "round(100*{Tab2Success}/{Tab2Total})" } } ] @@ -1563,13 +1066,13 @@ "json": "## Hybrid" }, "customWidth": "50", - "name": "tab3title" + "name": "tab2title" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"Column1\\\": \\\"{Tab3Percent}\\\", \\\"Column2\\\": \\\"Percent of successful checks\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"Column1\\\": \\\"{Tab2Percent}\\\", \\\"Column2\\\": \\\"Percent of successful checks\\\"}\",\"transformers\":null}", "size": 3, "queryType": 8, "visualization": "tiles", @@ -1603,7 +1106,7 @@ "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." }, - "name": "querytext9" + "name": "querytext4" }, { "type": 3, @@ -1658,14 +1161,14 @@ ] } }, - "name": "query9" + "name": "query4" }, { "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." }, - "name": "querytext10" + "name": "querytext5" }, { "type": 3, @@ -1720,14 +1223,14 @@ ] } }, - "name": "query10" + "name": "query5" }, { "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." }, - "name": "querytext11" + "name": "querytext6" }, { "type": 3, @@ -1782,14 +1285,14 @@ ] } }, - "name": "query11" + "name": "query6" }, { "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." }, - "name": "querytext12" + "name": "querytext7" }, { "type": 3, @@ -1834,248 +1337,30 @@ }, { "operator": "Default", - "thresholdValue": null, - "representation": "unknown", - "text": "Unknown" - } - ] - } - } - ] - } - }, - "name": "query12" - }, - { - "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": "querytext13" - }, - { - "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", - "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": "query13" - } - ] - }, - "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": "Query27Stats", - "type": 1, - "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())", - "crossComponentResources": [ - "{Subscription}" - ], - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources" - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query27FullyCompliant", - "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query27Stats:$.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": "{Query27Stats:$.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": "{Query27Stats:$.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": "## Virtual WAN" - }, - "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" - }, - "numberFormat": { - "unit": 0, - "options": { - "style": "decimal" + "thresholdValue": null, + "representation": "unknown", + "text": "Unknown" + } + ] } } - }, - "subtitleContent": { - "columnMatch": "Column2" - }, - "showBorder": true + ] } }, - "customWidth": "50", - "name": "TabPercentTile" + "name": "query7" }, { "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 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": "querytext27" + "name": "querytext8" }, { "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/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", @@ -2124,16 +1409,16 @@ ] } }, - "name": "query27" + "name": "query8" } ] }, "conditionalVisibility": { "parameterName": "VisibleTab", "comparison": "isEqualTo", - "value": "tab4" + "value": "tab2" }, - "name": "tab4" + "name": "tab2" }, { "type": 12, @@ -2152,9 +1437,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query23Stats", + "name": "Query11Stats", "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}" ], @@ -2168,9 +1453,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query23FullyCompliant", + "name": "Query11FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query23Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query11Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -2180,9 +1465,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query24Stats", + "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 == '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}" ], @@ -2196,9 +1481,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query24FullyCompliant", + "name": "Query12FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query24Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query12Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -2208,9 +1493,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query25Stats", + "name": "Query13Stats", "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}" ], @@ -2224,9 +1509,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query25FullyCompliant", + "name": "Query13FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query25Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query13Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -2236,9 +1521,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query26Stats", + "name": "Query14Stats", "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/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}" ], @@ -2252,9 +1537,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query26FullyCompliant", + "name": "Query14FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query26Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query14Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -2264,7 +1549,63 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Tab5Success", + "name": "Query15Stats", + "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": "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/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}" + ], + "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": "Tab3Success", "type": 1, "isHiddenWhenLocked": true, "timeContext": { @@ -2275,7 +1616,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query23Stats:$.Success}+{Query24Stats:$.Success}+{Query25Stats:$.Success}+{Query26Stats:$.Success}" + "resultVal": "{Query11Stats:$.Success}+{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query16Stats:$.Success}" } } ] @@ -2283,7 +1624,7 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Tab5Total", + "name": "Tab3Total", "type": 1, "isHiddenWhenLocked": true, "timeContext": { @@ -2294,7 +1635,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query23Stats:$.Total}+{Query24Stats:$.Total}+{Query25Stats:$.Total}+{Query26Stats:$.Total}" + "resultVal": "{Query11Stats:$.Total}+{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query16Stats:$.Total}" } } ] @@ -2302,7 +1643,7 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Tab5Percent", + "name": "Tab3Percent", "type": 1, "isHiddenWhenLocked": true, "timeContext": { @@ -2313,7 +1654,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "round(100*{Tab5Success}/{Tab5Total})" + "resultVal": "round(100*{Tab3Success}/{Tab3Total})" } } ] @@ -2328,16 +1669,16 @@ { "type": 1, "content": { - "json": "## Segmentation" + "json": "## Internet" }, "customWidth": "50", - "name": "tab5title" + "name": "tab3title" }, { "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\\\": \\\"{Tab3Percent}\\\", \\\"Column2\\\": \\\"Percent of successful checks\\\"}\",\"transformers\":null}", "size": 3, "queryType": 8, "visualization": "tiles", @@ -2369,15 +1710,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": "querytext23" + "name": "querytext11" }, { "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", @@ -2426,20 +1767,20 @@ ] } }, - "name": "query23" + "name": "query11" }, { "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": "querytext24" + "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 == '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", @@ -2488,20 +1829,144 @@ ] } }, - "name": "query24" + "name": "query12" }, { "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": "querytext25" + "name": "querytext13" }, { "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", + "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": "query13" + }, + { + "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." + }, + "name": "querytext14" + }, + { + "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", + "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": "query14" + }, + { + "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." + }, + "name": "querytext15" + }, + { + "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", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2550,20 +2015,20 @@ ] } }, - "name": "query25" + "name": "query15" }, { "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": "querytext26" + "name": "querytext16" }, { "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", @@ -2612,16 +2077,16 @@ ] } }, - "name": "query26" + "name": "query16" } ] }, "conditionalVisibility": { "parameterName": "VisibleTab", "comparison": "isEqualTo", - "value": "tab5" + "value": "tab3" }, - "name": "tab5" + "name": "tab3" }, { "type": 12, @@ -2640,93 +2105,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query5Stats", - "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": "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", - "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": "Query6FullyCompliant", - "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query6Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 8 - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query7Stats", - "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())", - "crossComponentResources": [ - "{Subscription}" - ], - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources" - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query7FullyCompliant", - "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query7Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 8 - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query8Stats", + "name": "Query17Stats", "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' | 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}" ], @@ -2740,9 +2121,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query8FullyCompliant", + "name": "Query17FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query8Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query17Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -2752,7 +2133,7 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Tab6Success", + "name": "Tab4Success", "type": 1, "isHiddenWhenLocked": true, "timeContext": { @@ -2763,7 +2144,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query5Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}" + "resultVal": "{Query17Stats:$.Success}" } } ] @@ -2771,7 +2152,7 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Tab6Total", + "name": "Tab4Total", "type": 1, "isHiddenWhenLocked": true, "timeContext": { @@ -2782,7 +2163,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query5Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}" + "resultVal": "{Query17Stats:$.Total}" } } ] @@ -2790,7 +2171,7 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Tab6Percent", + "name": "Tab4Percent", "type": 1, "isHiddenWhenLocked": true, "timeContext": { @@ -2801,7 +2182,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "round(100*{Tab6Success}/{Tab6Total})" + "resultVal": "round(100*{Tab4Success}/{Tab4Total})" } } ] @@ -2816,16 +2197,16 @@ { "type": 1, "content": { - "json": "## Hub and spoke" + "json": "## PaaS" }, "customWidth": "50", - "name": "tab6title" + "name": "tab4title" }, { "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\\\": \\\"{Tab4Percent}\\\", \\\"Column2\\\": \\\"Percent of successful checks\\\"}\",\"transformers\":null}", "size": 3, "queryType": 8, "visualization": "tiles", @@ -2857,15 +2238,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": "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": "querytext5" + "name": "querytext17" }, { "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' | 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", @@ -2910,86 +2291,208 @@ } ] } - } - ] - } + } + ] + } + }, + "name": "query17" + } + ] + }, + "conditionalVisibility": { + "parameterName": "VisibleTab", + "comparison": "isEqualTo", + "value": "tab4" + }, + "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": "Query9Stats", + "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": "Query9FullyCompliant", + "type": 1, + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query9Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 8 + }, + { + "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 | 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": "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": "Tab5Success", + "type": 1, + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "criteriaData": [ + { + "criteriaContext": { + "operator": "Default", + "resultValType": "expression", + "resultVal": "{Query9Stats:$.Success}+{Query10Stats:$.Success}" + } + } + ] + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Tab5Total", + "type": 1, + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "criteriaData": [ + { + "criteriaContext": { + "operator": "Default", + "resultValType": "expression", + "resultVal": "{Query9Stats:$.Total}+{Query10Stats:$.Total}" + } + } + ] + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Tab5Percent", + "type": 1, + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "criteriaData": [ + { + "criteriaContext": { + "operator": "Default", + "resultValType": "expression", + "resultVal": "round(100*{Tab5Success}/{Tab5Total})" + } + } + ] + } + ], + "style": "pills", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" }, - "name": "query5" + "name": "TabInvisibleParameters" }, { "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": "## IP plan" }, - "name": "querytext6" + "customWidth": "50", + "name": "tab5title" }, { "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", - "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\\\": \\\"{Tab5Percent}\\\", \\\"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": "query6" + "customWidth": "50", + "name": "TabPercentTile" }, { "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": "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": "querytext7" + "name": "querytext9" }, { "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' | 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", @@ -3038,20 +2541,20 @@ ] } }, - "name": "query7" + "name": "query9" }, { "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": "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": "querytext8" + "name": "querytext10" }, { "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' | 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", @@ -3100,16 +2603,16 @@ ] } }, - "name": "query8" + "name": "query10" } ] }, "conditionalVisibility": { "parameterName": "VisibleTab", "comparison": "isEqualTo", - "value": "tab6" + "value": "tab5" }, - "name": "tab6" + "name": "tab5" }, { "type": 12, @@ -3128,37 +2631,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query0Stats", - "type": 1, - "query": "resources | where type == 'microsoft.network/applicationgateways' | project id, compliant = properties.sku.name in ('Standard_v2', 'WAF_v2') | 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": "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", + "name": "Query18Stats", "type": 1, - "query": "resources | where type == 'microsoft.network/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard')| 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 == '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}" ], @@ -3172,9 +2647,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query1FullyCompliant", + "name": "Query18FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query1Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query18Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -3184,9 +2659,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query2Stats", + "name": "Query19Stats", "type": 1, - "query": "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 | project id, subnetId = tostring(subnets.id), subnetPrefixLength = split(subnets.properties.addressPrefix, '/')[1]) on subnetId | 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 == '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}" ], @@ -3200,9 +2675,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query2FullyCompliant", + "name": "Query19FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query2Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query19Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -3212,9 +2687,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query3Stats", + "name": "Query20Stats", "type": 1, - "query": "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| 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/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}" ], @@ -3228,9 +2703,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query3FullyCompliant", + "name": "Query20FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query3Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query20Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -3240,9 +2715,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query4Stats", + "name": "Query21Stats", "type": 1, - "query": "resources | where type=='microsoft.network/loadbalancers' | extend countOutRules=array_length(properties.outboundRules) | extend compliant = (countOutRules == 0) | 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,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}" ], @@ -3256,9 +2731,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query4FullyCompliant", + "name": "Query21FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query4Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query21Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -3268,7 +2743,7 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Tab7Success", + "name": "Tab6Success", "type": 1, "isHiddenWhenLocked": true, "timeContext": { @@ -3279,7 +2754,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}+{Query4Stats:$.Success}" + "resultVal": "{Query18Stats:$.Success}+{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}" } } ] @@ -3287,7 +2762,7 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Tab7Total", + "name": "Tab6Total", "type": 1, "isHiddenWhenLocked": true, "timeContext": { @@ -3298,7 +2773,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}+{Query4Stats:$.Total}" + "resultVal": "{Query18Stats:$.Total}+{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}" } } ] @@ -3306,7 +2781,7 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Tab7Percent", + "name": "Tab6Percent", "type": 1, "isHiddenWhenLocked": true, "timeContext": { @@ -3317,7 +2792,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "round(100*{Tab7Success}/{Tab7Total})" + "resultVal": "round(100*{Tab6Success}/{Tab6Total})" } } ] @@ -3332,16 +2807,16 @@ { "type": 1, "content": { - "json": "## App delivery" + "json": "## Segmentation" }, "customWidth": "50", - "name": "tab7title" + "name": "tab6title" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"Column1\\\": \\\"{Tab7Percent}\\\", \\\"Column2\\\": \\\"Percent of successful checks\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"Column1\\\": \\\"{Tab6Percent}\\\", \\\"Column2\\\": \\\"Percent of successful checks\\\"}\",\"transformers\":null}", "size": 3, "queryType": 8, "visualization": "tiles", @@ -3373,77 +2848,15 @@ { "type": 1, "content": { - "json": "Ensure you are using Application Gateway v2 SKU. Check [this link](https://learn.microsoft.com/azure/application-gateway/overview-v2) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this." - }, - "name": "querytext0" - }, - { - "type": 3, - "content": { - "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/applicationgateways' | project id, compliant = properties.sku.name in ('Standard_v2', 'WAF_v2') | 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": "query0" - }, - { - "type": 1, - "content": { - "json": "Ensure you are using the Standard SKU for your Azure Load Balancers. Check [this link](https://learn.microsoft.com/azure/load-balancer/load-balancer-overview) for further information." + "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": "querytext1" + "name": "querytext18" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard') | 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", @@ -3492,20 +2905,20 @@ ] } }, - "name": "query1" + "name": "query18" }, { "type": 1, "content": { - "json": "Your application gateways should be deployed in subnets with IP prefixes equal or larger than /26. Check [this link](https://learn.microsoft.com/azure/application-gateway/configuration-infrastructure#size-of-the-subnet) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) 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": "querytext2" + "name": "querytext19" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "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 | project id, subnetId = tostring(subnets.id), subnetPrefixLength = split(subnets.properties.addressPrefix, '/')[1]) on subnetId | 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": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -3554,20 +2967,20 @@ ] } }, - "name": "query2" + "name": "query19" }, { "type": 1, "content": { - "json": "Deploy your WAF profiles for Front Door in 'Prevention' mode. Check [this link](https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-policy-settings) 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": "querytext3" + "name": "querytext20" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "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 | 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", @@ -3616,20 +3029,20 @@ ] } }, - "name": "query3" + "name": "query20" }, { "type": 1, "content": { - "json": "Use Azure NAT Gateway instead of Load Balancer outbound rules for better SNAT scalability. Check [this link](https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity) 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": "querytext4" + "name": "querytext21" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/loadbalancers' | extend countOutRules=array_length(properties.outboundRules) | extend compliant = (countOutRules == 0) | 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", @@ -3678,16 +3091,16 @@ ] } }, - "name": "query4" + "name": "query21" } ] }, "conditionalVisibility": { "parameterName": "VisibleTab", "comparison": "isEqualTo", - "value": "tab7" + "value": "tab6" }, - "name": "tab7" + "name": "tab6" } ], "$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json" diff --git a/workbooks/alz_checklist.en_network_tabcounters_template.json b/workbooks/alz_checklist.en_network_tabcounters_template.json index f030523c3..3263b9593 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\": \"4faf8281-0b6a-4a91-9e78-00613f25277c\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Internet\",\n \"subTarget\": \"tab0\",\n \"preText\": \"Internet\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"2899ee3c-25d5-4ac1-be02-00481298af82\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"PaaS\",\n \"subTarget\": \"tab1\",\n \"preText\": \"PaaS\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"8ce79d07-63e7-47cb-bde8-dbabb9631cd6\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"IP plan\",\n \"subTarget\": \"tab2\",\n \"preText\": \"IP plan\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"e376fa23-ff33-40d6-ba9b-3a573f160dcb\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Hybrid\",\n \"subTarget\": \"tab3\",\n \"preText\": \"Hybrid\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"d42cf044-08bd-4117-b08b-7ac45a73db0a\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Virtual WAN\",\n \"subTarget\": \"tab4\",\n \"preText\": \"Virtual WAN\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"7cc3680b-c425-4a61-81ee-12fb427c87fa\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Segmentation\",\n \"subTarget\": \"tab5\",\n \"preText\": \"Segmentation\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"94154802-2756-4434-bf32-a9c31beb64e8\",\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 \"id\": \"5583239d-64f9-4966-a86c-ae1153be707a\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"App delivery\",\n \"subTarget\": \"tab7\",\n \"preText\": \"App delivery\",\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\": \"Query16Stats\",\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\": \"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/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\": \"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/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\": \"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/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\": \"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/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\": \"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/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\": \"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\": \"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\": \"{Query16Stats:$.Success}+{Query17Stats:$.Success}+{Query18Stats:$.Success}+{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.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\": \"{Query16Stats:$.Total}+{Query17Stats:$.Total}+{Query18Stats:$.Total}+{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.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\": \"## Internet\"\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\": \"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\": \"querytext16\"\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\": \"query16\"\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\": \"querytext17\"\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\": \"query17\"\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\": \"querytext18\"\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\": \"query18\"\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\": \"querytext19\"\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\": \"query19\"\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\": \"querytext20\"\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\": \"query20\"\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\": \"querytext21\"\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\": \"query21\"\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\": \"Query22Stats\",\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\": \"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\": \"{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\": \"{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\": \"## 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\": \"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 = 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\": \"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\": \"Query14Stats\",\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\": \"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/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\": \"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\": \"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\": \"{Query14Stats:$.Success}+{Query15Stats:$.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\": \"{Query14Stats:$.Total}+{Query15Stats:$.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\": \"## IP plan\"\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\": \"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\": \"querytext14\"\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\": \"query14\"\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\": \"querytext15\"\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\": \"query15\"\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\": \"Query9Stats\",\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\": \"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/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\": \"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/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\": \"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/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\": \"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/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\": \"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\": \"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\": \"{Query9Stats:$.Success}+{Query10Stats:$.Success}+{Query11Stats:$.Success}+{Query12Stats:$.Success}+{Query13Stats:$.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\": \"{Query9Stats:$.Total}+{Query10Stats:$.Total}+{Query11Stats:$.Total}+{Query12Stats:$.Total}+{Query13Stats:$.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\": \"## Hybrid\"\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\": \"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\": \"querytext9\"\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\": \"query9\"\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\": \"querytext10\"\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\": \"query10\"\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\": \"querytext11\"\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\": \"query11\"\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\": \"querytext12\"\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\": \"query12\"\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\": \"querytext13\"\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\": \"query13\"\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\": \"Query27Stats\",\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\": \"Query27FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query27Stats:$.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\": \"{Query27Stats:$.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\": \"{Query27Stats:$.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\": \"## Virtual WAN\"\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\": \"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\": \"querytext27\"\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\": \"query27\"\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\": \"Query23Stats\",\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\": \"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\": \"Query24Stats\",\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\": \"Query24FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query24Stats:$.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\": \"Query25Stats\",\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\": \"Query25FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query25Stats:$.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\": \"Query26Stats\",\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\": \"Query26FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query26Stats:$.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\": \"{Query23Stats:$.Success}+{Query24Stats:$.Success}+{Query25Stats:$.Success}+{Query26Stats:$.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\": \"{Query23Stats:$.Total}+{Query24Stats:$.Total}+{Query25Stats:$.Total}+{Query26Stats:$.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\": \"## Segmentation\"\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 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\": \"querytext23\"\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\": \"query23\"\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\": \"querytext24\"\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\": \"query24\"\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\": \"querytext25\"\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\": \"query25\"\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\": \"querytext26\"\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\": \"query26\"\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\": \"Query5Stats\",\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\": \"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/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\": \"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/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\": \"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/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\": \"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\": \"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\": \"{Query5Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.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\": \"{Query5Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.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\": \"querytext5\"\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\": \"query5\"\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\": \"querytext6\"\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\": \"query6\"\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\": \"querytext7\"\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\": \"query7\"\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\": \"querytext8\"\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\": \"query8\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab6\"\n },\n \"name\": \"tab6\"\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/applicationgateways' | project id, compliant = properties.sku.name in ('Standard_v2', 'WAF_v2') | 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\": \"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/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard')| 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/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 | project id, subnetId = tostring(subnets.id), subnetPrefixLength = split(subnets.properties.addressPrefix, '/')[1]) on subnetId | 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\": \"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/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| 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/loadbalancers' | extend countOutRules=array_length(properties.outboundRules) | extend compliant = (countOutRules == 0) | 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\": \"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\": \"Tab7Success\",\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}+{Query4Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab7Total\",\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}+{Query4Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab7Percent\",\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*{Tab7Success}/{Tab7Total})\"\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\": \"## App delivery\"\n },\n \"customWidth\": \"50\",\n \"name\": \"tab7title\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"Column1\\\\\\\": \\\\\\\"{Tab7Percent}\\\\\\\", \\\\\\\"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 you are using Application Gateway v2 SKU. Check [this link](https://learn.microsoft.com/azure/application-gateway/overview-v2) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext0\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/applicationgateways' | project id, compliant = properties.sku.name in ('Standard_v2', 'WAF_v2') | 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\": \"query0\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure you are using the Standard SKU for your Azure Load Balancers. Check [this link](https://learn.microsoft.com/azure/load-balancer/load-balancer-overview) 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/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard') | 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\": \"Your application gateways should be deployed in subnets with IP prefixes equal or larger than /26. Check [this link](https://learn.microsoft.com/azure/application-gateway/configuration-infrastructure#size-of-the-subnet) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext2\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"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 | project id, subnetId = tostring(subnets.id), subnetPrefixLength = split(subnets.properties.addressPrefix, '/')[1]) on subnetId | 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\": \"query2\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Deploy your WAF profiles for Front Door in 'Prevention' mode. Check [this link](https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-policy-settings) 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/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 | 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 \"type\": 1,\n \"content\": {\n \"json\": \"Use Azure NAT Gateway instead of Load Balancer outbound rules for better SNAT scalability. Check [this link](https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity) for further information.\"\n },\n \"name\": \"querytext4\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/loadbalancers' | extend countOutRules=array_length(properties.outboundRules) | extend compliant = (countOutRules == 0) | 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\": \"query4\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab7\"\n },\n \"name\": \"tab7\"\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\": \"74251644-5f78-479c-93ff-b7f35e6e44fe\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Virtual WAN\",\n \"subTarget\": \"tab0\",\n \"preText\": \"Virtual WAN\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"c2454e4b-6c09-4565-9f21-6d21ff74fa99\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Hub and spoke\",\n \"subTarget\": \"tab1\",\n \"preText\": \"Hub and spoke\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"708118a0-f71c-41e9-96cf-bf5f702f6fa6\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Hybrid\",\n \"subTarget\": \"tab2\",\n \"preText\": \"Hybrid\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"e73353bf-1ca0-472a-91ad-d493e32f4631\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Internet\",\n \"subTarget\": \"tab3\",\n \"preText\": \"Internet\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"772b9526-386b-4ad6-a30d-30cf9b188afb\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"PaaS\",\n \"subTarget\": \"tab4\",\n \"preText\": \"PaaS\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"329cedec-47f7-4405-87ce-3b36382b96bd\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"IP plan\",\n \"subTarget\": \"tab5\",\n \"preText\": \"IP plan\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"edb56912-4c88-4e05-93be-4e9cf75e7bc8\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Segmentation\",\n \"subTarget\": \"tab6\",\n \"preText\": \"Segmentation\",\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\": \"Query22Stats\",\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\": \"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\": \"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\": \"{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\": \"{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 \"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\": \"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\": \"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\": \"querytext22\"\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\": \"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\": 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\": \"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\": \"{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\": \"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\": \"{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\": \"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\": \"## Hub and spoke\"\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\": \"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\": \"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\": \"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\": \"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\": \"{Query4Stats:$.Success}+{Query5Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.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\": \"{Query4Stats:$.Total}+{Query5Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.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\": \"## Hybrid\"\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\": \"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 },\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\": \"Query11Stats\",\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\": \"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/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\": \"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.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\": \"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.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\": \"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.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\": \"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/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\": \"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\": \"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\": \"{Query11Stats:$.Success}+{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query16Stats:$.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\": \"{Query11Stats:$.Total}+{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query16Stats:$.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\": \"querytext11\"\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\": \"query11\"\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\": \"querytext12\"\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\": \"query12\"\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\": \"querytext13\"\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\": \"query13\"\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\": \"querytext14\"\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\": \"query14\"\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\": \"querytext15\"\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\": \"query15\"\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\": \"querytext16\"\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\": \"query16\"\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\": \"Query17Stats\",\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\": \"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\": \"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\": \"{Query17Stats:$.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\": \"{Query17Stats:$.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\": \"## PaaS\"\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\": \"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\": \"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 = 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\": \"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\": 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\": \"Query9Stats\",\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\": \"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 | 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\": \"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\": \"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\": \"{Query9Stats:$.Success}+{Query10Stats:$.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\": \"{Query9Stats:$.Total}+{Query10Stats:$.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\": \"querytext9\"\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\": \"query9\"\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\": \"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 | 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\": \"query10\"\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,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\": \"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 == '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\": \"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/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\": \"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/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\": \"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\": \"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}+{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.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}+{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.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\": \"## Segmentation\"\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\": \"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\": \"querytext18\"\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\": \"query18\"\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\": \"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 == '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\": \"query19\"\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\": \"querytext20\"\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\": \"query20\"\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\": \"querytext21\"\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\": \"query21\"\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 52fa9dc72..8a30783e2 100644 --- a/workbooks/alz_checklist.en_network_workbook.json +++ b/workbooks/alz_checklist.en_network_workbook.json @@ -70,76 +70,67 @@ "style": "tabs", "links": [ { - "id": "42490c02-f8a4-4642-b9da-2517d19d3485", + "id": "59912db4-f358-4487-89d9-ce176b890a03", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Internet", + "linkLabel": "Hybrid", "subTarget": "tab0", - "preText": "Internet", + "preText": "Hybrid", "style": "primary" }, { - "id": "27c6ac13-b5f0-47e3-8998-adf837f0b8e5", + "id": "20345556-90f1-4cd3-bcaa-969a7720384f", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Virtual WAN", + "linkLabel": "Internet", "subTarget": "tab1", - "preText": "Virtual WAN", + "preText": "Internet", "style": "primary" }, { - "id": "11ac1f17-1be6-4dc8-a4aa-074bbd85106d", + "id": "d0aebca9-e0fa-4f03-acb0-062fec7aaa07", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "IP plan", + "linkLabel": "Hub and spoke", "subTarget": "tab2", - "preText": "IP plan", + "preText": "Hub and spoke", "style": "primary" }, { - "id": "4f2520e0-c6d4-4c36-9a8c-93e231256294", + "id": "886dffa3-64a6-4d73-9323-1f1dd152fc79", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Segmentation", + "linkLabel": "Virtual WAN", "subTarget": "tab3", - "preText": "Segmentation", + "preText": "Virtual WAN", "style": "primary" }, { - "id": "a7147cc4-8bb6-41f3-a7d3-fb8cf3e1647d", + "id": "ee85a6d2-766b-4169-a45d-1b663086a47c", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Hybrid", + "linkLabel": "IP plan", "subTarget": "tab4", - "preText": "Hybrid", + "preText": "IP plan", "style": "primary" }, { - "id": "9350bc51-249a-4163-adad-6922252d22ca", + "id": "aafd474e-7f94-4e94-8c13-1881dca97ce9", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Hub and spoke", + "linkLabel": "Segmentation", "subTarget": "tab5", - "preText": "Hub and spoke", + "preText": "Segmentation", "style": "primary" }, { - "id": "7eebae73-c793-4d70-90c8-d565ca9b1d54", + "id": "18669e8b-c80a-455b-9ec0-ed009f74c2b3", "cellValue": "VisibleTab", "linkTarget": "parameter", "linkLabel": "PaaS", "subTarget": "tab6", "preText": "PaaS", "style": "primary" - }, - { - "id": "77abab39-8cba-4e4d-8d8b-cfbd5e19f899", - "cellValue": "VisibleTab", - "linkTarget": "parameter", - "linkLabel": "App delivery", - "subTarget": "tab7", - "preText": "App delivery", - "style": "primary" } ] }, @@ -154,84 +145,22 @@ { "type": 1, "content": { - "json": "## Internet" + "json": "## Hybrid" }, "name": "tab0title" }, { "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." - }, - "name": "querytext16" - }, - { - "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", - "size": 0, - "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": "query16" - }, - { - "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 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": "querytext17" + "name": "querytext4" }, { "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/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", @@ -280,20 +209,20 @@ ] } }, - "name": "query17" + "name": "query4" }, { "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": "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": "querytext18" + "name": "querytext5" }, { "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/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", @@ -342,20 +271,20 @@ ] } }, - "name": "query18" + "name": "query5" }, { "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": "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": "querytext19" + "name": "querytext6" }, { "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/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", @@ -404,20 +333,20 @@ ] } }, - "name": "query19" + "name": "query6" }, { "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": "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": "querytext20" + "name": "querytext7" }, { "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' 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", @@ -466,20 +395,20 @@ ] } }, - "name": "query20" + "name": "query7" }, { "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 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": "querytext21" + "name": "querytext8" }, { "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/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", @@ -528,7 +457,7 @@ ] } }, - "name": "query21" + "name": "query8" } ] }, @@ -548,314 +477,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." - }, - "name": "querytext27" - }, - { - "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", - "size": 0, - "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": "query27" - } - ] - }, - "conditionalVisibility": { - "parameterName": "VisibleTab", - "comparison": "isEqualTo", - "value": "tab1" - }, - "name": "tab1" - }, - { - "type": 12, - "content": { - "version": "NotebookGroup/1.0", - "groupType": "editable", - "items": [ - { - "type": 1, - "content": { - "json": "## IP plan" - }, - "name": "tab2title" - }, - { - "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." - }, - "name": "querytext14" - }, - { - "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", - "size": 0, - "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": "query14" - }, - { - "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." - }, - "name": "querytext15" - }, - { - "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", - "size": 0, - "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": "query15" - } - ] - }, - "conditionalVisibility": { - "parameterName": "VisibleTab", - "comparison": "isEqualTo", - "value": "tab2" - }, - "name": "tab2" - }, - { - "type": 12, - "content": { - "version": "NotebookGroup/1.0", - "groupType": "editable", - "items": [ - { - "type": 1, - "content": { - "json": "## Segmentation" - }, - "name": "tab3title" - }, - { - "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." - }, - "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 == '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", - "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": "query23" - }, - { - "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 Azure Bastion in a subnet /26 or larger. Check [this link](https://learn.microsoft.com/azure/bastion/bastion-faq#subnet) for further information." }, - "name": "querytext24" + "name": "querytext11" }, { "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/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", @@ -904,20 +541,20 @@ ] } }, - "name": "query24" + "name": "query11" }, { "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 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": "querytext25" + "name": "querytext12" }, { "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.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", @@ -966,20 +603,20 @@ ] } }, - "name": "query25" + "name": "query12" }, { "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": "Use Azure Firewall Premium for additional security and protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information." }, - "name": "querytext26" + "name": "querytext13" }, { "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.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", @@ -1023,47 +660,25 @@ "text": "Unknown" } ] - } - } - ] - } - }, - "name": "query26" - } - ] - }, - "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" + "name": "query13" }, { "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": "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": "querytext9" + "name": "querytext14" }, { "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.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", @@ -1112,20 +727,20 @@ ] } }, - "name": "query9" + "name": "query14" }, { "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": "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": "querytext15" }, { "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.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", @@ -1174,20 +789,20 @@ ] } }, - "name": "query10" + "name": "query15" }, { "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": "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": "querytext16" }, { "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/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", @@ -1236,20 +851,42 @@ ] } }, - "name": "query11" + "name": "query16" + } + ] + }, + "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" }, { "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": "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": "querytext12" + "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 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' | 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": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1298,20 +935,20 @@ ] } }, - "name": "query12" + "name": "query0" }, { "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": "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": "querytext13" + "name": "querytext1" }, { "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' | 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": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1360,42 +997,20 @@ ] } }, - "name": "query13" - } - ] - }, - "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" + "name": "query1" }, { "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": "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": "querytext5" + "name": "querytext2" }, { "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/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": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1444,20 +1059,20 @@ ] } }, - "name": "query5" + "name": "query2" }, { "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": "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": "querytext6" + "name": "querytext3" }, { "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' | 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": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1506,20 +1121,42 @@ ] } }, - "name": "query6" + "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" }, { "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": "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": "querytext7" + "name": "querytext22" }, { "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/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", @@ -1568,20 +1205,42 @@ ] } }, - "name": "query7" + "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": "## IP plan" + }, + "name": "tab4title" }, { "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 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": "querytext8" + "name": "querytext9" }, { "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' | 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": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1630,42 +1289,20 @@ ] } }, - "name": "query8" - } - ] - }, - "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": "query9" }, { "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": "querytext22" + "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 = 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": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1714,16 +1351,16 @@ ] } }, - "name": "query22" + "name": "query10" } ] }, "conditionalVisibility": { "parameterName": "VisibleTab", "comparison": "isEqualTo", - "value": "tab6" + "value": "tab4" }, - "name": "tab6" + "name": "tab4" }, { "type": 12, @@ -1734,22 +1371,22 @@ { "type": 1, "content": { - "json": "## App delivery" + "json": "## Segmentation" }, - "name": "tab7title" + "name": "tab5title" }, { "type": 1, "content": { - "json": "Ensure you are using Application Gateway v2 SKU. Check [this link](https://learn.microsoft.com/azure/application-gateway/overview-v2) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) 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": "querytext0" + "name": "querytext18" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/applicationgateways' | project id, compliant = properties.sku.name in ('Standard_v2', 'WAF_v2') | 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 == '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", @@ -1798,20 +1435,20 @@ ] } }, - "name": "query0" + "name": "query18" }, { "type": 1, "content": { - "json": "Ensure you are using the Standard SKU for your Azure Load Balancers. Check [this link](https://learn.microsoft.com/azure/load-balancer/load-balancer-overview) 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": "querytext1" + "name": "querytext19" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard') | 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", @@ -1860,20 +1497,20 @@ ] } }, - "name": "query1" + "name": "query19" }, { "type": 1, "content": { - "json": "Your application gateways should be deployed in subnets with IP prefixes equal or larger than /26. Check [this link](https://learn.microsoft.com/azure/application-gateway/configuration-infrastructure#size-of-the-subnet) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) 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": "querytext2" + "name": "querytext20" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "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 | project id, subnetId = tostring(subnets.id), subnetPrefixLength = split(subnets.properties.addressPrefix, '/')[1]) on subnetId | 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/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", @@ -1922,20 +1559,20 @@ ] } }, - "name": "query2" + "name": "query20" }, { "type": 1, "content": { - "json": "Deploy your WAF profiles for Front Door in 'Prevention' mode. Check [this link](https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-policy-settings) 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": "querytext3" + "name": "querytext21" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "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 | 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", @@ -1984,20 +1621,42 @@ ] } }, - "name": "query3" + "name": "query21" + } + ] + }, + "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" }, { "type": 1, "content": { - "json": "Use Azure NAT Gateway instead of Load Balancer outbound rules for better SNAT scalability. Check [this link](https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity) 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": "querytext4" + "name": "querytext17" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/loadbalancers' | extend countOutRules=array_length(properties.outboundRules) | extend compliant = (countOutRules == 0) | 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": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2046,16 +1705,16 @@ ] } }, - "name": "query4" + "name": "query17" } ] }, "conditionalVisibility": { "parameterName": "VisibleTab", "comparison": "isEqualTo", - "value": "tab7" + "value": "tab6" }, - "name": "tab7" + "name": "tab6" } ], "$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json" diff --git a/workbooks/alz_checklist.en_network_workbook_template.json b/workbooks/alz_checklist.en_network_workbook_template.json index 86f231184..e3d72e0e4 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\": \"42490c02-f8a4-4642-b9da-2517d19d3485\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Internet\",\n \"subTarget\": \"tab0\",\n \"preText\": \"Internet\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"27c6ac13-b5f0-47e3-8998-adf837f0b8e5\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Virtual WAN\",\n \"subTarget\": \"tab1\",\n \"preText\": \"Virtual WAN\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"11ac1f17-1be6-4dc8-a4aa-074bbd85106d\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"IP plan\",\n \"subTarget\": \"tab2\",\n \"preText\": \"IP plan\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"4f2520e0-c6d4-4c36-9a8c-93e231256294\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Segmentation\",\n \"subTarget\": \"tab3\",\n \"preText\": \"Segmentation\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"a7147cc4-8bb6-41f3-a7d3-fb8cf3e1647d\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Hybrid\",\n \"subTarget\": \"tab4\",\n \"preText\": \"Hybrid\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"9350bc51-249a-4163-adad-6922252d22ca\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Hub and spoke\",\n \"subTarget\": \"tab5\",\n \"preText\": \"Hub and spoke\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"7eebae73-c793-4d70-90c8-d565ca9b1d54\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"PaaS\",\n \"subTarget\": \"tab6\",\n \"preText\": \"PaaS\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"77abab39-8cba-4e4d-8d8b-cfbd5e19f899\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"App delivery\",\n \"subTarget\": \"tab7\",\n \"preText\": \"App delivery\",\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\": \"## Internet\"\n },\n \"name\": \"tab0title\"\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\": \"querytext16\"\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\": \"query16\"\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\": \"querytext17\"\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\": \"query17\"\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\": \"querytext18\"\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\": \"query18\"\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\": \"querytext19\"\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\": \"query19\"\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\": \"querytext20\"\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\": \"query20\"\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\": \"querytext21\"\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\": \"query21\"\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\": \"querytext27\"\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\": \"query27\"\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\": \"## IP plan\"\n },\n \"name\": \"tab2title\"\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\": \"querytext14\"\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\": \"query14\"\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\": \"querytext15\"\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\": \"query15\"\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\": \"querytext23\"\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\": \"query23\"\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\": \"querytext24\"\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\": \"query24\"\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\": \"querytext25\"\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\": \"query25\"\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\": \"querytext26\"\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\": \"query26\"\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\": \"querytext9\"\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\": \"query9\"\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\": \"querytext10\"\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\": \"query10\"\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\": \"querytext11\"\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\": \"query11\"\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\": \"querytext12\"\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\": \"query12\"\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\": \"querytext13\"\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\": \"query13\"\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\": \"querytext5\"\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\": \"query5\"\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\": \"querytext6\"\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\": \"query6\"\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\": \"querytext7\"\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\": \"query7\"\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\": \"querytext8\"\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\": \"query8\"\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\": \"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 = 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\": \"query22\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab6\"\n },\n \"name\": \"tab6\"\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\": \"## App delivery\"\n },\n \"name\": \"tab7title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure you are using Application Gateway v2 SKU. Check [this link](https://learn.microsoft.com/azure/application-gateway/overview-v2) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext0\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/applicationgateways' | project id, compliant = properties.sku.name in ('Standard_v2', 'WAF_v2') | 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\": \"query0\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure you are using the Standard SKU for your Azure Load Balancers. Check [this link](https://learn.microsoft.com/azure/load-balancer/load-balancer-overview) 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/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard') | 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\": \"Your application gateways should be deployed in subnets with IP prefixes equal or larger than /26. Check [this link](https://learn.microsoft.com/azure/application-gateway/configuration-infrastructure#size-of-the-subnet) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext2\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"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 | project id, subnetId = tostring(subnets.id), subnetPrefixLength = split(subnets.properties.addressPrefix, '/')[1]) on subnetId | 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\": \"query2\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Deploy your WAF profiles for Front Door in 'Prevention' mode. Check [this link](https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-policy-settings) 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/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 | 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 \"type\": 1,\n \"content\": {\n \"json\": \"Use Azure NAT Gateway instead of Load Balancer outbound rules for better SNAT scalability. Check [this link](https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity) for further information.\"\n },\n \"name\": \"querytext4\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/loadbalancers' | extend countOutRules=array_length(properties.outboundRules) | extend compliant = (countOutRules == 0) | 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\": \"query4\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab7\"\n },\n \"name\": \"tab7\"\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\": \"59912db4-f358-4487-89d9-ce176b890a03\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Hybrid\",\n \"subTarget\": \"tab0\",\n \"preText\": \"Hybrid\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"20345556-90f1-4cd3-bcaa-969a7720384f\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Internet\",\n \"subTarget\": \"tab1\",\n \"preText\": \"Internet\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"d0aebca9-e0fa-4f03-acb0-062fec7aaa07\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Hub and spoke\",\n \"subTarget\": \"tab2\",\n \"preText\": \"Hub and spoke\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"886dffa3-64a6-4d73-9323-1f1dd152fc79\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Virtual WAN\",\n \"subTarget\": \"tab3\",\n \"preText\": \"Virtual WAN\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"ee85a6d2-766b-4169-a45d-1b663086a47c\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"IP plan\",\n \"subTarget\": \"tab4\",\n \"preText\": \"IP plan\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"aafd474e-7f94-4e94-8c13-1881dca97ce9\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Segmentation\",\n \"subTarget\": \"tab5\",\n \"preText\": \"Segmentation\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"18669e8b-c80a-455b-9ec0-ed009f74c2b3\",\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\": 1,\n \"content\": {\n \"json\": \"## Hybrid\"\n },\n \"name\": \"tab0title\"\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 },\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\": \"querytext11\"\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\": \"query11\"\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\": \"querytext12\"\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\": \"query12\"\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\": \"querytext13\"\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\": \"query13\"\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\": \"querytext14\"\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\": \"query14\"\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\": \"querytext15\"\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\": \"query15\"\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\": \"querytext16\"\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\": \"query16\"\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\": 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\": \"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\": \"querytext22\"\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\": \"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\": \"## IP plan\"\n },\n \"name\": \"tab4title\"\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\": \"querytext9\"\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\": \"query9\"\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\": \"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 | 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\": \"query10\"\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\": \"querytext18\"\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\": \"query18\"\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\": \"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 == '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\": \"query19\"\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\": \"querytext20\"\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\": \"query20\"\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\": \"querytext21\"\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\": \"query21\"\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\": \"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 = 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\": \"query17\"\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_workbook.json b/workbooks/alz_checklist.en_workbook.json index 517142ba6..8ed7a9af2 100644 --- a/workbooks/alz_checklist.en_workbook.json +++ b/workbooks/alz_checklist.en_workbook.json @@ -70,7 +70,7 @@ "style": "tabs", "links": [ { - "id": "c8f1fe1a-9886-4c3d-9374-220dc1243572", + "id": "710db2a3-07c5-421a-9cc9-d32a2db2e66a", "cellValue": "VisibleTab", "linkTarget": "parameter", "linkLabel": "Network Topology and Connectivity", @@ -79,7 +79,7 @@ "style": "primary" }, { - "id": "eaac16e3-adf3-42aa-9c93-170d9b64feaa", + "id": "05a319d4-c241-4c55-95c3-8f6bc7db020a", "cellValue": "VisibleTab", "linkTarget": "parameter", "linkLabel": "Security", @@ -88,7 +88,7 @@ "style": "primary" }, { - "id": "76d9ca30-abf4-4298-9585-141d2c0a26fb", + "id": "04b8b1a2-883a-4029-a285-dd6703f93a0a", "cellValue": "VisibleTab", "linkTarget": "parameter", "linkLabel": "Resource Organization", @@ -113,322 +113,12 @@ }, "name": "tab0title" }, - { - "type": 1, - "content": { - "json": "Ensure you are using Application Gateway v2 SKU. Check [this link](https://learn.microsoft.com/azure/application-gateway/overview-v2) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this." - }, - "name": "querytext3" - }, - { - "type": 3, - "content": { - "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/applicationgateways' | project id, compliant = properties.sku.name in ('Standard_v2', 'WAF_v2') | 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", - "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": "query3" - }, - { - "type": 1, - "content": { - "json": "Ensure you are using the Standard SKU for your Azure Load Balancers. Check [this link](https://learn.microsoft.com/azure/load-balancer/load-balancer-overview) for further information." - }, - "name": "querytext4" - }, - { - "type": 3, - "content": { - "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard') | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", - "size": 0, - "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": "query4" - }, - { - "type": 1, - "content": { - "json": "Your application gateways should be deployed in subnets with IP prefixes equal or larger than /26. Check [this link](https://learn.microsoft.com/azure/application-gateway/configuration-infrastructure#size-of-the-subnet) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this." - }, - "name": "querytext5" - }, - { - "type": 3, - "content": { - "version": "KqlItem/1.0", - "query": "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 | project id, subnetId = tostring(subnets.id), subnetPrefixLength = split(subnets.properties.addressPrefix, '/')[1]) on subnetId | 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", - "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": "query5" - }, - { - "type": 1, - "content": { - "json": "Deploy your WAF profiles for Front Door in 'Prevention' mode. Check [this link](https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-policy-settings) for further information." - }, - "name": "querytext6" - }, - { - "type": 3, - "content": { - "version": "KqlItem/1.0", - "query": "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 | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", - "size": 0, - "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": "query6" - }, - { - "type": 1, - "content": { - "json": "Use Azure NAT Gateway instead of Load Balancer outbound rules for better SNAT scalability. Check [this link](https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity) for further information." - }, - "name": "querytext7" - }, - { - "type": 3, - "content": { - "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/loadbalancers' | extend countOutRules=array_length(properties.outboundRules) | extend compliant = (countOutRules == 0) | 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", - "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": "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." }, - "name": "querytext8" + "name": "querytext3" }, { "type": 3, @@ -483,14 +173,14 @@ ] } }, - "name": "query8" + "name": "query3" }, { "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." }, - "name": "querytext9" + "name": "querytext4" }, { "type": 3, @@ -545,14 +235,14 @@ ] } }, - "name": "query9" + "name": "query4" }, { "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." }, - "name": "querytext10" + "name": "querytext5" }, { "type": 3, @@ -607,14 +297,14 @@ ] } }, - "name": "query10" + "name": "query5" }, { "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." }, - "name": "querytext11" + "name": "querytext6" }, { "type": 3, @@ -669,14 +359,14 @@ ] } }, - "name": "query11" + "name": "query6" }, { "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." }, - "name": "querytext12" + "name": "querytext7" }, { "type": 3, @@ -731,14 +421,14 @@ ] } }, - "name": "query12" + "name": "query7" }, { "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." }, - "name": "querytext13" + "name": "querytext8" }, { "type": 3, @@ -793,14 +483,14 @@ ] } }, - "name": "query13" + "name": "query8" }, { "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." }, - "name": "querytext14" + "name": "querytext9" }, { "type": 3, @@ -855,14 +545,14 @@ ] } }, - "name": "query14" + "name": "query9" }, { "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." }, - "name": "querytext15" + "name": "querytext10" }, { "type": 3, @@ -917,14 +607,14 @@ ] } }, - "name": "query15" + "name": "query10" }, { "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": "querytext16" + "name": "querytext11" }, { "type": 3, @@ -979,14 +669,14 @@ ] } }, - "name": "query16" + "name": "query11" }, { "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." }, - "name": "querytext17" + "name": "querytext12" }, { "type": 3, @@ -1041,14 +731,14 @@ ] } }, - "name": "query17" + "name": "query12" }, { "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." }, - "name": "querytext18" + "name": "querytext13" }, { "type": 3, @@ -1103,14 +793,14 @@ ] } }, - "name": "query18" + "name": "query13" }, { "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." }, - "name": "querytext19" + "name": "querytext14" }, { "type": 3, @@ -1165,14 +855,14 @@ ] } }, - "name": "query19" + "name": "query14" }, { "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." }, - "name": "querytext20" + "name": "querytext15" }, { "type": 3, @@ -1227,14 +917,14 @@ ] } }, - "name": "query20" + "name": "query15" }, { "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." }, - "name": "querytext21" + "name": "querytext16" }, { "type": 3, @@ -1289,14 +979,14 @@ ] } }, - "name": "query21" + "name": "query16" }, { "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." }, - "name": "querytext22" + "name": "querytext17" }, { "type": 3, @@ -1351,14 +1041,14 @@ ] } }, - "name": "query22" + "name": "query17" }, { "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." }, - "name": "querytext23" + "name": "querytext18" }, { "type": 3, @@ -1413,14 +1103,14 @@ ] } }, - "name": "query23" + "name": "query18" }, { "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." }, - "name": "querytext24" + "name": "querytext19" }, { "type": 3, @@ -1475,14 +1165,14 @@ ] } }, - "name": "query24" + "name": "query19" }, { "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." }, - "name": "querytext25" + "name": "querytext20" }, { "type": 3, @@ -1537,14 +1227,14 @@ ] } }, - "name": "query25" + "name": "query20" }, { "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." }, - "name": "querytext26" + "name": "querytext21" }, { "type": 3, @@ -1599,14 +1289,14 @@ ] } }, - "name": "query26" + "name": "query21" }, { "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": "querytext27" + "name": "querytext22" }, { "type": 3, @@ -1661,14 +1351,14 @@ ] } }, - "name": "query27" + "name": "query22" }, { "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": "querytext28" + "name": "querytext23" }, { "type": 3, @@ -1723,14 +1413,14 @@ ] } }, - "name": "query28" + "name": "query23" }, { "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": "querytext29" + "name": "querytext24" }, { "type": 3, @@ -1785,14 +1475,14 @@ ] } }, - "name": "query29" + "name": "query24" }, { "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." }, - "name": "querytext30" + "name": "querytext25" }, { "type": 3, @@ -1847,7 +1537,7 @@ ] } }, - "name": "query30" + "name": "query25" } ] }, @@ -1876,7 +1566,7 @@ "content": { "json": "Use different Azure Key Vaults for different applications and regions to avoid transaction scale limits and restrict access to secrets. Check [this link](https://learn.microsoft.com/azure/key-vault/general/overview-throttling) for further information." }, - "name": "querytext31" + "name": "querytext26" }, { "type": 3, @@ -1931,7 +1621,7 @@ ] } }, - "name": "query31" + "name": "query26" } ] }, diff --git a/workbooks/alz_checklist.en_workbook_template.json b/workbooks/alz_checklist.en_workbook_template.json index 44cc11602..aec569cf9 100644 --- a/workbooks/alz_checklist.en_workbook_template.json +++ b/workbooks/alz_checklist.en_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\\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\": \"c8f1fe1a-9886-4c3d-9374-220dc1243572\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Network Topology and Connectivity\",\n \"subTarget\": \"tab0\",\n \"preText\": \"Network Topology and Connectivity\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"eaac16e3-adf3-42aa-9c93-170d9b64feaa\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Security\",\n \"subTarget\": \"tab1\",\n \"preText\": \"Security\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"76d9ca30-abf4-4298-9585-141d2c0a26fb\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Resource Organization\",\n \"subTarget\": \"tab2\",\n \"preText\": \"Resource Organization\",\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\": \"## Network Topology and Connectivity\"\n },\n \"name\": \"tab0title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure you are using Application Gateway v2 SKU. Check [this link](https://learn.microsoft.com/azure/application-gateway/overview-v2) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext3\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/applicationgateways' | project id, compliant = properties.sku.name in ('Standard_v2', 'WAF_v2') | 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\": \"query3\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure you are using the Standard SKU for your Azure Load Balancers. Check [this link](https://learn.microsoft.com/azure/load-balancer/load-balancer-overview) for further information.\"\n },\n \"name\": \"querytext4\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard') | 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\": \"Your application gateways should be deployed in subnets with IP prefixes equal or larger than /26. Check [this link](https://learn.microsoft.com/azure/application-gateway/configuration-infrastructure#size-of-the-subnet) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext5\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"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 | project id, subnetId = tostring(subnets.id), subnetPrefixLength = split(subnets.properties.addressPrefix, '/')[1]) on subnetId | 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\": \"query5\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Deploy your WAF profiles for Front Door in 'Prevention' mode. Check [this link](https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-policy-settings) 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/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 | 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\": \"Use Azure NAT Gateway instead of Load Balancer outbound rules for better SNAT scalability. Check [this link](https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity) for further information.\"\n },\n \"name\": \"querytext7\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/loadbalancers' | extend countOutRules=array_length(properties.outboundRules) | extend compliant = (countOutRules == 0) | 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\": \"query7\"\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\": \"querytext8\"\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\": \"query8\"\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\": \"querytext9\"\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\": \"query9\"\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\": \"querytext10\"\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\": \"query10\"\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\": \"querytext11\"\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\": \"query11\"\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\": \"querytext12\"\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\": \"query12\"\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\": \"querytext13\"\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\": \"query13\"\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\": \"querytext14\"\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\": \"query14\"\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\": \"querytext15\"\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\": \"query15\"\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\": \"querytext16\"\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\": \"query16\"\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\": \"querytext17\"\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\": \"query17\"\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\": \"querytext18\"\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\": \"query18\"\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\": \"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 == '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\": \"query19\"\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\": \"querytext20\"\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\": \"query20\"\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\": \"querytext21\"\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\": \"query21\"\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\": \"querytext22\"\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\": \"query22\"\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\": \"querytext23\"\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\": \"query23\"\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\": \"querytext24\"\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\": \"query24\"\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\": \"querytext25\"\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\": \"query25\"\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\": \"querytext26\"\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\": \"query26\"\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\": \"querytext27\"\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\": \"query27\"\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\": \"querytext28\"\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\": \"query28\"\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\": \"querytext29\"\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\": \"query29\"\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\": \"querytext30\"\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\": \"query30\"\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\": \"## Security\"\n },\n \"name\": \"tab1title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use different Azure Key Vaults for different applications and regions to avoid transaction scale limits and restrict access to secrets. Check [this link](https://learn.microsoft.com/azure/key-vault/general/overview-throttling) for further information.\"\n },\n \"name\": \"querytext31\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"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) | 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\": \"query31\"\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\": \"## Resource Organization\"\n },\n \"name\": \"tab2title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Enforce reasonably flat management group hierarchy with no more than four levels. Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/resource-org-management-groups) for further information.. [This training](https://learn.microsoft.com/learn/modules/azure-architecture-fundamentals/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext0\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resourcecontainers| where type == 'microsoft.resources/subscriptions'| extend ManagementGroup = tostring(tags),mgmtChain = properties.managementGroupAncestorsChain| extend compliant =( array_length(mgmtChain) <= 4 and array_length(mgmtChain) > 1) | 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\": \"Enforce no subscriptions are placed under the root management group. Check [this link](https://learn.microsoft.com/azure/governance/management-groups/how-to/protect-resource-hierarchy#setting---default-management-group) for further information.\"\n },\n \"name\": \"querytext1\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resourcecontainers| where type == 'microsoft.resources/subscriptions'| extend ManagementGroup = tostring(tags),mgmtChain = properties.managementGroupAncestorsChain| extend compliant = (array_length(mgmtChain) > 1) | 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\": \"Ensure tags are used for billing and cost management. Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/track-costs) for further information.. [This training](https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext2\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | extend compliant = isnotnull(['tags']) | project name, id, subscriptionId, resourceGroup, tags, 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 },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab2\"\n },\n \"name\": \"tab2\"\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\\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\": \"710db2a3-07c5-421a-9cc9-d32a2db2e66a\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Network Topology and Connectivity\",\n \"subTarget\": \"tab0\",\n \"preText\": \"Network Topology and Connectivity\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"05a319d4-c241-4c55-95c3-8f6bc7db020a\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Security\",\n \"subTarget\": \"tab1\",\n \"preText\": \"Security\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"04b8b1a2-883a-4029-a285-dd6703f93a0a\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Resource Organization\",\n \"subTarget\": \"tab2\",\n \"preText\": \"Resource Organization\",\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\": \"## Network Topology and Connectivity\"\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\": \"querytext3\"\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\": \"query3\"\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\": \"querytext4\"\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\": \"query4\"\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\": \"querytext5\"\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\": \"query5\"\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\": \"querytext6\"\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\": \"query6\"\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\": \"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 !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\": \"query7\"\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\": \"querytext8\"\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\": \"query8\"\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\": \"querytext9\"\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\": \"query9\"\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\": \"querytext10\"\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\": \"query10\"\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\": \"querytext11\"\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\": \"query11\"\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\": \"querytext12\"\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\": \"query12\"\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\": \"querytext13\"\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\": \"query13\"\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\": \"querytext14\"\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\": \"query14\"\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\": \"querytext15\"\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\": \"query15\"\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\": \"querytext16\"\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\": \"query16\"\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\": \"querytext17\"\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\": \"query17\"\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\": \"querytext18\"\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\": \"query18\"\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\": \"querytext19\"\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\": \"query19\"\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\": \"querytext20\"\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\": \"query20\"\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\": \"querytext21\"\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\": \"query21\"\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\": \"querytext22\"\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\": \"query22\"\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\": \"querytext23\"\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\": \"query23\"\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\": \"querytext24\"\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\": \"query24\"\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\": \"querytext25\"\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\": \"query25\"\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\": \"## Security\"\n },\n \"name\": \"tab1title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use different Azure Key Vaults for different applications and regions to avoid transaction scale limits and restrict access to secrets. Check [this link](https://learn.microsoft.com/azure/key-vault/general/overview-throttling) for further information.\"\n },\n \"name\": \"querytext26\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"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) | 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\": \"query26\"\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\": \"## Resource Organization\"\n },\n \"name\": \"tab2title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Enforce reasonably flat management group hierarchy with no more than four levels. Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/resource-org-management-groups) for further information.. [This training](https://learn.microsoft.com/learn/modules/azure-architecture-fundamentals/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext0\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resourcecontainers| where type == 'microsoft.resources/subscriptions'| extend ManagementGroup = tostring(tags),mgmtChain = properties.managementGroupAncestorsChain| extend compliant =( array_length(mgmtChain) <= 4 and array_length(mgmtChain) > 1) | 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\": \"Enforce no subscriptions are placed under the root management group. Check [this link](https://learn.microsoft.com/azure/governance/management-groups/how-to/protect-resource-hierarchy#setting---default-management-group) for further information.\"\n },\n \"name\": \"querytext1\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resourcecontainers| where type == 'microsoft.resources/subscriptions'| extend ManagementGroup = tostring(tags),mgmtChain = properties.managementGroupAncestorsChain| extend compliant = (array_length(mgmtChain) > 1) | 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\": \"Ensure tags are used for billing and cost management. Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/track-costs) for further information.. [This training](https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext2\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | extend compliant = isnotnull(['tags']) | project name, id, subscriptionId, resourceGroup, tags, 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 },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab2\"\n },\n \"name\": \"tab2\"\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/network_appdelivery_checklist.en_counters_workbook.json b/workbooks/network_appdelivery_checklist.en_counters_workbook.json new file mode 100644 index 000000000..fe6cd99c6 --- /dev/null +++ b/workbooks/network_appdelivery_checklist.en_counters_workbook.json @@ -0,0 +1,716 @@ +{ + "version": "Notebook/1.0", + "items": [ + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "parameters": [ + { + "id": "497a107e-dde8-433e-b263-35ac8e8f7834", + "version": "KqlParameterItem/1.0", + "name": "Subscription", + "type": 6, + "multiSelect": true, + "quote": "'", + "delimiter": ",", + "typeSettings": { + "additionalResourceOptions": [ + "value::all" + ], + "includeAll": true, + "showDefault": false + }, + "timeContext": { + "durationMs": 86400000 + }, + "value": [ + "value::all" + ] + }, + { + "id": "844e4f4e-df51-4e3c-8eaf-0dc78b92c721", + "version": "KqlParameterItem/1.0", + "name": "OnlyFailed", + "label": "Only show failed", + "type": 2, + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "jsonData": "[\r\n { \"value\":true, \"label\":\"True\" },\r\n { \"value\":false, \"label\":\"False\", \"selected\":true }\r\n]" + } + ], + "style": "pills", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "name": "WorkbookSelectors" + }, + { + "type": 1, + "content": { + "json": "If you set \"Only show failed\" to \"Yes\", the different queries will only show items that have failed their compliance checks.", + "style": "info" + }, + "name": "InfoBox" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [ + "value::all" + ], + "parameters": [ + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query0Stats", + "type": 1, + "query": "resources | where type == 'microsoft.network/applicationgateways' | project id, compliant = properties.sku.name in ('Standard_v2', 'WAF_v2') | 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": "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/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard')| 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 + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query2Stats", + "type": 1, + "query": "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 | project id, subnetId = tostring(subnets.id), subnetPrefixLength = split(subnets.properties.addressPrefix, '/')[1]) on subnetId | 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 + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query2FullyCompliant", + "type": 1, + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query2Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 8 + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query3Stats", + "type": 1, + "query": "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| 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": "Query3FullyCompliant", + "type": 1, + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query3Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 8 + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query4Stats", + "type": 1, + "query": "resources | where type=='microsoft.network/loadbalancers' | extend countOutRules=array_length(properties.outboundRules) | extend compliant = (countOutRules == 0) | 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": "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": "Tab0Success", + "type": 1, + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "criteriaData": [ + { + "criteriaContext": { + "operator": "Default", + "resultValType": "expression", + "resultVal": "{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}+{Query4Stats:$.Success}" + } + } + ] + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Tab0Total", + "type": 1, + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "criteriaData": [ + { + "criteriaContext": { + "operator": "Default", + "resultValType": "expression", + "resultVal": "{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}+{Query4Stats:$.Total}" + } + } + ] + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Tab0Percent", + "type": 1, + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "criteriaData": [ + { + "criteriaContext": { + "operator": "Default", + "resultValType": "expression", + "resultVal": "round(100*{Tab0Success}/{Tab0Total})" + } + } + ] + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "WorkbookTotal", + "type": 1, + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "criteriaData": [ + { + "criteriaContext": { + "operator": "Default", + "resultValType": "expression", + "resultVal": "{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}+{Query4Stats:$.Total}" + } + } + ] + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "WorkbookSuccess", + "type": 1, + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "criteriaData": [ + { + "criteriaContext": { + "operator": "Default", + "resultValType": "expression", + "resultVal": "{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}+{Query4Stats:$.Success}" + } + } + ] + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "WorkbookPercent", + "type": 1, + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "criteriaData": [ + { + "criteriaContext": { + "operator": "Default", + "resultValType": "expression", + "resultVal": "round(100*{WorkbookSuccess}/{WorkbookTotal})" + } + } + ] + } + ], + "style": "pills", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + "name": "InvisibleParameters" + }, + { + "type": 1, + "content": { + "json": "## Azure Application Delivery\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)." + }, + "customWidth": "50", + "name": "MarkdownHeader" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"WorkbookPercent\\\": \\\"{WorkbookPercent}\\\", \\\"SubTitle\\\": \\\"Percent of successful checks\\\"}\",\"transformers\":null}", + "size": 4, + "queryType": 8, + "visualization": "tiles", + "tileSettings": { + "titleContent": { + "columnMatch": "WorkbookPercent", + "formatter": 4, + "formatOptions": { + "min": 0, + "max": 100, + "palette": "redGreen" + } + }, + "subtitleContent": { + "columnMatch": "SubTitle", + "formatter": 1 + }, + "showBorder": true + } + }, + "customWidth": "50", + "name": "ProgressTile" + }, + { + "type": 11, + "content": { + "version": "LinkItem/1.0", + "style": "tabs", + "links": [ + { + "id": "66708dfe-a217-4aae-8bf6-1a8930f97868", + "cellValue": "VisibleTab", + "linkTarget": "parameter", + "linkLabel": "Network Topology and Connectivity ({Tab0Success:value}/{Tab0Total:value})", + "subTarget": "tab0", + "preText": "Network Topology and Connectivity", + "style": "primary" + } + ] + }, + "name": "Tabs" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## Network Topology and Connectivity" + }, + "name": "tab0title" + }, + { + "type": 1, + "content": { + "json": "Ensure you are using Application Gateway v2 SKU. Check [this link](https://learn.microsoft.com/azure/application-gateway/overview-v2) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this." + }, + "name": "querytext0" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources | where type == 'microsoft.network/applicationgateways' | project id, compliant = properties.sku.name in ('Standard_v2', 'WAF_v2') | 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", + "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": "query0" + }, + { + "type": 1, + "content": { + "json": "Ensure you are using the Standard SKU for your Azure Load Balancers. Check [this link](https://learn.microsoft.com/azure/load-balancer/load-balancer-overview) for further information." + }, + "name": "querytext1" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources | where type == 'microsoft.network/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard') | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "size": 0, + "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": "query1" + }, + { + "type": 1, + "content": { + "json": "Your application gateways should be deployed in subnets with IP prefixes equal or larger than /26. Check [this link](https://learn.microsoft.com/azure/application-gateway/configuration-infrastructure#size-of-the-subnet) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this." + }, + "name": "querytext2" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "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 | project id, subnetId = tostring(subnets.id), subnetPrefixLength = split(subnets.properties.addressPrefix, '/')[1]) on subnetId | 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", + "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": "query2" + }, + { + "type": 1, + "content": { + "json": "Deploy your WAF profiles for Front Door in 'Prevention' mode. Check [this link](https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-policy-settings) for further information." + }, + "name": "querytext3" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "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 | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "size": 0, + "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": "query3" + }, + { + "type": 1, + "content": { + "json": "Use Azure NAT Gateway instead of Load Balancer outbound rules for better SNAT scalability. Check [this link](https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity) for further information." + }, + "name": "querytext4" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources | where type=='microsoft.network/loadbalancers' | extend countOutRules=array_length(properties.outboundRules) | extend compliant = (countOutRules == 0) | 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", + "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": "query4" + } + ] + }, + "conditionalVisibility": { + "parameterName": "VisibleTab", + "comparison": "isEqualTo", + "value": "tab0" + }, + "name": "tab0" + } + ], + "$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json" +} \ No newline at end of file diff --git a/workbooks/network_appdelivery_checklist.en_counters_workbook_template.json b/workbooks/network_appdelivery_checklist.en_counters_workbook_template.json new file mode 100644 index 000000000..d1b8f192b --- /dev/null +++ b/workbooks/network_appdelivery_checklist.en_counters_workbook_template.json @@ -0,0 +1,57 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "workbookDisplayName": { + "type": "string", + "defaultValue": "Azure Application Delivery", + "metadata": { + "description": "The friendly name for the workbook that is used in the Gallery or Saved List. Needs to be unique in the scope of the resource group and source" + } + }, + "workbookType": { + "type": "string", + "defaultValue": "workbook", + "metadata": { + "description": "The gallery that the workbook will be shown under. Supported values include workbook, `tsg`, Azure Monitor, etc." + } + }, + "workbookSourceId": { + "type": "string", + "defaultValue": "Azure Monitor", + "metadata": { + "description": "The id of resource instance to which the workbook will be associated" + } + }, + "workbookId": { + "type": "string", + "defaultValue": "[newGuid()]", + "metadata": { + "description": "The unique guid for this workbook instance" + } + } + }, + "resources": [ + { + "name": "[parameters('workbookId')]", + "type": "Microsoft.Insights/workbooks", + "location": "[resourceGroup().location]", + "kind": "shared", + "apiVersion": "2018-06-17-preview", + "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/applicationgateways' | project id, compliant = properties.sku.name in ('Standard_v2', 'WAF_v2') | 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\": \"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/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard')| 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/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 | project id, subnetId = tostring(subnets.id), subnetPrefixLength = split(subnets.properties.addressPrefix, '/')[1]) on subnetId | 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\": \"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/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| 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/loadbalancers' | extend countOutRules=array_length(properties.outboundRules) | extend compliant = (countOutRules == 0) | 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\": \"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\": \"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}+{Query4Stats:$.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}+{Query4Stats:$.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\": \"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\": \"{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}+{Query4Stats:$.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\": \"{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}+{Query4Stats:$.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 Application Delivery\\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\": \"66708dfe-a217-4aae-8bf6-1a8930f97868\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Network Topology and Connectivity ({Tab0Success:value}/{Tab0Total:value})\",\n \"subTarget\": \"tab0\",\n \"preText\": \"Network Topology and Connectivity\",\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\": \"## Network Topology and Connectivity\"\n },\n \"name\": \"tab0title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure you are using Application Gateway v2 SKU. Check [this link](https://learn.microsoft.com/azure/application-gateway/overview-v2) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext0\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/applicationgateways' | project id, compliant = properties.sku.name in ('Standard_v2', 'WAF_v2') | 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\": \"query0\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure you are using the Standard SKU for your Azure Load Balancers. Check [this link](https://learn.microsoft.com/azure/load-balancer/load-balancer-overview) 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/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard') | 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\": \"Your application gateways should be deployed in subnets with IP prefixes equal or larger than /26. Check [this link](https://learn.microsoft.com/azure/application-gateway/configuration-infrastructure#size-of-the-subnet) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext2\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"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 | project id, subnetId = tostring(subnets.id), subnetPrefixLength = split(subnets.properties.addressPrefix, '/')[1]) on subnetId | 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\": \"query2\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Deploy your WAF profiles for Front Door in 'Prevention' mode. Check [this link](https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-policy-settings) 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/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 | 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 \"type\": 1,\n \"content\": {\n \"json\": \"Use Azure NAT Gateway instead of Load Balancer outbound rules for better SNAT scalability. Check [this link](https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity) for further information.\"\n },\n \"name\": \"querytext4\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/loadbalancers' | extend countOutRules=array_length(properties.outboundRules) | extend compliant = (countOutRules == 0) | 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\": \"query4\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab0\"\n },\n \"name\": \"tab0\"\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')]" + } + } + ], + "outputs": { + "workbookId": { + "type": "string", + "value": "[resourceId( 'Microsoft.Insights/workbooks', parameters('workbookId'))]" + } + } +} \ No newline at end of file diff --git a/workbooks/network_appdelivery_checklist.en_workbook.json b/workbooks/network_appdelivery_checklist.en_workbook.json new file mode 100644 index 000000000..8a4370b80 --- /dev/null +++ b/workbooks/network_appdelivery_checklist.en_workbook.json @@ -0,0 +1,419 @@ +{ + "version": "Notebook/1.0", + "items": [ + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "parameters": [ + { + "id": "497a107e-dde8-433e-b263-35ac8e8f7834", + "version": "KqlParameterItem/1.0", + "name": "Subscription", + "type": 6, + "multiSelect": true, + "quote": "'", + "delimiter": ",", + "typeSettings": { + "additionalResourceOptions": [ + "value::all" + ], + "includeAll": true, + "showDefault": false + }, + "timeContext": { + "durationMs": 86400000 + }, + "value": [ + "value::all" + ] + }, + { + "id": "844e4f4e-df51-4e3c-8eaf-0dc78b92c721", + "version": "KqlParameterItem/1.0", + "name": "OnlyFailed", + "label": "Only show failed", + "type": 2, + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "jsonData": "[\r\n { \"value\":true, \"label\":\"True\" },\r\n { \"value\":false, \"label\":\"False\", \"selected\":true }\r\n]" + } + ], + "style": "pills", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "name": "WorkbookSelectors" + }, + { + "type": 1, + "content": { + "json": "If you set \"Only show failed\" to \"Yes\", the different queries will only show items that have failed their compliance checks.", + "style": "info" + }, + "name": "InfoBox" + }, + { + "type": 1, + "content": { + "json": "## Azure Application Delivery\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)." + }, + "customWidth": "100", + "name": "MarkdownHeader" + }, + { + "type": 11, + "content": { + "version": "LinkItem/1.0", + "style": "tabs", + "links": [ + { + "id": "f02409dd-c037-45ec-b7f6-3b4a90c6bf6f", + "cellValue": "VisibleTab", + "linkTarget": "parameter", + "linkLabel": "Network Topology and Connectivity", + "subTarget": "tab0", + "preText": "Network Topology and Connectivity", + "style": "primary" + } + ] + }, + "name": "Tabs" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## Network Topology and Connectivity" + }, + "name": "tab0title" + }, + { + "type": 1, + "content": { + "json": "Ensure you are using Application Gateway v2 SKU. Check [this link](https://learn.microsoft.com/azure/application-gateway/overview-v2) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this." + }, + "name": "querytext0" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources | where type == 'microsoft.network/applicationgateways' | project id, compliant = properties.sku.name in ('Standard_v2', 'WAF_v2') | 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", + "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": "query0" + }, + { + "type": 1, + "content": { + "json": "Ensure you are using the Standard SKU for your Azure Load Balancers. Check [this link](https://learn.microsoft.com/azure/load-balancer/load-balancer-overview) for further information." + }, + "name": "querytext1" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources | where type == 'microsoft.network/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard') | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "size": 0, + "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": "query1" + }, + { + "type": 1, + "content": { + "json": "Your application gateways should be deployed in subnets with IP prefixes equal or larger than /26. Check [this link](https://learn.microsoft.com/azure/application-gateway/configuration-infrastructure#size-of-the-subnet) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this." + }, + "name": "querytext2" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "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 | project id, subnetId = tostring(subnets.id), subnetPrefixLength = split(subnets.properties.addressPrefix, '/')[1]) on subnetId | 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", + "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": "query2" + }, + { + "type": 1, + "content": { + "json": "Deploy your WAF profiles for Front Door in 'Prevention' mode. Check [this link](https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-policy-settings) for further information." + }, + "name": "querytext3" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "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 | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "size": 0, + "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": "query3" + }, + { + "type": 1, + "content": { + "json": "Use Azure NAT Gateway instead of Load Balancer outbound rules for better SNAT scalability. Check [this link](https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity) for further information." + }, + "name": "querytext4" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources | where type=='microsoft.network/loadbalancers' | extend countOutRules=array_length(properties.outboundRules) | extend compliant = (countOutRules == 0) | 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", + "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": "query4" + } + ] + }, + "conditionalVisibility": { + "parameterName": "VisibleTab", + "comparison": "isEqualTo", + "value": "tab0" + }, + "name": "tab0" + } + ], + "$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json" +} \ No newline at end of file diff --git a/workbooks/network_appdelivery_checklist.en_workbook_template.json b/workbooks/network_appdelivery_checklist.en_workbook_template.json new file mode 100644 index 000000000..ea8d5ecff --- /dev/null +++ b/workbooks/network_appdelivery_checklist.en_workbook_template.json @@ -0,0 +1,57 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "workbookDisplayName": { + "type": "string", + "defaultValue": "Azure Application Delivery", + "metadata": { + "description": "The friendly name for the workbook that is used in the Gallery or Saved List. Needs to be unique in the scope of the resource group and source" + } + }, + "workbookType": { + "type": "string", + "defaultValue": "workbook", + "metadata": { + "description": "The gallery that the workbook will be shown under. Supported values include workbook, `tsg`, Azure Monitor, etc." + } + }, + "workbookSourceId": { + "type": "string", + "defaultValue": "Azure Monitor", + "metadata": { + "description": "The id of resource instance to which the workbook will be associated" + } + }, + "workbookId": { + "type": "string", + "defaultValue": "[newGuid()]", + "metadata": { + "description": "The unique guid for this workbook instance" + } + } + }, + "resources": [ + { + "name": "[parameters('workbookId')]", + "type": "Microsoft.Insights/workbooks", + "location": "[resourceGroup().location]", + "kind": "shared", + "apiVersion": "2018-06-17-preview", + "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 Application Delivery\\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\": \"f02409dd-c037-45ec-b7f6-3b4a90c6bf6f\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Network Topology and Connectivity\",\n \"subTarget\": \"tab0\",\n \"preText\": \"Network Topology and Connectivity\",\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\": \"## Network Topology and Connectivity\"\n },\n \"name\": \"tab0title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure you are using Application Gateway v2 SKU. Check [this link](https://learn.microsoft.com/azure/application-gateway/overview-v2) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext0\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/applicationgateways' | project id, compliant = properties.sku.name in ('Standard_v2', 'WAF_v2') | 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\": \"query0\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure you are using the Standard SKU for your Azure Load Balancers. Check [this link](https://learn.microsoft.com/azure/load-balancer/load-balancer-overview) 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/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard') | 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\": \"Your application gateways should be deployed in subnets with IP prefixes equal or larger than /26. Check [this link](https://learn.microsoft.com/azure/application-gateway/configuration-infrastructure#size-of-the-subnet) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext2\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"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 | project id, subnetId = tostring(subnets.id), subnetPrefixLength = split(subnets.properties.addressPrefix, '/')[1]) on subnetId | 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\": \"query2\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Deploy your WAF profiles for Front Door in 'Prevention' mode. Check [this link](https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-policy-settings) 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/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 | 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 \"type\": 1,\n \"content\": {\n \"json\": \"Use Azure NAT Gateway instead of Load Balancer outbound rules for better SNAT scalability. Check [this link](https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity) for further information.\"\n },\n \"name\": \"querytext4\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/loadbalancers' | extend countOutRules=array_length(properties.outboundRules) | extend compliant = (countOutRules == 0) | 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\": \"query4\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab0\"\n },\n \"name\": \"tab0\"\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')]" + } + } + ], + "outputs": { + "workbookId": { + "type": "string", + "value": "[resourceId( 'Microsoft.Insights/workbooks', parameters('workbookId'))]" + } + } +} \ No newline at end of file